from fastapi import APIRouter, Query, HTTPException from fastapi.responses import JSONResponse from pathlib import Path import xml.etree.ElementTree as ET router = APIRouter(prefix="/badge", tags=["coverage", "badge"]) # ---------- Helper functions ---------- def parse_coverage_percentage(coverage_file: Path) -> float: """Parse the overall coverage percentage from coverage.xml.""" tree = ET.parse(coverage_file) root = tree.getroot() line_rate = float(root.attrib.get("line-rate", 0)) return round(line_rate * 100, 2) def get_color(pct: float) -> str: """Return badge color based on coverage.""" if pct >= 90: return "brightgreen" if pct >= 75: return "green" if pct >= 60: return "yellow" if pct >= 40: return "orange" return "red" # ---------- Route ---------- @router.get("/{project}", response_class=JSONResponse) async def get_coverage_badge(project: str): """ Return a Shields.io-compatible badge JSON for the given project's coverage. Example: /coverage/badge?project=mongo-ops Use with Shields.io: https://img.shields.io/endpoint?url=https://api.aetoskia.com/coverage/mongo-ops/badge """ project_dir = Path.cwd() / project coverage_file = project_dir / "coverage.xml" if not coverage_file.exists(): raise HTTPException(status_code=404, detail=f"No coverage.xml found in '{project}'") pct = parse_coverage_percentage(coverage_file) return { "schemaVersion": 1, "label": f"{project} coverage", "message": f"{pct}%", "color": get_color(pct), }