from collections import defaultdict from typing import Any from fastapi import APIRouter, HTTPException from app.adapters.db import db from app.api.dsp import schemas from app.dsp.enums import DSPClientStatus, DSPId from app.dsp.gateway import dsp_gateway from app.dsp.models import DSPClient router = APIRouter(prefix="/dsp", tags=["DSP"]) def _client_schema(client: DSPClient) -> schemas.DSPClient: return schemas.DSPClient( id=client.id, name=client.name, display_name=client.display_name, client_id=client.client_id, status=client.status, configured=dsp_gateway.is_configured(client.name), stats=dsp_gateway.stats(client.name), nominal_rps=client.nominal_rps, ) @router.get( "/list", response_model=list[schemas.DSP], ) def get_dsps() -> Any: with db.autocommit(): clients = DSPClient.query.order_by(DSPClient.dsp_id, DSPClient.name).all() groups: defaultdict[DSPId, list[DSPClient]] = defaultdict(list) for client in clients: groups[client.dsp_id].append(client) return [ schemas.DSP(id=dsp_id, clients=[_client_schema(c) for c in cs]) for dsp_id, cs in sorted(groups.items()) ] @router.post( "/client/{name}/pause", response_model=schemas.DSPClient, ) def pause_dsp(name: str) -> Any: with db.transaction(): client = DSPClient.query.where(DSPClient.name == name).first() if client is None: raise HTTPException( status_code=404, detail=f"DSP client '{name}' not found" ) client.status = DSPClientStatus.paused client.save() return _client_schema(client) @router.post( "/client/{name}/resume", response_model=schemas.DSPClient, ) def resume_dsp(name: str) -> Any: with db.transaction(): client = DSPClient.query.where(DSPClient.name == name).first() if client is None: raise HTTPException( status_code=404, detail=f"DSP client '{name}' not found" ) client.status = DSPClientStatus.active client.save() return _client_schema(client)