?Home • ?Features • ?Installation • ?Usage • Documentation • ?API
✅Requirements • CLI • ?Docker • ?Limitations
Python library to programmatically schedule ComfyUI workflows via the ComfyUI API
Branch | Build Status | Commits Since | Last Commit |
---|---|---|---|
Master | |||
Develop |
ComfyUI API Endpoint <| <= Comfy Catapult <=> HTTP Server <| <= Public users
<| <|
<| Your python program <| Your Webui/JS frontend
<| <|
<| Your workflows <|
<| Your HTTP server <|
Comfy Catapult is a library for scheduling and running ComfyUI workflows from a Python program, via the existing API endpoint. ComfyUI typically works by hosting this API endpoint for its user interface.
This makes it easier for you to make workflows via the UI, and then use it from a program.
# Inside your environment:
# From pypi:
pip install comfy_catapult
# From git:
pip install git+https://github.com/realazthat/[email protected]
Project | ComfyUI API Wrapper | Outsource Backend | Distribute Execution | Wrap Workflow | Studio |
---|---|---|---|---|---|
CushyStudio | ? | ? | ? | ? | Yes |
ComfyUI-Serving-Toolkit | X | ? | ? | Yes | ? |
ComfyUI_NetDist | X | ? | Yes | ? | ? |
ComfyUI script_examples | Yes | No | No | No | No |
comfyui-python-api | ? | ? | ? | Yes | ? |
comfyui-deploy | ? | ? | ? | Yes | ? |
ComfyUI-to-Python-Extension | ? | ? | ? | Yes | ? |
ComfyScript | ? | ? | ? | Yes | ? |
hordelib | ? | Yes | ? | ? | ? |
comfyui-cloud | ? | Yes | ? | ? | ? |
comfy_runner | ? | ? | ? | ? | ? |
ComfyUI-ComfyRun | ? | ? | ? | ? | ? |
From
comfy_catapult/catapult_base.py
:
async def Catapult(
self,
*,
job_id: JobID,
prepared_workflow: dict,
important: Sequence[APINodeID],
use_future_api: Literal[True],
job_debug_path: Optional[Path] = None
) -> Tuple[JobStatus, 'asyncio.Future[dict]']:
From
examples/sdxlturbo_example_catapulter.py
:
class ExampleWorkflowInfo:
# Direct wrapper around the ComfyUI API.
client: ComfyAPIClientBase
# Job scheduler (the main point of this library).
catapult: ComfyCatapultBase
# Something to help with retrieving files from the ComfyUI storage.
remote: RemoteFileAPIBase
comfy_api_url: str
# This should be the workflow json as a dict.
workflow_template_dict: dict
# This should begin as a deep copy of the template.
workflow_dict: dict
# This will hold the node ids that we must have results for.
important: List[APINodeID]
# Make this any string unique to this job.
job_id: str
# When the job is complete, this will be the `/history` json/dictionary for
# this job.
job_history_dict: Optional[dict]
# These are inputs that modify this particular workflow.
ckpt_name: Optional[str]
positive_prompt: str
negative_prompt: str
# For this particular workflow, this will define the path to the output image.
output_path: Path
async def RunExampleWorkflow(*, job_info: ExampleWorkflowInfo):
# You have to write this function, to change the workflow_dict as you like.
await PrepareWorkflow(job_info=job_info)
job_id: str = job_info.job_id
workflow_dict: dict = job_info.workflow_dict
important: List[APINodeID] = job_info.important
# Here the magic happens, the job is submitted to the ComfyUI server.
status, future = await job_info.catapult.Catapult(
job_id=job_id,
prepared_workflow=workflow_dict,
important=important,
use_future_api=True)
# Wait for the job to complete.
while not future.done():
status, _ = await job_info.catapult.GetStatus(job_id=job_id)
print(f'status: {status}', file=sys.stderr)
await asyncio.sleep(3)
job_info.job_history_dict = await future
# Now that the job is done, you have to write something that will go and get
# the results you care about, if necessary.
await DownloadResults(job_info=job_info)
In ComfyUI web interface:
Enable Dev mode Options
.Save (API format)
.execute
options:
Example usage:
python -m comfy_catapult.cli
execute --workflow-path ./test_data/sdxlturbo_example_api.json
3.8.0, 3.9.0, 3.10.0, 3.11.0, 3.12.0
, tested in GitHub Actions
workflow (./.github/workflows/build-and-test.yml).Docker images are published to ghcr.io/realazthat/comfy-catapult at each tag.
# Use the published images at https://ghcr.io/realazthat/comfy-catapult.
docker run --rm --tty ghcr.io/realazthat/comfy-catapult:v3.0.0 --help
# /data in the docker image is the working directory, so paths are simpler.
docker run --rm --tty
-v "${PWD}:/data"
-e "COMFY_API_URL=${COMFY_API_URL}"
ghcr.io/realazthat/comfy-catapult:v3.0.0
execute --workflow-path ./test_data/sdxlturbo_example_api.json
If you want to build the image yourself, you can use the Dockerfile in the repository.
# Build the docker image.
docker build -t my-comfy-catapult-image .
# Print usage.
docker run --rm --tty my-comfy-catapult-image --help
# /data in the docker image is the working directory, so paths are simpler.
docker run --rm --tty
-v "${PWD}:/data"
-e "COMFY_API_URL=${COMFY_API_URL}"
my-comfy-catapult-image
execute --workflow-path ./test_data/sdxlturbo_example_api.json
For running pre.sh
(Linux-like environment).
From ./.github/dependencies.yml, which is used for the GH Action to do a fresh install of everything:
bash: scripts.
findutils: scripts.
grep: tests.
xxd: tests.
git: scripts, tests.
xxhash: scripts (changeguard).
rsync: out-of-directory test.
jq: dependency for [yq](https://github.com/kislyuk/yq), which is used to generate
the README; the README generator needs to use `tomlq` (which is a part of `yq`)
to query `pyproject.toml`.
Requires pyenv
, or an exact matching version of python as in
./.python-version.
jq
, (installation) required for
yq, which is itself required for our
./README.md
generation, which uses tomlq
(from the
yq package) to include version strings from
./pyproject.toml.
act (to run the GH Action locally):
Generate animation:
docker (for building the docker image).
develop
branch.git add path/to/file.py
.bash scripts/pre.sh
, this will format, lint, and test the code.git status
check if anything changed (generated ./README.md
for example), if so, git add
the changes, and go back to the previous step.git commit -m "..."
.develop
(or push to develop if you have the rights).These instructions are for maintainers of the project.
develop
branch: Run bash ./scripts/pre.sh
to ensure
everything is in order.develop
branch: Bump the version in
./pyproject.toml, following semantic versioning
principles. Also modify the last_release
and last_stable_release
in the
[tool.comfy_catapult-project-metadata]
table as appropriate.develop
branch: Commit these changes with a message like "Prepare release
X.Y.Z". (See the contributions section above).master
branch: Merge the develop
branch into the master
branch:
git checkout master && git merge develop --no-ff
.master
branch: Tag the release: Create a git tag for the release with
git tag -a vX.Y.Z -m "Version X.Y.Z"
.bash ./scripts/utilities/deploy-to-pypi.sh
.git push
and
git push --tags
.git checkout develop && git merge master
The --no-ff
option adds a commit
to the master branch for the merge, so refork the develop branch from the
master branch.git push origin develop
Push the develop branch to GitHub.