Muscles framework core
Project description
Muscles Core (Release Candidate)
Muscles is the release-candidate framework core. The core package contains the application lifecycle, configuration, shared schema objects, routing tree and strategy interface. HTTP, ASGI and CLI packages reuse these primitives instead of implementing their own framework model.
Recommended Application Shape (Canonical Path)
Most projects use this lifecycle:
Appclass receives a runtime object (runtime.strategy,runtime.routes,runtime.rest_api).Contextis created withruntime.strategy.- REST API object is created through
runtime.rest_api(...). - Endpoints are registered with
runtime.routes.init(...)orapi.init(...). - Execution goes through
Context.execute(...).
from muscles import ApplicationMeta, Configurator, Context
from muscles.wsgi import wsgi_app
class App(metaclass=ApplicationMeta):
package_paths = []
shutup = False
config = Configurator(obj={})
def __init__(self, runtime):
self.runtime = runtime
self.context = Context(runtime.strategy, params={})
self.api = runtime.rest_api(prefix="/api/v1")
register_pages(runtime.routes)
register_api(self.api, runtime.routes)
def __call__(self, environ, start_response):
self.context.set_param("environ", environ)
self.context.set_param("start_response", start_response)
return self.context.execute()
wsgi_app(App(wsgi_runtime()))
This style keeps runtime-specific glue thin and leaves endpoint modules with the behavior and OpenAPI metadata.
Packages
muscles- core classes, schemas, routing and application metaclass.muscles-wsgi- WSGI runtime, pages, REST API and Swagger UI.muscles-asgi- ASGI runtime with the same routing and REST API model.muscles-cli- console command strategy built on the same route/group idea.muscles-jsonrpc- JSON-RPC projection for core actions.muscles-sse- Server-Sent Events projection for streaming actions.muscles-mcp- Model Context Protocol projection for AI tools.muscles-sql- SQL persistence helpers, named connections and diagnostics.muscles-otel- optional lifecycle telemetry hooks and tracer provider.muscles-documents- document loading, parsing, chunking and sync actions.muscles-ai- read-only AI/RAG actions and runtime contracts.muscles-benchmarks- benchmark and regression suite for the ecosystem.muscular-example- layered learning examples for Muscles applications.
How Packages Fit Together
muscles is the core contract. Runtime packages such as muscles-asgi,
muscles-wsgi and muscles-cli project the same app model into a concrete
transport. Extension packages such as muscles-otel, muscles-sql,
muscles-documents and muscles-ai add services, actions and diagnostics
through the package lifecycle:
from muscles import install_package, inspect_application, doctor_application
from muscles_otel import OtelPackage
app = App()
tracer = install_package(app, {"enabled": True}, OtelPackage())
contract = inspect_application(app)
doctor = doctor_application(app)
Use the DependencyContainer for live objects that app code resolves at
runtime. Use ApplicationRegistry for metadata that tools can inspect: routes,
actions, package capabilities, doctor checks and generator providers. In plain
terms: the container is for running the app, the registry is for understanding
the app.
More detail: docs/package-lifecycle.md.
Repository Map
Core and runtimes:
muscles- framework core and canonical documentation.muscles-asgi- ASGI HTTP/API runtime.muscles-wsgi- WSGI HTTP/API runtime.muscles-cli- CLI runtime, project scaffolding and inspection commands.
Protocol projections:
muscles-jsonrpc- JSON-RPC 2.0 projection over actions.muscles-sse- SSE delivery forStreamResultaction output.muscles-mcp- MCP tools/resources generated from Muscles contracts.
Framework extensions:
muscles-sql- SQL layer for models, repositories, transactions and named SQL connections.muscles-otel- optional lifecycle telemetry hooks for package, strategy and action execution.muscles-documents- document source ingestion, parsing, chunking and sync planning.muscles-ai- AI/RAG actions that can use document and data integrations.
Support repositories:
muscles-benchmarks- golden-path benchmarks and regression checks.muscular-example- layered example application.muscles-landing- product site/application built on Muscles.muscular-asgi- deprecated ASGI compatibility package.
Installation
The release-candidate packages are distributed through PyPI. Install the core framework with:
pip install "muscles>=1.0.0rc3,<2.0.0"
For local development, source checkouts and the full ecosystem matrix, see docs/installation.md.
Installation matrix:
- core only:
pip install "muscles>=1.0.0rc3,<2.0.0" - ASGI runtime:
pip install muscles-asgi - WSGI runtime:
pip install muscles-wsgi - CLI tooling:
pip install muscles-cli - JSON-RPC projection:
pip install git+https://github.com/butkoden/muscles-jsonrpc.git - SSE projection:
pip install git+https://github.com/butkoden/muscles-sse.git - MCP projection:
pip install muscles-mcp - SQL extension:
pip install muscles-sql - OTel extension:
pip install git+https://github.com/butkoden/muscles-otel.git - documents extension:
pip install git+https://github.com/butkoden/muscles-documents.git - AI extension:
pip install muscles-ai - full/dev (source checkouts): clone all repositories and use
PYTHONPATHwith siblingsrcpaths.
More detail: docs/installation.md. Repository ownership map: docs/repositories.md.
Core documentation:
- English: docs/doc.md
- Russian: docs/doc.ru.md
- Framework package lifecycle: docs/package-lifecycle.md
- Public API reference: docs/public-api.md
- Справочник публичного API: docs/public-api.ru.md
Naming
Use Muscles as the public framework name. Keep muscles for the Python
package/import name and muscles-* for official package identifiers.
More detail: docs/naming.md.
Positioning
Muscles is a framework for a single application model that can be projected into multiple runtimes (WSGI, ASGI, CLI). It is not optimized for the shortest "one endpoint in five minutes" path. It is optimized for consistency: the same schemas, routing tree, lifecycle hooks and rules metadata stay reusable across transports.
When To Use Muscles
- you need Web/API/CLI to share one domain model and metadata;
- you want routing, schemas and rules to be declared once and reused;
- you want AI-assisted changes to follow a stable project structure.
When Not To Use Muscles
- you only need a tiny HTTP service with no shared model beyond one runtime;
- your team prefers runtime-specific framework patterns per interface;
- you need mature batteries-included admin/ORM stack out of the box.
FastAPI Relation
FastAPI is a strong choice for API-first delivery speed. Muscles targets a different trade-off: one reusable model for API, pages and CLI workflows. These tools can coexist in a portfolio; Muscles should not claim production maturity or performance superiority without benchmark evidence.
More detail: docs/positioning.md. Golden tutorial reference (planned): Issue #16.
Golden Path Structure
Use the official Muscles project structure as the default style for people and AI assistants:
app/
application.py
config.py
domain/
schemas/
web/
api/
cli/
rules/
templates/
static/
tests/
More detail: docs/golden-path.md. Tutorial: docs/golden-tutorial.md.
Application Shape
An application is usually a class with ApplicationMeta, a Configurator and a
Context bound to a strategy:
from muscles import ApplicationMeta, Configurator, Context
from muscles.wsgi import WsgiStrategy
class App(metaclass=ApplicationMeta):
config = Configurator(obj={"main": {"DEBUG": True}})
context = Context(WsgiStrategy, params={})
def run(self, *args):
return self.context.execute(*args, shutup=True)
Context owns lifecycle hooks and strategy execution. Keep it instance-local:
lists of hooks and params must not be shared between app instances.
Routing
The core routing tree lives in muscles.core.schema.itinerary. It is used as a
generic structure for:
- page routes;
- REST API controllers/actions;
- CLI groups and commands;
- URL building and reverse lookup.
The current implementation indexes routes by (path, method) and keeps a match
cache. Static routes are checked before dynamic routes, so common paths avoid
walking the whole tree. Duplicate route registration is idempotent by route
name, which keeps repeated imports from making routing slower.
More detail: docs/architecture.md.
Backend primitives such as route groups, guards, middleware, exception mapping, Bearer JWT auth, CORS and response helpers are documented in docs/backend-framework.md.
BackendPipeline is the shared execution contract for runtime adapters. It
handles typed handler arguments, dependency resolution, guards, route-level
security and middleware, while ASGI/WSGI keep protocol parsing and response
serialization. DependencyContainer adds explicit app, request and
transient scopes for integrations that need more structure than legacy global
dependency registration.
Schemas And OpenAPI
Schema classes (Model, Collection, Column, String, Key, request and
response bodies) describe data once and can be reused by runtime strategies. The
WSGI and ASGI packages read these structures to build OpenAPI automatically.
More detail: docs/schema.md.
Rules
Decorators such as @rules are intended to attach access control and metadata
to the same objects that routing uses. The important design rule is that a route,
API action or command should carry its permissions and properties together with
its schema, so every strategy can enforce or expose them consistently.
Practical examples: docs/value-objects-rules.md.
Actions And Protocol Projections
Actions are first-class application contracts in core. Declare an action once on a Muscles application instance, then let HTTP, CLI, MCP, JSON-RPC, SSE or other protocol projections call it through the same dispatcher:
from muscles import ApplicationMeta, Context, ActionDispatcher
class BookingApp(metaclass=ApplicationMeta):
context = Context(MyStrategy, transport="app", params={})
app = BookingApp()
@app.action(
name="bookings.create",
description="Create a booking request",
input_schema={
"type": "object",
"properties": {
"title": {"type": "string"},
"guest_count": {"type": "integer"},
},
"required": ["title"],
},
rules=["bookings.public_create"],
transports=["http", "cli", "mcp"],
)
def create_booking(payload, context):
return {"title": payload["title"], "transport": context.transport}
result = ActionDispatcher(app).execute(
"bookings.create",
{"title": "Discovery call"},
transport="mcp",
)
inspect_application(app) is the source of truth for discovery. Protocol
packages should build tools, methods, routes or stream metadata from this
contract and send execution back to ActionDispatcher. They should not keep a
second validation, permissions or business model.
The action registry is application-scoped. New protocol projections should avoid mutable module-level registries as their source of truth, because those leak state between app instances and tests.
Stream Results
English:
Streaming actions return StreamResult(source=...) with business
StreamEvent(type="progress" | "log" | "result" | "error", data=...) items.
The core contract is protocol-neutral: SSE heartbeat, MCP envelopes, JSON-RPC
notifications and CLI progress lines are transport projections over the same
events. Transports should preserve backpressure with bounded delivery and call
close() on disconnect when the source supports it. Long-blocking sources must
cooperate by unblocking the active next() call after close().
Русский:
Streaming actions возвращают StreamResult(source=...) с business events
StreamEvent(type="progress" | "log" | "result" | "error", data=...).
Core contract не зависит от протокола: SSE heartbeat, MCP envelopes,
JSON-RPC notifications и CLI progress lines являются transport-проекциями одних
и тех же событий. Transport должен сохранять backpressure через bounded delivery
и вызывать close() при disconnect, если source это поддерживает. Долгие
blocking sources должны быть cooperative: close() должен разблокировать
активный next().
User docs:
- English: docs/action-contract.en.md
- Русский: docs/action-contract.ru.md
AI Workflow
Official AI-oriented instructions:
Production Deploy
Umbrella guide: docs/production-deploy.md.
Benchmarks
Benchmark docs: docs/benchmarks.md.
Contributing
See CONTRIBUTING.md.
Development
Run tests from each repository with its local src on PYTHONPATH:
PYTHONPATH=src python -m pytest -q
When testing an integration app that uses all packages from sibling checkouts:
PYTHONPATH=../muscles/src:../muscles-wsgi/src:../muscles-asgi/src:../muscles-cli/src:../muscles-jsonrpc/src:../muscles-sse/src:../muscles-mcp/src:../muscles-sql/src:../muscles-otel/src:../muscles-documents/src:../muscles-ai/src python -m pytest -q
Project details
Release history Release notifications | RSS feed
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 muscles-1.0.0rc4.tar.gz.
File metadata
- Download URL: muscles-1.0.0rc4.tar.gz
- Upload date:
- Size: 62.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef91b33ef60f4c4dbc5c4df620a1e70ebab505f204be4200ea632d0f1ff02f29
|
|
| MD5 |
d7bae3d1cbc94f647e754afc791d185a
|
|
| BLAKE2b-256 |
92658d1d41707a554a208cf384decaf6b8b48d4c12ef3f3a92be70861eb7b1a6
|
Provenance
The following attestation bundles were made for muscles-1.0.0rc4.tar.gz:
Publisher:
release.yml on butkoden/muscles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
muscles-1.0.0rc4.tar.gz -
Subject digest:
ef91b33ef60f4c4dbc5c4df620a1e70ebab505f204be4200ea632d0f1ff02f29 - Sigstore transparency entry: 2261211765
- Sigstore integration time:
-
Permalink:
butkoden/muscles@e782e0f88f054fea12a0647951501e1ba6b329a2 -
Branch / Tag:
refs/tags/v1.0.0rc4 - Owner: https://github.com/butkoden
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e782e0f88f054fea12a0647951501e1ba6b329a2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file muscles-1.0.0rc4-py3-none-any.whl.
File metadata
- Download URL: muscles-1.0.0rc4-py3-none-any.whl
- Upload date:
- Size: 76.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad436d9d13a1c4e9cd41c2597febbd51b5c6992f8b62c563f45bdb85ef9d7939
|
|
| MD5 |
1e664d174f0f9048974dbc8268d15058
|
|
| BLAKE2b-256 |
ba4aeb89db0cf7e1faa34261a4812a6390f7cb998d8271ff3211e6b348646989
|
Provenance
The following attestation bundles were made for muscles-1.0.0rc4-py3-none-any.whl:
Publisher:
release.yml on butkoden/muscles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
muscles-1.0.0rc4-py3-none-any.whl -
Subject digest:
ad436d9d13a1c4e9cd41c2597febbd51b5c6992f8b62c563f45bdb85ef9d7939 - Sigstore transparency entry: 2261211867
- Sigstore integration time:
-
Permalink:
butkoden/muscles@e782e0f88f054fea12a0647951501e1ba6b329a2 -
Branch / Tag:
refs/tags/v1.0.0rc4 - Owner: https://github.com/butkoden
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e782e0f88f054fea12a0647951501e1ba6b329a2 -
Trigger Event:
release
-
Statement type: