API Reference

Below is the Sphinx API reference. For more context or quick-start guides, see:

Plugin-free router runtime for Genro Routes.

This module exposes BaseRouter, which binds methods on an object instance, resolves path selectors (using ‘/’ separator), and exposes rich introspection without any plugin logic. Subclasses add middleware but must preserve these semantics.

Constructor and slots

Constructor signature:

BaseRouter(owner, name=None, prefix=None, *, description=None,
           default_entry="index", branch=False, parent_router=None)
  • owner is required; None raises ValueError. Routers are bound to this instance and never re-bound.

  • description: optional human-readable description of this router’s purpose. Included in nodes() output for documentation/introspection.

  • default_entry: the fallback entry name (default: “index”) used when a path cannot be fully resolved. The router returns this entry with any unconsumed path segments passed as positional arguments when invoked.

  • parent_router: optional parent router. When provided, this router is automatically attached as a child using name as the alias. Requires name to be set; raises ValueError on name collision.

  • Slots: instance, name, prefix, description (optional router description), _entries (logical name → MethodEntry with handler), _children (name → child router).

Lazy binding

Routers use lazy binding: methods decorated with @route are discovered and registered automatically on first use (node/nodes). No explicit bind() call is needed.

Marker discovery

_iter_marked_methods walks the reversed MRO of type(owner) (child first wins), scans __dict__ for plain functions carrying _route_decorator_kw markers. Only markers whose name matches this router’s name are used.

Handler table and wrapping

  • _register_callable creates a MethodEntry and stores it in _entries.

  • _rebuild_handlers updates each entry’s handler attribute by passing through _wrap_handler (default: passthrough). Subclasses may inject middleware.

Lookup and execution

  • node(path, **kwargs) resolves path using best-match resolution. Returns a RouterNode wrapper that is callable. The RouterNode contains metadata about the resolved entry. Unconsumed path segments are passed as positional arguments when the node is invoked.

Children (instance hierarchies)

include(source, name=...) links a Router or RouterNode into this router. Accepts a Router (child hierarchy) or RouterNode (entry alias).

detach_instance(child) removes all routers belonging to a child instance.

Instance attachment is handled by RoutingClass.attach_instance(), which sets _routing_parent and links child routers into parent routers. Attached child routers inherit plugins via _on_attached_to_parent.

Introspection

  • nodes(**kwargs) builds a nested dict of routers and entries respecting filters. Returns dict with entries and routers keys only if non-empty. Output includes description (router’s description) and owner_doc (owner class docstring) for documentation purposes.

Output modes

  • nodes(mode="openapi") returns flat OpenAPI format with all paths merged.

  • nodes(mode="h_openapi") returns hierarchical OpenAPI format preserving the router tree structure with description and owner_doc at each level.

Hooks for subclasses

  • _wrap_handler: override to wrap callables (middleware stack).

  • _after_entry_registered: invoked after registering a handler.

  • _on_attached_to_parent: invoked when a child router is linked into this router.

  • _describe_entry_extra: allow subclasses to extend per-entry description.

class genro_routes.core.base_router.BaseRouter(owner, name=None, prefix=None, *, description=None, default_entry='index', get_default_handler=None, get_kwargs=None, branch=False, parent_router=None)[source]

Bases: RouterInterface

Plugin-free router bound to an object instance.

Responsibilities:
  • Register bound methods/functions with logical names (optionally via markers)

  • Resolve path selectors (using ‘/’ separator) across child routers

  • Expose handler tables and introspection data

  • Provide hooks for subclasses to wrap handlers or filter introspection

Parameters:
  • owner (Any)

  • name (str | None)

  • prefix (str | None)

  • description (str | None)

  • default_entry (str)

  • get_default_handler (Callable | None)

  • get_kwargs (dict[str, Any] | None)

  • branch (bool)

  • parent_router (BaseRouter | None)

__init__(owner, name=None, prefix=None, *, description=None, default_entry='index', get_default_handler=None, get_kwargs=None, branch=False, parent_router=None)[source]
Parameters:
  • owner (Any)

  • name (str | None)

  • prefix (str | None)

  • description (str | None)

  • default_entry (str)

  • get_default_handler (Callable | None)

  • get_kwargs (dict[str, Any] | None)

  • branch (bool)

  • parent_router (BaseRouter | None)

instance
name: str | None
prefix
description
default_entry
property current_capabilities: set[str]

Collect capabilities from instance and parent chain.

Walks up the _routing_parent chain accumulating capabilities from each RoutingClass instance.

Returns:

Combined set of capabilities from all instances in the hierarchy.

add_entry(target, *, name=None, metadata=None, replace=False, **options)[source]

Register handler(s) on this router.

Note

For most use cases, prefer the @route decorator. Use add_entry directly only for dynamic registration (e.g., introspection-based mapping of external libraries).

Parameters:
  • target (Any) – Callable, attribute name(s), comma-separated string, or wildcard marker.

  • name (str | None) – Logical name override for this entry.

  • metadata (dict[str, Any] | None) – Extra metadata stored on the MethodEntry.

  • replace (bool) – Allow overwriting an existing logical name.

  • options (Any) – Extra metadata merged into entry metadata.

Return type:

BaseRouter

Returns:

self (to allow chaining).

Raises:
  • ValueError – on handler name collision when replace is False.

  • AttributeError – when resolving missing attributes on owner.

  • TypeError – on unsupported target type.

include(source, *, name=None)[source]

Include a Router or RouterNode (entry alias) into this router.

Accepts two source types:

  • Router: links the source router as a child of this router. Plugin inheritance is triggered via _on_attached_to_parent. If the source router belongs to a RoutingClass, _routing_parent is set on the owner.

  • RouterNode: creates an alias for a single entry in this router. The original handler is shared — no copy is made.

Parameters:
  • source (Any) – A Router instance or a RouterNode from node().

  • name (str | None) – Alias in this router. For Router sources, defaults to source.name. For RouterNode sources, required.

Raises:
  • TypeError – If source is not a Router or RouterNode.

  • ValueError – If name is required but not provided.

  • ValueError – If alias collision in _children or _entries.

Return type:

None

Examples:

# Include a router
self._sys.include(swagger.api, name="swagger")

# Include an entry as alias
fatture.api.include(
    pagamenti.api.node("collega_a_fattura"),
    name="collega_pagamento",
)
detach_instance(routing_child)[source]

Detach all routers belonging to a RoutingClass instance.

Parameters:

routing_child (Any)

Return type:

BaseRouter

get_url(path, **kwargs)[source]

Build a URL path for a handler, appending positional parameters.

Accepts a path (e.g., "users/detail") or an endpoint_id with @ prefix (e.g., "@invoice.detail"). Keyword arguments that match positional parameters in the handler’s signature are appended as path segments in declaration order.

Parameters:
  • path (str) – Handler path or "@endpoint_id".

  • **kwargs (Any) – Parameter values to append to the path. Only positional-or-keyword parameters are appended (in declaration order). Keyword-only parameters are ignored.

Return type:

str

Returns:

The full URL path string.

Raises:

ValueError – If the path does not resolve to a valid handler.

Example:

# Given: @route("api", endpoint_id="invoice.detail")
#        def detail(self, invoice_id): ...
# Mounted at: billing/detail

router.get_url("@invoice.detail", invoice_id=123)
# → "billing/detail/123"

router.get_url("billing/detail", invoice_id=123)
# → "billing/detail/123"
router_at_path(path)[source]

Find the router at the given path.

Parameters:

path (str) – Path to navigate (e.g., “child/grandchild”).

Return type:

BaseRouter | None

Returns:

The router at the path, or None if not found.

nodes(basepath=None, lazy=False, mode=None, pattern=None, forbidden=False, **kwargs)[source]

Return a tree of routers/entries/metadata respecting filters.

Parameters:
  • basepath (str | None) – Optional path to start from (e.g., “child/grandchild”). If provided, returns nodes starting from that point in the hierarchy instead of from this router.

  • lazy (bool) – If True, child routers are returned as router references instead of recursively expanded. Use basepath to navigate and expand specific children on demand.

  • mode (str | None) –

    Output format mode. Supported modes:

    • None: Standard introspection format with full metadata.

    • ”openapi”: Flat OpenAPI format with all paths merged.

    • ”h_openapi”: Hierarchical OpenAPI format preserving the router tree structure.

  • pattern (str | None) – Optional regex pattern to filter entry names. Only entries whose name matches the pattern are included. Applied before plugin deny_reason() checks.

  • forbidden (bool) – If True, include entries that are not allowed (e.g., due to authorization or capability requirements). These entries will have a forbidden field with the reason (e.g., “not_authorized”, “not_available”). Default False.

  • **kwargs (Any) – Filter arguments passed to plugins via deny_reason().

Returns:

  • name: Router name

  • description: Router description (if set)

  • owner_doc: Owner class docstring (for documentation)

  • router: Reference to this router

  • instance: Owner instance

  • plugin_info: Plugin configuration info

  • entries: Dict of entry names to entry info (if any)

  • routers: Dict of child names to child nodes (if any)

When mode is specified, output is translated to that format.

Return type:

A dict containing

node(path, errors=None, openapi=False, **kwargs)[source]

Return info about a single node (router or entry) at the given path.

Unlike nodes() which returns the full subtree, this method returns information about just one specific node without recursion.

This method always performs best-match resolution: it walks the path as far as possible, tracking the last valid callable node (entry or router with default_entry). If the exact path is not found, it falls back to that last valid node and passes unconsumed path segments as positional arguments when the node is invoked.

The returned RouterNode is callable - invoking it executes the handler.

Parameters:
  • path (str) – Path to the node (e.g., “entry_name” or “child/grandchild/entry”).

  • errors (dict[str, type[Exception]] | None) –

    Optional dict mapping error codes to custom exception classes. Available codes (see RouterNode.ERROR_CODES):

    • not_found: Path not found or varargs_required

    • not_authorized: Auth tags don’t match (403)

    • not_authenticated: Auth required but not provided (401)

    • validation_error: Pydantic validation failed

    Example:

    node = router.node("handler", errors={
        'not_found': HTTPNotFound,
        'not_authorized': HTTPForbidden,
    })
    

  • openapi (bool) – If True, populate the openapi attribute with OpenAPI info.

  • **kwargs (Any) – Plugin-prefixed filter kwargs (e.g., auth_tags=”x”).

Returns:

  • path: Full path to this node
    • error: Error code (None if ok, else “not_found”, “not_authorized”, etc.)

    • doc: Entry docstring

    • metadata: Entry metadata dict

    • openapi: OpenAPI info dict (if openapi=True was passed)

The RouterNode is callable:

node = router.node("my_handler")
result = node()  # Invoke the handler

If error is set, calling the node raises the mapped exception.

Return type:

A RouterNode with these public properties

iter_plugins()[source]
Return type:

list[Any]

Router with plugin pipeline for Genro Routes.

Router extends BaseRouter with a global plugin registry, per-router plugin instances, middleware wrapping, and plugin state stored on the router.

Internal state

  • _plugin_specs: list of _PluginSpec (factory, kwargs copy).

  • _plugins: instantiated plugins in the order they were attached.

  • _plugins_by_name: name → plugin instance (first wins).

  • _inherited_from: set of parent ids already inherited to avoid double cloning when the same child is attached multiple times.

  • _plugin_info: per-plugin state store on the router.

Global registry

Router.register_plugin(name, plugin_class) validates that plugin_class is a subclass of BasePlugin and name is non-empty.

Attaching plugins

plug(plugin_name, **config) looks up the plugin class by name in the global registry. It stores a _PluginSpec, instantiates the plugin, appends to _plugins and _plugins_by_name, applies plugin.on_decore to all existing entries, rebuilds handlers, and returns self.

Wrapping pipeline

_wrap_handler(entry, call_next) builds middleware layers from the current _plugins in reverse order (last attached closest to the handler).

Inheritance behaviour

_on_attached_to_parent(parent) runs when a child router is attached. Parent specs are cloned once per parent. Cloned specs are instantiated into new plugins that are prepended ahead of existing child plugins.

Example:

from genro_routes import Router, RoutingClass, route

class MyService(RoutingClass):
    def __init__(self):
        self.api = Router(self, name="api").plug("logging")

    @route("api")
    def hello(self):
        return "Hello!"
class genro_routes.core.router.Router(*args, **kwargs)[source]

Bases: BaseRouter

Router with plugin registry and pipeline support.

Extends BaseRouter with:
  • Global plugin registry for registering plugin classes

  • Per-router plugin instances with middleware wrapping

  • Plugin state management and configuration

  • Plugin inheritance when attaching child routers

__init__(*args, **kwargs)[source]
classmethod register_plugin(plugin_class, name=None)[source]

Register a plugin class globally.

Parameters:
  • plugin_class (type[BasePlugin]) – A BasePlugin subclass with plugin_code defined.

  • name (str | None) – Optional override name. If provided, overwrites any existing registration. If not provided, uses plugin_code and raises if already registered with a different class.

Raises:
  • TypeError – If plugin_class is not a BasePlugin subclass.

  • ValueError – If plugin_code is missing or name collision occurs.

Return type:

None

classmethod available_plugins()[source]

Return a copy of the global plugin registry.

Return type:

dict[str, type[BasePlugin]]

plug(plugin, **config)[source]

Attach a plugin by name (previously registered globally).

Parameters:
  • plugin (str) – Name of the plugin to attach.

  • **config (Any) – Configuration options passed to the plugin.

Return type:

Router

Returns:

self (for method chaining).

Raises:
  • TypeError – If plugin is not a string.

  • ValueError – If plugin is not registered or already attached.

iter_plugins()[source]

Return attached plugin instances in application order.

Return type:

list[BasePlugin]

get_config(plugin_name, method_name=None)[source]

Return merged plugin configuration.

Retrieves the effective configuration for a plugin, merging global (router-level) settings with optional per-handler overrides.

Parameters:
  • plugin_name (str) – Name of the attached plugin.

  • method_name (str | None) – If provided, includes handler-specific overrides merged on top of global config.

Return type:

dict[str, Any]

Returns:

Dict of configuration values. Per-handler values override global.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> router.plug("logging")
>>> router.logging.configure(before=False)
>>> router.logging.configure(_target="slow_handler", after=True)
>>> router.get_config("logging")
{'enabled': True, 'before': False}
>>> router.get_config("logging", "slow_handler")
{'enabled': True, 'before': False, 'after': True}
__getattr__(name)[source]

Access attached plugins by name as attributes.

Enables fluent plugin configuration via attribute access syntax. Only works for attached plugins; other attribute access follows normal Python behavior.

Parameters:

name (str) – Plugin name (e.g., “logging”, “auth”, “pydantic”).

Return type:

Any

Returns:

The BasePlugin instance attached under that name.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> router.plug("logging").plug("auth")
>>> router.logging.configure(before=False)
>>> router.auth.configure(rule="admin")
set_plugin_enabled(method_name, plugin_name, enabled=True)[source]

Enable or disable a plugin for a specific handler at runtime.

Sets a runtime override in the “locals” store, which takes precedence over static configuration. Use “_all_” as method_name to affect all handlers globally.

Parameters:
  • method_name (str) – Handler name or “_all_” for global setting.

  • plugin_name (str) – Name of the attached plugin.

  • enabled (bool) – True to enable, False to disable.

Raises:

AttributeError – If no plugin with that name is attached.

Return type:

None

Example

>>> router.set_plugin_enabled("slow_handler", "logging", False)
>>> router.set_plugin_enabled("_all_", "pydantic", False)
is_plugin_enabled(method_name, plugin_name)[source]

Check if a plugin is enabled for a specific handler.

Resolution order (first found wins): 1. entry locals (runtime override via set_plugin_enabled) 2. entry config (static via configure(_target=method_name, enabled=…)) 3. global locals (runtime override via set_plugin_enabled for _all_) 4. global config (static via configure(enabled=…)) 5. default: True

Parameters:
  • method_name (str)

  • plugin_name (str)

Return type:

bool

set_runtime_data(method_name, plugin_name, key, value)[source]

Store arbitrary runtime data for a plugin/handler combination.

Plugins can use this to store handler-specific state that persists across invocations but is not part of the configuration schema.

Parameters:
  • method_name (str) – Handler name or “_all_” for global data.

  • plugin_name (str) – Name of the attached plugin.

  • key (str) – Data key to store.

  • value (Any) – Value to store (any type).

Raises:

AttributeError – If no plugin with that name is attached.

Return type:

None

Example

>>> router.set_runtime_data("handler", "auth", "last_access", time.time())
get_runtime_data(method_name, plugin_name, key, default=None)[source]

Retrieve runtime data for a plugin/handler combination.

Parameters:
  • method_name (str) – Handler name or “_all_” for global data.

  • plugin_name (str) – Name of the attached plugin.

  • key (str) – Data key to retrieve.

  • default (Any) – Value to return if key not found.

Return type:

Any

Returns:

The stored value, or default if not found.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> last = router.get_runtime_data("handler", "auth", "last_access")
instance
name: str | None
prefix
description
default_entry

Decorator helpers for marking routed methods.

This module contains only marker helpers; no router mutation happens at decoration time.

route(router, *, name=None, **kwargs)

Returns a decorator storing metadata on the function under _route_decorator_kw as a list of dicts. Each payload starts with {"name": router}.

  • Explicit logical name: if name is provided, the payload sets entry_name to that value. Otherwise the handler name defaults to the function name.

  • Extra **kwargs are copied verbatim into the payload (e.g. plugin flags).

  • Multiple routers can target the same function by stacking decorators.

  • The decorator returns the original function unchanged aside from the marker.

Re-exports

This module re-exports RoutingClass and Router for convenience so user code can import everything from one place.

genro_routes.core.decorators.route(router=None, *, name=None, endpoint_id=None, **kwargs)[source]

Mark a bound method for inclusion in the given router.

Parameters:
  • router (str | None) – Router identifier (e.g. "api"). If None, uses the default router (only works if the class has exactly one router).

  • name (str | None) – Optional explicit entry name (overrides function name/prefix stripping).

  • endpoint_id (str | None) – Optional globally unique identifier for reverse lookup. When set, the handler can be resolved via router.node("@endpoint_id").

  • **kwargs (Any) – Extra metadata merged into handler entry (e.g. plugin flags).

Return type:

Callable[[Callable], Callable]

Returns:

Decorator that marks the function for the specified router.

Example:

@route("api")
def list_users(self):
    return ["alice", "bob"]

@route("api", name="custom_name", logging_enabled=False)
def get_user(self, user_id):
    return {"id": user_id}

# With single router - @route() works without arguments:
class Table(RoutingClass):
    def __init__(self):
        self.api = Router(self, name="api")  # single router

    @route()  # Uses the only router automatically
    def add(self, data):
        ...

# With multiple routers - must specify:
class Service(RoutingClass):
    def __init__(self):
        self.api = Router(self, name="api")
        self.admin = Router(self, name="admin")

    @route("api")  # Must specify router name
    def public(self):
        ...
class genro_routes.core.decorators.RoutingClass[source]

Bases: object

Mixin providing helper proxies for runtime routers.

Subclass this to enable automatic router registration and configuration via the routing property.

attach_instance(child, *, name=None, **router_specs)[source]

Attach a child RoutingClass instance and optionally link its routers.

Sets child._routing_parent = self and links child routers to parent routers according to the provided mapping.

Parameters:
  • child (RoutingClass) – The RoutingClass instance to attach.

  • name (str | None) – Shortcut for the 1:1 case (child has a single router). The child’s default router is linked to this instance’s default router under the given alias.

  • **router_specs (str) – Explicit mapping with router_<parent_router> keys. Values are comma-separated "child_router:alias" pairs.

Raises:
  • TypeError – If child is not a RoutingClass instance.

  • ValueError – If name and router_* specs are both provided.

  • ValueError – If name is used but child or parent has multiple routers.

  • ValueError – If a referenced router does not exist.

  • ValueError – If there is an alias collision in _children.

Return type:

None

Examples:

# 1:1 shortcut
self.attach_instance(child, name="sales")

# Explicit cross-mapping
self.attach_instance(child,
    router_api="orders:sales,billing:invoices",
    router_admin="mgmt:management",
)
property routing: _RoutingProxy

Return a proxy for router configuration and lookup.

property ctx: RoutingContext | None

Return the execution context, walking up the parent chain.

property default_router: Any

Return the default router for this instance.

Returns the router only if exactly one router is registered. This allows @route() without arguments to work when there’s an unambiguous single router.

If multiple routers are registered, returns None and @route() requires an explicit router name argument.

Returns:

The single router or None if zero or multiple.

Return type:

Router | None

property capabilities

Return the capabilities declared by this instance.

Capabilities represent what features/dependencies this service has available at runtime. Used by EnvPlugin to filter entries based on capability requirements.

Capabilities must be a CapabilitiesSet subclass instance. Each capability is defined as a method decorated with @capability that returns True if the capability is currently available.

Returns:

A CapabilitiesSet instance, or empty set if not configured.

Example:

from genro_routes.plugins.env import CapabilitiesSet, capability

class PaymentCapabilities(CapabilitiesSet):
    def __init__(self, service):
        self._service = service

    @capability
    def stripe(self) -> bool:
        return self._service._stripe_configured

    @capability
    def paypal(self) -> bool:
        return self._service._paypal_configured

class PaymentService(RoutingClass):
    def __init__(self):
        self.api = Router(self, name="api").plug("env")
        self._stripe_configured = True
        self._paypal_configured = False
        self.capabilities = PaymentCapabilities(self)
result_wrapper(value, **metadata)[source]

Wrap a handler result with metadata.

Use this when a handler needs to return additional metadata (e.g., mime_type) along with the result value.

Parameters:
  • value (Any) – The actual result to return.

  • **metadata (Any) – Key-value pairs of metadata (e.g., mime_type=”text/html”).

Return type:

ResultWrapper

Returns:

A ResultWrapper instance containing value and metadata.

Example

@route(“root”) def _resource(self, name: str):

content, mime_type = self.load_resource(name) return self.result_wrapper(content, mime_type=mime_type)

class genro_routes.core.decorators.Router(*args, **kwargs)[source]

Bases: BaseRouter

Router with plugin registry and pipeline support.

Extends BaseRouter with:
  • Global plugin registry for registering plugin classes

  • Per-router plugin instances with middleware wrapping

  • Plugin state management and configuration

  • Plugin inheritance when attaching child routers

__init__(*args, **kwargs)[source]
classmethod register_plugin(plugin_class, name=None)[source]

Register a plugin class globally.

Parameters:
  • plugin_class (type[BasePlugin]) – A BasePlugin subclass with plugin_code defined.

  • name (str | None) – Optional override name. If provided, overwrites any existing registration. If not provided, uses plugin_code and raises if already registered with a different class.

Raises:
  • TypeError – If plugin_class is not a BasePlugin subclass.

  • ValueError – If plugin_code is missing or name collision occurs.

Return type:

None

classmethod available_plugins()[source]

Return a copy of the global plugin registry.

Return type:

dict[str, type[BasePlugin]]

plug(plugin, **config)[source]

Attach a plugin by name (previously registered globally).

Parameters:
  • plugin (str) – Name of the plugin to attach.

  • **config (Any) – Configuration options passed to the plugin.

Return type:

Router

Returns:

self (for method chaining).

Raises:
  • TypeError – If plugin is not a string.

  • ValueError – If plugin is not registered or already attached.

iter_plugins()[source]

Return attached plugin instances in application order.

Return type:

list[BasePlugin]

get_config(plugin_name, method_name=None)[source]

Return merged plugin configuration.

Retrieves the effective configuration for a plugin, merging global (router-level) settings with optional per-handler overrides.

Parameters:
  • plugin_name (str) – Name of the attached plugin.

  • method_name (str | None) – If provided, includes handler-specific overrides merged on top of global config.

Return type:

dict[str, Any]

Returns:

Dict of configuration values. Per-handler values override global.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> router.plug("logging")
>>> router.logging.configure(before=False)
>>> router.logging.configure(_target="slow_handler", after=True)
>>> router.get_config("logging")
{'enabled': True, 'before': False}
>>> router.get_config("logging", "slow_handler")
{'enabled': True, 'before': False, 'after': True}
__getattr__(name)[source]

Access attached plugins by name as attributes.

Enables fluent plugin configuration via attribute access syntax. Only works for attached plugins; other attribute access follows normal Python behavior.

Parameters:

name (str) – Plugin name (e.g., “logging”, “auth”, “pydantic”).

Return type:

Any

Returns:

The BasePlugin instance attached under that name.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> router.plug("logging").plug("auth")
>>> router.logging.configure(before=False)
>>> router.auth.configure(rule="admin")
set_plugin_enabled(method_name, plugin_name, enabled=True)[source]

Enable or disable a plugin for a specific handler at runtime.

Sets a runtime override in the “locals” store, which takes precedence over static configuration. Use “_all_” as method_name to affect all handlers globally.

Parameters:
  • method_name (str) – Handler name or “_all_” for global setting.

  • plugin_name (str) – Name of the attached plugin.

  • enabled (bool) – True to enable, False to disable.

Raises:

AttributeError – If no plugin with that name is attached.

Return type:

None

Example

>>> router.set_plugin_enabled("slow_handler", "logging", False)
>>> router.set_plugin_enabled("_all_", "pydantic", False)
is_plugin_enabled(method_name, plugin_name)[source]

Check if a plugin is enabled for a specific handler.

Resolution order (first found wins): 1. entry locals (runtime override via set_plugin_enabled) 2. entry config (static via configure(_target=method_name, enabled=…)) 3. global locals (runtime override via set_plugin_enabled for _all_) 4. global config (static via configure(enabled=…)) 5. default: True

Parameters:
  • method_name (str)

  • plugin_name (str)

Return type:

bool

set_runtime_data(method_name, plugin_name, key, value)[source]

Store arbitrary runtime data for a plugin/handler combination.

Plugins can use this to store handler-specific state that persists across invocations but is not part of the configuration schema.

Parameters:
  • method_name (str) – Handler name or “_all_” for global data.

  • plugin_name (str) – Name of the attached plugin.

  • key (str) – Data key to store.

  • value (Any) – Value to store (any type).

Raises:

AttributeError – If no plugin with that name is attached.

Return type:

None

Example

>>> router.set_runtime_data("handler", "auth", "last_access", time.time())
get_runtime_data(method_name, plugin_name, key, default=None)[source]

Retrieve runtime data for a plugin/handler combination.

Parameters:
  • method_name (str) – Handler name or “_all_” for global data.

  • plugin_name (str) – Name of the attached plugin.

  • key (str) – Data key to retrieve.

  • default (Any) – Value to return if key not found.

Return type:

Any

Returns:

The stored value, or default if not found.

Raises:

AttributeError – If no plugin with that name is attached.

Example

>>> last = router.get_runtime_data("handler", "auth", "last_access")
instance
name: str | None
prefix
description
default_entry