Instance-scoped routing engine for Python with hierarchical handlers and composable plugins
Project description
SmartRoute
SmartRoute is a fully runtime routing engine that lets you expose Python methods as "endpoints" (CLI tools, orchestrators, internal services) without global blueprints or shared registries. Each instance creates its own routers, can attach child routers, configure plugins, and provides ready-to-use runtime introspection.
Use SmartRoute when you need to:
- Compose internal services with many handlers (application APIs, orchestrators, CLI automation)
- Build dashboards/portals that register routers dynamically and need runtime introspection
- Extend handler behavior with plugins (logging, validation, audit trails)
SmartRoute provides a consistent, well-tested foundation for these patterns.
Key Features
- Instance-scoped routers – Each object instantiates its own routers (
Router(self, ...)) with isolated state. - Friendly registration –
@route(...)accepts explicit names, auto-strips prefixes, and supports custom metadata. - Simple hierarchies –
attach_instance(child, name="alias")connects RoutedClass instances with dotted path access (parent.api.get("child.method")). - Plugin pipeline –
BasePluginprovideson_decore/wrap_handlerhooks and plugins inherit from parents automatically. - Runtime configuration –
routedclass.configure()applies global or per-handler overrides with wildcards and returns reports ("?"). - Optional extras –
logging,pydanticplugins and SmartAsync wrapping are opt-in; the core has minimal dependencies. For scope/channel policies, use the ecosystem plugin (see Publish-ready plugin). - Full coverage – The package ships with a comprehensive test suite and no hidden compatibility layers.
Quick Example
from smartroute import RoutedClass, Router, route
class OrdersAPI(RoutedClass):
def __init__(self, label: str):
self.label = label
self.api = Router(self, name="orders")
@route("orders")
def list(self):
return ["order-1", "order-2"]
@route("orders")
def retrieve(self, ident: str):
return f"{self.label}:{ident}"
@route("orders")
def create(self, payload: dict):
return {"status": "created", **payload}
orders = OrdersAPI("acme")
print(orders.api.get("list")()) # ["order-1", "order-2"]
print(orders.api.get("retrieve")("42")) # acme:42
overview = orders.api.members()
print(overview["handlers"].keys()) # dict_keys(['list', 'retrieve', 'create'])
Hierarchical Routing
Build nested service structures with dotted path access:
class UsersAPI(RoutedClass):
def __init__(self):
self.api = Router(self, name="api")
@route("api")
def list(self):
return ["alice", "bob"]
class Application(RoutedClass):
def __init__(self):
self.api = Router(self, name="api")
self.users = UsersAPI()
# Attach child service
self.api.attach_instance(self.users, name="users")
app = Application()
print(app.api.get("users.list")()) # ["alice", "bob"]
# Introspect hierarchy
info = app.api.members()
print(info["children"].keys()) # dict_keys(['users'])
Publish-ready plugin
For scope/channel policies, SmartRoute uses an ecosystem plugin. To attach scopes and channels for publication, use the SmartPublisher plugin:
from smartpublisher.smartroute_plugins.publish import PublishPlugin
from smartroute import Router
# Import registers the plugin as "publish"
router = Router(self, name="api").plug("publish")
This keeps the core lean while letting SmartPublisher own the canonical rules for scopes/channels. Projects that do not need publication policies can skip the plugin entirely.
Installation
pip install smartroute
For development:
git clone https://github.com/genropy/smartroute.git
cd smartroute
pip install -e ".[all]"
To use the Pydantic plugin:
pip install smartroute[pydantic]
Core Concepts
Router– Runtime router bound directly to an object viaRouter(self, name="api")@route("name")– Decorator that marks bound methods for the router with the matching nameRoutedClass– Mixin that tracks routers per instance and exposes theroutedclassproxyBasePlugin– Base class for creating plugins withon_decoreandwrap_handlerhooksobj.routedclass– Proxy exposed by every RoutedClass that provides helpers likeget_router(...)andconfigure(...)for managing routers/plugins without polluting the instance namespace.
Pattern Highlights
- Explicit naming + prefixes –
@route("api", name="detail")andRouter(prefix="handle_")separate method names from public route names (test_prefix_and_name_override). - Explicit instance hierarchies –
self.api.attach_instance(self.child, name="alias")connects RoutedClass instances with parent tracking and auto-detachment (test_attach_and_detach_instance_single_router_with_alias). - Branch routers –
Router(branch=True, auto_discover=False)creates pure organizational nodes without handlers (test_branch_router_blocks_auto_discover_and_entries). - Built-in and custom plugins –
Router(...).plug("logging"),Router(...).plug("pydantic"), or custom plugins (llm-docs/PATTERNS.md#pattern-12-custom-plugin-development). Scope/channel policies live in the SmartPublisher ecosystem plugin. - Runtime configuration –
routedclass.configure("api:logging/foo", enabled=False)applies targeted overrides with wildcards or batch updates (see dedicated guide). - Dynamic registration –
router.add_entry(handler)orrouter.add_entry("*")allow publishing handlers computed at runtime (tests/test_router_runtime_extras.py).
Documentation
- Full Documentation – Complete guides, tutorials, and API reference
- Quick Start – Get started in 5 minutes
- FAQ – Common questions and answers about SmartRoute and plugins
- LLM Reference – Token-optimized reference for AI code generation
- API Details – Complete API reference generated from tests
- Usage Patterns – Common patterns extracted from test suite
Testing
SmartRoute achieves 100% test coverage with 94 comprehensive tests (898 statements):
PYTHONPATH=src pytest --cov=src/smartroute --cov-report=term-missing
All examples in documentation are verified by the test suite and linked with test anchors.
Repository Structure
smartroute/
├── src/smartroute/
│ ├── core/ # Core router implementation
│ │ ├── router.py # Router runtime implementation
│ │ ├── decorators.py # @route decorator
│ │ └── routed.py # RoutedClass mixin
│ └── plugins/ # Built-in plugins
│ ├── logging.py # LoggingPlugin
│ └── pydantic.py # PydanticPlugin
├── tests/ # Test suite (100% coverage)
│ ├── test_switcher_basic.py # Core functionality
│ ├── test_router_edge_cases.py # Edge cases
│ ├── test_plugins_new.py # Plugin system
│ ├── test_pydantic_plugin.py # Pydantic validation
│ └── test_coverage_gaps.py # Coverage gap tests
├── docs/ # Human documentation (Sphinx)
├── llm-docs/ # LLM-optimized documentation
└── examples/ # Example implementations
Project Status
SmartRoute is currently in beta (v0.8.0). The core API is stable with complete documentation.
- Test Coverage: 100% (94 tests, 898 statements)
- Python Support: 3.10, 3.11, 3.12
- License: MIT
Current Limitations
- Instance methods only – Routers assume decorated functions are bound methods (no static/class method or free function support)
- No SmartAsync plugin –
get(..., use_smartasync=True)is optional but there's no dedicated SmartAsync plugin - Minimal plugin system – Intentionally simple; advanced features (e.g., Pydantic declarative config) must be added manually
Roadmap
- ✅ Complete Sphinx documentation with tutorials and API reference
- Additional plugins (async, storage, audit trail, metrics)
- Benchmarks and performance comparison
- Example applications and use cases
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
Acknowledgments
SmartRoute was designed with lessons learned from real-world production use.
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 smartroute-0.8.4.tar.gz.
File metadata
- Download URL: smartroute-0.8.4.tar.gz
- Upload date:
- Size: 46.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 |
e5d7b838878f4c0aa55983fd0b46399ca7ea4b5eef5f62aec2e0672f331762b0
|
|
| MD5 |
4ce8f0d60375b000e6341a333615658c
|
|
| BLAKE2b-256 |
798fbcd98e69186169d1198c85baa513588d9580d47199ec70d2dd3da98497aa
|
Provenance
The following attestation bundles were made for smartroute-0.8.4.tar.gz:
Publisher:
publish.yml on genropy/smartroute
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartroute-0.8.4.tar.gz -
Subject digest:
e5d7b838878f4c0aa55983fd0b46399ca7ea4b5eef5f62aec2e0672f331762b0 - Sigstore transparency entry: 726799717
- Sigstore integration time:
-
Permalink:
genropy/smartroute@b60194c88a47eb18b540ae80a95f783aec2de778 -
Branch / Tag:
refs/tags/v0.8.4 - Owner: https://github.com/genropy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b60194c88a47eb18b540ae80a95f783aec2de778 -
Trigger Event:
push
-
Statement type:
File details
Details for the file smartroute-0.8.4-py3-none-any.whl.
File metadata
- Download URL: smartroute-0.8.4-py3-none-any.whl
- Upload date:
- Size: 35.1 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 |
08a2545089b56cd1fbc23c06b70f1ac7b03c5813e74beabc01c5dfb24b870789
|
|
| MD5 |
0de92f1fc005e6eea2005a9f0658f52d
|
|
| BLAKE2b-256 |
2bb296b9ab66639ccf364c70427e2d8232f03b63b68db8e277d7e8e941127ea0
|
Provenance
The following attestation bundles were made for smartroute-0.8.4-py3-none-any.whl:
Publisher:
publish.yml on genropy/smartroute
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartroute-0.8.4-py3-none-any.whl -
Subject digest:
08a2545089b56cd1fbc23c06b70f1ac7b03c5813e74beabc01c5dfb24b870789 - Sigstore transparency entry: 726799721
- Sigstore integration time:
-
Permalink:
genropy/smartroute@b60194c88a47eb18b540ae80a95f783aec2de778 -
Branch / Tag:
refs/tags/v0.8.4 - Owner: https://github.com/genropy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b60194c88a47eb18b540ae80a95f783aec2de778 -
Trigger Event:
push
-
Statement type: