Add deploy environment header (Comfy-Env) to partner node API calls#13425
Add deploy environment header (Comfy-Env) to partner node API calls#13425Kosinkadink merged 13 commits intomasterfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@comfy_api_nodes/util/client.py`:
- Around line 620-623: The X-Comfy-Env header is only being set inside the
"relative URL" branch, so absolute requests to the Comfy API host miss it;
update the logic so payload_headers["X-Comfy-Env"] is added whenever the request
targets the Comfy API host (either parsed_url has no scheme/netloc or
parsed_url.netloc matches cfg.endpoint.host or cfg.endpoint.netloc), not only
for relative URLs. Keep the existing get_auth_header(cfg.node_cls) behavior for
relative URLs but move or add the X-Comfy-Env assignment to run for both the
relative-URL branch and for absolute URLs whose netloc equals the configured
Comfy API endpoint (use parsed_url, payload_headers, cfg.endpoint to
locate/compare).
In `@comfy/deploy_environment.py`:
- Around line 21-25: The code reads env_file and caches its raw contents into
_cached_value which can contain newlines or control characters that will break
the X-Comfy-Env HTTP header; inside the with open(...) block (where env_file,
value and _cached_value are used) sanitize the value before caching by taking
only the first line (value.splitlines()[0] if any) and stripping it, then remove
any control/non-ASCII or non-printable characters (e.g. filter out chars with
ord() < 32 or ==127) so the resulting string is header-safe, and assign that
sanitized string to _cached_value before returning.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8f031b8d-8871-468e-a44f-985ac78a0163
📒 Files selected for processing (3)
.gitignorecomfy/deploy_environment.pycomfy_api_nodes/util/client.py
4de0e4e to
d443728
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
comfy_api_nodes/util/client.py (1)
620-623:⚠️ Potential issue | 🟠 Major
X-Comfy-Envis still not applied to absolute Comfy API URLs.At Line 620, the header is gated by the relative-URL check, so absolute URLs targeting the same API host won’t include
X-Comfy-Env. That leaves environment signaling incomplete versus the PR goal.Suggested fix
- if not parsed_url.scheme and not parsed_url.netloc: # is URL relative? - payload_headers.update(get_auth_header(cfg.node_cls)) - payload_headers["X-Comfy-Env"] = get_deploy_environment() + is_relative = not parsed_url.scheme and not parsed_url.netloc + if is_relative: # relative URL uses default API host and auth + payload_headers.update(get_auth_header(cfg.node_cls)) + + base_netloc = urlparse(default_base_url()).netloc.lower() + target_netloc = parsed_url.netloc.lower() if parsed_url.netloc else base_netloc + if target_netloc == base_netloc: + payload_headers["X-Comfy-Env"] = get_deploy_environment()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@comfy_api_nodes/util/client.py` around lines 620 - 623, The X-Comfy-Env header is only added for relative URLs (parsed_url.scheme/netloc empty); change the condition so X-Comfy-Env is also applied when the request targets the Comfy API host even if an absolute URL is used: update the branch that sets payload_headers (where parsed_url, payload_headers, get_auth_header(cfg.node_cls) and get_deploy_environment() are used) to add X-Comfy-Env when parsed_url.netloc is empty OR parsed_url.netloc equals the Comfy API host (compare parsed_url.netloc against the configured base/API host from cfg, e.g. urlparse(cfg.base_url or cfg.api_url).netloc), leaving other header logic (cfg.endpoint.headers) intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@comfy_api_nodes/util/client.py`:
- Around line 620-623: The X-Comfy-Env header is only added for relative URLs
(parsed_url.scheme/netloc empty); change the condition so X-Comfy-Env is also
applied when the request targets the Comfy API host even if an absolute URL is
used: update the branch that sets payload_headers (where parsed_url,
payload_headers, get_auth_header(cfg.node_cls) and get_deploy_environment() are
used) to add X-Comfy-Env when parsed_url.netloc is empty OR parsed_url.netloc
equals the Comfy API host (compare parsed_url.netloc against the configured
base/API host from cfg, e.g. urlparse(cfg.base_url or cfg.api_url).netloc),
leaving other header logic (cfg.endpoint.headers) intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 20aaffab-13c7-4d73-99e7-67dbe3edda7b
📒 Files selected for processing (3)
.gitignorecomfy/deploy_environment.pycomfy_api_nodes/util/client.py
✅ Files skipped from review due to trivial changes (1)
- .gitignore
🚧 Files skipped from review as they are similar to previous changes (1)
- comfy/deploy_environment.py
Read a .comfy_environment file from the ComfyUI base directory to determine the deployment environment (e.g. standalone, portable, desktop). Defaults to 'local_git' when the file is absent. The value is sent as an X-Comfy-Deploy-Env header on all requests to api.comfy.org, allowing the API to differentiate between environment types. The .comfy_environment file is gitignored so launchers/installers can write it without affecting the repository. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d939e-6b4d-738b-8d1a-ac7cbf6736a4
d443728 to
e7fbb3c
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@comfy/deploy_environment.py`:
- Around line 14-33: get_deploy_environment currently lazily sets the
module-level _cached_value without any synchronization, so concurrent callers
can race and a temporary read failure can permanently pin _DEFAULT_DEPLOY_ENV;
fix by introducing a module-level lock (e.g., threading.Lock) and surround the
check/read/set of _cached_value with the lock (use double-checked locking: check
_cached_value before acquiring and re-check after acquiring) so only one thread
performs the file open/read logic for _ENV_FILENAME and sets _cached_value
(falling back to _DEFAULT_DEPLOY_ENV on error) while keeping logger warning
behavior intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e3340ae7-563e-4db0-a340-61b02aa19c8d
📒 Files selected for processing (3)
.gitignorecomfy/deploy_environment.pycomfy_api_nodes/util/client.py
✅ Files skipped from review due to trivial changes (1)
- .gitignore
🚧 Files skipped from review as they are similar to previous changes (1)
- comfy_api_nodes/util/client.py
…stallations Write a .comfy_environment file containing 'local-launcher' in the ComfyUI base directory for standalone installations. This file is read by ComfyUI (Comfy-Org/ComfyUI#13425) and sent as an X-Comfy-Env header on API requests to api.comfy.org, allowing the API to differentiate launcher-managed installations from vanilla git clones. The file is written in three places: - postInstall: after fresh standalone install completes - fixupCopy: when duplicating an existing standalone installation - handleLaunch: on every standalone launch (ensures the file survives accidental deletion or git clean) Closes #425 Amp-Thread-ID: https://ampcode.com/threads/T-019da8c0-98de-726c-ae34-7558a9cb1e3c Co-authored-by: Amp <amp@ampcode.com>
…stallations Write a .comfy_environment file containing 'local-launcher' in the ComfyUI base directory for standalone installations. This file is read by ComfyUI (Comfy-Org/ComfyUI#13425) and sent as an X-Comfy-Env header on API requests to api.comfy.org, allowing the API to differentiate launcher-managed installations from vanilla git clones. The file is written in three places: - postInstall: after fresh standalone install completes - fixupCopy: when duplicating an existing standalone installation - handleLaunch: on every standalone launch (ensures the file survives accidental deletion or git clean) Closes #425 Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019da8c0-98de-726c-ae34-7558a9cb1e3c
Amp-Thread-ID: https://ampcode.com/threads/T-019db205-95da-7654-ace4-40f12a5f6e69 Co-authored-by: Amp <amp@ampcode.com>
…andalone installations (#428) * Write .comfy_environment file with 'local-launcher' for standalone installations Write a .comfy_environment file containing 'local-launcher' in the ComfyUI base directory for standalone installations. This file is read by ComfyUI (Comfy-Org/ComfyUI#13425) and sent as an X-Comfy-Env header on API requests to api.comfy.org, allowing the API to differentiate launcher-managed installations from vanilla git clones. The file is written in three places: - postInstall: after fresh standalone install completes - fixupCopy: when duplicating an existing standalone installation - handleLaunch: on every standalone launch (ensures the file survives accidental deletion or git clean) Closes #425 Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019da8c0-98de-726c-ae34-7558a9cb1e3c * writeComfyEnvironment: idempotent, dir-existence check, tests, snake_case value Code-review fixes for #428: - Rename marker value from 'local-launcher' to 'local_launcher' to match the underscore convention used by ComfyUI's default 'local_git' value. - Skip the write when ComfyUI/ does not yet exist (avoids ENOENT log spam). - Read-before-write: short-circuit when the file already has the expected content, so handleLaunch's per-launch call no longer churns mtime or causes redundant disk I/O. - Add unit tests covering write, idempotency, mismatch rewrite, missing dir, and write-failure swallowing. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com> * Rename marker value to 'local_desktop2_standalone' More descriptive than 'local_launcher': identifies it as the standalone-source environment under Desktop 2.0 specifically, leaving room for future Desktop 2.0 environment variants (e.g. local_desktop2_portable, local_desktop2_git). Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
Defense-in-depth: cap readline() so a malformed or maliciously-large single-line file cannot blow up memory before the value is sanitized. Adds tests-unit/deploy_environment_test.py covering: missing file fallback, basic read, whitespace strip, multi-line (only first line used), empty + whitespace-only files, control-char stripping (header-injection protection), non-ASCII stripping, 128-byte read cap, cache stickiness, and OSError fallback. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com>
Replaces the hand-rolled '_cached_value' module global with @functools.cache, which is the standard Python idiom for memoization. Tests now use the built-in get_deploy_environment.cache_clear() to reset between cases. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com>
Default value is now 'local-git' (was 'local_git'). Dashes are easier to type and more conventional in HTTP-header-adjacent identifiers. Tests updated accordingly. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com>
folder_paths.base_path is overridden by --base-directory to a user-supplied location. Launchers/installers write the .comfy_environment marker next to the ComfyUI install itself, so reading from base_path would silently fall back to 'local-git' whenever --base-directory is in use, defeating the purpose of the env header. Amp-Thread-ID: https://ampcode.com/threads/T-019df554-0cf8-755a-9f84-674e974aa5d1 Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019df554-0cf8-755a-9f84-674e974aa5d1 Co-authored-by: Amp <amp@ampcode.com>
guill
left a comment
There was a problem hiding this comment.
One suggestion for a test to add, but no requests on actual functionality.
We should make sure this actually fulfills whatever purpose we're hoping to use it for. (E.g. if the goal is to see what percentage of Partner Node requests come from Desktop vs. git installs, we should make sure this header isn't going to get stripped by GCP ingest before it gets to us.)
Per @guill review on PR #13425: add tests covering Windows-style line endings, since editors often save files with CRLF and we want to confirm the CR never leaks into the returned value. - `_write_env_file` now opens with `newline=""` so the on-disk bytes match the literal string passed in (deterministic across host OSes, no `\n` -> `\r\n` translation on Windows). New tests: - `test_crlf_line_ending`: `"...\r\n"` -> value (no trailing CR). - `test_crlf_multiline_only_first_line_used`: `readline(128)` stops at the translated newline boundary for CRLF lines. - `test_crlf_with_surrounding_whitespace`: leading/trailing spaces + CRLF still yield the bare value. - `test_lone_cr_line_ending`: classic-Mac / legacy editor `"...\r"` is also handled by universal-newlines decoding. 15/15 unit tests pass. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019df5a8-36be-7107-a4af-c7e4f51687df
…#462) 'local_desktop2_standalone' -> 'local-desktop2-standalone'. Pairs with the same convention shift on the ComfyUI side (Comfy-Org/ComfyUI#13425). Dashes are easier to type and more conventional in HTTP-header-adjacent identifiers. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com>
…471) * Switch .comfy_environment value convention from underscores to dashes (#462) 'local_desktop2_standalone' -> 'local-desktop2-standalone'. Pairs with the same convention shift on the ComfyUI side (Comfy-Org/ComfyUI#13425). Dashes are easier to type and more conventional in HTTP-header-adjacent identifiers. Amp-Thread-ID: https://ampcode.com/threads/T-019df26e-96f4-7518-94da-0e4263680e3c Co-authored-by: Amp <amp@ampcode.com> * chore(branding): refresh app icons to match new rounded-square logo Replace the old standalone-glyph ComfyUI logo with the new rounded- square brand icon (charcoal background + yellow C glyph) so the app/dock/tray/installer all use the same identity that the NSIS installer wizard already adopted. - Replace assets/Comfy_Logo_x32.png, x256.png, x512.png with new versions; add x64 and x1024 sizes. - Replace resources/icon.png (electron-builder generic fallback, byte-identical duplicate of x256) with the new x256. - electron-builder.yml: bump mac.icon source from x512 to x1024 so the generated .icns fills the 512@2x = 1024 slot crisply on Retina. - electron-builder.yml: bump linux.icon source from x256 to x512 for sharper desktop entries / app menus on HiDPI Linux. - src/main/index.ts: bump TRAY_ICON from x32 to x64 so Electron has a high-DPI source to downsample for the system tray. The win.icon source stays at x256 (electron-builder's documented minimum) — NSIS wraps it through the existing installerIcon.ico. Amp-Thread-ID: https://ampcode.com/threads/T-019df5fe-9641-702c-8f8f-c01242315676 Co-authored-by: Amp <amp@ampcode.com> * chore(branding): mirror icon-source bumps in todesktop.json Amp-Thread-ID: https://ampcode.com/threads/T-019df5fe-9641-702c-8f8f-c01242315676 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
Summary
Adds a
Comfy-Envheader to API requests sent toapi.comfy.org, allowing the API to differentiate between environment types (e.g.local-git,local-desktop2-standalone).Relates to Comfy-Org/ComfyUI-Desktop-2.0-Beta#416, paired with Comfy-Org/ComfyUI-Desktop-2.0-Beta#428.
How it works
comfy/deploy_environment.pyreads a.comfy_environmentfile from the ComfyUI install directory (resolved from this module's own path so--base-directorycannot redirect the lookup).32 <= ord(c) < 127) - this both sanitizes the value and prevents header-injection / CRLF-smuggling attacks.local-git.@functools.cache(one read per process; tests usecache_clear()for isolation).Comfy-Envheader on relative-URL requests incomfy_api_nodes/util/client.py- the relative-URL gate ensures the header is only attached toapi.comfy.orgcalls, never to third-party endpoints reached via custom hostnames..comfy_environmentfile is gitignored so launchers/installers can write it without affecting the repository.Naming convention
Values use dashes (
local-git,local-desktop2-standalone) rather than underscores - easier to type and more conventional for HTTP-header-adjacent identifiers.Usage
Launchers or installers write a
.comfy_environmentfile in the ComfyUI install directory with the desired value:local-desktop2-standaloneNo CLI args or environment variables needed. Git clone users get
local-gitautomatically.Tests
New
tests-unit/deploy_environment_test.pycovers:local-gitOSErrorduring read falls back to default11 tests, all passing locally.
Manual verification
Deployed PR via
comfy-runnerto a local standalone installation and verified the header is sent correctly on partner node API calls (Gemini image generation viaapi.comfy.org).Test 1 - Custom environment file:
.comfy_environmentwith contentstandalone_testin the ComfyUI install directoryComfy-Env: standalone_test?Test 2 - Default fallback (no file):
.comfy_environmentfile and restarted ComfyUIComfy-Env: local-git?API Node PR Checklist
Scope
Pricing & Billing
If Need pricing update:
QA
Comms