Add initial work from Codex

This commit is contained in:
2026-03-20 15:13:33 +01:00
parent 19771ddd37
commit adb5c1a439
48 changed files with 7054 additions and 16 deletions

View File

@@ -0,0 +1 @@
"""Read-only MSSQL query microservice."""

View File

@@ -0,0 +1,85 @@
from __future__ import annotations
import logging
from contextlib import asynccontextmanager
import pandas as pd
from fastapi import Depends, FastAPI, Response
from app.core.config import settings
from app.core.otel import (
TelemetryProviders,
configure_otel,
instrument_fastapi,
instrument_sqlalchemy_engines,
shutdown_otel,
)
from app.core.security import InternalPrincipal, require_internal_principal
from app.db.engine import create_warehouse_engines, dispose_engines
from app.services.warehouse_service import ReadOnlyWarehouseClient
from microservices.common.http import current_trace_headers
logging.basicConfig(level=settings.log_level)
LOGGER = logging.getLogger(__name__)
def _frame_to_rows(df: pd.DataFrame) -> list[dict]:
rows: list[dict] = []
for _, row in df.iterrows():
payload: dict = {}
for key, value in row.items():
if hasattr(value, "isoformat"):
payload[str(key)] = value.isoformat()
else:
payload[str(key)] = value
rows.append(payload)
return rows
@asynccontextmanager
async def lifespan(app: FastAPI):
telemetry: TelemetryProviders = configure_otel(settings)
engines = create_warehouse_engines()
instrument_sqlalchemy_engines(engines)
app.state.query_client = ReadOnlyWarehouseClient(engines)
LOGGER.info("BI query service ready with read-only MSSQL engines")
yield
dispose_engines(engines)
shutdown_otel(telemetry)
app = FastAPI(title="bi-query-service", version="0.1.0", lifespan=lifespan)
instrument_fastapi(app)
@app.get("/internal/health")
def health(response: Response) -> dict:
response.headers.update(current_trace_headers())
return {"status": "ok", "service": "bi-query-service"}
@app.get("/internal/daily-sales")
def daily_sales(
response: Response, _auth: InternalPrincipal = Depends(require_internal_principal)
) -> list[dict]:
response.headers.update(current_trace_headers())
client: ReadOnlyWarehouseClient = app.state.query_client
return _frame_to_rows(client.fetch_daily_sales())
@app.get("/internal/product-performance")
def product_performance(
response: Response, _auth: InternalPrincipal = Depends(require_internal_principal)
) -> list[dict]:
response.headers.update(current_trace_headers())
client: ReadOnlyWarehouseClient = app.state.query_client
return _frame_to_rows(client.fetch_product_performance())
@app.get("/internal/customer-performance")
def customer_performance(
response: Response, _auth: InternalPrincipal = Depends(require_internal_principal)
) -> list[dict]:
response.headers.update(current_trace_headers())
client: ReadOnlyWarehouseClient = app.state.query_client
return _frame_to_rows(client.fetch_customer_performance())