From a773ec26fcedb2540dc5a04acdf71269d704dc63 Mon Sep 17 00:00:00 2001 From: chrischristiansen-glitch Date: Fri, 12 Jun 2026 18:00:35 +0200 Subject: [PATCH] feat: add GET /docs/{path} proxy + browser panel prep --- main.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/main.py b/main.py index 6a6a78d..3b49496 100644 --- a/main.py +++ b/main.py @@ -10,6 +10,7 @@ CG5a: POST /notify/webhook — push til Slack/Teams/Chat/Discord/etc. CG5b: POST /notify/email — SendGrid digest til kunde-e-post. CG5c: POST /notify/sms — Twilio SMS, Guard+-tier, spike-varsler. CG5-onboard: GET /onboard + POST /onboard/complete — klient-onboarding wizard. +DOCS: GET /docs/{path} — proxy til privat GitHub-repo via ADC/PAT. """ import os @@ -146,6 +147,34 @@ if _static_dir.is_dir(): app.mount("/static", StaticFiles(directory=str(_static_dir), html=True), name="static") +# ── DOCS PROXY (MD-filer fra privat GitHub-repo) ────────────────────────────── +_GH_REPO = "vauco-saas/OSVauco" +_GH_BRANCH = os.environ.get("DOCS_BRANCH", "main") + +@app.get("/docs/{path:path}") +async def proxy_doc(path: str): + """ + Henter vilkårlig fil fra privat GitHub-repo. + Bruker GITHUB_PAT env-var (Secret Manager → Cloud Run). + Fallback: forsøker uten auth (fungerer ikke for private repos, men feiler pent). + """ + token = os.environ.get("GITHUB_PAT") + url = f"https://raw.githubusercontent.com/{_GH_REPO}/{_GH_BRANCH}/{path}" + headers = {"Authorization": f"token {token}"} if token else {} + try: + async with httpx.AsyncClient(timeout=10.0) as client: + resp = await client.get(url, headers=headers) + except httpx.TimeoutException: + raise HTTPException(status_code=504, detail="GitHub timeout") + if resp.status_code == 404: + raise HTTPException(status_code=404, detail=f"Fil ikke funnet: {path}") + if resp.status_code == 401: + raise HTTPException(status_code=503, detail="GitHub auth feilet — sjekk GITHUB_PAT i Secret Manager") + if resp.status_code != 200: + raise HTTPException(status_code=resp.status_code, detail="GitHub feil") + return Response(content=resp.text, media_type="text/plain; charset=utf-8") + + # ── MODELLER ────────────────────────────────────────────────────────────────── class RunRequest(BaseModel): message: str