diff --git a/server.py b/server.py index 51e8c05..abc99e8 100644 --- a/server.py +++ b/server.py @@ -1652,22 +1652,28 @@ async def get_asset_by_name_legacy(name: str): @app.get("/assets/{name}") async def get_asset(name: str, request: Request): - """Get asset by name. HTML for browsers, JSON for APIs.""" + """Get asset by name. HTML for browsers (default), JSON only if explicitly requested.""" registry = await load_registry() + + # Check if JSON explicitly requested + accept = request.headers.get("accept", "") + wants_json = "application/json" in accept and "text/html" not in accept + if name not in registry.get("assets", {}): - if wants_html(request): - content = f''' -

Asset Not Found

-

No asset named "{name}" exists.

-

← Back to Assets

- ''' - return HTMLResponse(base_html("Asset Not Found", content, get_user_from_cookie(request))) - raise HTTPException(404, f"Asset not found: {name}") + if wants_json: + raise HTTPException(404, f"Asset not found: {name}") + content = f''' +

Asset Not Found

+

No asset named "{name}" exists.

+

← Back to Assets

+ ''' + return HTMLResponse(base_html("Asset Not Found", content, get_user_from_cookie(request))) - if wants_html(request): - return await ui_asset_detail(name, request) + if wants_json: + return registry["assets"][name] - return registry["assets"][name] + # Default to HTML for browsers + return await ui_asset_detail(name, request) @app.get("/assets/by-run-id/{run_id}") @@ -2372,26 +2378,30 @@ async def get_activities(request: Request, page: int = 1, limit: int = 20): @app.get("/activities/{activity_index}") async def get_activity_detail(activity_index: int, request: Request): - """Get single activity. HTML for browsers, JSON for APIs.""" + """Get single activity. HTML for browsers (default), JSON only if explicitly requested.""" activities = await load_activities() + # Check if JSON explicitly requested + accept = request.headers.get("accept", "") + wants_json = ("application/json" in accept or "application/activity+json" in accept) and "text/html" not in accept + if activity_index < 0 or activity_index >= len(activities): - if wants_html(request): - content = ''' -

Activity Not Found

-

This activity does not exist.

-

← Back to Activities

- ''' - return HTMLResponse(base_html("Activity Not Found", content, get_user_from_cookie(request))) - raise HTTPException(404, "Activity not found") + if wants_json: + raise HTTPException(404, "Activity not found") + content = ''' +

Activity Not Found

+

This activity does not exist.

+

← Back to Activities

+ ''' + return HTMLResponse(base_html("Activity Not Found", content, get_user_from_cookie(request))) activity = activities[activity_index] - if wants_html(request): - # Reuse the UI activity detail logic - return await ui_activity_detail(activity_index, request) + if wants_json: + return activity - return activity + # Default to HTML for browsers + return await ui_activity_detail(activity_index, request) @app.get("/activity/{activity_index}") @@ -2408,12 +2418,12 @@ async def get_object(content_hash: str, request: Request): # Find asset by hash for name, asset in registry.get("assets", {}).items(): if asset.get("content_hash") == content_hash: - # Check Accept header for content negotiation + # Check Accept header - only return JSON if explicitly requested accept = request.headers.get("accept", "") - wants_html = "text/html" in accept and "application/json" not in accept and "application/activity+json" not in accept + wants_json = ("application/json" in accept or "application/activity+json" in accept) and "text/html" not in accept - if wants_html: - # Redirect to detail page for browsers + if not wants_json: + # Default: redirect to detail page for browsers return RedirectResponse(url=f"/assets/{name}", status_code=303) owner = asset.get("owner", "unknown")