Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: Bug report
about: Create a bug report to help us improve.
title: ""
labels: bug
assignees: ""
---

**Describe the bug**
A clear and concise description of what the bug is.

**SDK version**
Output of `pip show comfy-sdk` (or `python -c "import comfy_sdk; print(comfy_sdk.__version__)"`).

**Python version**
Output of `python --version`.

**Which deployment**
Comfy Cloud / serverless / self-hosted (behind [comfy-api-proxy](https://github.com/Comfy-Org/comfy-api-proxy)) — and the proxy version if self-hosted.

**Minimal reproduction**
The smallest snippet that reproduces it. Please redact your API key.

```python
from comfy_sdk import Comfy

client = Comfy(api_key="comfyui-...")
# ...
```

**Expected behavior**
A clear and concise description of what you expected to happen.

**Actual behavior**
What happened instead, including the full traceback if there is one.

```
paste traceback here
```

**Nice to have**

- [ ] Terminal output
- [ ] The workflow JSON (or a trimmed version of it)
- [ ] Screenshots

**Additional context**
Add any other context about the problem here.
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: Feature request
about: Submit a feature request for this repo.
title: ""
labels: enhancement
assignees: ""
---

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**What are you trying to do?**
The use case behind the request — what you are building, and what is awkward or
impossible today.

**Proposed API**
If you have a shape in mind, sketch it.

```python
from comfy_sdk import Comfy

client = Comfy(api_key="comfyui-...")
# ...
```

**Which deployment does this matter for**
Comfy Cloud / serverless / self-hosted — or all of them.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've
considered, including whether `comfy_low` (the lower-level protocol layer this
SDK is built on) already covers it.

**Additional context**
Add any other context or screenshots about the feature request here.
53 changes: 53 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: 2
updates:
# Python dependencies declared in pyproject.toml (runtime deps plus the
# pil/codegen/dev extras). "pip" is Dependabot's ecosystem name for the
# PEP 621 project table; it reads pyproject.toml, not requirements.txt.
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
commit-message:
prefix: "chore"
include: "scope"
labels:
- "dependencies"
groups:
# One PR for the low-risk bumps, so routine patch churn does not eat
# the PR limit and hide a major that actually needs review.
python-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
ignore:
# Pinned on purpose: the codegen-drift CI job diffs the generated models
# byte-for-byte, so a generator bump reformats the output and fails the
# gate until src/comfy_low/models/_generated.py is regenerated in the
# same commit. Majors still come through for a deliberate upgrade.
- dependency-name: "datamodel-code-generator"
update-types:
- "version-update:semver-minor"
- "version-update:semver-patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
commit-message:
prefix: "ci"
labels:
- "dependencies"
- "github-actions"
groups:
actions-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
165 changes: 165 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Changelog

All notable changes to `comfy-sdk` are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Entries for `v0.1.0` through `v0.1.8` were reconstructed from the published
[GitHub Releases](https://github.com/Comfy-Org/comfy-python-sdk/releases); those
release notes remain the fuller account, including the end-to-end verification
notes for each version.

## [Unreleased]

_Nothing yet — add an entry here when your change lands._

## [0.1.8] - 2026-08-13

### Added

- `Job.get_workflow()` / `AsyncJob.get_workflow()` — fetch the workflow behind a
job, including one rehydrated by id. Returns the graph and a `format`
discriminator: `save` (the authoring workflow at the version the job ran, with
canvas layout and editor-only nodes intact) or `api` (the executed API-format
graph). Jobs submitted through this SDK always get `api` today.
- Asset deletion — `Asset.delete()` and `assets.delete(id)`. Thanks to
[@jab416171](https://github.com/jab416171) for the implementation. Requires
backend support: Comfy Cloud has it; self-hosted needs a `comfy-api-proxy` new
enough to serve `DELETE /api/v2/assets/{id}`, older proxies return
`405 Method Not Allowed`.
- `job_id` on outputs and assets, so you can get from an output file back to the
job that produced it without a side table. Absent for uploaded assets, which
have no producing job.
- `expires_at` on assets.

### Fixed

- `job_id` and `expires_at` were present on the wire but not exposed by the
public wrapper classes, so they were unreachable without touching a private
attribute.

## [0.1.7] - 2026-08-12

There is no 0.1.6 on PyPI — that number was consumed by a release-pipeline
failure and never published.

### Changed

- **Breaking:** the base URL moves from a constructor argument to the
`COMFY_BASE_URL` environment variable. `Comfy()` / `AsyncComfy()` target Comfy
Cloud by default; point the client at another deployment by setting
`COMFY_BASE_URL`. The variable is read on each construction (not at import),
must be an `http(s)` URL, and unset-or-blank means Comfy Cloud.
- **Breaking:** `api_key` is keyword-only, so the old positional form raises
`TypeError` rather than quietly reading a URL as a key.
- `comfy_low`, the documented escape hatch the clients are built on, still takes
a base URL directly and is unchanged.

## [0.1.5] - 2026-07-30

Maintenance release. No API changes — existing code needs no updates.

### Fixed

- Ship `py.typed` (PEP 561), so type checkers in consuming projects actually see
the SDK's type information. Previously the annotations were shipped but ignored.
- Derive `__version__` from installed distribution metadata instead of a
hardcoded string, so it can no longer drift from the released version.

### Changed

- Ship an MIT license (the package previously declared none) and fill in the
empty package metadata.
- Stop sweeping local dev droppings into the sdist — it now contains only what is
needed to build and run the tests.
- The repository moved from `Comfy-Org/ComfyPythonSDK` to
`Comfy-Org/comfy-python-sdk`. GitHub redirects the old URLs and the PyPI
package name is unchanged (`comfy-sdk`). This is the first release to carry
the corrected repository/issues URLs in its published metadata.
- Docstrings for the public methods that had none; README aligned with the
TypeScript and Swift SDK READMEs.

## [0.1.4] - 2026-07-28

Comfy Cloud now serves the v2 API on `cloud.comfy.org`. `api.comfy.org`
continues to serve the node registry.

### Changed

- **Breaking:** `api.comfy.org/api/v2/*` no longer responds. If you pass that
host explicitly, requests 404 until you update.
- `base_url` now defaults to `https://cloud.comfy.org`, so `Comfy(api_key=...)`
targets Comfy Cloud with no host argument. `COMFY_CLOUD_BASE_URL` is exported
for callers who want the value.
- Spec server URL, README, and docstrings updated to the new host.
- Passing an explicit `base_url` still wins — self-hosted and serverless callers
are unaffected.

## [0.1.3] - 2026-07-27

### Fixed

- Serverless gateway: follow-up links no longer 404 after submit. A gateway
serving the v2 API under a mount prefix (e.g. `/deployment/{id}/api/v2`)
returns `job.urls.*` links that already include that prefix; resolving them
against a `base_url` carrying the same prefix doubled it, so the first
`Job.refresh()` after a successful submit raised `NotFound`. Server-returned
links (leading slash, containing `/api/`) now resolve against the origin —
the link is authoritative about its own path. Internal shorthand paths still
resolve under `base_url`; Comfy Cloud and self-hosted behavior is unchanged.

### Added

- An env-gated live integration suite (`tests/integration/test_gateway_e2e.py`)
covering upload → blake3 dedup fast path → img2img submit → poll → output
download against a real gateway. Skipped unless `COMFY_BASE_URL` /
`COMFY_API_KEY` are set.

## [0.1.2] - 2026-07-23

### Added

- `Output.get_download_url()` — get a fetchable URL for an output instead of
streaming the bytes through your process. On Comfy Cloud / serverless it is a
short-lived, self-authorizing signed storage URL (with `expires_at`); on a
self-hosted proxy it is the content endpoint (`expires_at=None`). Available on
both `Output` and `AsyncOutput`.
- The client now identifies itself via a `User-Agent` header; pass `client_info=`
to attribute your own integration's traffic.

### Fixed

- SSE: a read-idle timeout, so a stalled stream can no longer hang `events()`.
- Map entity-specific 404s (`job_not_found` / `asset_not_found`) to `NotFound`.

## [0.1.1] - 2026-07-21

### Added

- Optional `api_key=` parameter on `submit()` / `run()` (sync and async) that
authenticates partner (API) nodes in a workflow, sent as
`extra_data.api_key_comfy_org`. Omit it (or pass `""`) and no `extra_data` is
sent. The key is never logged or persisted and does not participate in
idempotency.

## [0.1.0] - 2026-07-21

First public release of the Comfy API v2 Python SDK (`comfy-sdk`).

### Added

- Run ComfyUI workflows across self-hosted, Comfy Cloud, and serverless from one
typed client: upload/dedup inputs, submit a workflow, follow it (poll or SSE),
and download outputs.
- Sync and async clients. Python 3.10+.

[unreleased]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.8...HEAD
[0.1.8]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.7...v0.1.8
[0.1.7]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.5...v0.1.7
[0.1.5]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.4...v0.1.5
[0.1.4]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/Comfy-Org/comfy-python-sdk/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/Comfy-Org/comfy-python-sdk/releases/tag/v0.1.0
Loading
Loading