Muscles ASGI
muscles-asgi is the ASGI runtime for Muscles. It mirrors the WSGI API model
while using ASGI scopes/events for async-capable servers.
Installation
pip install muscles-asgi
Canonical ecosystem install matrix is documented in core: Muscles installation matrix.
Related Repositories
muscles- core contracts, routing, actions and canonical documentation.muscles-wsgi- WSGI runtime with the same application model.muscles-cli- CLI projection and developer commands.muscles-sse- streaming projection for action results.muscles-mcp- MCP projection that can bind to ASGI entrypoints.muscles-benchmarks- ASGI regression and architecture checks.
Runtime
An app binds Context to AsgiStrategy:
from muscles import ApplicationMeta, Configurator, Context
from muscles.asgi import AsgiStrategy
class App(metaclass=ApplicationMeta):
config = Configurator(obj={"main": {"HOST": "0.0.0.0", "PORT": "8080"}})
context = Context(AsgiStrategy, params={})
def run(self, *args):
return self.context.execute(*args, shutup=True)
The ASGI package shares core schemas, route matching and OpenAPI generation with the other runtimes. It should not duplicate core itinerary code.
Schema Ownership
ASGI does not ship its own muscles.asgi.schema_ package. Framework schemas,
columns, fields, request/response bodies, security objects and value objects
belong to muscles.core.schema and should be imported from muscles:
from muscles import Column, JsonRequestBody, Model, String
REST API And Swagger
RestApi controllers/actions are projected into OpenAPI automatically. Generated
paths include the external API prefix, so a mounted route such as
/api/v1/bookings appears in Swagger exactly as clients must call it.
More detail: docs/openapi-and-routing.md. Backend pipeline features are documented in docs/backend-pipeline.md.
Application Inspection
Use mount_api(app, api) after declaring a RestApi to project ASGI routes into
the core ApplicationRegistry. This makes routes visible to
inspect_application(app) and CLI/doctor tooling without making the registry
the HTTP dispatch source.
Call it after all controllers/actions are registered and before running
inspection, doctor checks or generators. It is safe to call more than once:
already projected routes are skipped. finalize_api(app, api) is an alias for
projects that prefer a "declare, then finalize" bootstrap style.
asgi_app(app) also calls mount_application_apis(app) once when the ASGI
entrypoint is created, so APIs stored as attributes on the application are
visible to runtime inspection without additional app-side adapters.
from muscles import inspect_application
from muscles.asgi import RestApi, finalize_api
app = App()
api = RestApi(name="Api", prefix="/api")
@api.init("/ping", method="get")
def ping(request):
return {"ok": True}
finalize_api(app, api)
assert any(route["path"] == "/api/ping" for route in inspect_application(app)["routes"])
Request dispatch still uses the ASGI RestApi route tree. The projected routes
are lightweight descriptors for tools that need to understand the application
without knowing ASGI internals.
When the application has a neutral TelemetryProvider, ASGI records a
muscles.server.dispatch span for matched routes with app, route, method and
HTTP status attributes.
Action Bridge
ActionAsgiAdapter is an optional HTTP projection for Muscles actions. It keeps
package-specific features out of ASGI routes: packages register normal core
actions, and ASGI exposes only the actions explicitly allowed by the project.
from muscles.asgi import ActionAsgiAdapter
application = ActionAsgiAdapter.from_application(
app,
allowed_actions={"bookings.echo"},
)
The bridge accepts JSON POST /actions/<action-name> requests, executes through
core ActionDispatcher(..., transport="http"), returns JSON for non-stream
results, and returns application/problem+json for core action errors. Stream
actions should be projected through muscles-sse.
Request Handling
Request parsing does not require cgi, multipart or python-magic at import
time. Multipart form data uses the standard library path, and missing MIME
detection falls back safely.
ASGI request execution is stateless on Context: request-specific data
(scope, receive, send) is passed directly into context.execute(...)
per request. The strategy keeps a persistent server lifecycle while request
state stays isolated.
Development
Run tests with sibling packages on PYTHONPATH:
PYTHONPATH=../muscles/src:src python -m pytest -q
Production notes: docs/production.md.
Metadata
Release files for muscles-asgi 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| muscles_asgi-1.0.2.tar.gz | 196.9 kB | With provenance | Details for muscles_asgi-1.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| muscles_asgi-1.0.2-py3-none-any.whl | Python 3 | none | any | Details for muscles_asgi-1.0.2-py3-none-any.whl |
Total release size: 404.6 kB
Release files / muscles_asgi-1.0.2.tar.gz
| Download URL | muscles_asgi-1.0.2.tar.gz |
|---|---|
| Size | 196.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b7b3242453d4440eccb096fcef6cbf62f7e39088fc795ab1b46bb54e1ac378c8
|
|
BLAKE2b-256 checksum How to use checksums |
1f8b8e5eab58ad1b064a37585ea018c8b91cde2b58ce1999260c2e04c96eaa63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / muscles_asgi-1.0.2-py3-none-any.whl
| Download URL | muscles_asgi-1.0.2-py3-none-any.whl |
|---|---|
| Size | 207.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c4b5a94c7b3fbf973afbdcfa95952ae41f7bbab58aa690cb3e039e5efb0d887c
|
|
BLAKE2b-256 checksum How to use checksums |
8f854c8bf333135c9e2af31b6d7e6a6680b8c088c5b56739e2f78a6b38ae62a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logSecurity for muscles-asgi 1.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for muscles_asgi-1.0.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.