Files
ad/molodetz/routers/docs.py
T
retoor e512556703 Auto-generate docs downloads from the API group registry
Shared endpoint enricher builds curl, request, and response samples for
every registry endpoint so download.md/html stay complete without a
hand-maintained duplicate. Group pages reuse the same curl builder.
2026-10-05 16:00:14 +02:00

76 lines
3.2 KiB
Python

# retoor <retoor@molodetz.nl>
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse, PlainTextResponse
from molodetz.docs_api import group_by_slug, ordered_groups
from molodetz.docs_export import curl_example, export_html, export_markdown
from molodetz.docs_live import live_services
from molodetz.docs_prose import page_by_slug, render_page, sidebar
from molodetz.docs_search import search
from molodetz.seo import base_seo_context, base_url
from molodetz.templating import templates
from molodetz.utils.auth import get_current_user, is_admin, not_found
router = APIRouter()
def _ctx(request, title, **extra):
viewer = get_current_user(request)
viewer_is_admin = is_admin(viewer)
groups = [group for group in ordered_groups() if viewer_is_admin or group["slug"] != "admin"]
seo = base_seo_context(request, title, breadcrumbs=[("Molodetz", "/"), ("Docs", "/docs")])
return {"sidebar": sidebar(viewer_is_admin), "api_groups": groups, "viewer_is_admin": viewer_is_admin, "seo": seo, "doc_title": title, **extra}
@router.get("/docs")
async def docs_index(request: Request):
return templates.TemplateResponse(request, "docs/index.html", _ctx(request, "Documentation", body=render_page("welcome")))
@router.get("/docs/search")
async def docs_search(request: Request):
query = request.query_params.get("q", "")[:200]
viewer_is_admin = is_admin(get_current_user(request))
results = search(query, viewer_is_admin)
return templates.TemplateResponse(request, "docs/search.html", _ctx(request, "Search", query=query, results=results))
@router.get("/docs/download.md")
async def docs_download_md(request: Request):
viewer_is_admin = is_admin(get_current_user(request))
return PlainTextResponse(export_markdown(viewer_is_admin), media_type="text/markdown; charset=utf-8")
@router.get("/docs/download.html")
async def docs_download_html(request: Request):
viewer_is_admin = is_admin(get_current_user(request))
return HTMLResponse(export_html(viewer_is_admin))
@router.get("/docs/api/{group_slug}")
async def docs_api_group(request: Request, group_slug: str):
group = group_by_slug(group_slug)
viewer = get_current_user(request)
if group is None or (group["slug"] == "admin" and not is_admin(viewer)):
not_found("Unknown API group")
base = base_url(request)
username = viewer["username"] if viewer else "retoor"
api_key = viewer["api_key"] if viewer else "YOUR_API_KEY"
endpoints = []
for item in group["endpoints"]:
endpoints.append({**item, "curl": curl_example(item, base, username, api_key)})
return templates.TemplateResponse(
request,
"docs/api.html",
_ctx(request, f"API: {group['title']}", group=group, endpoints=endpoints, viewer=viewer, services=live_services() if group["slug"] == "admin" else []),
)
@router.get("/docs/{slug}")
async def docs_page(request: Request, slug: str):
page = page_by_slug(slug)
viewer_is_admin = is_admin(get_current_user(request))
if page is None or (page.get("admin") and not viewer_is_admin):
not_found("Page not found")
return templates.TemplateResponse(request, "docs/page.html", _ctx(request, page["title"], body=render_page(slug), page=page))