feat: fetch a job's execution log on demand with get_logs() - #122
Draft
guill wants to merge 1 commit into
Draft
Conversation
`Job.get_logs()` / `AsyncJob.get_logs()` return what a run printed as a `JobLogs` (`text`, `truncated`, `captured_at`, `complete`), or `None`. The log is a resource of its own rather than a field on the job, so submitting and polling never download one — `run()` to terminal issues zero log requests, and a caller pays only when it asks. Nothing is cached, so an early `None` on a job that has not finished cannot mask the log it goes on to produce; read again after a terminal status. `None` is an ordinary answer, not an error, covering every reason there is nothing to read — the contract deliberately does not distinguish them. A surface that captures no logs omits `urls.logs` entirely, and the SDK answers from its absence without a request rather than building the path itself, which would 404 as though the job were missing. Spec synced from the canonical contract and models regenerated.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueComment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
Job.get_logs()andAsyncJob.get_logs(), which fetch what a run printed and return aJobLogs(text,truncated,captured_at,complete) orNone.The log is a resource of its own rather than a field on the job, so submitting and polling never download one —
run()to terminal issues zero log requests, and a caller pays only when it asks. Nothing is cached, so an earlyNoneon a job that has not finished cannot mask the log it goes on to produce; read again after a terminal status.Noneis an ordinary answer, not an error. It covers every reason there is nothing to read — the deployment captures no logs at all, the job has not finished, it predates capture, the run was killed before the worker could report an outcome, capture failed, or the log is withheld from anonymous callers — and the API deliberately does not distinguish them.A surface that captures no logs omits
urls.logsentirely. The SDK answers from that absence without a request, rather than building the path itself, which would 404 as though the job were missing.Consumer impact
Purely additive. Nothing is removed or narrowed, and existing code keeps working:
Job.get_logs(),AsyncJob.get_logs(),ComfyLow.get_job_logs(),AsyncComfyLow.get_job_logs(), and the exportedJobLogsmodel.JobUrls.logs, optional — a server that does not send it still validates.Output.node_idgained a description in the generated model. Documentation only; its type and requiredness are unchanged.The vendored spec is synced from the canonical contract and the models regenerated.
Testing
pytest— 731 passed, 4 skipped. New behavioural coverage: 200 yields a typed value, 204 yieldsNone, three calls make three requests,run()to terminal issues none, a missingurls.logsshort-circuits without a request, an emptyurls.logsis treated the same way, and the SDK follows the link rather than rebuilding the path.ruff check,ruff format --check,mypy src— clean.scripts/check_drift.py— models in sync with the vendored spec.scripts/check_public_repo_hygiene.py— clean.Also verified end to end by driving the real SDK against a live HTTP server, not only the test doubles.
Opened as a draft: the server side of this contract is not released yet.