How Pixelle-Video Handles Image Generation Requests with RunningHub
Pixelle-Video routes all image generation requests through a unified service layer that transparently targets either a local ComfyUI instance or RunningHub's cloud-hosted ComfyUI service, with RunningHub configured as the default cloud-first backend.
The AIDC-AI/Pixelle-Video repository abstracts AI image generation behind a flexible architecture that prioritizes ease of use. By default, all pixelle_video.media() calls hit RunningHub's cloud infrastructure unless explicitly configured for self-hosting. This design eliminates local GPU requirements for beginners while preserving full flexibility for advanced users.
The Seven-Step Request Lifecycle
1. Resolve the Workflow Path
Every image generation request begins with resolve_workflow_path() in pixelle_video/utils/workflow_util.py. This function constructs a canonical identifier using the pattern <source>/<service>.json.
# Default behavior: source='runninghub'
workflow_path = resolve_workflow_path("image_flux.json")
# Returns: "runninghub/image_flux.json"
The get_default_source() function in the same file returns 'runninghub' as the default, establishing the cloud-first architecture.
2. Scan Available Workflows
The MediaService._scan_workflows() method in pixelle_video/services/media.py walks the workflows/ directory and indexes all JSON files. It categorizes each workflow by source (runninghub or selfhost) and media type (files prefixed with image_ or video_).
3. Build Execution Parameters
The service collects generation parameters into a dictionary passed to the underlying ComfyKit executor:
params = {
"prompt": "a futuristic city at sunset",
"width": 1024,
"height": 1024,
"steps": 30,
"cfg": 7.5,
"negative_prompt": "blurry, low quality"
}
4. Get or Create a ComfyKit Instance
self.core._get_or_create_comfykit() lazily instantiates a ComfyKit object. This shared instance handles all communication with the selected backend, caching credentials and connection state across multiple requests.
5. Dispatch to the Correct Backend
The critical routing logic resides in MediaService.__call__ (lines 33-41 of pixelle_video/services/media.py):
# RunningHub path (default)
if workflow_info["source"] == "runninghub" and "workflow_id" in workflow_info:
# Sends workflow_id to ComfyKit for cloud execution
result = await self.comfykit.execute(
workflow_id=workflow_info["workflow_id"],
params=params
)
else:
# Self-host path: send absolute file path to local ComfyUI
result = await self.comfykit.execute(
workflow_path=workflow_info["absolute_path"],
params=params,
comfyui_url=overrides.get("comfyui_url")
)
6. Receive and Parse the Result
The ExecuteResult from ComfyKit contains either images or videos arrays. The service extracts the first URL, logs the successful generation, and wraps everything in a MediaResult object.
7. Return to Caller
The final output is a MediaResult instance from pixelle_video/models/media.py:
class MediaResult:
media_type: str # "image" or "video"
url: str # CDN URL from RunningHub or local server
duration: Optional[float] # seconds, for videos only
Code Examples: RunningHub vs. Self-Host
Default RunningHub Image Generation
import pixelle_video
# Simplest call: uses runninghub/image_flux.json by default
media = await pixelle_video.media(prompt="a futuristic city at sunset")
print("Image URL:", media.url)
# Output: https://cdn.runninghub.ai/...
Explicit RunningHub with Custom Workflow
media = await pixelle_video.media(
prompt="a cyberpunk portrait",
workflow="image_flux.json", # resolves to runninghub/image_flux.json
width=1024,
height=1024,
steps=30,
cfg=7.5
)
Force Self-Host Execution
media = await pixelle_video.media(
prompt="an enchanted forest",
source="selfhost", # override default source
workflow="selfhost/image_nano_banana.json",
comfyui_url="http://127.0.0.1:8188", # optional: custom local URL
width=768,
height=768
)
Video Generation via RunningHub
media = await pixelle_video.media(
prompt="a rocket launch sequence",
workflow="video_wan2.1_fusionx.json", # runninghub/video_wan2.1_fusionx.json
media_type="video",
duration=12.5, # seconds, often driven by TTS audio length
width=1280,
height=720
)
print("Video URL:", media.url, "Duration:", media.duration)
Key Implementation Files
| File | Purpose |
|---|---|
pixelle_video/services/media.py |
Core MediaService class implementing the seven-step request lifecycle |
pixelle_video/utils/workflow_util.py |
resolve_workflow_path() and get_default_source() helpers |
pixelle_video/models/media.py |
MediaResult dataclass definition |
web/components/settings.py |
UI for configuring RunningHub API credentials |
config.example.yaml |
Configuration schema including runninghub_api_key |
workflows/runninghub/image_flux.json |
Default RunningHub image generation workflow |
pixelle_video/services/comfy_base_service.py |
Base class with shared _resolve_workflow and logging utilities |
Summary
- Pixelle-Video routes image generation requests through a unified
MediaServicethat transparently handles both RunningHub cloud and local ComfyUI backends. - RunningHub is the default source, configured via
get_default_source()inworkflow_util.py, making cloud execution the zero-config path for new users. - The seven-step lifecycle—resolve workflow, scan available workflows, build parameters, get ComfyKit instance, dispatch to backend, parse result, and return MediaResult—ensures consistent handling regardless of backend choice.
- Backend selection happens at dispatch time in
MediaService.__call__(lines 33-41 ofmedia.py), routing to RunningHub viaworkflow_idor to self-host via absolute file path.
Frequently Asked Questions
How do I switch from RunningHub to a local ComfyUI instance?
Add source="selfhost" to your pixelle_video.media() call. Optionally specify comfyui_url if your local server runs on a non-standard port. The service will skip the workflow_id lookup and send the absolute path to your local ComfyUI server instead.
Where does Pixelle-Video store my RunningHub API key?
The API key is read from your configuration file (typically config.yaml in the project root, following the schema in config.example.yaml). The web/components/settings.py UI provides a convenient interface to paste and validate this key before any cloud requests are dispatched.
Can I use custom workflows with RunningHub?
Yes. Pass a workflow parameter to pixelle_video.media()—for example, workflow="image_flux.json". The resolve_workflow_path() function automatically prepends runninghub/ to create runninghub/image_flux.json, then extracts the corresponding workflow_id for the RunningHub API call.
What happens if RunningHub is unavailable?
The ComfyKit executor will surface the HTTP error or timeout from the RunningHub API. You can catch this exception and retry, or fall back to source="selfhost" if you have a local ComfyUI instance running. The service layer does not automatically fail over between backends to avoid unexpected credit consumption or quality differences.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →