diff --git a/app/__init__.py b/app/__init__.py index 5de6621..01477ba 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -164,12 +164,13 @@ def create_app() -> FastAPI: return JSONResponse({"detail": "Not found"}, status_code=404) # Include routers - from .routers import auth, storage, api, recipes, cache, runs, home, effects, inbox + from .routers import auth, storage, api, recipes, cache, runs, home, effects, inbox, fragments # Home and auth routers (root level) app.include_router(home.router, tags=["home"]) app.include_router(auth.router, prefix="/auth", tags=["auth"]) app.include_router(inbox.router, tags=["inbox"]) + app.include_router(fragments.router, tags=["fragments"]) # Feature routers app.include_router(storage.router, prefix="/storage", tags=["storage"]) diff --git a/app/routers/fragments.py b/app/routers/fragments.py new file mode 100644 index 0000000..76935fe --- /dev/null +++ b/app/routers/fragments.py @@ -0,0 +1,27 @@ +""" +Art-DAG fragment endpoints. + +Exposes HTML fragments at ``/internal/fragments/{type}`` for consumption +by coop apps via the fragment client. +""" + +from fastapi import APIRouter, Request, Response + +router = APIRouter() + +# Registry of fragment handlers: type -> async callable(request) returning HTML str +_handlers: dict[str, object] = {} + +FRAGMENT_HEADER = "X-Fragment-Request" + + +@router.get("/internal/fragments/{fragment_type}") +async def get_fragment(fragment_type: str, request: Request): + if not request.headers.get(FRAGMENT_HEADER): + return Response(content="", status_code=403) + + handler = _handlers.get(fragment_type) + if handler is None: + return Response(content="", media_type="text/html", status_code=200) + html = await handler(request) + return Response(content=html, media_type="text/html", status_code=200)