# What Is the Purpose of the 'tts' Router in the Pixelle-Video FastAPI Backend?

> Discover the purpose of the 'tts' router in the Pixelle-Video FastAPI backend. Learn how it handles Text-to-Speech requests via the /tts/synthesize endpoint for seamless client integration.

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

---

**The `tts` router in the Pixelle-Video FastAPI backend serves as the public HTTP entry point that exposes Text-to-Speech (TTS) functionality to clients, handling request validation, logging, service invocation, and response formatting through a single `/tts/synthesize` endpoint.**

The Pixelle-Video repository (AIDC-AI/Pixelle-Video) is an open-source video generation platform that combines multiple AI modalities. The `tts` router ([`api/routers/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/tts.py)) provides a clean, version-stable API contract that bridges external HTTP clients and the internal TTS service implementation. This article explains the router's architecture, request flow, and practical usage with complete code examples.

---

## Overview of the TTS Router Architecture

The `tts` router is built on FastAPI's `APIRouter` class and mounted with the prefix `/tts`. It exposes one primary endpoint that orchestrates the entire synthesis pipeline.

| Component | File Path | Purpose |
|-----------|-----------|---------|
| Router definition | [`api/routers/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/tts.py) | FastAPI `APIRouter` with `/tts` prefix |
| Request/response schemas | [`api/schemas/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/schemas/tts.py) | Pydantic models for validation |
| Core TTS service | [`pixelle_video/services/tts_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/tts_service.py) | Actual synthesis logic |
| Utility functions | [`pixelle_video/utils/tts_util.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/utils/tts_util.py) | Duration calculation, local Edge-TTS |

---

## The /tts/synthesize Endpoint: Request Flow

When a client sends a POST request to `/tts/synthesize`, the router executes a six-step pipeline. Understanding this flow helps developers debug issues and extend functionality.

### Step 1: Request Validation

The router parses the incoming JSON body using the `TTSSynthesizeRequest` Pydantic model defined in [`api/schemas/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/schemas/tts.py). This model enforces type safety for:

- `text` (required string): The text to synthesize
- `workflow` (optional string): ComfyUI workflow identifier
- `ref_audio` (optional string): Reference audio for voice cloning
- `voice_id` (optional string): Deprecated legacy field for backward compatibility

```python

# From api/schemas/tts.py

from pydantic import BaseModel
from typing import Optional

class TTSSynthesizeRequest(BaseModel):
    text: str
    workflow: Optional[str] = None
    ref_audio: Optional[str] = None
    voice_id: Optional[str] = None

```

### Step 2: Logging for Traceability

The router logs the incoming text using Python's standard logging infrastructure. This enables audit trails and debugging without exposing sensitive parameters.

```python

# From api/routers/tts.py (lines 24-94)

import logging

logger = logging.getLogger(__name__)

# Inside the endpoint handler:

logger.info(f"TTS synthesis request received: text='{request.text[:50]}...'")

```

### Step 3: Parameter Assembly

The router constructs a `tts_params` dictionary that normalizes user input. It handles the deprecated `voice_id` field to maintain backward compatibility while preferring newer parameters.

```python

# Parameter assembly logic from api/routers/tts.py

tts_params = {
    "text": request.text,
    "workflow": request.workflow,
    "ref_audio": request.ref_audio,
}

# Backward compatibility handling

if request.voice_id and not request.workflow:
    tts_params["workflow"] = f"legacy/{request.voice_id}.json"

```

### Step 4: Service Invocation

The router delegates actual synthesis to the core TTS service via `await pixelle_video.tts(**tts_params)`. This asynchronous call allows the FastAPI worker to handle other requests during processing.

The core service ([`pixelle_video/services/tts_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/tts_service.py)) implements a strategy pattern that selects between:

- **Local Edge-TTS**: Fast, offline synthesis using Microsoft's Edge speech engine
- **ComfyUI Workflow**: Cloud-based synthesis through configurable ComfyUI pipelines

```python

# Service invocation from api/routers/tts.py

from pixelle_video.services import tts_service

# Async call to core service

audio_path = await tts_service.synthesize(**tts_params)

```

### Step 5: Duration Calculation

After successful generation, the router computes the audio duration using `get_audio_duration` from [`pixelle_video/utils/tts_util.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/utils/tts_util.py). This metadata enables clients to synchronize playback or validate output quality.

```python

# Duration calculation from api/routers/tts.py

from pixelle_video.utils.tts_util import get_audio_duration

duration = get_audio_duration(audio_path)

```

### Step 6: Response Construction

The router returns a `TTSSynthesizeResponse` containing the file path and duration. Errors are caught, logged, and transformed into `HTTPException` with appropriate status codes.

```python

# From api/schemas/tts.py

class TTSSynthesizeResponse(BaseModel):
    success: bool
    message: str
    audio_path: str
    duration: float

# Error handling from api/routers/tts.py

from fastapi import HTTPException

try:
    # ... synthesis pipeline ...

    return TTSSynthesizeResponse(
        success=True,
        message="Success",
        audio_path=audio_path,
        duration=duration
    )
except Exception as e:
    logger.error(f"TTS synthesis failed: {str(e)}")
    raise HTTPException(status_code=500, detail=str(e))

```

---

## Practical Usage Examples

### Calling the Endpoint with cURL

```bash
curl -X POST https://your-pixelle-video.example.com/tts/synthesize \
  -H "Content-Type: application/json" \
  -d '{
        "text": "Hello, welcome to Pixelle-Video!",
        "workflow": "runninghub/tts_edge.json"
      }'

```

**Response:**

```json
{
  "success": true,
  "message": "Success",
  "audio_path": "output/7f3e2c9a5b1c4e9a8d0f.mp3",
  "duration": 3.42
}

```

### Using Python with httpx

```python
import httpx

payload = {
    "text": "你好，世界！",
    "workflow": "runninghub/tts_edge.json",
    "ref_audio": "samples/voice_demo.wav"
}
resp = httpx.post(
    "https://your-pixelle-video.example.com/tts/synthesize",
    json=payload,
    timeout=30.0
)
resp.raise_for_status()
data = resp.json()
print(f"Audio saved at: {data['audio_path']} (duration {data['duration']} s)")

```

### Testing with FastAPI TestClient

```python
from fastapi.testclient import TestClient
from api.main import app

client = TestClient(app)

response = client.post(
    "/tts/synthesize",
    json={"text": "Testing internal call"}
)

assert response.status_code == 200
print(response.json())

```

---

## Key Files and Their Roles

| File | Role |
|------|------|
| **[`api/routers/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/tts.py)** | Defines the `/tts` router and `/synthesize` endpoint with complete request/response handling |
| **[`api/schemas/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/schemas/tts.py)** | Pydantic models `TTSSynthesizeRequest` and `TTSSynthesizeResponse` for validation |
| **[`pixelle_video/services/tts_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/tts_service.py)** | Core synthesis logic, routing between local Edge-TTS and ComfyUI workflows |
| **[`pixelle_video/utils/tts_util.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/utils/tts_util.py)** | Helper utilities `get_audio_duration` and `edge_tts` for local synthesis |
| **[`pixelle_video/tts_voices.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/tts_voices.py)** | Voice speed-to-rate conversion mappings |

---

## Summary

- The **`tts` router** ([`api/routers/tts.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/api/routers/tts.py)) is the public HTTP gateway for all Text-to-Speech operations in Pixelle-Video.
- It exposes a single POST endpoint **`/tts/synthesize`** that validates requests, logs operations, delegates to the core service, and returns structured responses.
- The router implements **backward compatibility** for deprecated `voice_id` parameters while promoting modern `workflow` and `ref_audio` fields.
- **Error handling** transforms service failures into `HTTPException` responses with appropriate status codes and logged details.
- The router remains **agnostic to synthesis implementation**, delegating actual audio generation to [`pixelle_video/services/tts_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/tts_service.py).

---

## Frequently Asked Questions

### What HTTP method and path does the tts router use?

The `tts` router accepts **POST requests** at the path **`/tts/synthesize`**. The router is mounted with the prefix `/tts` in the main FastAPI application, and the synthesize endpoint is defined at the route `/synthesize`.

### How does the tts router handle invalid requests?

The router uses **Pydantic model validation** through `TTSSynthesizeRequest`. If the incoming JSON fails validation—such as missing the required `text` field or providing incorrect types—FastAPI automatically returns a **422 Unprocessable Entity** response with detailed error messages before the router's handler executes.

### Can I use the tts router with voice cloning reference audio?

Yes. The `TTSSynthesizeRequest` schema includes an optional **`ref_audio`** field. When provided, the core TTS service ([`pixelle_video/services/tts_service.py`](https://github.com/AIDC-AI/Pixelle-Video/blob/main/pixelle_video/services/tts_service.py)) can use this reference audio for voice cloning workflows, depending on the configured inference mode and selected workflow.

### What happens when the tts synthesis fails?

The router wraps the synthesis pipeline in a **try-except block**. If `pixelle_video.tts()` raises an exception, the router logs the error with `logger.error()` and raises an `HTTPException` with **status code 500** and the error details as the response body. This ensures clients receive meaningful error information while internal details are logged server-side.