paper-dynasty-database/app/main.py
Cal Corum 419fb757df
All checks were successful
Build Docker Image / build (push) Successful in 8m3s
Build Docker Image / build (pull_request) Successful in 7m55s
Merge main into next-release
Resolve conflicts in app/main.py and app/routers_v2/players.py:
keep main's render pipeline optimization (Phase 0) with asyncio.Lock,
error-tolerant shutdown, and --no-sandbox launch args. The next-release
browser code was an earlier version of the same feature.

Add evolution router import and inclusion from next-release.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:53:46 -05:00

133 lines
3.6 KiB
Python

import logging
import os
from contextlib import asynccontextmanager
from datetime import datetime
from fastapi import FastAPI, Request
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.openapi.utils import get_openapi
_log_date = f"{datetime.now().year}-{datetime.now().month}-{datetime.now().day}"
logging.basicConfig(
filename=f"logs/database/{_log_date}.log",
format="%(asctime)s - database - %(levelname)s - %(message)s",
level=logging.INFO if os.environ.get("LOG_LEVEL") == "INFO" else logging.WARNING,
)
# from fastapi.staticfiles import StaticFiles
# from fastapi.templating import Jinja2Templates
from .db_engine import db
from .routers_v2.players import get_browser, shutdown_browser
from .routers_v2 import (
current,
awards,
teams,
rarity,
cardsets,
players,
packtypes,
packs,
cards,
events,
results,
rewards,
decisions,
batstats,
pitstats,
notifications,
paperdex,
gamerewards,
gauntletrewards,
gauntletruns,
battingcards,
battingcardratings,
pitchingcards,
pitchingcardratings,
cardpositions,
scouting,
mlbplayers,
stratgame,
stratplays,
scout_opportunities,
scout_claims,
evolution,
)
@asynccontextmanager
async def lifespan(app):
# Startup: warm up the persistent Chromium browser
await get_browser()
yield
# Shutdown: clean up browser and playwright
await shutdown_browser()
app = FastAPI(
# root_path='/api',
lifespan=lifespan,
responses={404: {"description": "Not found"}},
docs_url="/api/docs",
redoc_url="/api/redoc",
)
# app.mount("/static", StaticFiles(directory="storage/static"), name="static")
# templates = Jinja2Templates(directory=os.path.dirname(os.path.abspath(__file__)))
app.include_router(current.router)
app.include_router(awards.router)
app.include_router(teams.router)
app.include_router(rarity.router)
app.include_router(cardsets.router)
app.include_router(players.router)
app.include_router(packtypes.router)
app.include_router(packs.router)
app.include_router(cards.router)
app.include_router(events.router)
app.include_router(results.router)
app.include_router(rewards.router)
app.include_router(batstats.router)
app.include_router(pitstats.router)
app.include_router(notifications.router)
app.include_router(paperdex.router)
app.include_router(gamerewards.router)
app.include_router(gauntletrewards.router)
app.include_router(gauntletruns.router)
app.include_router(battingcards.router)
app.include_router(battingcardratings.router)
app.include_router(pitchingcards.router)
app.include_router(pitchingcardratings.router)
app.include_router(cardpositions.router)
app.include_router(scouting.router)
app.include_router(mlbplayers.router)
app.include_router(stratgame.router)
app.include_router(stratplays.router)
app.include_router(decisions.router)
app.include_router(scout_opportunities.router)
app.include_router(scout_claims.router)
app.include_router(evolution.router)
@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
try:
db.connect(reuse_if_open=True)
response = await call_next(request)
return response
finally:
if not db.is_closed():
db.close()
@app.get("/api/docs", include_in_schema=False)
async def get_docs(req: Request):
return get_swagger_ui_html(
openapi_url=req.scope.get("root_path") + "/openapi.json", title="Swagger"
)
@app.get("/api/openapi.json", include_in_schema=False)
async def openapi():
return get_openapi(title="Paper Dynasty API", version="0.1.1", routes=app.routes)