Added documentation for route path pattern matching.
@@ -119,6 +119,7 @@ async def stats_page(ctx: RouteContext) -> dict:
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `request` | `aiohttp.web.Request` | The aiohttp request object. Access query params, body, headers, path info, etc. |
|
||||
| `match_info` | `dict[str, str]` | Captured path parameters from `{name}` patterns. Empty dict for plain routes. |
|
||||
| `module` | `ModuleContext` | The full module context with all services. |
|
||||
|
||||
All `ModuleContext` services are available directly on `ctx` (see [Proxied Properties](#proxied-properties) below).
|
||||
|
||||
@@ -43,6 +43,60 @@ Routes are automatically prefixed under `/owlbot/<module_name>/`. So if the modu
|
||||
|
||||
This avoids conflicts between modules and with the webhook endpoint. Only the relative path is needed in the decorator.
|
||||
|
||||
## Path Parameters
|
||||
|
||||
Route paths support `{name}` patterns for capturing dynamic segments, using the same syntax as aiohttp. When a request arrives, the URL path is matched against registered route patterns and the captured segments populate `ctx.match_info`.
|
||||
|
||||
Given the route `@on_route("/users/{id}/posts/{slug}")` and a request to `/owlbot/my_module/users/42/posts/hello-world`:
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| `ctx.match_info["id"]` | `"42"` |
|
||||
| `ctx.match_info["slug"]` | `"hello-world"` |
|
||||
|
||||
For plain routes without `{...}` patterns, `ctx.match_info` is an empty dict `{}`.
|
||||
|
||||
### Single Segment
|
||||
|
||||
`{name}` matches a single path segment (no `/`):
|
||||
|
||||
```python
|
||||
@on_route("/users/{id}")
|
||||
async def get_user(ctx: RouteContext) -> dict:
|
||||
user_id = ctx.match_info["id"] # e.g., "123"
|
||||
return {"user_id": user_id}
|
||||
```
|
||||
|
||||
Registered as `/owlbot/my_module/users/{id}`, this matches `/owlbot/my_module/users/123` but not `/owlbot/my_module/users/123/posts`.
|
||||
|
||||
### Custom Regex
|
||||
|
||||
`{name:regex}` matches with a custom regex pattern:
|
||||
|
||||
```python
|
||||
@on_route("/users/{id:\\d+}")
|
||||
async def get_user(ctx: RouteContext) -> dict:
|
||||
user_id = ctx.match_info["id"] # only digits
|
||||
return {"user_id": int(user_id)}
|
||||
```
|
||||
|
||||
### Catch-All
|
||||
|
||||
`{name:.*}` matches the remaining path, including `/` characters. This is useful for prefix-style routing:
|
||||
|
||||
```python
|
||||
@on_route("/api/{path:.*}", methods=["GET", "POST"])
|
||||
async def api_catchall(ctx: RouteContext) -> dict:
|
||||
remaining = ctx.match_info["path"] # e.g., "users/123/posts"
|
||||
return {"path": remaining}
|
||||
```
|
||||
|
||||
> **Note:** The catch-all requires at least one character after the prefix. `/api/{path:.*}` matches `/api/x` but not `/api`.
|
||||
|
||||
### Match Order
|
||||
|
||||
Routes are matched in registration order (first match wins). Routes defined with `@on_route` at import time are registered before dynamically registered routes, so they naturally get priority.
|
||||
|
||||
## Response Types
|
||||
|
||||
Route handlers support three return types:
|
||||
@@ -128,6 +182,9 @@ async def list_page(ctx: RouteContext) -> web.Response:
|
||||
`ctx.request` is a standard `aiohttp.web.Request`. Some common patterns:
|
||||
|
||||
```python
|
||||
# Path parameters (from {name} patterns):
|
||||
user_id = ctx.match_info["id"] # e.g., "123"
|
||||
|
||||
# Query parameters:
|
||||
format = ctx.request.query.get("format", "json")
|
||||
|
||||
@@ -165,6 +222,20 @@ async def setup(ctx: ModuleContext) -> None:
|
||||
)
|
||||
```
|
||||
|
||||
Dynamic registration also supports path patterns:
|
||||
|
||||
```python
|
||||
async def user_handler(ctx: RouteContext) -> dict:
|
||||
return {"user_id": ctx.match_info["id"]}
|
||||
|
||||
@on_setup
|
||||
async def setup(ctx: ModuleContext) -> None:
|
||||
ctx.routes.register(
|
||||
path="/users/{id}",
|
||||
handler=user_handler,
|
||||
)
|
||||
```
|
||||
|
||||
### Available Methods
|
||||
|
||||
| Method | Description |
|
||||
|
||||
Reference in New Issue
Block a user