# ============================================================================= # QWHPI — Quebec Weekly Housing Price Index # Author : Simon-Pierre Boucher # Contact : contact@spboucher.ai # File : api/app/deps.py # Purpose : Shared dependencies — series validation, ETag and CSV helpers. # ============================================================================= """Shared FastAPI dependencies and response helpers.""" from __future__ import annotations import hashlib import polars as pl from fastapi import HTTPException, Request, Response from app.services import data VALID_TYPES = {"all", "unifamilial", "condo", "plex"} def validate_series(geography: str, property_type: str) -> None: if property_type not in VALID_TYPES: raise HTTPException(422, f"property_type must be one of {sorted(VALID_TYPES)}") if geography not in data.geography_ids(): raise HTTPException(404, f"unknown geography '{geography}' — see /v1/geographies") def etag_for(request: Request, response: Response, *parts: str) -> bool: """Set the ETag; return True when the client's copy is fresh (304).""" raw = "|".join([data.data_vintage(), data.model_version(), str(request.url), *parts]) tag = '"' + hashlib.sha256(raw.encode()).hexdigest()[:32] + '"' response.headers["ETag"] = tag response.headers["Cache-Control"] = "public, max-age=300" return request.headers.get("if-none-match") == tag def csv_response(df: pl.DataFrame) -> Response: return Response( content=df.write_csv(), media_type="text/csv", headers={"X-Author": "Simon-Pierre Boucher "}, )