Skip to main content

ASGI protocol inspector — validates, traces, and analyzes your ASGI app

Project description

asgion

PyPI Python License

ASGI protocol inspector — validates your ASGI application against the ASGI specification at runtime. Catches protocol violations, state machine errors, and event schema mismatches before they become production bugs.

Zero runtime dependencies. Python 3.12+.

Quickstart

Python API

pip install asgion
from asgion import inspect

app = inspect(app)  # wrap any ASGI app — zero config

Use with any ASGI server:

import uvicorn

uvicorn.run(inspect(app), host="127.0.0.1", port=8000)

CLI

pip install asgion[cli]
asgion check myapp:app

What It Catches

162 rules across 12 layers — scope fields, event schemas, state machines, extensions, and semantic checks for HTTP, WebSocket, and Lifespan.

[G-005]  error    Message must be a dict
[HE-017] error    response.body 'body' must be bytes, got str
[HF-004] error    Duplicate http.response.start
[WE-012] warning  websocket.send has both 'bytes' and 'text' set

Every rule has an ID, severity, summary, and hint. See the full list: docs/rules.md

CLI Reference

asgion check

asgion check APP_PATH [OPTIONS]

Check an ASGI app for protocol violations.

Option Description
APP_PATH Module:attribute path (e.g. myapp:app)
--url PATH URL paths to check (repeatable, default /)
--strict Exit 1 on any violations
--format text|json Output format (default text)
--exclude-rules IDS Comma-separated rule IDs to skip
--min-severity LEVEL Minimum severity: perf, info, warning, error
--no-color Disable ANSI colors (also respects NO_COLOR env)
--no-lifespan Skip lifespan startup/shutdown checks

Exit codes: 0 = clean, 1 = violations (with --strict), 2 = runtime error.

asgion rules

asgion rules [OPTIONS]

List all validation rules.

Option Description
--format text|json Output format (default text)
--layer LAYER Filter by layer: general, http, websocket, lifespan
--severity LEVEL Filter by severity: perf, info, warning, error
--no-color Disable ANSI colors

asgion --version

Print version and exit.

Python API

from asgion import inspect

wrapped = inspect(
    app,
    strict=False,                          # True to raise on violations
    on_violation=lambda v: print(v),       # real-time callback
    exclude_paths=["/health", "/metrics"], # skip these paths
    exclude_rules={"HE-012", "G-008"},     # suppress specific rules
)

Parameters

Parameter Type Default Description
app ASGIApp required The ASGI application to wrap
strict bool False Raise ASGIProtocolError on any violation
on_violation callback None Called with each Violation in real-time
exclude_paths list[str] None Paths to skip validation
exclude_rules set[str] None Rule IDs to suppress
registry ValidatorRegistry None Custom validator registry

Violation

@dataclass(frozen=True, slots=True)
class Violation:
    rule_id: str       # "HF-001", "G-010"
    severity: Severity # error, warning, info, perf
    message: str       # human-readable description
    hint: str          # suggestion for fixing
    scope_type: str    # "http", "websocket", "lifespan"
    path: str          # "/api/users"
    method: str        # "GET"

pytest Plugin

pip install asgion[pytest]
async def test_my_app(asgi_inspect):
    app = asgi_inspect(my_app)
    async with httpx.AsyncClient(transport=ASGITransport(app)) as client:
        resp = await client.get("/users")
    assert app.violations == []

Auto-check violations with a marker:

@pytest.mark.asgi_validate(min_severity="error")
async def test_strict(asgi_inspect):
    app = asgi_inspect(my_app)
    # ... drive the app — violations checked automatically at teardown

Or enable globally for all tests using asgi_inspect:

pytest --asgi-strict
pytest --asgi-strict --asgi-min-severity warning

Comparison

Feature asgion asgiref.testing Manual testing
Scope validation 71 rules basic none
Event schema checks 42 rules none manual
State machine (FSM) 35 rules none none
Semantic checks 11 rules none none
Extension validation 11 rules none none
pytest plugin yes no n/a
Real-time callbacks yes no n/a
CLI tool yes no no
Zero dependencies yes no (asgiref) n/a
Rule suppression per-rule no n/a

Contributing

git clone https://github.com/ack1d/asgion.git
cd asgion
uv sync --group dev
uv run pytest              # run tests
uv run ruff check src/     # lint
uv run mypy src/           # type check

License

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

asgion-0.2.0.tar.gz (28.4 kB view details)

Uploaded Source

Built Distribution

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

asgion-0.2.0-py3-none-any.whl (41.7 kB view details)

Uploaded Python 3

File details

Details for the file asgion-0.2.0.tar.gz.

File metadata

  • Download URL: asgion-0.2.0.tar.gz
  • Upload date:
  • Size: 28.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for asgion-0.2.0.tar.gz
Algorithm Hash digest
SHA256 16925c1a2207b7ee5f06411250ff7c8881a292473b96f0c67d74a2c73e520787
MD5 077ca051e1c0390e72f51ba0636f9642
BLAKE2b-256 17293ee62bf0551bac6c321a13a0b91c5156c5b59ca0098e000d3657e9180953

See more details on using hashes here.

Provenance

The following attestation bundles were made for asgion-0.2.0.tar.gz:

Publisher: publish.yml on ack1d/asgion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file asgion-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: asgion-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 41.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for asgion-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dae95b19ad8d68a88bd0388ecb905c07d54bf5ba13819c963bfa9c3d2dda257d
MD5 e207dcf9a5705fb849714548be60ceb8
BLAKE2b-256 306338fe7e2c1b5a19037b4ce7ab54f0f0c9e5eaddadf0301d140a725a32fbf3

See more details on using hashes here.

Provenance

The following attestation bundles were made for asgion-0.2.0-py3-none-any.whl:

Publisher: publish.yml on ack1d/asgion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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