Files
celery/app/__init__.py
giles b47417704e Fix /media route by mounting cache router directly
Avoids Depends() resolution issues with manual function calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:21:26 +00:00

98 lines
3.2 KiB
Python

"""
Art-DAG L1 Server Application Factory.
Creates and configures the FastAPI application with all routers and middleware.
"""
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from artdag_common import create_jinja_env
from .config import settings
def create_app() -> FastAPI:
"""
Create and configure the L1 FastAPI application.
Returns:
Configured FastAPI instance
"""
app = FastAPI(
title="Art-DAG L1 Server",
description="Content-addressed media processing with distributed execution",
version="1.0.0",
)
# Database lifecycle events
from database import init_db, close_db
@app.on_event("startup")
async def startup():
await init_db()
@app.on_event("shutdown")
async def shutdown():
await close_db()
# Initialize Jinja2 templates
template_dir = Path(__file__).parent / "templates"
app.state.templates = create_jinja_env(template_dir)
# Custom 404 handler
@app.exception_handler(404)
async def not_found_handler(request: Request, exc):
from artdag_common.middleware import wants_html
if wants_html(request):
from artdag_common import render
return render(app.state.templates, "404.html", request,
user=None,
status_code=404,
)
return JSONResponse({"detail": "Not found"}, status_code=404)
# Include routers
from .routers import auth, storage, api, recipes, cache, runs, home
# Home and auth routers (root level)
app.include_router(home.router, tags=["home"])
app.include_router(auth.router, prefix="/auth", tags=["auth"])
# Feature routers
app.include_router(storage.router, prefix="/storage", tags=["storage"])
app.include_router(api.router, prefix="/api", tags=["api"])
# Runs router - handles both /runs and /run/{id} patterns
app.include_router(runs.router, prefix="/runs", tags=["runs"])
# Also mount at /run for single-run detail URLs
from fastapi import APIRouter
run_detail_router = APIRouter()
@run_detail_router.get("/{run_id}")
async def run_detail_redirect(run_id: str, request: Request):
from .routers.runs import run_detail
return await run_detail(run_id, request)
app.include_router(run_detail_router, prefix="/run", tags=["runs"])
# Recipes router - handles both /recipes and /recipe/{id} patterns
app.include_router(recipes.router, prefix="/recipes", tags=["recipes"])
recipe_detail_router = APIRouter()
@recipe_detail_router.get("/{recipe_id}")
async def recipe_detail_redirect(recipe_id: str, request: Request):
from .routers.recipes import get_recipe
return await get_recipe(recipe_id, request)
app.include_router(recipe_detail_router, prefix="/recipe", tags=["recipes"])
# Cache router - handles /cache and /media
app.include_router(cache.router, prefix="/cache", tags=["cache"])
# Also mount cache router at /media for convenience
app.include_router(cache.router, prefix="/media", tags=["media"])
return app
# Create the default app instance
app = create_app()