Files
lux_fiscal/backend/app/api/v1/health.py
T
lauadminandClaude Sonnet 5 2664cb8213 Initial commit: backend scaffold, auth, frontend login
- FastAPI + SQLAlchemy async + Alembic + Postgres backend
- Auth: JWT access + rotating refresh tokens, argon2, roles, audit log
- React 19 + Vite frontend: login page, protected route, auth context
- Docker Compose: postgres, redis, migrate, api, worker (placeholder), frontend/nginx

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 15:07:15 +03:00

70 lines
2.1 KiB
Python

"""Проверки живости и готовности."""
from __future__ import annotations
from typing import Literal
import redis.asyncio as aioredis
from fastapi import APIRouter, Response, status
from pydantic import BaseModel
from sqlalchemy import text
from app.api.deps import SessionDep
from app.core.config import settings
from app.core.logging import get_logger
router = APIRouter(tags=["health"])
log = get_logger(__name__)
class HealthResponse(BaseModel):
status: Literal["ok", "degraded"]
environment: str
database: bool
redis: bool
@router.get("/health", response_model=HealthResponse)
async def health() -> HealthResponse:
"""Liveness: процесс жив. Внешние зависимости не проверяются.
Оркестратор не должен перезапускать контейнер из-за недоступного Postgres —
перезапуск приложения проблему БД не решает.
"""
return HealthResponse(
status="ok", environment=settings.environment, database=True, redis=True
)
@router.get("/health/ready", response_model=HealthResponse)
async def readiness(session: SessionDep, response: Response) -> HealthResponse:
"""Readiness: приложение способно обслуживать запросы."""
db_ok = True
redis_ok = True
try:
await session.execute(text("SELECT 1"))
except Exception as exc: # noqa: BLE001 — health-check не должен падать сам
db_ok = False
log.warning("readiness_db_failed", error=str(exc))
client = aioredis.from_url(settings.redis_url)
try:
await client.ping()
except Exception as exc: # noqa: BLE001
redis_ok = False
log.warning("readiness_redis_failed", error=str(exc))
finally:
await client.aclose()
healthy = db_ok and redis_ok
if not healthy:
response.status_code = status.HTTP_503_SERVICE_UNAVAILABLE
return HealthResponse(
status="ok" if healthy else "degraded",
environment=settings.environment,
database=db_ok,
redis=redis_ok,
)