# How Pixelle-Video Handles Image Generation Requests with RunningHub

> Discover how Pixelle-Video efficiently handles image generation requests by seamlessly integrating with RunningHub, leveraging its cloud-hosted ComfyUI service as the default backend for robust performance and scalability.

- Repository: [AIDC-AI/Pixelle-Video](https://github.com/AIDC-AI/Pixelle-Video)
- Tags: how-to-guide
- Published: 2026-04-23

---

**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](https://github.com/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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/utils/workflow_util.py). This function constructs a canonical identifier using the pattern `<source>/<service>.json`.

```python

# 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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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:

```python
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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/media.py)):

```python

# 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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/models/media.py):

```python
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

```python
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

```python
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

```python
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

```python
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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/media.py) | Core `MediaService` class implementing the seven-step request lifecycle |
| [`pixelle_video/utils/workflow_util.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/utils/workflow_util.py) | `resolve_workflow_path()` and `get_default_source()` helpers |
| [`pixelle_video/models/media.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/models/media.py) | `MediaResult` dataclass definition |
| [`web/components/settings.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/web/components/settings.py) | UI for configuring RunningHub API credentials |
| [`config.example.yaml`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/config.example.yaml) | Configuration schema including `runninghub_api_key` |
| [`workflows/runninghub/image_flux.json`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/workflows/runninghub/image_flux.json) | Default RunningHub image generation workflow |
| [`pixelle_video/services/comfy_base_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/config.yaml) in the project root, following the schema in [`config.example.yaml`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/config.example.yaml)). The [`web/components/settings.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/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.