Skip to content

Requests and responses

Request

Immutable view of an incoming HTTP request, handed to the Python handler. frozen means no Python-side mutation, so no locking is needed even on free-threaded builds.

body property

body

The raw request body. A pydantic-annotated argument is the usual way to read a body; this is for handlers that parse it themselves.

cookies property

cookies

Cookies parsed from the Cookie header.

headers property

headers

Every header, lowercased. Repeated headers are joined with ", " as HTTP itself defines.

method property

method

The HTTP method, uppercase.

path property

path

The request path, without the query string.

query property

query

The raw query string, or None. Declared query parameters are already coerced and passed as handler arguments; this is for the rest.

header method descriptor

header(name, default=None)

One header by name, case-insensitively. None if absent.

This is the cheap path: no dict is built, and a header that is not valid UTF-8 reads as absent rather than raising.

Response dataclass

Response(
    body: bytes | str = b"",
    status: int = 200,
    content_type: str = "application/json",
    headers: dict[str, str] = dict(),
)

A ready-to-send response.

body may be bytes or str; str is encoded as UTF-8. headers are sent in addition to the content type.

body class-attribute instance-attribute

body: bytes | str = b''

status class-attribute instance-attribute

status: int = 200

content_type class-attribute instance-attribute

content_type: str = 'application/json'

headers class-attribute instance-attribute

headers: dict[str, str] = field(default_factory=dict)

encoded

encoded() -> bytes
Source code in python/aether/_response.py
def encoded(self) -> bytes:
    return self.body.encode() if isinstance(self.body, str) else bytes(self.body)

header_list

header_list() -> list[tuple[str, str]] | None
Source code in python/aether/_response.py
def header_list(self) -> list[tuple[str, str]] | None:
    return list(self.headers.items()) if self.headers else None

Reply

Reply(
    value: Any = None,
    status: int | None = None,
    headers: dict[str, str] | None = None,
)

A handler's result on its way back out.

value is whatever the handler returned: a dict, a model, a Response, an SSE, or None. status overrides what that value would otherwise imply. headers are added to the response.

Source code in python/aether/_middleware.py
def __init__(
    self,
    value: Any = None,
    status: int | None = None,
    headers: dict[str, str] | None = None,
) -> None:
    self.value = value
    self.status = status
    self.headers = headers if headers is not None else {}

value instance-attribute

value = value

status instance-attribute

status = status

headers instance-attribute

headers = headers if headers is not None else {}