Initial travel knowledge graph release
This commit is contained in:
59
app/main.py
Normal file
59
app/main.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""City Knowledge Graph Admin — FastAPI entry point."""
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
from app.api import api_router
|
||||
from app.db import init_pool, close_pool
|
||||
|
||||
|
||||
class SPAStaticFiles(StaticFiles):
|
||||
"""Serve the admin SPA with client-side-routing fallback.
|
||||
|
||||
Any unknown path under /admin (e.g. /admin/login-v2, /admin/plaza/graph)
|
||||
falls back to index.html so React Router can handle it on a hard
|
||||
navigation or page refresh — instead of returning a 404.
|
||||
"""
|
||||
|
||||
async def get_response(self, path: str, scope):
|
||||
try:
|
||||
return await super().get_response(path, scope)
|
||||
except StarletteHTTPException as exc:
|
||||
if exc.status_code == 404:
|
||||
return await super().get_response("index.html", scope)
|
||||
raise
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(_app: FastAPI):
|
||||
await init_pool()
|
||||
yield
|
||||
await close_pool()
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="ZN-KG Admin",
|
||||
version="0.1.0",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.include_router(api_router)
|
||||
|
||||
# Serve built admin-web SPA (when available)
|
||||
try:
|
||||
app.mount("/admin", SPAStaticFiles(directory="app/static/admin", html=True), name="admin-web")
|
||||
except Exception:
|
||||
pass
|
||||
Reference in New Issue
Block a user