ASGI protocol inspector — validates, traces, and analyzes your ASGI app
Project description
asgion
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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b54d2b479490138a44baf6533096184c262c5f3dcaa62bfa61db16f3f9d9ca4
|
|
| MD5 |
191732652b5505a26ea59e66db1307a4
|
|
| BLAKE2b-256 |
e13bc1da894dcec1ea025fcba7a25d487fbcf61e7702735c545971c5384875ea
|
Provenance
The following attestation bundles were made for asgion-0.5.0.tar.gz:
Publisher:
publish.yml on ack1d/asgion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asgion-0.5.0.tar.gz -
Subject digest:
1b54d2b479490138a44baf6533096184c262c5f3dcaa62bfa61db16f3f9d9ca4 - Sigstore transparency entry: 993676297
- Sigstore integration time:
-
Permalink:
ack1d/asgion@f935b051cce3556257b380cb5be4396f54e8e8ea -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/ack1d
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f935b051cce3556257b380cb5be4396f54e8e8ea -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c1c4a5d9158efa172a5b3b47be3b620d7c4ce2463103935ff853cd2cd5eaf86
|
|
| MD5 |
7d45be75903d4969862c2b21c4e77813
|
|
| BLAKE2b-256 |
ec579f862800ca2900a1fbe03ebe20aca9c8a94c8efe901a00ad154f1543aa37
|
Provenance
The following attestation bundles were made for asgion-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on ack1d/asgion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asgion-0.5.0-py3-none-any.whl -
Subject digest:
9c1c4a5d9158efa172a5b3b47be3b620d7c4ce2463103935ff853cd2cd5eaf86 - Sigstore transparency entry: 993676396
- Sigstore integration time:
-
Permalink:
ack1d/asgion@f935b051cce3556257b380cb5be4396f54e8e8ea -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/ack1d
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f935b051cce3556257b380cb5be4396f54e8e8ea -
Trigger Event:
release
-
Statement type: