mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 23:50:12 +01:00
feat(preview): sampling, metrics, governance, server mana data
Preview endpoint + fast caches; curated pins + role quotas + rarity/overlap tuning; catalog+preview metrics; governance enforcement flags; server mana/color identity fields; docs/tests/scripts updated.
This commit is contained in:
parent
8f47dfbb81
commit
c4a7fc48ea
40 changed files with 6092 additions and 17312 deletions
|
|
@ -14,13 +14,41 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
|||
from starlette.middleware.gzip import GZipMiddleware
|
||||
from typing import Any
|
||||
from .services.combo_utils import detect_all as _detect_all
|
||||
from .services.theme_catalog_loader import prewarm_common_filters # type: ignore
|
||||
|
||||
# Resolve template/static dirs relative to this file
|
||||
_THIS_DIR = Path(__file__).resolve().parent
|
||||
_TEMPLATES_DIR = _THIS_DIR / "templates"
|
||||
_STATIC_DIR = _THIS_DIR / "static"
|
||||
|
||||
app = FastAPI(title="MTG Deckbuilder Web UI")
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def _lifespan(app: FastAPI): # pragma: no cover - simple infra glue
|
||||
"""FastAPI lifespan context replacing deprecated on_event startup hooks.
|
||||
|
||||
Consolidates previous startup tasks:
|
||||
- prewarm_common_filters (optional fast filter cache priming)
|
||||
- theme preview card index warm (CSV parse avoidance for first preview)
|
||||
|
||||
Failures in warm tasks are intentionally swallowed to avoid blocking app start.
|
||||
"""
|
||||
# Prewarm theme filter cache (guarded internally by env flag)
|
||||
try:
|
||||
prewarm_common_filters()
|
||||
except Exception:
|
||||
pass
|
||||
# Warm preview card index once
|
||||
try: # local import to avoid cost if preview unused
|
||||
from .services import theme_preview as _tp # type: ignore
|
||||
_tp._maybe_build_card_index() # internal warm function
|
||||
except Exception:
|
||||
pass
|
||||
yield # (no shutdown tasks currently)
|
||||
|
||||
|
||||
app = FastAPI(title="MTG Deckbuilder Web UI", lifespan=_lifespan)
|
||||
app.add_middleware(GZipMiddleware, minimum_size=500)
|
||||
|
||||
# Mount static if present
|
||||
|
|
@ -64,6 +92,8 @@ def _compat_template_response(*args, **kwargs): # type: ignore[override]
|
|||
|
||||
templates.TemplateResponse = _compat_template_response # type: ignore[assignment]
|
||||
|
||||
# (Startup prewarm moved to lifespan handler _lifespan)
|
||||
|
||||
# Global template flags (env-driven)
|
||||
def _as_bool(val: str | None, default: bool = False) -> bool:
|
||||
if val is None:
|
||||
|
|
@ -80,6 +110,7 @@ ENABLE_PRESETS = _as_bool(os.getenv("ENABLE_PRESETS"), False)
|
|||
ALLOW_MUST_HAVES = _as_bool(os.getenv("ALLOW_MUST_HAVES"), False)
|
||||
RANDOM_MODES = _as_bool(os.getenv("RANDOM_MODES"), False) # initial snapshot (legacy)
|
||||
RANDOM_UI = _as_bool(os.getenv("RANDOM_UI"), False)
|
||||
THEME_PICKER_DIAGNOSTICS = _as_bool(os.getenv("WEB_THEME_PICKER_DIAGNOSTICS"), False)
|
||||
def _as_int(val: str | None, default: int) -> int:
|
||||
try:
|
||||
return int(val) if val is not None and str(val).strip() != "" else default
|
||||
|
|
@ -109,6 +140,7 @@ templates.env.globals.update({
|
|||
"random_ui": RANDOM_UI,
|
||||
"random_max_attempts": RANDOM_MAX_ATTEMPTS,
|
||||
"random_timeout_ms": RANDOM_TIMEOUT_MS,
|
||||
"theme_picker_diagnostics": THEME_PICKER_DIAGNOSTICS,
|
||||
})
|
||||
|
||||
# --- Simple fragment cache for template partials (low-risk, TTL-based) ---
|
||||
|
|
@ -552,6 +584,8 @@ try:
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
## (Additional startup warmers consolidated into lifespan handler)
|
||||
|
||||
# --- Exception handling ---
|
||||
def _wants_html(request: Request) -> bool:
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue