Skip to content

Add deploy environment header (Comfy-Env) to partner node API calls#13425

Merged
Kosinkadink merged 13 commits intomasterfrom
feature/deploy-environment-header
May 5, 2026
Merged

Add deploy environment header (Comfy-Env) to partner node API calls#13425
Kosinkadink merged 13 commits intomasterfrom
feature/deploy-environment-header

Conversation

@Kosinkadink
Copy link
Copy Markdown
Member

@Kosinkadink Kosinkadink commented Apr 16, 2026

Summary

Adds a Comfy-Env header to API requests sent to api.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

  1. A new module comfy/deploy_environment.py reads a .comfy_environment file from the ComfyUI install directory (resolved from this module's own path so --base-directory cannot redirect the lookup).
  2. If the file exists, its first line is read (capped at 128 bytes), stripped of whitespace, and filtered to printable ASCII (32 <= ord(c) < 127) - this both sanitizes the value and prevents header-injection / CRLF-smuggling attacks.
  3. If the file is absent or the sanitized value is empty, the value defaults to local-git.
  4. The result is memoized via @functools.cache (one read per process; tests use cache_clear() for isolation).
  5. The value is sent as a Comfy-Env header on relative-URL requests in comfy_api_nodes/util/client.py - the relative-URL gate ensures the header is only attached to api.comfy.org calls, never to third-party endpoints reached via custom hostnames.
  6. The .comfy_environment file 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_environment file in the ComfyUI install directory with the desired value:

local-desktop2-standalone

No CLI args or environment variables needed. Git clone users get local-git automatically.

Tests

New tests-unit/deploy_environment_test.py covers:

  • missing-file fallback to local-git
  • basic value read + whitespace stripping
  • multi-line file (only first line used)
  • empty file / whitespace-only file fallbacks
  • control-char stripping (header-injection protection)
  • non-ASCII stripping
  • 128-byte read cap on a huge single-line file
  • cache stickiness across calls
  • OSError during read falls back to default

11 tests, all passing locally.

Manual verification

Deployed PR via comfy-runner to a local standalone installation and verified the header is sent correctly on partner node API calls (Gemini image generation via api.comfy.org).

Test 1 - Custom environment file:

  • Created .comfy_environment with content standalone_test in the ComfyUI install directory
  • Ran an API node workflow (Gemini image gen)
  • Confirmed via debug logging that the outgoing request header was Comfy-Env: standalone_test ?

Test 2 - Default fallback (no file):

  • Deleted the .comfy_environment file and restarted ComfyUI
  • Ran the same API node workflow
  • Confirmed the outgoing request header was Comfy-Env: local-git ?

API Node PR Checklist

Scope

  • Is API Node Change

Pricing & Billing

  • Need pricing update
  • No pricing update

If Need pricing update:

  • Metronome rate cards updated
  • Auto-billing tests updated and passing

QA

  • QA done
  • QA not required

Comms

  • Informed Kosinkadink

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds .comfy_environment to .gitignore. Introduces comfy/deploy_environment.py with _DEFAULT_DEPLOY_ENV = "local_git", _ENV_FILENAME = ".comfy_environment", a module-level _cached_value, and get_deploy_environment() which reads the file’s first line (UTF-8, max 128 chars), strips whitespace, filters to printable ASCII, caches the result, and falls back to the default on missing or error conditions (logging non-FileNotFoundError exceptions). The HTTP client injects an X-Comfy-Env header for relative requests. Unit tests for these behaviors were added.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is detailed and directly addresses the changeset: it explains the new deploy environment feature, how it works, testing performed, and relates it to specific issues.
Title check ✅ Passed The title directly reflects the main objective: adding an X-Comfy-Env header to API calls for partner nodes.

✏️ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1de83f9 and 4de0e4e.

📒 Files selected for processing (3)
  • .gitignore
  • comfy/deploy_environment.py
  • comfy_api_nodes/util/client.py

Comment thread comfy_api_nodes/util/client.py
Comment thread comfy/deploy_environment.py Outdated
@Kosinkadink Kosinkadink force-pushed the feature/deploy-environment-header branch from 4de0e4e to d443728 Compare April 16, 2026 03:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
comfy_api_nodes/util/client.py (1)

620-623: ⚠️ Potential issue | 🟠 Major

X-Comfy-Env is 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4de0e4e and d443728.

📒 Files selected for processing (3)
  • .gitignore
  • comfy/deploy_environment.py
  • comfy_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
@Kosinkadink Kosinkadink force-pushed the feature/deploy-environment-header branch from d443728 to e7fbb3c Compare April 16, 2026 03:15
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d443728 and e7fbb3c.

📒 Files selected for processing (3)
  • .gitignore
  • comfy/deploy_environment.py
  • comfy_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

Comment thread comfy/deploy_environment.py Outdated
@Kosinkadink Kosinkadink added the Core Core team dependency label Apr 20, 2026
Kosinkadink added a commit to Comfy-Org/ComfyUI-Desktop-2.0-Beta that referenced this pull request Apr 20, 2026
…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>
Kosinkadink added a commit to Comfy-Org/ComfyUI-Desktop-2.0-Beta that referenced this pull request Apr 20, 2026
…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
Comment thread comfy/deploy_environment.py Outdated
Kosinkadink added a commit to Comfy-Org/ComfyUI-Desktop-2.0-Beta that referenced this pull request May 4, 2026
…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>
Kosinkadink and others added 2 commits May 4, 2026 06:55
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>
Kosinkadink and others added 2 commits May 4, 2026 16:52
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>
@Kosinkadink Kosinkadink changed the title Add deploy environment header (X-Comfy-Env) to partner node API calls Add deploy environment header (Comfy-Env) to partner node API calls May 5, 2026
rattus128
rattus128 previously approved these changes May 5, 2026
Comment thread tests-unit/deploy_environment_test.py
guill
guill previously approved these changes May 5, 2026
Copy link
Copy Markdown
Member

@guill guill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@Kosinkadink Kosinkadink dismissed stale reviews from guill and rattus128 via fe7efc6 May 5, 2026 02:40
Kosinkadink added a commit to Comfy-Org/ComfyUI-Desktop-2.0-Beta that referenced this pull request May 5, 2026
…#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>
@Kosinkadink Kosinkadink merged commit e758594 into master May 5, 2026
17 checks passed
Kosinkadink added a commit to Comfy-Org/ComfyUI-Desktop-2.0-Beta that referenced this pull request May 6, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Core Core team dependency

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants