Lonelyguyse1's picture
deploy: restore with README
2ce19b1
Raw
History Blame Contribute Delete
2.59 kB
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from pathlib import Path
import sentry_sdk
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from dotenv import load_dotenv
from app.api import router
from app.routes.auth import router as auth_router
load_dotenv(Path(__file__).resolve().parents[2] / ".env")
sentry_dsn = os.getenv("SENTRY_DSN", "").strip()
if sentry_dsn:
sentry_config = {
"dsn": sentry_dsn,
"environment": os.getenv("SENTRY_ENVIRONMENT", "").strip() or "production",
}
sentry_release = os.getenv("SENTRY_RELEASE", "").strip()
if sentry_release:
sentry_config["release"] = sentry_release
sentry_sdk.init(**sentry_config)
def frontend_directory():
app_root = Path(__file__).resolve().parents[1]
candidates = (
app_root / "frontend",
app_root.parent / "frontend",
app_root.parent.parent / "frontend",
Path("/frontend"),
)
return next((path for path in candidates if path.exists()), None)
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
from app.routes.preview import preload_pdfs
preload_pdfs()
_prewarm_cache()
yield
from app import cache
cache.close()
def _prewarm_cache():
"""Warm frequently-read caches at startup to avoid cold-start latency."""
import logging
import threading
logger = logging.getLogger(__name__)
def _worker():
try:
from app import cache
from app.supabase import supabase
rows = supabase.table("refined_submissions").select("id,status").in_("status", ["refined"]).eq("visible", True).order("id").execute().data
ids = [row["id"] for row in rows]
cache.put("all_course_ids", ids, ttl=300)
logger.info("Cache prewarm complete: %d courses", len(ids))
except Exception:
logger.debug("Cache prewarm failed", exc_info=True)
threading.Thread(target=_worker, daemon=True, name="cache-prewarm").start()
app = FastAPI(title="Syntagma", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router, prefix="/api")
app.include_router(auth_router, prefix="/api")
frontend_dir = frontend_directory()
if not frontend_dir:
raise RuntimeError("Frontend directory not found")
app.mount("/", StaticFiles(directory=frontend_dir, html=True), name="frontend")