COTexplorer/app/api/routes/commodities.py
Greg 37f8eac932 Initial commit: CFTC COT Explorer
FastAPI application that ingests CFTC Commitments of Traders data into SQLite
and exposes it via a REST API with analytics endpoints (screener, percentile rank,
concentration). Includes CLI for historical and weekly data ingestion, Docker setup,
and a frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 11:23:00 +01:00

65 lines
2.2 KiB
Python

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))