# How MoneyPrinterTurbo Supports Both API and Web UI: Architecture Explained

> Explore MoneyPrinterTurbo's architecture. Learn how its FastAPI API and Streamlit Web UI share a service layer without code duplication for seamless video generation.

- Repository: [Harry/MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo)
- Tags: architecture
- Published: 2026-03-23

---

**MoneyPrinterTurbo exposes its video generation engine through two front-ends—a FastAPI REST API and a Streamlit Web UI—both calling the same shared service layer without code duplication.**

MoneyPrinterTurbo is an open-source AI video generation tool that automates the creation of short-form content. To accommodate both developers and non-technical users, the project provides programmatic access via a REST API and an interactive graphical interface via a Web UI. This dual-interface architecture ensures that whether you are integrating MoneyPrinterTurbo into a pipeline or using it manually, you leverage the identical core logic.

## Architecture Overview

The project follows a **clean separation of concerns** between transport and business logic. The heavy-lifting video generation workflow lives in a single core library (`app/services`), while two thin front-ends expose that functionality:

- **REST API**: A FastAPI application that handles HTTP requests and returns JSON responses.
- **Web UI**: A Streamlit dashboard that renders forms and buttons in the browser.

Both entry points import the same services ([`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py), [`app/services/llm.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/llm.py)) and configuration ([`app/config/config.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/config/config.py)). The UI does not call the HTTP endpoints; it directly invokes the Python functions, ensuring zero latency overhead and no need to maintain duplicate business logic.

## REST API Implementation

The API layer is built on **FastAPI** and served via an ASGI server. It exposes versioned endpoints under `/v1/*` for creating video tasks, checking status, and retrieving results.

### ASGI Application Entry Point

The FastAPI instance is created in **[`app/asgi.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/asgi.py)**. This file registers all routers and mounts static directories for serving generated videos.

```python

# app/asgi.py

instance = FastAPI(...)
instance.include_router(root_api_router)   # Registers all /v1/* routes

```

### Routing Structure

The **[`app/router.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/router.py)** file aggregates versioned routers. It creates a root `APIRouter` and includes the v1 endpoints, ensuring a clean URL structure (`/v1/videos`, `/v1/tasks`).

### Video Generation Endpoints

Concrete endpoint logic resides in **[`app/controllers/v1/video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/controllers/v1/video.py)**. The `create_video` function accepts a JSON payload, validates it against Pydantic models, and delegates to the shared task manager.

```python

# app/controllers/v1/video.py

@router.post("/videos", response_model=TaskResponse)
def create_video(
    background_tasks: BackgroundTasks,
    request: Request,
    body: TaskVideoRequest,
):
    return create_task(request, body, stop_at="video")

```

The `create_task` utility generates a UUID, stores the task in the manager, and launches the heavy work asynchronously via `task_manager.add_task(tm.start, ...)`. The actual video generation logic in `tm.start` is shared with the Web UI.

## Web UI Implementation

The graphical interface is implemented with **Streamlit**, providing an interactive dashboard for users who prefer point-and-click operation over HTTP requests.

### Entry Point and Configuration

The UI launches via **`streamlit run webui/Main.py`**. This script imports the same configuration and service modules as the API, ensuring consistency.

```python

# webui/Main.py

from app.config import config
from app.services import llm, voice
from app.services import task as tm

```

### Direct Service Invocation

When a user clicks the **Generate Video** button, the UI directly invokes the core pipeline without making an HTTP request to the API. This eliminates network overhead and keeps the architecture simple.

```python

# webui/Main.py (excerpt)

if start_button:
    config.save_config()
    task_id = str(uuid4())
    result = tm.start(task_id=task_id, params=params)   # Direct call, no HTTP

    # Display results...

```

The `tm.start` function, defined in **[`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py)**, orchestrates the entire workflow: script generation via `llm.generate_script`, material downloading, video rendering, and audio mixing. Because both the API and UI call this same function, feature parity is guaranteed.

## Shared Core Services

All business logic resides in the **`app/services/`** directory and **`app/models/`**, decoupled from transport concerns.

### Task Management

The **[`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py)** file contains the `start` function that implements the video generation pipeline. It accepts parameters such as `task_id` and `stop_at`, allowing the API to control execution stages while the UI runs the full flow.

### Configuration and Models

- **[`app/config/config.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/config/config.py)** holds shared settings (LLM API keys, voice providers, UI language), accessible to both front-ends.
- **[`app/models/schema.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/models/schema.py)** defines **Pydantic** models like `TaskVideoRequest` and `TaskResponse`, ensuring consistent data validation across the API and type hints for the UI.

## Summary

- **MoneyPrinterTurbo** exposes a unified video generation engine through two front-ends: a **FastAPI REST API** and a **Streamlit Web UI**.
- The **API** ([`app/asgi.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/asgi.py), [`app/controllers/v1/video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/controllers/v1/video.py)) wraps core services in HTTP endpoints, handling JSON requests and asynchronous task execution.
- The **Web UI** ([`webui/Main.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/webui/Main.py)) provides an interactive dashboard that directly invokes the same service functions (`tm.start`), bypassing HTTP for lower latency.
- Both interfaces share **identical business logic** in [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py), [`app/config/config.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/config/config.py), and [`app/models/schema.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/models/schema.py), ensuring feature parity and maintainability.
- This **clean separation of transport and core logic** allows developers to add new interfaces (CLI, gRPC, etc.) without duplicating the video generation pipeline.

## Frequently Asked Questions

### How do I start the MoneyPrinterTurbo API server?

To launch the REST API, run `uvicorn app.asgi:app` from the project root. This starts the FastAPI application defined in [`app/asgi.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/asgi.py), making the `/v1/*` endpoints available for programmatic video generation requests.

### Can the Web UI and API run simultaneously?

Yes. Because the Web UI (`streamlit run webui/Main.py`) and the API (`uvicorn app.asgi:app`) are separate processes that only share the underlying service layer, they can operate concurrently on the same machine without conflict, provided port configurations do not collide.

### Does the Web UI consume the REST API endpoints internally?

No. The Web UI imports and calls Python functions directly from [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py) (e.g., `tm.start`). This design avoids HTTP overhead and network latency, ensuring that both the UI and API use the exact same core logic while maintaining optimal performance for interactive use.

### Where is the shared video generation logic located?

The central pipeline resides in **[`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py)**, specifically within the `start` function. This module orchestrates script generation, material downloading, video rendering, and audio mixing. Both the FastAPI controllers and the Streamlit UI import and execute this function, guaranteeing consistent behavior across interfaces.