feat: indie status page MVP -- FastAPI + SQLite
- 8 DB models (services, incidents, monitors, subscribers, etc.) - Full CRUD API for services, incidents, monitors - Public status page with live data - Incident detail page with timeline - API key authentication - Uptime monitoring scheduler - 13 tests passing - TECHNICAL_DESIGN.md with full spec
This commit is contained in:
commit
902133edd3
4655 changed files with 1342691 additions and 0 deletions
|
|
@ -0,0 +1,34 @@
|
|||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
|
||||
from fastapi.utils import is_body_allowed_for_status_code
|
||||
from fastapi.websockets import WebSocket
|
||||
from starlette.exceptions import HTTPException
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import JSONResponse, Response
|
||||
from starlette.status import WS_1008_POLICY_VIOLATION
|
||||
|
||||
|
||||
async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
|
||||
headers = getattr(exc, "headers", None)
|
||||
if not is_body_allowed_for_status_code(exc.status_code):
|
||||
return Response(status_code=exc.status_code, headers=headers)
|
||||
return JSONResponse(
|
||||
{"detail": exc.detail}, status_code=exc.status_code, headers=headers
|
||||
)
|
||||
|
||||
|
||||
async def request_validation_exception_handler(
|
||||
request: Request, exc: RequestValidationError
|
||||
) -> JSONResponse:
|
||||
return JSONResponse(
|
||||
status_code=422,
|
||||
content={"detail": jsonable_encoder(exc.errors())},
|
||||
)
|
||||
|
||||
|
||||
async def websocket_request_validation_exception_handler(
|
||||
websocket: WebSocket, exc: WebSocketRequestValidationError
|
||||
) -> None:
|
||||
await websocket.close(
|
||||
code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue