from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse from app.api.routes import jobs, clips, renders @asynccontextmanager async def lifespan(app: FastAPI): yield app = FastAPI( title="ClipForge", description="Self-hosted AI video clipper", version="0.1.0", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(jobs.router, prefix="/api") app.include_router(clips.router, prefix="/api") app.include_router(renders.router, prefix="/api") @app.get("/", response_class=HTMLResponse) async def root(): return """ClipForge

ClipForge

Self-hosted AI video clipper

API Endpoints

POST/api/jobs Create job (YouTube URL)
POST/api/jobs/upload Upload video file
GET/api/jobs/{id} Job status
GET/api/jobs/{id}/clips Get clips
GET/api/jobs/{id}/progress SSE progress stream
POST/api/clips/{id}/render Render clip
GET/api/renders/{id}/download Download render

Interactive Docs

/docs — Swagger UI
/redoc — ReDoc

""" @app.get("/health") async def health(): return {"status": "ok", "service": "clipforge"}