From c5195ff51b1108d0cc14924e3a706ef0a4f97a43 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Mon, 3 Nov 2025 20:41:49 +0530 Subject: [PATCH] badge router --- main.py | 72 ++++++++++++++---------------------------------- routers/badge.py | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 routers/badge.py diff --git a/main.py b/main.py index b38281d..591d0d9 100644 --- a/main.py +++ b/main.py @@ -1,58 +1,28 @@ -from fastapi import FastAPI, HTTPException, Query -from fastapi.responses import JSONResponse -from pathlib import Path -import xml.etree.ElementTree as ET +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware -app = FastAPI() +from routers.badge import router as coverage_badge_router + +app = FastAPI(title="Coverage API") + +# Optional: CORS for your frontend or badges +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # tighten if needed + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Mount routers +app.include_router(coverage_badge_router) @app.get("/health") -async def health_check(): +async def root(): 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) - } +@app.get("/") +async def root(): + return {"message": "Coverage API is running"} diff --git a/routers/badge.py b/routers/badge.py new file mode 100644 index 0000000..75f53fb --- /dev/null +++ b/routers/badge.py @@ -0,0 +1,57 @@ +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), + }