Skip to content

RouteTable & RouteEntry

toolregistry_server.RouteTable dataclass

RouteTable(_registry: ToolRegistry)

Central router table that bridges ToolRegistry and protocol adapters.

The RouteTable provides a unified view of all registered tools and their routing information. It supports:

  • Querying routes by name or listing all routes
  • Enabling/disabling tools dynamically
  • Observer pattern for change notifications
  • ETag generation for cache validation
Example
from toolregistry import ToolRegistry
from toolregistry_server import RouteTable

registry = ToolRegistry()

@registry.register
def greet(name: str) -> str:
    return f"Hello, {name}!"

route_table = RouteTable(registry)
routes = route_table.list_routes()
print(routes[0].path)
# /tools/default/greet

etag property

etag: str

Get ETag for cache validation.

Returns:

Type Description
str

An ETag string based on the current version.

version property

version: int

Get the current version number.

Returns:

Type Description
int

The version number, incremented on each change.

__post_init__

__post_init__() -> None

Initialize the route table from the registry.

Source code in src/toolregistry_server/route_table.py
def __post_init__(self) -> None:
    """Initialize the route table from the registry."""
    self._rebuild()
    self._registry.on_change(self._on_registry_change)

add_listener

add_listener(callback: Callable[[str, str], None]) -> None

Add a listener for route changes.

The callback will be invoked with (tool_name, event) whenever a route changes. Events include: "enable", "disable", "refresh", "refresh_all".

Parameters:

Name Type Description Default
callback Callable[[str, str], None]

Function to call on changes.

required
Source code in src/toolregistry_server/route_table.py
def add_listener(self, callback: Callable[[str, str], None]) -> None:
    """Add a listener for route changes.

    The callback will be invoked with (tool_name, event) whenever
    a route changes. Events include: "enable", "disable", "refresh",
    "refresh_all".

    Args:
        callback: Function to call on changes.
    """
    self._listeners.append(callback)

disable

disable(tool_name: str, reason: str = '') -> None

Disable a tool.

The route table is automatically refreshed via the registry change callback.

Parameters:

Name Type Description Default
tool_name str

The name of the tool to disable.

required
reason str

Optional reason for disabling.

''

Raises:

Type Description
KeyError

If the tool is not found.

Source code in src/toolregistry_server/route_table.py
def disable(self, tool_name: str, reason: str = "") -> None:
    """Disable a tool.

    The route table is automatically refreshed via the registry change
    callback.

    Args:
        tool_name: The name of the tool to disable.
        reason: Optional reason for disabling.

    Raises:
        KeyError: If the tool is not found.
    """
    self._registry.disable(tool_name, reason)

enable

enable(tool_name: str) -> None

Enable a tool.

The route table is automatically refreshed via the registry change callback.

Parameters:

Name Type Description Default
tool_name str

The name of the tool to enable.

required

Raises:

Type Description
KeyError

If the tool is not found.

Source code in src/toolregistry_server/route_table.py
def enable(self, tool_name: str) -> None:
    """Enable a tool.

    The route table is automatically refreshed via the registry change
    callback.

    Args:
        tool_name: The name of the tool to enable.

    Raises:
        KeyError: If the tool is not found.
    """
    self._registry.enable(tool_name)

get_route

get_route(tool_name: str) -> RouteEntry | None

Get a specific route by tool name.

Parameters:

Name Type Description Default
tool_name str

The name of the tool.

required

Returns:

Type Description
RouteEntry | None

The RouteEntry if found, None otherwise.

Source code in src/toolregistry_server/route_table.py
def get_route(self, tool_name: str) -> RouteEntry | None:
    """Get a specific route by tool name.

    Args:
        tool_name: The name of the tool.

    Returns:
        The RouteEntry if found, None otherwise.
    """
    return self._routes.get(tool_name)

list_routes

list_routes(enabled_only: bool = True, include_deferred: bool = True) -> list[RouteEntry]

List all routes, optionally filtering by enabled state or defer flag.

Parameters:

Name Type Description Default
enabled_only bool

If True, only return enabled routes.

True
include_deferred bool

If False, exclude routes whose tool has metadata.defer == True. Use False when building the initial tool list presented to an LLM so that deferred tools are only surfaced via discover_tools.

True

Returns:

Type Description
list[RouteEntry]

List of RouteEntry objects.

Source code in src/toolregistry_server/route_table.py
def list_routes(
    self,
    enabled_only: bool = True,
    include_deferred: bool = True,
) -> list[RouteEntry]:
    """List all routes, optionally filtering by enabled state or defer flag.

    Args:
        enabled_only: If True, only return enabled routes.
        include_deferred: If False, exclude routes whose tool has
            ``metadata.defer == True``.  Use ``False`` when building
            the initial tool list presented to an LLM so that deferred
            tools are only surfaced via ``discover_tools``.

    Returns:
        List of RouteEntry objects.
    """
    routes = self._routes.values()
    if enabled_only:
        routes = (r for r in routes if r.enabled)
    if not include_deferred:
        routes = (r for r in routes if not r.deferred)
    return list(routes)

refresh

refresh(tool_name: str) -> None

Refresh a single route's state from registry.

Parameters:

Name Type Description Default
tool_name str

The name of the tool to refresh.

required
Source code in src/toolregistry_server/route_table.py
def refresh(self, tool_name: str) -> None:
    """Refresh a single route's state from registry.

    Args:
        tool_name: The name of the tool to refresh.
    """
    tool = self._registry.get_tool(tool_name)
    if tool:
        self._routes[tool_name] = self._tool_to_route(tool)

refresh_all

refresh_all() -> None

Refresh all routes from registry.

Source code in src/toolregistry_server/route_table.py
def refresh_all(self) -> None:
    """Refresh all routes from registry."""
    self._rebuild()
    self._notify_listeners("*", "refresh_all")

remove_listener

remove_listener(callback: Callable[[str, str], None]) -> None

Remove a listener.

Parameters:

Name Type Description Default
callback Callable[[str, str], None]

The callback to remove.

required

Raises:

Type Description
ValueError

If the callback is not found.

Source code in src/toolregistry_server/route_table.py
def remove_listener(self, callback: Callable[[str, str], None]) -> None:
    """Remove a listener.

    Args:
        callback: The callback to remove.

    Raises:
        ValueError: If the callback is not found.
    """
    self._listeners.remove(callback)

toolregistry_server.RouteEntry dataclass

RouteEntry(tool_name: str, namespace: str, method_name: str, path: str, description: str, parameters_schema: dict[str, Any], handler: Callable[..., Any], is_async: bool, parameters_model: Any | None = None, handler_factory: Callable[..., Callable[..., Any]] | None = None, enabled: bool = True, disable_reason: str | None = None, deferred: bool = False)

A single route entry in the central router table.

Attributes:

Name Type Description
tool_name str

Full tool name (e.g., "calculator-evaluate")

namespace str

Tool namespace (e.g., "calculator")

method_name str

Method name within namespace (e.g., "evaluate")

path str

HTTP path for the route (e.g., "/tools/calculator/evaluate")

description str

Tool description

parameters_schema dict[str, Any]

JSON Schema for tool parameters

handler Callable[..., Any]

The actual tool callable

is_async bool

Whether the handler is async

enabled bool

Whether the tool is currently enabled

disable_reason str | None

Reason for disabling, if disabled