adec664c52
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from fastapi import FastAPI, Request
|
|
from fastapi.responses import RedirectResponse
|
|
from jinja2 import Environment, FileSystemLoader
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
from app.database import engine, Base, SessionLocal
|
|
from app.models import User
|
|
from app.seed import seed
|
|
from app.routers import contracts, admin, auth, positions, trades
|
|
|
|
TEMPLATES_DIR = Path(__file__).parent / "templates"
|
|
|
|
|
|
def setup_jinja(app: FastAPI):
|
|
env = Environment(loader=FileSystemLoader(str(TEMPLATES_DIR)))
|
|
app.state.templates = env
|
|
|
|
|
|
class AuthMiddleware(BaseHTTPMiddleware):
|
|
async def dispatch(self, request: Request, call_next):
|
|
# Public paths
|
|
if request.url.path in ("/auth/login", "/auth/logout") or request.url.path.startswith("/auth/"):
|
|
return await call_next(request)
|
|
|
|
# Check session
|
|
user_id = request.cookies.get("ft_session")
|
|
if user_id:
|
|
db = SessionLocal()
|
|
try:
|
|
user = db.query(User).filter(User.id == int(user_id)).first()
|
|
if user:
|
|
request.state.user = user
|
|
return await call_next(request)
|
|
except (ValueError, TypeError):
|
|
pass
|
|
finally:
|
|
db.close()
|
|
|
|
# Redirect to login
|
|
return RedirectResponse(f"/auth/login?next={request.url.path}", status_code=303)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
setup_jinja(app)
|
|
Base.metadata.create_all(bind=engine)
|
|
seed()
|
|
yield
|
|
|
|
|
|
app = FastAPI(title="期货量化系统", lifespan=lifespan)
|
|
|
|
app.add_middleware(AuthMiddleware)
|
|
|
|
app.include_router(auth.router)
|
|
app.include_router(contracts.router)
|
|
app.include_router(admin.router)
|
|
app.include_router(positions.router)
|
|
app.include_router(trades.router)
|
|
|
|
|
|
@app.get("/")
|
|
def root():
|
|
return RedirectResponse("/contracts")
|