File size: 2,385 Bytes
4851501 |
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 |
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from pathlib import Path
import os
from backend.core.database import init_db
from backend.api.api import api_router
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
try:
await init_db()
except Exception as e:
print(f"WARNING: Database initialization failed. Running in MOCK mode. Error: {e}")
yield
# Shutdown
app = FastAPI(
title="GeoQuery API",
description="Geospatial Analysis Agent API",
version="0.1.0",
lifespan=lifespan
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all for dev
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(api_router, prefix="/api/v1")
# Serve static files (Frontend)
static_dir = Path(__file__).parent / "static"
if static_dir.exists():
app.mount("/_next", StaticFiles(directory=static_dir / "_next"), name="next")
# app.mount("/assets", StaticFiles(directory=static_dir / "assets"), name="assets") # Standard Next.js Output might not use this top-level
@app.get("/{full_path:path}")
async def serve_frontend(full_path: str):
# API requests are already handled by include_router above (because specific routes take precedence? No, order matters).
# Wait, explicit routes define earlier take precedence.
# But include_router adds routes.
# A catch-all route /{full_path:path} will capture everything NOT matched by previous routes.
# Since api_router is included first (implicitly? No, verify order).
# FastAPI router priority: First declared wins.
# So app.include_router MUST be before this catch-all. It is.
file_path = static_dir / full_path
if file_path.exists() and file_path.is_file():
return FileResponse(file_path)
# Fallback to index.html for SPA routing
index_path = static_dir / "index.html"
if index_path.exists():
return FileResponse(index_path)
return {"error": "Frontend not found"}
else:
@app.get("/")
def read_root():
return {"message": "GeoQuery API is running (Frontend not built)"}
|