Files
training-software/api/views.py
Paperclip CTO 8054c1e1e4 feat(TRA-233): Django M1 foundation scaffold
- Environment-split settings: base/local/test/prod with django-environ
- Postgres + Redis + Celery wiring (broker, beat, result backend)
- All 9 domain app stubs: accounts, courses, cms, tracking, quizzes,
  training, certificates, reports, notifications
- api app: /healthz/ endpoint, custom DRF exception handler,
  SecurityAuditMiddleware, permissions/throttle/upload-validation stubs
- DRF global baseline: JWT+session auth, closed-by-default permissions,
  cursor/page pagination, drf-spectacular schema generation
- Dockerfile (multi-env build arg), docker-compose.yml (local),
  docker-compose.test.yml (CI-friendly tmpfs Postgres)
- pytest.ini with smoke + settings marker definitions
- tests/test_smoke.py: startup, URL resolution, healthcheck shape
- tests/test_settings_matrix.py: per-profile security assertions
- .github/workflows/ci.yml: test, lint, schema CI jobs
- .env.example with all required vars documented
- .gitignore

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-07 09:11:23 +02:00

41 lines
1.2 KiB
Python

import time
from django.db import connection, OperationalError
from django.core.cache import cache
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
@api_view(["GET"])
@authentication_classes([])
@permission_classes([AllowAny])
def healthcheck(request):
"""Liveness + readiness probe endpoint. Returns 200 when all dependencies are reachable."""
checks = {}
overall_ok = True
# Database
try:
connection.ensure_connection()
checks["db"] = "ok"
except OperationalError as exc:
checks["db"] = f"error: {exc}"
overall_ok = False
# Cache / Redis
try:
key = "_healthcheck"
cache.set(key, "1", timeout=5)
assert cache.get(key) == "1"
checks["cache"] = "ok"
except Exception as exc:
checks["cache"] = f"error: {exc}"
overall_ok = False
http_status = status.HTTP_200_OK if overall_ok else status.HTTP_503_SERVICE_UNAVAILABLE
return Response(
{"status": "ok" if overall_ok else "degraded", "checks": checks},
status=http_status,
)