✅ Allgreen - Python Health Checks Made Simple
Add quick, simple, and beautiful health checks to your Python application via a /healthcheck endpoint.
Perfect for monitoring application health, smoke testing, and ensuring your services are running properly in production.
Features
- Simple DSL - Define health checks in intuitive, readable Python
- Async Support - Write checks as
async def, awaited natively in ASGI apps - Beautiful Web Dashboard - Responsive UI with automatic dark mode
- Fast & Lightweight - Minimal dependencies, maximum performance
- Timeout Protection - Prevent hanging checks with configurable timeouts
- Rate Limiting - Control expensive operations ("2 times per hour")
- Environment Conditions - Run checks only in specific environments
- Result Caching - Cache expensive operations between rate-limited runs
- Multiple Output Formats - HTML dashboard, JSON API, or both
- Prometheus Metrics - Built-in
/metricsendpoint, no extra dependencies - Framework Agnostic - Works with Flask, Django, FastAPI, or standalone
Installation
Choose the installation that fits your needs:
# Core functionality only (no web dependencies)
pip install allgreen
# With Flask integration
pip install allgreen[flask]
# With Django integration
pip install allgreen[django]
# With FastAPI integration
pip install allgreen[fastapi]
Framework-agnostic design - use only what you need!
Quick Start
1. Create your health checks
Create an allgreen_config.py file in your project root:
Note: Config files should use absolute imports only. Relative imports are not supported to avoid import conflicts.
# allgreen_config.py
@check("Database connection is healthy")
def database_check():
# Your database connection logic
make_sure(db.is_connected(), "Database should be accessible")
@check("API response time is acceptable")
def api_performance_check():
response_time = api.ping()
expect(response_time).to_be_less_than(200) # milliseconds
@check("Disk space is sufficient")
def disk_space_check():
usage_percent = get_disk_usage()
expect(usage_percent).to_be_less_than(90)
2. Add to your application
Core Only (no web framework):
from allgreen import get_registry, load_config
load_config()
results = get_registry().run_all()
# Process results as needed
Flask Integration:
pip install allgreen[flask]
from flask import Flask
from allgreen.integrations.flask_integration import mount_healthcheck
app = Flask(__name__)
mount_healthcheck(app, app_name="My API")
Django Integration:
pip install allgreen[django]
# urls.py
from django.urls import path
from allgreen.integrations.django_integration import healthcheck_view
urlpatterns = [
path("healthcheck/", healthcheck_view, name="healthcheck"),
]
FastAPI Integration:
pip install allgreen[fastapi]
from fastapi import FastAPI
from allgreen.integrations.fastapi_integration import create_router
app = FastAPI()
app.include_router(create_router(app_name="My API"))
3. View your dashboard
Visit /healthcheck in your browser to see a beautiful dashboard, or add ?format=json for machine-readable output.
Complete DSL Reference
Basic Assertions
@check("Basic truthiness check")
def basic_check():
make_sure(True, "Custom failure message")
make_sure(user.is_authenticated())
Expectation Methods
@check("Mathematical expectations")
def math_check():
expect(2 + 2).to_eq(4)
expect(api.response_time()).to_be_less_than(100)
expect(database.connection_count()).to_be_greater_than(0)
Advanced Features
Async Checks
Checks can be defined with async def — they work in every supported framework:
import asyncio
import httpx
@check("Upstream API is healthy", timeout=5)
async def upstream_check():
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/health")
expect(response.status_code).to_eq(200)
- FastAPI / ASGI: async checks run natively on the event loop (no thread hop); sync checks run in a worker thread pool so they never block the loop
- Flask / Django / core-only: async checks are executed transparently via a dedicated event loop
- Timeouts apply to async checks too, via task cancellation
- Sync and async checks can be freely mixed in one config file
Timeout Protection
@check("Slow external service", timeout=30) # 30 seconds max
def external_service_check():
# This check will be terminated if it takes longer than 30 seconds
response = external_api.health_check()
make_sure(response.ok)
Rate Limiting for Expensive Operations
@check("Expensive API call", run="2 times per hour", timeout=60)
def expensive_check():
# This check only runs twice per hour, caching results between runs
result = paid_api.run_diagnostics()
expect(result.status).to_eq("healthy")
@check("Daily backup verification", run="1 time per day")
def daily_backup_check():
# Perfect for expensive operations that should only run occasionally
backup_status = verify_backup_integrity()
make_sure(backup_status.valid)
Supported rate limiting patterns:
"1 time per minute""5 times per hour""2 times per day"
Environment-Specific Checks
@check("Production database performance", only_in="production")
def prod_db_check():
# Only runs in production environment
expect(db.query_time()).to_be_less_than(10)
@check("Development tools available", except_in=["production", "staging"])
def dev_tools_check():
# Skipped in production and staging
make_sure(debug_tools.available())
@check("Conditional feature check", if_condition=lambda: feature_flag.enabled())
def feature_check():
# Only runs when condition is true
expect(new_feature.status()).to_eq("operational")
Web Interface
HTML Dashboard
Visit /healthcheck for a beautiful, responsive dashboard featuring:
- Color-coded check results (pass/fail/skip)
- Automatic dark mode based on system preferences
- ⏱️ Execution timing for each check
- 📊 Summary statistics
- Mobile-responsive design
JSON API
Access /healthcheck.json or /healthcheck?format=json for machine-readable output:
{
"status": "passed",
"environment": "production",
"stats": {
"total": 8,
"passed": 6,
"failed": 1,
"skipped": 1
},
"checks": [
{
"description": "Database connection",
"status": "passed",
"duration_ms": 23.4
}
]
}
HTTP Status Codes
- 200 OK - All checks passing
- 503 Service Unavailable - One or more checks failing
Perfect for integration with monitoring tools like:
- UptimeRobot
- Pingdom
- Datadog
- Custom monitoring solutions
Prometheus Metrics
Flask and FastAPI integrations expose a /metrics endpoint out of the box (no
prometheus_client dependency needed). It renders the standard text exposition
format:
# HELP allgreen_up Overall health status (1 = all checks passing)
# TYPE allgreen_up gauge
allgreen_up 1
# HELP allgreen_checks Number of health checks by status
# TYPE allgreen_checks gauge
allgreen_checks{status="passed"} 3
allgreen_checks{status="failed"} 0
allgreen_checks{status="skipped"} 1
allgreen_checks{status="error"} 0
# HELP allgreen_check_status Health check result (1 = passed, 0 = failed)
# TYPE allgreen_check_status gauge
allgreen_check_status{check="Database connection"} 1
# HELP allgreen_check_duration_seconds Health check execution time
# TYPE allgreen_check_duration_seconds gauge
allgreen_check_duration_seconds{check="Database connection"} 0.023400
The endpoint always returns 200 - overall health is conveyed via the
allgreen_up metric so Prometheus can keep scraping even when checks fail.
Customize or disable the route with metrics_path:
# Flask
mount_healthcheck(app, metrics_path="/prometheus") # custom path
mount_healthcheck(app, metrics_path=None) # disabled
# FastAPI
create_router(metrics_path="/prometheus")
For Django, wire up the view in urls.py:
from allgreen.integrations.django_integration import metrics_view
urlpatterns = [
path("metrics/", metrics_view, name="metrics"),
]
Sample Prometheus scrape config:
scrape_configs:
- job_name: myapp-health
metrics_path: /metrics
scrape_interval: 60s
static_configs:
- targets: ["myapp.example.com"]
Framework Integration
Flask Application
from flask import Flask
from allgreen.integrations.flask_integration import mount_healthcheck
app = Flask(__name__)
# Mount health checks
mount_healthcheck(
app,
app_name="My Flask API",
config_path="config/allgreen_config.py",
environment="production",
)
if __name__ == "__main__":
app.run()
Django Integration
# urls.py
from django.urls import path
from allgreen.integrations.django_integration import healthcheck_view
urlpatterns = [
path("healthcheck/", healthcheck_view, name="healthcheck"),
]
# For custom configuration
from allgreen.integrations.django_integration import create_healthcheck_view
custom_view = create_healthcheck_view(
app_name="My Django App",
config_path="myapp/health_checks.py",
environment="production",
)
urlpatterns = [
path("health/", custom_view, name="healthcheck"),
]
FastAPI Integration
from fastapi import FastAPI
from allgreen.integrations.fastapi_integration import create_router
app = FastAPI()
# Method 1: Mount router
health_router = create_router(app_name="My FastAPI", config_path="config/allgood.py")
app.include_router(health_router)
# Method 2: Individual endpoint
from allgreen.integrations.fastapi_integration import healthcheck_endpoint
@app.get("/healthcheck")
async def health(request: Request):
return await healthcheck_endpoint(request, app_name="My FastAPI")
Examples
Check out the examples/ directory for complete working examples:
examples/allgreen_config.py- Basic health checks configurationexamples/advanced_allgreen_config.py- Advanced features (timeouts, rate limiting)examples/core_only_example.py- Core-only usage (no web dependencies)examples/flask_example.py- Flask integration exampleexamples/django_example.py- Django integration exampleexamples/fastapi_example.py- FastAPI integration example
Configuration File Locations
Allgreen automatically looks for configuration files in these locations:
allgreen_config.py(project root)config/allgreen_config.py- Custom path via
config_pathparameter
Environment Variables
ENVIRONMENT- Sets the environment for conditional checks (default: "development")
Best Practices
Good Health Check Examples
@check("Database queries are fast")
def db_performance():
start = time.time()
users = User.objects.all()[:10]
duration = (time.time() - start) * 1000
expect(duration).to_be_less_than(100) # under 100ms
@check("External API is responsive")
def api_health():
response = requests.get("https://api.example.com/health", timeout=5)
expect(response.status_code).to_eq(200)
@check("Cache is working", run="5 times per hour")
def cache_check():
cache.set("test_key", "test_value")
expect(cache.get("test_key")).to_eq("test_value")
What to Avoid
- Don't make checks that modify data
- Avoid checks that depend on external timing
- Don't put business logic in health checks
- Avoid checks that could cause cascading failures
Security Notes
- Health check endpoints don't require authentication by default
- Consider restricting access in production environments
- Avoid exposing sensitive system information in check descriptions
- Rate limiting helps prevent abuse of expensive operations
Development
git clone https://github.com/navinpai/allgreen
cd allgreen
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"
# Run tests
python -m pytest
# Run linting and formatting checks
ruff check .
ruff format --check .
# Run type checking
mypy
# Start example server
python test_server.py
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
python -m pytest) - Run linting, formatting, and type checks (
ruff check . && ruff format --check . && mypy) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Inspired by the Allgood Ruby gem
- Built with ❤️ for the Python community
Metadata
Release files for allgreen 0.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| allgreen-0.12.0.tar.gz | 32.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| allgreen-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.7 kB
Release files / allgreen-0.12.0.tar.gz
| Download URL | allgreen-0.12.0.tar.gz |
|---|---|
| Size | 32.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bdfcb8f5808414b732e7e985c94791c7c6dacc06f5197c4c0bde7f0fe42add21
|
|
BLAKE2b-256 checksum How to use checksums |
63cfbeef9e65429dd416aaf60acf0eb3c699752a7e35f593cdf3d6b14f2ebbb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / allgreen-0.12.0-py3-none-any.whl
| Download URL | allgreen-0.12.0-py3-none-any.whl |
|---|---|
| Size | 29.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e810fb975cd44e4ee59a6928d9140378c0f1cc88a2aa2bfe2d88f72206d6713b
|
|
BLAKE2b-256 checksum How to use checksums |
e91539e2defd2f082c04d24d0543f2c9a3c0f15efc516302c1c43d7970f8c61e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|