From 1ea32af19d0436d499f80f70f96280d2a497730c Mon Sep 17 00:00:00 2001 From: demo-bot Date: Sun, 9 Aug 2026 15:35:39 +0000 Subject: [PATCH] decomposer: generate deliverable files for Define the service contract and project architecture for the FastAPI endpoint monitoring service.; Implement the typed monitor CRUD API and concurrency-safe in-memory state according to the service design.; Implement secure on-demand endpoint checks with status updates, latency measurement, robust error handling, and redacted structured logs.; Add operational API endpoints and environment-driven runtime configuration to the monitoring service.; Create automated tests for the monitoring service.; Package the service with Docker and developer documentation.; Validate the complete project. --- app/main.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 app/main.py diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..dcfbbbb --- /dev/null +++ b/app/main.py @@ -0,0 +1,50 @@ +import logging +from contextlib import asynccontextmanager +from typing import AsyncIterator + +from fastapi import FastAPI, HTTPException, Request +from fastapi.exceptions import RequestValidationError +from fastapi.responses import JSONResponse + +from app.api import router +from app.checker import EndpointChecker +from app.settings import Settings, get_settings +from app.store import MonitorStore + + +def configure_logging(level: str) -> None: + logging.basicConfig(level=level.upper(), format="%(message)s") + + +def create_app(settings: Settings | None = None) -> FastAPI: + config = settings or get_settings() + + @asynccontextmanager + async def lifespan(application: FastAPI) -> AsyncIterator[None]: + configure_logging(config.log_level) + application.state.store = MonitorStore() + application.state.checker = EndpointChecker(config) + yield + + application = FastAPI(title="Endpoint Monitor", version="1.0.0", lifespan=lifespan) + application.include_router(router) + + @application.exception_handler(HTTPException) + async def http_error(_request: Request, exc: HTTPException) -> JSONResponse: + if isinstance(exc.detail, tuple): + code, message = exc.detail + else: + code, message = "http_error", str(exc.detail) + return JSONResponse(status_code=exc.status_code, + content={"error": {"code": code, "message": message}}, + headers=exc.headers) + + @application.exception_handler(RequestValidationError) + async def validation_error(_request: Request, _exc: RequestValidationError) -> JSONResponse: + return JSONResponse(status_code=422, content={"error": { + "code": "validation_error", "message": "Request validation failed"}}) + + return application + + +app = create_app()