From 3e978e525a14cffa18f3078a61cd848472362ff8 Mon Sep 17 00:00:00 2001 From: hideyukiMORI Date: Tue, 19 May 2026 20:20:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20/health=20=E3=82=A8=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=83=9D=E3=82=A4=E3=83=B3=E3=83=88=E3=82=92=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=81=99=E3=82=8B=20(#7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HealthStatus dataclass と HealthCheckProtocol を nene2.http に追加 - /health エンドポイントを HealthStatus ベースに刷新(200 ok / 503 degraded) - PHP 版 HealthCheckInterface に対応 Co-Authored-By: Claude Sonnet 4.6 --- src/example/app.py | 7 +++++-- src/nene2/http/__init__.py | 5 ++++- src/nene2/http/health.py | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/nene2/http/health.py diff --git a/src/example/app.py b/src/example/app.py index 1c12356..f252a0b 100644 --- a/src/example/app.py +++ b/src/example/app.py @@ -4,6 +4,7 @@ from fastapi.responses import JSONResponse from nene2.config import AppSettings +from nene2.http import HealthStatus from nene2.middleware import ErrorHandlerMiddleware from nene2.validation.exceptions import ValidationException @@ -73,9 +74,11 @@ def create_app(settings: AppSettings | None = None) -> FastAPI: ) ) - @app.get("/health") + @app.get("/health", tags=["system"], summary="Health check") async def health() -> JSONResponse: - return JSONResponse({"status": "ok"}) + status = HealthStatus(status="ok") + code = 200 if status.is_healthy else 503 + return JSONResponse({"status": status.status, "checks": status.checks}, status_code=code) return app diff --git a/src/nene2/http/__init__.py b/src/nene2/http/__init__.py index e317ea5..02624f3 100644 --- a/src/nene2/http/__init__.py +++ b/src/nene2/http/__init__.py @@ -1,9 +1,12 @@ -"""HTTP helpers — JSON responses, pagination, problem details.""" +"""HTTP helpers — JSON responses, pagination, problem details, health.""" +from .health import HealthCheckProtocol, HealthStatus from .pagination import PaginationQuery, PaginationQueryParser, PaginationResponse from .problem_details import problem_details_response __all__ = [ + "HealthCheckProtocol", + "HealthStatus", "PaginationQuery", "PaginationQueryParser", "PaginationResponse", diff --git a/src/nene2/http/health.py b/src/nene2/http/health.py new file mode 100644 index 0000000..6690e7b --- /dev/null +++ b/src/nene2/http/health.py @@ -0,0 +1,20 @@ +"""HealthCheckProtocol and HealthStatus — framework health check contract.""" + +from dataclasses import dataclass, field +from typing import Protocol + + +@dataclass(frozen=True, slots=True) +class HealthStatus: + status: str + checks: dict[str, str] = field(default_factory=dict) + + @property + def is_healthy(self) -> bool: + return self.status == "ok" + + +class HealthCheckProtocol(Protocol): + """Contract for application health checks.""" + + def check(self) -> HealthStatus: ...