""" MPR FastAPI Application Serves GraphQL API and Lambda callback endpoint. """ import os import sys from typing import Optional from uuid import UUID # Add project root to path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Initialize Django before importing models os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mpr.settings") import django django.setup() from fastapi import FastAPI, Header, HTTPException from fastapi.middleware.cors import CORSMiddleware from strawberry.fastapi import GraphQLRouter from api.graphql import schema as graphql_schema CALLBACK_API_KEY = os.environ.get("CALLBACK_API_KEY", "") app = FastAPI( title="MPR API", description="Media Processor — GraphQL API", version="0.1.0", docs_url="/docs", redoc_url="/redoc", ) # CORS app.add_middleware( CORSMiddleware, allow_origins=["http://mpr.local.ar", "http://localhost:5173"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # GraphQL graphql_router = GraphQLRouter(schema=graphql_schema, graphql_ide="graphiql") app.include_router(graphql_router, prefix="/graphql") @app.get("/") def root(): """API root.""" return { "name": "MPR API", "version": "0.1.0", "graphql": "/graphql", } @app.post("/api/jobs/{job_id}/callback") def job_callback( job_id: UUID, payload: dict, x_api_key: Optional[str] = Header(None), ): """ Callback endpoint for Lambda to report job completion. Protected by API key. """ if CALLBACK_API_KEY and x_api_key != CALLBACK_API_KEY: raise HTTPException(status_code=403, detail="Invalid API key") from django.utils import timezone from mpr.media_assets.models import TranscodeJob try: job = TranscodeJob.objects.get(id=job_id) except TranscodeJob.DoesNotExist: raise HTTPException(status_code=404, detail="Job not found") status = payload.get("status", "failed") job.status = status job.progress = 100.0 if status == "completed" else job.progress update_fields = ["status", "progress"] if payload.get("error"): job.error_message = payload["error"] update_fields.append("error_message") if status in ("completed", "failed"): job.completed_at = timezone.now() update_fields.append("completed_at") job.save(update_fields=update_fields) return {"ok": True}