Plugin API Reference

This section documents the built-in plugins provided by SmartRoute.

For additional reference, see:

  • LLM API Details - Complete plugin API reference

  • Scope/channel policies are available via SmartPublisher (smartpublisher.smartroute_plugins.publish.PublishPlugin).

Auto-Generated Plugin API

Logging plugin (source of truth).

Rebuild behaviour exactly as described; no hidden defaults beyond this text.

Responsibilities

  • Wrap each handler call and emit configurable messages: before (default True) logs "{entry.name} start"; after (default True) logs "{entry.name} end (<ms> ms)" with elapsed time.

  • Sinks: when print is true, always use print(message); when log is true, use logger.info(message) if the logger reports handlers via hasHandlers(), otherwise fall back to print(message); else no output.

  • enabled gates the plugin entirely (default True).

  • Use a provided logging.Logger (default logging.getLogger("smartroute")).

Configuration

  • Accepted keys (router-level or per-handler): enabled, before, after, log, print. They can be provided as individual kwargs (e.g. logging_after=False) or in logging_flags (e.g. "enabled:off,before:on,after:on,log:on,print:off").

  • Runtime: router.logging.configure mirrors the same options, plus per-handler via configure["handler"].before = False.

  • flags string values are parsed like other plugins via BasePlugin.

Behaviour and API

  • LoggingPlugin(name=None, logger=None, **cfg) delegates to BasePlugin; if name is falsy it sets "logger" as the plugin name. logger is stored in self._logger; additional **cfg seeds initial config.

  • _emit(message, cfg) chooses sink based on cfg as described above.

  • wrap_handler(route, entry, call_next) applies the configuration on each call. Exceptions propagate; the end message is skipped when an exception is raised.

Registration

At module import, the plugin registers itself globally as "logging" via Router.register_plugin(LoggingPlugin).

class smartroute.plugins.logging.LoggingPlugin(router, *, logger=None, **cfg)[source]

Bases: BasePlugin

Simplified logging plugin for SmartRoute.

Parameters:

logger (Optional[Logger])

plugin_code: str = 'logging'
plugin_description: str = 'Logs handler calls with timing'
__init__(router, *, logger=None, **cfg)[source]
Parameters:

logger (Optional[Logger])

configure(enabled=True, before=True, after=True, log=True, print=False)[source]

Configure logging plugin options.

The wrapper added by __init_subclass__ handles writing to store.

Parameters:
  • enabled (bool)

  • before (bool)

  • after (bool)

  • log (bool)

  • print (bool)

wrap_handler(route, entry, call_next)[source]

Wrap handler with start/end logging and timing.

Parameters:
  • entry (MethodEntry)

  • call_next (Callable)

Pydantic validation plugin (source of truth).

Rebuild exactly from this contract; no hidden behaviour.

Responsibilities

  • At registration time (on_decore), inspect handler type hints and build a Pydantic model capturing annotated parameters.

  • At call time (wrap_handler), validate annotated args/kwargs before calling the real handler; non-annotated parameters bypass validation.

  • Surface validation failures as Pydantic ValidationError with contextual title "Validation error in <entry.name>".

Dependencies and guards

  • Importing this module requires pydantic; otherwise an ImportError is raised with install guidance. Under TYPE_CHECKING it hints Router import.

  • If type hint resolution fails or no usable hints remain after dropping the return annotation, no model is created and wrapping becomes a passthrough.

Behaviour and data

  • PydanticPlugin(name=None, **config): delegates to BasePlugin; default name is "pydantic".

  • on_decore(route, func, entry):
    • resolves type hints via get_type_hints(func); exceptions skip model.

    • removes return hint if present.

    • builds a fields dict from function signature:
      • annotated parameters missing from signature get required ellipsis.

      • parameters with default use that default; otherwise required.

    • creates a model <func.__name__>_Model via create_model.

    • stores metadata in entry.metadata["pydantic"]: {"model": model, "hints": hints, "signature": sig}.

  • wrap_handler(route, entry, call_next):
    • calls get_model() to check if validation is disabled or no model exists.

    • if get_model() returns None, returns call_next (passthrough).

    • binds incoming args/kwargs with the captured signature (sig.bind) and applies defaults.

    • splits bound arguments into two dicts: annotated (validated) and non-annotated (passthrough).

    • runs the model with annotated args; on ValidationError raises a new ValidationError.from_exception_data with the contextual title.

    • merges validated values back with passthrough args into final_args and calls call_next(**final_args).

    • return value is propagated unchanged.

  • get_model(entry): returns the Pydantic model unless config disabled is truthy or no model exists.

Registration

Registers itself globally as "pydantic" during module import via Router.register_plugin(PydanticPlugin).

class smartroute.plugins.pydantic.PydanticPlugin(router, **config)[source]

Bases: BasePlugin

Validate handler inputs with Pydantic using type hints.

Parameters:

config (Any)

plugin_code: str = 'pydantic'
plugin_description: str = 'Validates handler inputs using Pydantic type hints'
__init__(router, **config)[source]
Parameters:

config (Any)

configure(disabled=False)[source]

Configure pydantic plugin options.

The wrapper added by __init_subclass__ handles writing to store.

Parameters:

disabled (bool)

on_decore(route, func, entry)[source]

Override to run logic when a handler is registered.

Called once per handler at decoration time. Use this to: - Inspect type hints and store metadata - Pre-compute validation models - Annotate entry.metadata for later use in wrap_handler

Parameters:
  • router – The Router instance registering the handler.

  • func (Callable) – The original handler function.

  • entry (MethodEntry) – MethodEntry with name, func, router, plugins, metadata.

  • route (Router)

Return type:

None

wrap_handler(route, entry, call_next)[source]

Validate annotated parameters with the cached Pydantic model before calling.

Parameters:
  • route (Router)

  • entry (MethodEntry)

  • call_next (Callable)

get_model(entry)[source]

Return the Pydantic model for this handler if not disabled.

Parameters:

entry (MethodEntry)

Return type:

Optional[Tuple[str, Any]]

name
entry_metadata(router, entry)[source]

Return pydantic metadata for introspection.

Parameters:
  • router (Any)

  • entry (MethodEntry)

Return type:

Dict[str, Any]