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 MediaService that transparently handles both RunningHub cloud and local ComfyUI backends.
  • RunningHub is the default source, configured via get_default_source() in workflow_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 of media.py), routing to RunningHub via workflow_id or 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →