Routers
Routing implementations for genro-asgi.
StaticRouter
Filesystem-backed router for serving static files.
StaticRouter - Storage-backed router with best-match path resolution.
- Classes:
- StaticRouter – maps URL paths to StorageNodes using best-match
strategy. Implements RouterInterface.
- StaticRouterNode – result of resolution: wraps a StorageNode with
extra_args (unconsumed segments) and partial_kwargs.
Walks the path segment-by-segment, returns the deepest valid node.
Unconsumed segments are available in extra_args for the caller.
- class genro_asgi.routers.static_router.StaticRouter(root, name=None, *, html_index=True)[source]
Bases:
RouterInterfaceStorage-backed router with best-match resolution.
Wraps a StorageNode (filesystem, S3, HTTP, etc.) and resolves paths using best-match strategy. Returns RouterNode whose callable yields the underlying StorageNode.
- name
Router name for introspection (optional)
- __init__(root, name=None, *, html_index=True)[source]
Initialize router with a storage root.
- Parameters:
root (
StorageNode) – StorageNode pointing to the directory to serve.name (
str|None) – Optional name for introspection and debugging.html_index (
bool) – Reserved for future use (index.html resolution).
- node(path, **kwargs)[source]
Resolve path using best-match strategy.
Walks path segment by segment until a non-existent node is found. Returns the deepest valid node with unconsumed segments in extra_args.
- Parameters:
path (
str) – Relative path, optionally with query string. Examples: “css/style.css”, “api/v2/users?limit=10”- Returns:
callable() → StorageNode (the resolved file or directory)
extra_args: list of path segments after the resolved node
partial_kwargs: dict parsed from query string
type: “entry” (file) or “router” (directory)
metadata: {“mime_type”, “isdir”, “isfile”}
None if root doesn’t exist.
- Return type:
Examples
# Exact file match node = router.node(“style.css”) node.extra_args # [] node() # StorageNode for style.css
# Partial match with extra segments node = router.node(“docs/api/v2/users”) # If only docs/api/ exists: node.extra_args # [“v2”, “users”] node() # StorageNode for docs/api/
# With query string node = router.node(“data?format=json&limit=10”) node.partial_kwargs # {“format”: “json”, “limit”: “10”}
- nodes(basepath=None, lazy=False, mode=None, pattern=None, **kwargs)[source]
Return a tree of files/directories respecting filters.
- Parameters:
basepath (
str|None) – Path to start from (e.g., “images/icons”). If provided, returns nodes starting from that point.lazy (
bool) – If True, child directories are returned as callables instead of recursively expanded.mode (
str|None) – Output format mode (reserved for compatibility).pattern (
str|None) – Regex pattern to filter entry names. Only files whose name matches are included.
- Returns:
name, description, router, entries, routers. Empty dict if root doesn’t exist or is empty.
- Return type:
- class genro_asgi.routers.static_router.StaticRouterNode(storage_node, node_type, name, path, extra_args, partial_kwargs, metadata)[source]
Bases:
objectMinimal RouterNode for StaticRouter. Returns StorageNode on __call__.
- type
“entry” (file) or “router” (directory)
- name
basename of the storage node
- path
resolved path (consumed segments)
- callable
self (for compatibility with tests expecting .callable)
- extra_args
list of unconsumed path segments
- partial_kwargs
dict from parsed query string
- metadata
{“mime_type”: str, “isdir”: bool, “isfile”: bool}
- __init__(storage_node, node_type, name, path, extra_args, partial_kwargs, metadata)[source]
Args: storage_node: Resolved file node from LocalStorage. node_type: MIME type of the resource. name: Filename (basename). path: URL path that matched this node. extra_args: Remaining path segments after match. partial_kwargs: Query parameters parsed from URL. metadata: Route metadata (e.g. auth_tags).
- property callable: StaticRouterNode
Return self for compatibility with code expecting .callable attribute.
- extra_args
- metadata
- name
- partial_kwargs
- path
- type