# What Is the Purpose of the `video` Router in the FastAPI Backend?

> Discover the purpose of the video router in the FastAPI backend. It handles video generation, request validation, and result packaging for your applications.

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

---

**The `video` router in the Pixelle-Video FastAPI backend serves as the central entry point for all video-generation operations, exposing synchronous and asynchronous endpoints that handle request validation, media size determination, service invocation, and result packaging.**

The `video` router ([`api/routers/video.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/video.py)) is the core API interface that transforms HTTP requests into AI-generated videos. This component bridges client applications with the sophisticated video generation pipeline implemented in the AIDC-AI/Pixelle-Video repository. Understanding the `video` router's purpose is essential for developers integrating with or extending this FastAPI backend.

## Endpoint Structure and Routing

The `video` router registers under the `/video` prefix and groups two primary endpoints that cater to different use cases.

### Synchronous Video Generation

The `POST /video/generate/sync` endpoint performs **blocking video generation**, waiting until the complete video is ready before returning a response. This approach suits short clips (typically under 30 seconds) where immediate results are preferred over scalability.

Key characteristics of the sync endpoint:
- Returns a complete `VideoGenerateResponse` with `video_url`, `duration`, and `file_size`
- Blocks the HTTP connection throughout generation
- Ideal for prototyping and simple integrations

### Asynchronous Video Generation

The `POST /video/generate/async` endpoint initiates **non-blocking generation**, returning immediately with a `task_id` that clients poll through the `/api/tasks/{task_id}` endpoint.

This pattern enables:
- Long-running video generation without connection timeouts
- Scalable queue-based processing
- Progress tracking and status monitoring

## Request Validation and Schema Handling

The `video` router leverages FastAPI's automatic validation through Pydantic models defined in [`api/schemas/video.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/schemas/video.py). The `VideoGenerateRequest` model encapsulates all generation parameters:

- `text` – The narrative or script content
- `mode` – Generation mode (e.g., "narration")
- `title` – Video title metadata
- `n_scenes` – Number of scenes to generate
- `frame_template` – HTML template selection
- `media_workflow` – Image generation backend
- `video_fps` – Output frame rate
- `voice_id` and TTS configuration options

FastAPI automatically validates incoming JSON against this schema, rejecting malformed requests before they reach the business logic.

## Media Size Determination

Before invoking the core generation service, the `video` router determines the required output dimensions. This process uses `HTMLFrameGenerator` from [`pixelle_video/services/frame_html.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/frame_html.py) to extract `media_width` and `media_height` from the selected HTML frame template.

This ensures generated videos match the template's aspect ratio and resolution, preventing distortion or cropping issues.

## Service Invocation and Dependency Injection

The `video` router accesses the core video generation capability through **dependency injection**. The `PixelleVideoDep` dependency (defined in [`api/dependencies.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/dependencies.py)) provides an initialized instance of the video service.

The router calls `pixelle_video.generate_video` with assembled parameters, handling:
- Legacy field compatibility (e.g., mapping `voice_id`)
- Optional TTS audio data
- Reference audio for voice cloning

## Result Packaging and URL Generation

After successful generation, the `video` router performs final processing:

1. **File size calculation** using `os.path.getsize`
2. **Path-to-URL conversion** via the `path_to_url` helper, constructing public URLs under `/api/files/...` based on the request's host
3. **Response formation** as either `VideoGenerateResponse` (sync) or `VideoGenerateAsyncResponse` (async)

## Background Task Management

For asynchronous requests, the `video` router integrates with the global `task_manager` from [`api/tasks/manager.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/tasks/manager.py). This component:
- Registers the generation job
- Tracks execution progress
- Stores final results for retrieval
- Enables status polling via the tasks API

## Code Examples

### Synchronous Generation with cURL

```bash
curl -X POST "http://localhost:8000/api/video/generate/sync" \
     -H "Content-Type: application/json" \
     -d '{
          "text": "A quick tour of the city skyline.",
          "mode": "narration",
          "title": "City Tour",
          "n_scenes": 5,
          "frame_template": "standard",
          "media_workflow": "stable-diffusion",
          "video_fps": 24
        }'

```

### Asynchronous Generation and Polling

```bash

# Submit request

TASK_ID=$(curl -s -X POST "http://localhost:8000/api/video/generate/async" \
   -H "Content-Type: application/json" \
   -d '{"text":"Long story...","frame_template":"standard"}' | jq -r .task_id)

# Poll task status until completed

while true; do
  STATUS=$(curl -s "http://localhost:8000/api/tasks/$TASK_ID" | jq -r .status)
  echo "Task status: $STATUS"
  [[ $STATUS == "completed" ]] && break
  sleep 2
done

# Retrieve result

curl "http://localhost:8000/api/tasks/$TASK_ID"

```

### Python Client with httpx

```python
import httpx

client = httpx.AsyncClient(base_url="http://localhost:8000")

# Sync request

resp = await client.post("/api/video/generate/sync", json={
    "text": "Product showcase video",
    "mode": "narration",
    "n_scenes": 3,
    "frame_template": "standard"
})
print(resp.json()["video_url"])

# Async request

resp = await client.post("/api/video/generate/async", json={...})
task_id = resp.json()["task_id"]

# Poll /api/tasks/{task_id} for completion

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`api/routers/video.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/video.py) | Defines the `/video` router, sync/async endpoints, and `path_to_url` helper |
| [`api/schemas/video.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/schemas/video.py) | Pydantic models for request/response validation |
| [`api/dependencies.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/dependencies.py) | Provides `PixelleVideoDep` dependency injection |
| [`api/tasks/manager.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/tasks/manager.py) | Manages background tasks for async generation |
| [`pixelle_video/services/frame_html.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/frame_html.py) | Extracts media dimensions from HTML templates |
| [`pixelle_video/service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/service.py) | Core orchestration of LLM, TTS, image generation, and video rendering |

## Summary

- The **`video` router** ([`api/routers/video.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/video.py)) is the FastAPI entry point for all video generation operations in Pixelle-Video.

- It exposes **two endpoints**: `POST /video/generate/sync` for blocking generation and `POST /video/generate/async` for background task-based generation.

- The router handles **request validation** via Pydantic schemas, **media size determination** from HTML templates, and **service invocation** through dependency injection.

- Results are packaged with **file size calculation** and **URL generation** for client access.

- **Background task management** enables scalable asynchronous processing with status polling.

## Frequently Asked Questions

### What is the difference between sync and async video generation in the Pixelle-Video API?

The synchronous endpoint (`/video/generate/sync`) blocks until the video is fully generated, making it suitable for short clips under 30 seconds where immediate results are needed. The asynchronous endpoint (`/video/generate/async`) returns immediately with a `task_id`, allowing long-running generation to proceed in the background while the client polls for completion via `/api/tasks/{task_id}`.

### How does the video router determine the output resolution?

The router extracts `media_width` and `media_height` from the selected HTML frame template using `HTMLFrameGenerator` from [`pixelle_video/services/frame_html.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/frame_html.py). This ensures the generated video matches the template's native dimensions, preventing aspect ratio mismatches or cropping artifacts.

### What happens to the generated video file after creation?

After generation completes, the router calculates the file size with `os.path.getsize`, converts the absolute filesystem path to a public URL using the `path_to_url` helper, and returns this URL in the response. The URL is constructed relative to the request's host under the `/api/files/` prefix, making the video accessible for download or streaming.

### Can I use custom voice settings when generating videos?

Yes. The `VideoGenerateRequest` schema accepts `voice_id` and additional TTS-related parameters. The router handles these fields, including legacy compatibility mappings, and passes them to the core generation service. You can also provide reference audio for voice cloning workflows by including the appropriate fields in the request payload.