What Is the Purpose of the Image Router in the FastAPI Backend?
The image router in the FastAPI backend provides a dedicated REST API endpoint for AI image generation, abstracting ComfyUI workflow execution behind a stable, versioned HTTP interface.
The image router (api/routers/image.py) in the AIDC-AI/Pixelle-Video repository serves as a critical API surface layer. It transforms internal media generation capabilities into an externally consumable service, enabling clients to generate AI images without managing the complexity of underlying ComfyUI workflows.
Image Router Architecture and Components
Understanding the purpose of the image router requires examining its constituent parts and how they interact with the broader FastAPI application.
Router Registration and Path Prefix
The router is instantiated with a clear namespace and documentation grouping:
# api/routers/image.py
router = APIRouter(prefix="/image", tags=["Basic Services"])
This registration in api/app.py through app.include_router(image_router, prefix=api_config.api_prefix) mounts all routes under /api/image, creating a predictable URL structure for API consumers.
Core Endpoint: POST /image/generate
The primary purpose of the image router is fulfilled by the POST /image/generate endpoint, which accepts structured requests and returns generated image URLs:
@router.post("/generate", response_model=ImageGenerateResponse)
async def generate_image(
request: ImageGenerateRequest,
pixelle_video: PixelleVideoDep
) -> ImageGenerateResponse:
# Delegates to media service and validates output type
The endpoint leverages two Pydantic models defined in api/schemas/image.py:
- ImageGenerateRequest: Validates
prompt,width,height, and optionalworkflowparameters - ImageGenerateResponse: Serializes the response with
success,message, andimage_pathfields
Dependency Injection and Service Layer Integration
A key architectural purpose of the image router is clean separation of concerns through FastAPI's dependency injection system.
PixelleVideoDep Singleton Pattern
The PixelleVideoDep dependency, defined in api/dependencies.py, injects a singleton PixelleVideoCore instance:
# api/dependencies.py
PixelleVideoDep = Annotated[PixelleVideoCore, Depends(get_pixelle_video_core)]
This pattern ensures that:
- The router accesses shared state (ComfyUI connections, model caches) without global variables
- Resource-intensive initialization occurs once per application lifecycle
- Testing becomes straightforward through dependency overrides
Delegation to Media Service
The image router's purpose is orchestration, not execution. It delegates actual generation to pixelle_video/services/media.py:
# Internal call within the endpoint
result = await pixelle_video.media(
prompt=request.prompt,
width=request.width,
height=request.height,
workflow=request.workflow
)
The media.py service handles:
- ComfyUI workflow selection and parameter substitution
- Async queue management and result polling
- Output file handling and URL generation
Backward Compatibility and Type Safety
An important purpose of the image router is maintaining API stability while the underlying system evolves.
Video Workflow Guard
The unified media service in pixelle_video/services/media.py can produce either images or videos depending on the workflow. The image router enforces type safety:
# Validation within the endpoint
if result.is_video:
raise HTTPException(
status_code=400,
detail="Video workflow used. Please use /media/generate endpoint for video generation."
)
This guard:
- Prevents breaking changes for existing clients expecting image-only responses
- Directs users to the appropriate
/media/generateendpoint for video generation - Maintains clear error semantics with actionable resolution paths
Practical Usage Examples
cURL Request
curl -X POST "http://localhost:8000/api/image/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A serene mountain landscape at sunset, photorealistic style",
"width": 1024,
"height": 1024
}'
Response:
{
"success": true,
"message": "Success",
"image_path": "http://.../generated/abcd1234.png"
}
Python Client with httpx
import httpx
payload = {
"prompt": "A futuristic city skyline at night",
"width": 1024,
"height": 1024,
"workflow": "image_flux.json" # optional custom workflow
}
resp = httpx.post(
"http://localhost:8000/api/image/generate",
json=payload,
timeout=120.0 # generation may take time
)
resp.raise_for_status()
data = resp.json()
print("Generated image URL:", data["image_path"])
Handling Workflow Mismatch Errors
When a video workflow is accidentally specified, the API returns a clear error:
import httpx
payload = {
"prompt": "A dancing robot",
"workflow": "video_wan2.json" # This is a video workflow!
}
resp = httpx.post("http://localhost:8000/api/image/generate", json=payload)
print(resp.status_code) # 400
print(resp.json())
# {"detail": "Video workflow used. Please use /media/generate endpoint for video generation."}
Summary
The image router in the FastAPI backend serves several interconnected purposes:
- API Abstraction: Exposes ComfyUI image generation through a clean REST interface without exposing workflow complexity
- Type Safety: Enforces image-only responses through runtime validation, maintaining contract stability
- Dependency Management: Leverages FastAPI's injection system for singleton service access and testability
- Backward Compatibility: Preserves existing
/imageendpoints while directing video use cases to the newer/mediaendpoint - Documentation Integration: Auto-generates OpenAPI specs through Pydantic models and router tags
These design decisions position the image router as a stable, maintainable API surface that shields clients from internal implementation changes while providing clear migration paths as the Pixelle-Video platform evolves.
Frequently Asked Questions
What is the endpoint URL for image generation in Pixelle-Video?
The image generation endpoint is POST /api/image/generate. The /api prefix is configurable through api_config.api_prefix, and the /image prefix comes from the APIRouter definition in api/routers/image.py. The full path combines these: {api_prefix}/image/generate.
How does the image router handle custom ComfyUI workflows?
The POST /image/generate endpoint accepts an optional workflow parameter in the ImageGenerateRequest schema. This string specifies which JSON workflow file to execute. However, the router validates that the executed workflow produces an image output. If a video workflow is detected, it returns a 400 error directing the client to /media/generate.
What is the difference between the image router and the media router?
The image router (api/routers/image.py) is a specialized endpoint that guarantees image output and maintains backward compatibility with existing clients. The media router (typically api/routers/media.py) is a newer, unified endpoint that handles both image and video generation through the same service layer. The image router delegates to pixelle_video.media() but adds type validation; the media router exposes the full flexibility of the underlying service.
Why does the image router use dependency injection for PixelleVideoCore?
Dependency injection through PixelleVideoDep in api/dependencies.py achieves three goals: resource efficiency by ensuring one PixelleVideoCore instance manages all ComfyUI connections; testability by allowing mock injection during unit tests; and separation of concerns by keeping router code focused on HTTP handling while the core manages workflow execution. This pattern follows FastAPI best practices for scalable service architecture.
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 →