Spaces:
Running
Running
File size: 4,005 Bytes
7ac6163 56fa34f 7ac6163 56fa34f 7ac6163 3203a8c a76c4ac c1fe190 e49c006 7ac6163 cbff5e0 7ac6163 dd0b28c 7ac6163 dd0b28c 7ac6163 56fa34f 7ac6163 2e3db11 7ac6163 cbff5e0 7ac6163 cbff5e0 e993aad 8de7693 26c0314 7ac6163 3203a8c 54df631 c1fe190 e49c006 7ac6163 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | """
CrownCode backend entrypoint with enhanced error handling.
"""
from __future__ import annotations
import asyncio
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from .routes.health import router as health_router
from .routes.youtube import router as youtube_router
from .routes.data_processing import router as data_processing_router
from .routes.analyze import router as analyze_router
from .routes.commend import router as commend_router
from .routes.reservations import router as reservations_router
from .routes.dreams import router as dreams_router
from .routes.remix import router as remix_router
from .services.logging_config import setup_logging, get_logger
setup_logging(level=os.getenv("LOG_LEVEL", "INFO"))
logger = get_logger(__name__)
def _load_origins() -> list[str]:
raw = os.getenv("CROWNCODE_CORS_ORIGINS") or os.getenv("CORS_ORIGIN") or "http://localhost:3000"
if raw.strip() == "*":
logger.warning(
"CORS wildcard '*' is not recommended for production. "
"Set CROWNCODE_CORS_ORIGINS to an explicit origin list."
)
return ["*"]
origins = [origin.strip() for origin in raw.split(",") if origin.strip()]
if not origins:
# No origins configured — default to localhost for development
origins = ["http://localhost:3000"]
logger.warning("No CORS origins configured, defaulting to localhost")
logger.info(f"CORS configured for origins: {origins}")
return origins
@asynccontextmanager
async def lifespan(_app: FastAPI):
# On the Space (AURIS_WARMUP=1 in the Dockerfile) load the models and
# compile librosa's numba code before the first visitor; off in tests.
warm_task = None
if os.getenv("AURIS_WARMUP") == "1":
from .routes.analyze import warm_up
warm_task = asyncio.create_task(warm_up())
yield
if warm_task is not None and not warm_task.done():
warm_task.cancel()
app = FastAPI(title="CrownCode Backend API", version="0.1.0", lifespan=lifespan)
@app.get("/")
async def root():
"""Root endpoint for health check and API info."""
return {
"name": "CrownCode Backend API",
"version": "0.1.0",
"status": "running",
"docs": "/docs",
"health": "/api/health"
}
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError) -> JSONResponse:
logger.warning(f"Validation error: {exc}")
return JSONResponse(
status_code=400,
content={"detail": str(exc), "type": "validation_error"}
)
@app.exception_handler(FileNotFoundError)
async def file_not_found_handler(request: Request, exc: FileNotFoundError) -> JSONResponse:
logger.error(f"File not found: {exc}")
return JSONResponse(
status_code=404,
content={"detail": "Resource not found", "type": "not_found"}
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception) -> JSONResponse:
logger.error(f"Unhandled exception: {type(exc).__name__}: {exc}", exc_info=True)
return JSONResponse(
status_code=500,
content={"detail": "Internal server error", "type": "server_error"}
)
_origins = _load_origins()
app.add_middleware(
CORSMiddleware,
allow_origins=_origins,
allow_credentials="*" not in _origins,
allow_methods=["GET", "POST", "DELETE", "OPTIONS"],
allow_headers=["Content-Type", "Accept"],
expose_headers=["X-Remix-Analysis", "X-Multitrack-Analysis"],
)
app.include_router(health_router)
app.include_router(youtube_router)
app.include_router(data_processing_router)
app.include_router(analyze_router)
app.include_router(commend_router)
app.include_router(reservations_router)
app.include_router(dreams_router)
app.include_router(remix_router)
logger.info("CrownCode backend API initialized")
|