Structured healthcheck endpoints with shallow and deep response tiers, concurrent check execution, and built-in support for PostgreSQL, Redis, SQLAlchemy, and FastAPI.
Project description
Vitals (Python)
Structured deep healthcheck endpoints for Python services. Register health checks, run them concurrently with timeouts, and expose them via FastAPI.
Install
pip install vitals
Install with optional dependencies for the checks and integrations you need:
pip install vitals[asyncpg] # PostgreSQL via asyncpg
pip install vitals[redis] # Redis via redis-py
pip install vitals[sqlalchemy] # PostgreSQL via SQLAlchemy
pip install vitals[fastapi] # FastAPI integration
pip install vitals[all] # Everything
Quick Start
from vitals import HealthcheckRegistry, Status, CheckResult
from vitals.checks.postgres import AsyncpgPoolCheck
from vitals.checks.redis import RedisPoolCheck
from vitals.integrations.fastapi import create_healthcheck_route
from fastapi import FastAPI
registry = HealthcheckRegistry(default_timeout=5.0)
# Add checks using existing connection pools
registry.add("postgres", AsyncpgPoolCheck(pool))
registry.add("redis", RedisPoolCheck(redis_pool))
# Or add a custom check
@registry.check("api")
async def check_api() -> CheckResult:
start = time.monotonic()
async with httpx.AsyncClient() as client:
resp = await client.get("https://api.example.com/ping")
latency = (time.monotonic() - start) * 1000
return CheckResult(
status=Status.HEALTHY if resp.is_success else Status.OUTAGE,
latency_ms=latency,
message="" if resp.is_success else f"HTTP {resp.status_code}",
)
# Mount as a FastAPI route
app = FastAPI()
app.include_router(create_healthcheck_route(
registry,
token=os.environ.get("HEALTHCHECK_TOKEN"),
))
API
HealthcheckRegistry
registry = HealthcheckRegistry(default_timeout=5.0)
registry.add(name, check, *, timeout=None)
Register a named async check function.
async def my_check() -> CheckResult:
return CheckResult(status=Status.HEALTHY, latency_ms=0.0, message="")
registry.add("service", my_check, timeout=3.0)
registry.check(name, *, timeout=None)
Decorator form of add.
@registry.check("service", timeout=3.0)
async def check_service() -> CheckResult:
...
await registry.run()
Execute all registered checks concurrently using asyncio.TaskGroup. Returns a HealthcheckResponse with the worst overall status.
response = await registry.run()
response.status # Status.HEALTHY
response.to_dict() # {'status': 'healthy', 'timestamp': '...', 'checks': {...}}
response.http_status_code # 200
Status
from vitals import Status
Status.HEALTHY # 2
Status.DEGRADED # 1
Status.OUTAGE # 0
Status.from_string("degraded") # Status.DEGRADED
Status.HEALTHY.json_value # "healthy"
Built-in Checks
PostgreSQL
from vitals.checks.postgres import AsyncpgCheck, AsyncpgPoolCheck, SQLAlchemyCheck
# Fresh asyncpg connection each time
registry.add("pg", AsyncpgCheck("postgresql://localhost:5432/mydb"))
# Existing asyncpg pool
registry.add("pg", AsyncpgPoolCheck(pool))
# SQLAlchemy AsyncEngine
registry.add("pg", SQLAlchemyCheck(engine))
Redis
from vitals.checks.redis import RedisCheck, RedisPoolCheck
# Fresh connection each time
registry.add("redis", RedisCheck("redis://localhost:6379"))
# Existing redis.asyncio connection pool
registry.add("redis", RedisPoolCheck(pool))
Sync Checks
Wrap synchronous functions using asyncio.to_thread:
from vitals import sync_check, Status, CheckResult
def check_disk() -> CheckResult:
free = shutil.disk_usage("/").free
return CheckResult(
status=Status.HEALTHY if free > 1_000_000_000 else Status.DEGRADED,
latency_ms=0.0,
message=f"{free} bytes free",
)
registry.add("disk", sync_check(check_disk))
FastAPI Integration
from vitals.integrations.fastapi import create_healthcheck_route
router = create_healthcheck_route(
registry,
token="my-secret-token", # optional — omit to disable auth
path="/healthcheck/deep", # default
query_param_name="token", # default
include_in_schema=False, # default — hides from OpenAPI docs
)
app.include_router(router)
When a token is configured, requests must provide it via:
- Query parameter:
?token=my-secret-token - Bearer header:
Authorization: Bearer my-secret-token
Authentication
from vitals import verify_token, extract_token
# Timing-safe token comparison
verify_token("provided-token", "expected-token") # bool
# Extract token from request data
token = extract_token(
query_params={"token": "abc"},
authorization_header="Bearer abc",
query_param_name="token",
)
Response Format
{
"status": "healthy",
"timestamp": "2025-02-26T12:00:00.000Z",
"checks": {
"postgres": {
"status": "healthy",
"latencyMs": 4.2,
"message": ""
},
"redis": {
"status": "healthy",
"latencyMs": 1.1,
"message": ""
}
}
}
| Overall Status | HTTP Code |
|---|---|
healthy |
200 |
degraded |
503 |
outage |
503 |
| Auth failure | 403 |
Requirements
- Python >= 3.11
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 firebreak_vitals-1.1.0.tar.gz.
File metadata
- Download URL: firebreak_vitals-1.1.0.tar.gz
- Upload date:
- Size: 18.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.0.1 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e80e8191c65832e68dec31042fd4299ae8a0df570d4dc3b69c2aa7eb5cf7478
|
|
| MD5 |
5c360281054fe5fb633029732bdfcc26
|
|
| BLAKE2b-256 |
d8f410aaaef1ad49e3e883741d06e1cc9c02cc14cac1b5c3139361e3ec70f492
|
Provenance
The following attestation bundles were made for firebreak_vitals-1.1.0.tar.gz:
Publisher:
publish-python.yml on firebreak-io/vitals
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firebreak_vitals-1.1.0.tar.gz -
Subject digest:
1e80e8191c65832e68dec31042fd4299ae8a0df570d4dc3b69c2aa7eb5cf7478 - Sigstore transparency entry: 1857481703
- Sigstore integration time:
-
Permalink:
firebreak-io/vitals@470003f9d13e502b7ccf849a29b4b537e8f3a26b -
Branch / Tag:
refs/tags/python-v1.1.0 - Owner: https://github.com/firebreak-io
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@470003f9d13e502b7ccf849a29b4b537e8f3a26b -
Trigger Event:
push
-
Statement type:
File details
Details for the file firebreak_vitals-1.1.0-py3-none-any.whl.
File metadata
- Download URL: firebreak_vitals-1.1.0-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.0.1 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86fa032fb17b78cd62154d1c726e2f5a25ae8135a3f0116e344dbf7d28394a10
|
|
| MD5 |
8ea25810203e38f3687edcc78bcebc79
|
|
| BLAKE2b-256 |
0aa17b31f4c05fa67caf06da556bdbd15d68acb9c417a18283c118965e0dda83
|
Provenance
The following attestation bundles were made for firebreak_vitals-1.1.0-py3-none-any.whl:
Publisher:
publish-python.yml on firebreak-io/vitals
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firebreak_vitals-1.1.0-py3-none-any.whl -
Subject digest:
86fa032fb17b78cd62154d1c726e2f5a25ae8135a3f0116e344dbf7d28394a10 - Sigstore transparency entry: 1857481826
- Sigstore integration time:
-
Permalink:
firebreak-io/vitals@470003f9d13e502b7ccf849a29b4b537e8f3a26b -
Branch / Tag:
refs/tags/python-v1.1.0 - Owner: https://github.com/firebreak-io
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@470003f9d13e502b7ccf849a29b4b537e8f3a26b -
Trigger Event:
push
-
Statement type: