aw.routing
Configurable routing and decision chains for agentic workflows.
This module provides tools for building extensible, inspectable routing chains that follow the open-closed principle. Users can: - Use default configurations out of the box - Inspect all routing rules and mappings - Customize individual components - Extend with new routing strategies
The key pattern is: provide sensible defaults, make them visible, keep them mutable.
- class aw.routing.ConditionalRouter(strategies: list[~aw.routing.RoutingStrategy] = <factory>, short_circuit: ~typing.Callable[[~typing.Any], bool] | None = None)[source]
Router with short-circuit conditions.
Only accepts results that match the short-circuit condition, otherwise continues to next strategy.
>>> def try_url(x): return x.get('url_ext') >>> def try_type(x): return x.get('content_type_ext') >>> >>> # Only accept .pdf or .md, otherwise keep trying >>> router = ConditionalRouter( ... [try_url, try_type], ... short_circuit=lambda r: r in {'.pdf', '.md'} ... ) >>> >>> # .pdf matches short-circuit, return immediately >>> router({'url_ext': '.pdf', 'content_type_ext': '.html'}) '.pdf' >>> >>> # .jpg doesn't match, try next strategy, .md matches >>> router({'url_ext': '.jpg', 'content_type_ext': '.md'}) '.md'
- class aw.routing.ExtensionContext(url: str, content: bytes = b'', content_type: str = '', explicit_extension: str | None = None)[source]
Context for extension detection.
>>> ctx = ExtensionContext( ... url='https://example.com/file.pdf', ... content=b'%PDF-1.5', ... content_type='text/html' ... ) >>> ctx.url 'https://example.com/file.pdf'
- class aw.routing.ExtensionRouter(priority_extensions: frozenset = <factory>, content_type_map: dict = <factory>, magic_bytes_map: dict = <factory>)[source]
Route extension detection through configurable strategies.
This router implements the default logic for detecting file extensions, but every component is visible and customizable.
Examples
>>> # Use with defaults >>> router = ExtensionRouter() >>> ctx = ExtensionContext('https://example.com/file.pdf', b'%PDF-1.5') >>> router(ctx) '.pdf' >>> >>> # URL without extension, falls back to magic bytes >>> ctx = ExtensionContext('https://example.com/download', b'%PDF-1.5') >>> router(ctx) '.pdf' >>> >>> # Priority extensions short-circuit >>> ctx = ExtensionContext('https://example.com/file.pdf', b'<html>') >>> router(ctx) # .pdf from URL wins even though content is HTML '.pdf' >>> >>> # Customize content type mapping >>> router.content_type_map['.txt'] = 'text/x-log' >>> >>> # Add custom detector >>> def my_detector(ctx): return '.custom' if 'special' in ctx.url else None >>> router = router.with_prepended_strategy(my_detector)
- with_appended_strategy(strategy: Callable[[ExtensionContext], str | None]) ExtensionRouter[source]
Create new router with added strategy at lowest priority.
- with_prepended_strategy(strategy: Callable[[ExtensionContext], str | None]) ExtensionRouter[source]
Create new router with added strategy at highest priority.
- class aw.routing.MappingRouter(mapping: dict = <factory>, default: ~typing.Any = None, key_transform: ~typing.Callable[[~typing.Any], ~typing.Any] | None = None)[source]
Router based on a lookup mapping.
Provides a clean interface for switch-case style routing with: - Visible, mutable mapping - Optional default value or factory - Easy extension via dict interface
>>> # Content-Type to extension mapping >>> ct_map = { ... 'application/pdf': '.pdf', ... 'text/html': '.html', ... 'application/json': '.json', ... } >>> router = MappingRouter(ct_map) >>> >>> router('application/pdf') '.pdf' >>> router('text/plain') is None # No default True >>> >>> # With default >>> router_with_default = MappingRouter(ct_map, default='.bin') >>> router_with_default('text/plain') '.bin'
- copy() MappingRouter[source]
Create a copy with same configuration.
- class aw.routing.PriorityRouter(strategies: list[RoutingStrategy] = <factory>)[source]
Route through strategies in priority order, short-circuiting on first match.
This is a simpler, more specialized version of i2.routing_forest that’s optimized for the common case of “try these in order, stop at first success”.
>>> def try_a(x): return 'A' if x > 10 else None >>> def try_b(x): return 'B' if x > 5 else None >>> def try_c(x): return 'C' >>> >>> router = PriorityRouter([try_a, try_b, try_c]) >>> router(15) 'A' >>> router(8) 'B' >>> router(3) 'C'
- append(strategy: RoutingStrategy) PriorityRouter[source]
Add a strategy at the end (lowest priority).
- insert(index: int, strategy: RoutingStrategy) PriorityRouter[source]
Insert a strategy at a specific position.
- prepend(strategy: RoutingStrategy) PriorityRouter[source]
Add a strategy at the beginning (highest priority).
- class aw.routing.RoutingStrategy(*args, **kwargs)[source]
Protocol for routing strategies.
A routing strategy takes a context and returns a result or None.
- aw.routing.detect_explicit(ctx: ExtensionContext) str | None[source]
Use explicit extension if provided.
>>> ctx = ExtensionContext('', explicit_extension='pdf') >>> detect_explicit(ctx) '.pdf' >>> ctx = ExtensionContext('', explicit_extension='.json') >>> detect_explicit(ctx) '.json'
- aw.routing.detect_from_url(ctx: ExtensionContext) str | None[source]
Extract extension from URL path.
>>> ctx = ExtensionContext('https://example.com/file.pdf') >>> detect_from_url(ctx) '.pdf' >>> ctx = ExtensionContext('https://example.com/file') >>> detect_from_url(ctx) is None True
- aw.routing.make_content_type_detector(content_type_map: dict | None = None) Callable[[ExtensionContext], str | None][source]
Factory for content-type based detection.
Returns a detector function with the given mapping. Users can create custom detectors with different mappings.
>>> # Use default mapping >>> detector = make_content_type_detector() >>> ctx = ExtensionContext('', content_type='application/pdf') >>> detector(ctx) '.pdf' >>> >>> # Custom mapping >>> custom_map = {'text/plain': '.log'} >>> custom_detector = make_content_type_detector(custom_map) >>> ctx = ExtensionContext('', content_type='text/plain') >>> custom_detector(ctx) '.log'
- aw.routing.make_magic_bytes_detector(magic_bytes_map: dict | None = None) Callable[[ExtensionContext], str | None][source]
Factory for magic bytes based detection.
>>> detector = make_magic_bytes_detector() >>> ctx = ExtensionContext('', content=b'%PDF-1.5...') >>> detector(ctx) '.pdf' >>> ctx = ExtensionContext('', content=b'<html>...') >>> detector(ctx) '.html'