from __future__ import annotations from fastapi import Request from fastapi.responses import JSONResponse, RedirectResponse, Response def wants_json(request: Request) -> bool: path = request.url.path or "" accept = (request.headers.get("accept") or "").lower() requested_with = (request.headers.get("x-requested-with") or "").lower() return path.startswith("/api") or "application/json" in accept or requested_with == "xmlhttprequest" def ui_access_denied(message: str = "Access denied") -> Response: return Response( content=f"403 Forbidden: {message}", status_code=403, media_type="text/plain; charset=utf-8", ) def ui_not_found(message: str = "Not found") -> Response: return Response( content=f"404 Not Found: {message}", status_code=404, media_type="text/plain; charset=utf-8", ) def auth_required_response(request: Request): if wants_json(request): return JSONResponse({"detail": "Not authenticated"}, status_code=401) return RedirectResponse(url="/login", status_code=303) def forbidden_response(request: Request, message: str = "Access denied"): if wants_json(request): return JSONResponse({"detail": message}, status_code=403) return ui_access_denied(message) def not_found_response(request: Request, message: str = "Not found"): if wants_json(request): return JSONResponse({"detail": message}, status_code=404) return ui_not_found(message)