Skip to main content

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

Project description

asgion

CI Coverage PyPI Python License

ASGI protocol inspector and trace engine. Validates HTTP, WebSocket & Lifespan state machines, event schemas, and scope fields.

Highlights

  • Comprehensive validation — scope fields, event schemas, state machines, semantic checks
  • HTTP, WebSocket, Lifespan — all three ASGI protocols covered
  • Trace engine — record every receive()/send() with nanosecond timestamps and inline violation markers
  • CLI, Python API, pytest plugin — fits any workflow
  • Zero runtime dependencies — pure Python 3.12+
  • O(1) per message — safe for hot paths, no overhead when tracing is off

Quickstart

pip install asgion[cli]
asgion check myapp:app
── GET / ─────────────────────────────────────────────────────
  [HF-003] error: Duplicate http.response.start
    hint: Only one response.start is allowed per HTTP connection
  [HE-012] error: response.body 'body' must be bytes, got str

2 violations (2 error)

See the full rule list for all available rules and their descriptions.

Python API

from asgion import Inspector

inspector = Inspector(app)
# ... drive the app via httpx, TestClient, etc. ...
assert inspector.violations == []

As middleware:

from asgion import inspect

uvicorn.run(inspect(app))

Tracing

Record the full ASGI lifecycle for debugging and analysis:

inspector = Inspector(app, trace=True)
async with httpx.AsyncClient(transport=ASGITransport(inspector)) as client:
    await client.get("/api/users")

record = inspector.traces[0]
record.scope.method      # "GET"
record.scope.path        # "/api/users"
record.summary.ttfb_ns   # time to first byte (ns)
asgion trace myapp:app --out ./traces/   # save as JSON files
asgion trace myapp:app
TRACE  GET / (0.070ms, TTFB 0.042ms)

     0.020ms  send     http.response.body  4 bytes  ← HF-002 (error)
     0.042ms  send     http.response.start  200  (+0.022ms)  ← SEM-002 (info)
     0.059ms  send     http.response.body  5 bytes  (+0.016ms)

  Events: 3  |  Violations: 2 (1 error, 1 info)

Pytest Plugin

pip install asgion[pytest]
async def test_my_app(asgi_inspect):
    inspector = asgi_inspect(my_app)
    async with httpx.AsyncClient(transport=ASGITransport(inspector)) as client:
        await client.get("/users")
    assert inspector.violations == []
pytest --asgi-strict   # auto-check all tests

Configuration

Via pyproject.toml, .asgion.toml, or Python API. See configuration docs and full rule list.

[tool.asgion]
profile = "recommended"
exclude_rules = ["SEM-006"]

Contributing

git clone https://github.com/ack1d/asgion.git
cd asgion
uv sync --group dev
uv run pytest

If you have Task installed: task check runs lint, typecheck, and tests.

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.5.0.tar.gz (41.5 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.5.0-py3-none-any.whl (58.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for asgion-0.5.0.tar.gz
Algorithm Hash digest
SHA256 1b54d2b479490138a44baf6533096184c262c5f3dcaa62bfa61db16f3f9d9ca4
MD5 191732652b5505a26ea59e66db1307a4
BLAKE2b-256 e13bc1da894dcec1ea025fcba7a25d487fbcf61e7702735c545971c5384875ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for asgion-0.5.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.5.0-py3-none-any.whl.

File metadata

  • Download URL: asgion-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 58.9 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c1c4a5d9158efa172a5b3b47be3b620d7c4ce2463103935ff853cd2cd5eaf86
MD5 7d45be75903d4969862c2b21c4e77813
BLAKE2b-256 ec579f862800ca2900a1fbe03ebe20aca9c8a94c8efe901a00ad154f1543aa37

See more details on using hashes here.

Provenance

The following attestation bundles were made for asgion-0.5.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