diff --git a/django_healthy/health_checks/__init__.py b/django_healthy/health_checks/__init__.py
index e6e7b26..39286eb 100644
--- a/django_healthy/health_checks/__init__.py
+++ b/django_healthy/health_checks/__init__.py
@@ -1,7 +1,13 @@
from .base import HealthCheck, HealthCheckResult, HealthStatus
+from .service import HealthCheckService, HealthReport, HealthReportEntry
__all__ = [
"HealthCheck",
"HealthCheckResult",
"HealthStatus",
+ "HealthCheckService",
+ "HealthReport",
+ "HealthReportEntry",
]
+
+health_check_service = HealthCheckService()
diff --git a/django_healthy/templates/django_healthy/report.html b/django_healthy/templates/django_healthy/report.html
new file mode 100644
index 0000000..b75e861
--- /dev/null
+++ b/django_healthy/templates/django_healthy/report.html
@@ -0,0 +1,24 @@
+
+
+
+ Health Report
+
+
+
+
+ System |
+ Status |
+ Time |
+
+
+ {% for system, reported in report.entries.items %}
+
+ {{ system }} |
+ {{ reported.status.name }} |
+ {{ reported.duration.total_seconds }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/django_healthy/urls.py b/django_healthy/urls.py
index f98f419..1f4bc5a 100644
--- a/django_healthy/urls.py
+++ b/django_healthy/urls.py
@@ -1,9 +1,10 @@
from django.urls import path
-from .views import LivenessView
+from .views import HealthView, LivenessView
app_name = "django_healthy"
urlpatterns = [
path("ping/", LivenessView.as_view(), name="ping"),
+ path("health/", HealthView.as_view(), name="health"),
]
diff --git a/django_healthy/views.py b/django_healthy/views.py
index ef11cb3..2fe9401 100644
--- a/django_healthy/views.py
+++ b/django_healthy/views.py
@@ -3,8 +3,11 @@
from typing import ClassVar
from django.http import HttpRequest, HttpResponse
+from django.template.response import TemplateResponse
from django.views import View
+from .health_checks import HealthReport, health_check_service
+
class LivenessView(View):
http_method_names: ClassVar[list[str]] = [
@@ -16,3 +19,17 @@ class LivenessView(View):
async def get(self, request: HttpRequest) -> HttpResponse: # noqa: ARG002
return HttpResponse("Pong")
+
+
+class HealthView(View):
+ http_method_names: ClassVar[list[str]] = [
+ "get",
+ "head",
+ "options",
+ "trace",
+ ]
+
+ async def get(self, request: HttpRequest) -> HttpResponse:
+ report: HealthReport = await health_check_service.check_health()
+ context: dict[str, HealthReport] = {"report": report}
+ return TemplateResponse(request, "django_healthy/report.html", context)
diff --git a/tests/test_views.py b/tests/test_views.py
index a8ab1f0..c04528a 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -39,3 +39,20 @@ async def test_methods_not_allowed_async(self, method: str, async_client: AsyncC
response: HttpResponse = await django_client_method(reverse("django_healthy:ping"))
assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED
+
+
+class TestHealthView:
+ @pytest.mark.asyncio
+ async def test_get_async(self, async_client: AsyncClient):
+ response: HttpResponse = await async_client.get(reverse("django_healthy:health"))
+
+ assert response.status_code == HTTPStatus.OK
+
+ @pytest.mark.asyncio
+ @pytest.mark.parametrize("method", ["post", "put", "patch", "delete"])
+ async def test_methods_not_allowed_async(self, method: str, async_client: AsyncClient):
+ django_client_method = getattr(async_client, method)
+
+ response: HttpResponse = await django_client_method(reverse("django_healthy:health"))
+
+ assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED