Skip to content

Commit dea1c74

Browse files
robinjhuangchristian-byrneyoland68thot-experiment
authored
Add support for API Nodes in ComfyUI. (#7726)
* Add Ideogram generate node. * Add staging api. * COMFY_API_NODE_NAME node property * switch to boolean flag and use original node name for id * add optional to type * Add API_NODE and common error for missing auth token (#5) * Add Minimax Video Generation + Async Task queue polling example (#6) * [Minimax] Show video preview and embed workflow in ouput (#7) * [API Nodes] Send empty request body instead of empty dictionary. (#8) * Fixed: removed function from rebase. * Add pydantic. * Remove uv.lock * Remove polling operations. * Update stubs workflow. * Remove polling comments. * Update stubs. * Use pydantic v2. * Use pydantic v2. * Add basic OpenAITextToImage node * Add. * convert image to tensor. * Improve types. * Ruff. * Push tests. * Handle multi-form data. - Don't set content-type for multi-part/form - Use data field instead of JSON * Change to api.comfy.org * Handle error code 409. * separate out nodes per openai model * Update error message. * fix wrong output type * re-categorize nodes, remove ideogram (for now) * oops, fix mappings * fix ruff * Update frontend to 1.17.9 * embargo lift rename nodes * remove unused autogenerated model code * fix API type error and add b64 support for 4o * fix ruff * oops forgot mask scaling code * Remove unused types. --------- Co-authored-by: bymyself <cbyrne@comfy.org> Co-authored-by: Yoland Y <4950057+yoland68@users.noreply.github.com> Co-authored-by: thot-experiment <thot@thiic.cc>
1 parent 154f291 commit dea1c74

File tree

8 files changed

+979
-2
lines changed

8 files changed

+979
-2
lines changed
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Generate Pydantic Stubs from api.comfy.org
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * 1'
6+
workflow_dispatch:
7+
8+
jobs:
9+
generate-models:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.10'
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install 'datamodel-code-generator[http]'
25+
26+
- name: Generate API models
27+
run: |
28+
datamodel-codegen --use-subclass-enum --url https://api.comfy.org/openapi --output comfy_api_nodes/apis --output-model-type pydantic_v2.BaseModel
29+
30+
- name: Check for changes
31+
id: git-check
32+
run: |
33+
git diff --exit-code comfy_api_nodes/apis || echo "changes=true" >> $GITHUB_OUTPUT
34+
35+
- name: Create Pull Request
36+
if: steps.git-check.outputs.changes == 'true'
37+
uses: peter-evans/create-pull-request@v5
38+
with:
39+
commit-message: 'chore: update API models from OpenAPI spec'
40+
title: 'Update API models from api.comfy.org'
41+
body: |
42+
This PR updates the API models based on the latest api.comfy.org OpenAPI specification.
43+
44+
Generated automatically by the a Github workflow.
45+
branch: update-api-stubs
46+
delete-branch: true
47+
base: main
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# generated by datamodel-codegen:
2+
# filename: https://api.comfy.org/openapi
3+
# timestamp: 2025-04-23T15:56:33+00:00
4+
5+
from __future__ import annotations
6+
7+
from typing import Optional
8+
9+
from pydantic import BaseModel
10+
11+
from . import PixverseDto
12+
13+
14+
class ResponseData(BaseModel):
15+
ErrCode: Optional[int] = None
16+
ErrMsg: Optional[str] = None
17+
Resp: Optional[PixverseDto.V2OpenAPII2VResp] = None

comfy_api_nodes/apis/PixverseDto.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# generated by datamodel-codegen:
2+
# filename: https://api.comfy.org/openapi
3+
# timestamp: 2025-04-23T15:56:33+00:00
4+
5+
from __future__ import annotations
6+
7+
from typing import Optional
8+
9+
from pydantic import BaseModel, Field, constr
10+
11+
12+
class V2OpenAPII2VResp(BaseModel):
13+
video_id: Optional[int] = Field(None, description='Video_id')
14+
15+
16+
class V2OpenAPIT2VReq(BaseModel):
17+
aspect_ratio: str = Field(
18+
..., description='Aspect ratio (16:9, 4:3, 1:1, 3:4, 9:16)', examples=['16:9']
19+
)
20+
duration: int = Field(
21+
...,
22+
description='Video duration (5, 8 seconds, --model=v3.5 only allows 5,8; --quality=1080p does not support 8s)',
23+
examples=[5],
24+
)
25+
model: str = Field(
26+
..., description='Model version (only supports v3.5)', examples=['v3.5']
27+
)
28+
motion_mode: Optional[str] = Field(
29+
'normal',
30+
description='Motion mode (normal, fast, --fast only available when duration=5; --quality=1080p does not support fast)',
31+
examples=['normal'],
32+
)
33+
negative_prompt: Optional[constr(max_length=2048)] = Field(
34+
None, description='Negative prompt\n'
35+
)
36+
prompt: constr(max_length=2048) = Field(..., description='Prompt')
37+
quality: str = Field(
38+
...,
39+
description='Video quality ("360p"(Turbo model), "540p", "720p", "1080p")',
40+
examples=['540p'],
41+
)
42+
seed: Optional[int] = Field(None, description='Random seed, range: 0 - 2147483647')
43+
style: Optional[str] = Field(
44+
None,
45+
description='Style (effective when model=v3.5, "anime", "3d_animation", "clay", "comic", "cyberpunk") Do not include style parameter unless needed',
46+
examples=['anime'],
47+
)
48+
template_id: Optional[int] = Field(
49+
None,
50+
description='Template ID (template_id must be activated before use)',
51+
examples=[302325299692608],
52+
)
53+
water_mark: Optional[bool] = Field(
54+
False,
55+
description='Watermark (true: add watermark, false: no watermark)',
56+
examples=[False],
57+
)

0 commit comments

Comments
 (0)