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
/envem 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd27bdd7a719e38a2ed23533dff07a3d2c0676e58012bb207ffbab1f45ad4ef0
|
|
| MD5 |
6343701c05a53a4c3e4553fc8e3bff68
|
|
| BLAKE2b-256 |
44c09868a07cf6d5597002523986a7ac996e0ef9b49f6a68b2f3a09ca1226a0c
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fac3015c62f86305e3020ec93dffc2e80eb33f20cc6ea3ff7cd8e4dd1c9ba11
|
|
| MD5 |
e8be1dbdf3729207aac042fcfb276a80
|
|
| BLAKE2b-256 |
2aed427f30e59b1fd1facfce5df1ffbbba7689e400ed7c2b948a9aa86bcefa5e
|