perch / backend /main.py
GerardCB's picture
Fix 405 when saving a drawn layer in the deployed build
05d7afb verified
Raw
History Blame Contribute Delete
1.82 kB
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from pathlib import Path
from backend.api.api import api_router
app = FastAPI(
title="Perch API",
description="Avian distribution intelligence API (eBird Status and Trends)",
version="0.1.0",
)
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 the built frontend, if present. Registered after the API router so that
# the catch-all below cannot shadow /api/v1 routes.
static_dir = Path(__file__).parent / "static"
if static_dir.exists():
app.mount("/_next", StaticFiles(directory=static_dir / "_next"), name="next")
@app.get("/{full_path:path}")
async def serve_frontend(full_path: str):
# An unknown API path is an error, not a page. Falling through to
# index.html here would answer a bad API call with HTML and a 200,
# and it makes this route shadow the API for non-GET methods.
if full_path.startswith("api/"):
raise HTTPException(status_code=404, detail=f"No such API route: /{full_path}")
file_path = static_dir / full_path
if file_path.exists() and file_path.is_file():
return FileResponse(file_path)
# Fall back to index.html so client-side routing works.
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": "Perch API is running (frontend not built)"}