"""bincio serve — multi-user FastAPI application server. Handles auth, user management, and auth-gated write operations. nginx serves static files; this server only handles /api/* routes. Run via `bincio serve` CLI command. """ from __future__ import annotations import glob as _glob import threading from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware from bincio.serve import deps, tasks from bincio.serve.routers import ( activities, admin, auth, download, feed, garmin, gear, ideas, me, ogimage, segments, strava, uploads, ) app = FastAPI(title="BincioActivity Serve") @app.on_event("startup") async def _on_startup() -> None: """Startup tasks: clean orphaned tmp zips; launch site-rebuild worker if --webroot set.""" data_dir = deps._get_data_dir() for p in _glob.glob(str(data_dir / "*" / "tmp*.zip")): try: Path(p).unlink() except OSError: pass if deps.webroot is not None: threading.Thread(target=tasks._site_rebuild_worker, daemon=True, name="site-rebuild").start() app.add_middleware(GZipMiddleware, minimum_size=1024) app.add_middleware( CORSMiddleware, allow_origin_regex=r"https?://localhost(:\d+)?|https://[a-z0-9-]+\.bincio\.org", allow_credentials=True, allow_methods=["GET", "POST", "DELETE"], allow_headers=["Content-Type"], ) for _router in [ feed.router, auth.router, me.router, admin.router, activities.router, download.router, uploads.router, segments.router, strava.router, garmin.router, ideas.router, ogimage.router, gear.router, ]: app.include_router(_router)