Skip to main content

Lightweight ASGI health checks inspired by Spring Actuator

Project description

🩺 light-health

light-health é uma biblioteca Python leve, assíncrona e framework-agnostic para expor endpoints de health check e management no estilo Spring Boot Actuator, usando ASGI nativo e msgspec para máxima performance e baixo overhead.

🎯 Ideal para microsserviços, plataformas internas, sidecars e runtimes customizados.


✨ Principais Características

  • ASGI puro (sem dependência de FastAPI, Starlette ou Django)
  • Assíncrono
  • 🧱 Extensível via registry
  • 🚀 Alta performance com msgspec
  • 🔌 Plugável em qualquer framework ASGI
  • 🩺 Health, Readiness e Liveness
  • ⚙️ Management endpoints (loggers, env)
  • 📘 Compatível com Swagger/OpenAPI via adapter

📦 Instalação

pip install light-health

🧠 Conceito

Inspirado no Spring Actuator, a lib separa claramente:

  • Runtime (execução): ASGI puro, sem dependência de framework, ideal para produção
  • Contrato (documentação): Pode ser exposto via FastAPI, usado apenas para Swagger/OpenAPI

📁 Estrutura da Lib

light_health/
├── asgi/
│   ├── health.py        # Health / readiness / liveness
│   ├── management.py    # Loggers / Env
│   ├── management_models.py
├── checks/
│   ├── mongo.py
│   ├── redis.py
│   └── http.py
├── registry.py         # Registro de checks
├── status.py           # Status + agregação
└── __init__.py

🚀 Exemplo de Uso

from fastapi import FastAPI
import uvicorn
from pymongo import AsyncMongoClient
import redis.asyncio as redis

from light_health.asgi.base import HealthStatus,HealthCheck
from light_health.asgi.management import ManagementASGIApp
from light_health.asgi.health import HealthASGIApp
from light_health.registry import AsyncHealthRegistry
from light_health.status import HealthCheckResult, HealthState
from light_health.checks.mongo import mongo_health_check
from light_health.checks.redis import redis_health_check
from light_health.checks.http import http_health_check

mongo = AsyncMongoClient("mongodb://localhost:27017")
redis_client = redis.Redis(host="localhost", password="redis1234", port=6379)

registry = AsyncHealthRegistry()

async def process_alive():
    return HealthCheckResult(status=HealthState.UP)

registry.register_liveness("process", process_alive)
registry.register_readiness("mongo", mongo_health_check(mongo))
registry.register_readiness("redis", redis_health_check(redis_client))
registry.register_readiness(
    "external-api",
    http_health_check("https://httpbin.org/status/200"),
)

class MyCheck(HealthCheck):
    async def check(self) -> HealthStatus:
        return HealthStatus.up(details={"test_custom": "ok"})
    
registry_test = AsyncHealthRegistry()
registry_test.register_readiness("custom", MyCheck().check)

app = FastAPI()
app.mount("/actuator", HealthASGIApp(registry))
app.mount("/test", HealthASGIApp(registry_test))
app.mount("/management", ManagementASGIApp())

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Endpoints disponíveis:

🩺 Health Checks

Tipo Endpoint
Liveness /{root_path}/liveness
Readiness /{root_path}/readiness
Health /{root_path}/health
UP /{root_path}/up

🩺 Management

Tipo Endpoint
loggers /{root_path}/loggers
loggers update /{root_path}/loggers/update
env /{root_path}/env
env update /{root_path}/env/update

📘 Swagger / OpenAPI

Como os endpoints são ASGI puros, eles não aparecem automaticamente no Swagger.

Solução recomendada: criar rotas “espelho” apenas para documentação:

from light_health.management_models import LoggerUpdate, EnvUpdate

@app.post("/management/loggers/update", include_in_schema=True)
def update_logger_doc(payload: LoggerUpdate):
    """Atualiza o nível de um logger"""
    pass

O FastAPI usa isso apenas para gerar o OpenAPI. A execução real continua no ASGI.


⚙️ Management Endpoints

🔹 Loggers

  • Listar loggers:
    • GET /management/loggers
    • Resposta:
      {
        "root": "INFO",
        "uvicorn.error": "WARNING"
      }
      
  • Atualizar nível:
    • POST /management/loggers/update
    • Payload:
      {
        "level": "DEBUG",
        "logger_name": "uvicorn.error"
      }
      

🔹 Environment variables

  • Listar env:
    • GET /management/env
  • Atualizar env:
    • POST /management/env/update
    • Payload:
      {
        "key": "FEATURE_X",
        "value": "true"
      }
      

🚨 Segurança (IMPORTANTE)

⚠️ Nunca exponha /management publicamente!

Boas práticas:

  • Expor apenas em rede interna
  • Proteger via:
    • mTLS
    • Auth ASGI
    • NetworkPolicy (K8s)
  • Desabilitar /env em produção
  • Mesma recomendação do Spring Actuator

🧩 Extensibilidade

Criar um check customizado:

from light_health.checks.base import HealthCheck, HealthStatus

class MyCheck(HealthCheck):
    async def check(self) -> HealthStatus:
        return HealthStatus.up(details={"custom": "ok"})

⚡ Performance

  • msgspec para serialização
  • Async IO
  • Execução paralela dos checks
  • Overhead mínimo

Ideal para:

  • APIs de alta escala
  • Runtimes com pouco CPU/memória
  • Sidecars

🗺️ Roadmap

  • Auth ASGI
  • Metrics (Prometheus)
  • Feature flags
  • Info endpoint
  • Profiles (dev / prod)

🧠 Filosofia

Health e management são infra, não aplicação.

Essa lib foi pensada para:

  • Não acoplar frameworks
  • Ser reutilizável
  • Escalar com governança

📄 Licença

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

light_health-1.0.1.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

light_health-1.0.1-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file light_health-1.0.1.tar.gz.

File metadata

  • Download URL: light_health-1.0.1.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for light_health-1.0.1.tar.gz
Algorithm Hash digest
SHA256 cd27bdd7a719e38a2ed23533dff07a3d2c0676e58012bb207ffbab1f45ad4ef0
MD5 6343701c05a53a4c3e4553fc8e3bff68
BLAKE2b-256 44c09868a07cf6d5597002523986a7ac996e0ef9b49f6a68b2f3a09ca1226a0c

See more details on using hashes here.

File details

Details for the file light_health-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: light_health-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for light_health-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8fac3015c62f86305e3020ec93dffc2e80eb33f20cc6ea3ff7cd8e4dd1c9ba11
MD5 e8be1dbdf3729207aac042fcfb276a80
BLAKE2b-256 2aed427f30e59b1fd1facfce5df1ffbbba7689e400ed7c2b948a9aa86bcefa5e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page