| import os | |
| import logging | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi import Request | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from ylff.server import app | |
| logger = logging.getLogger(__name__) | |
| # Mount static files (Next.js exported assets) | |
| # We mount this AFTER the API routes defined in `ylff.server` so that API routes take precedence. | |
| # However, FastAPI mounts match by path. "/" matches everything. | |
| # So we need to be careful. | |
| # But `StaticFiles` only handles requests if the file exists? No, it catches everything under mount path. | |
| # So requests to /api/... might get caught if we mount at "/"? | |
| # NO: FastAPI router matches first. | |
| # Wait. `app = create_app()` includes routers. | |
| # If we add mount("/") now, it acts as a catch-all? | |
| # Actually, explicitly defined routes (like /api/v1/...) are checked before mounts? | |
| # It depends on order... but `app.mount()` typically adds to the routes list. | |
| # Since `app` is already created with API routes, appending mount("/") usually works as fallback. | |
| STATIC_DIR = "/app/static" | |
| if os.path.exists(STATIC_DIR): | |
| logger.info(f"Mounting static files from {STATIC_DIR}") | |
| # 1. Mount specific assets first | |
| app.mount("/_next", StaticFiles(directory=f"{STATIC_DIR}/_next"), name="next-static") | |
| # 2. Mount root for everything else (index.html, favicon, etc) | |
| # We must be careful not to shadow /api. | |
| # FastAPI docs say: "The order matters. Routes are matched in order." | |
| # Since API routes were added in `create_app` (imported above), they are already in `app.router.routes`. | |
| # `app.mount` adds to the end. So it effectively acts as fallback. | |
| app.mount("/", StaticFiles(directory=STATIC_DIR, html=True), name="root-static") | |
| else: | |
| logger.warning(f"Static directory {STATIC_DIR} not found. Running in API-only mode.") | |
| # Just to be safe, we can add a simple root endpoint ONLY if static dir is missing | |
| # (which StaticFiles handles otherwise) | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |