from fastapi import FastAPI, HTTPException, Query from fastapi.responses import JSONResponse from pathlib import Path import xml.etree.ElementTree as ET app = FastAPI() @app.get("/health") async def health_check(): return {"status": "ok"} 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" @app.get("/badge", response_class=JSONResponse) async def get_coverage_badge(project: str = Query(..., description="Project folder name")): """ Return a Shields.io-compatible badge JSON for the given project's coverage. Example: /badge?project=mongo-ops Use with Shields.io: https://img.shields.io/endpoint?url=https://api.aetoskia.com/coverage/badge?project=mongo-ops """ 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) }