Skip to main content

✅ Allgreen - Python Health Checks Made Simple

Python 3.10+ License: MIT

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 /metrics endpoint, 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:

Configuration File Locations

Allgreen automatically looks for configuration files in these locations:

  1. allgreen_config.py (project root)
  2. config/allgreen_config.py
  3. Custom path via config_path parameter

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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass (python -m pytest)
  6. Run linting, formatting, and type checks (ruff check . && ruff format --check . && mypy)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

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)

Source distribution for allgreen 0.12.0
File Size Uploaded
allgreen-0.12.0.tar.gz 32.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for allgreen 0.12.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

This release

0.12.0 This release

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page