from fastapi import APIRouter, HTTPException, Query from typing import Optional from app.db import get_db from app.api.models import CommodityMeta, ExchangeInfo router = APIRouter(prefix="/api", tags=["commodities"]) @router.get("/exchanges", response_model=list[ExchangeInfo]) def get_exchanges(): with get_db() as conn: rows = conn.execute( """ SELECT exchange_abbr, exchange, COUNT(*) AS commodity_count FROM commodities GROUP BY exchange_abbr ORDER BY commodity_count DESC """ ).fetchall() return [ExchangeInfo(**dict(r)) for r in rows] @router.get("/commodities", response_model=list[CommodityMeta]) def get_commodities(exchange: Optional[str] = Query(None)): sql = """ SELECT c.cftc_code, c.name, c.exchange, c.exchange_abbr, c.contract_unit, MIN(r.report_date) AS first_date, MAX(r.report_date) AS last_date, COUNT(DISTINCT r.report_date) AS week_count FROM commodities c LEFT JOIN reports r ON r.commodity_id = c.id """ params = [] if exchange: sql += " WHERE c.exchange_abbr = ?" params.append(exchange) sql += " GROUP BY c.id ORDER BY c.exchange_abbr, c.name" with get_db() as conn: rows = conn.execute(sql, params).fetchall() return [CommodityMeta(**dict(r)) for r in rows] @router.get("/commodities/{cftc_code}", response_model=CommodityMeta) def get_commodity(cftc_code: str): with get_db() as conn: row = conn.execute( """ SELECT c.cftc_code, c.name, c.exchange, c.exchange_abbr, c.contract_unit, MIN(r.report_date) AS first_date, MAX(r.report_date) AS last_date, COUNT(DISTINCT r.report_date) AS week_count FROM commodities c LEFT JOIN reports r ON r.commodity_id = c.id WHERE c.cftc_code = ? GROUP BY c.id """, (cftc_code,), ).fetchone() if not row: raise HTTPException(status_code=404, detail=f"Commodity {cftc_code} not found") return CommodityMeta(**dict(row))