Response

HTTP response classes.

HTTP Response classes for ASGI applications.

Response is created by Request and linked to it. The dispatcher calls handler, then uses response.set_result() to set the body with auto-detection of content type.

Main Pattern

Response is created empty by Request and configured via set_result():

# In dispatcher after calling handler:
result = await handler(**args)
request.response.set_result(result, mime_type=node.get("mime_type"))
await request.response(scope, receive, send)

TYTX Support

If request has X-TYTX-Transport header, set_result() automatically: - Serializes dict/list using genro_tytx.to_tytx() - Uses the same transport (json/msgpack) as the request - Sets Content-Type to application/vnd.tytx+{transport}

Classes

Response

Single response class. Has request reference, set_result(), set_header(), set_error().

Response Methods

set_result(result, mime_type=None)

Set body from result. Auto-detects content type: - dict/list: JSON (or TYTX if request.tytx_mode) - Path: file bytes with guessed media type - bytes: application/octet-stream - str: text/plain - None: empty body - other: str() as text/plain

set_header(name, value)

Add a response header.

set_error(error)

Set error response from exception. Maps error type to HTTP status.

Helper Functions

make_cookie(key, value, **options)

Creates Set-Cookie header tuple for use with headers parameter.

class genro_asgi.response.Response(content=None, status_code=200, headers=None, media_type=None, request=None)[source]

Bases: object

Base HTTP response class.

Sends bytes or string content with headers through the ASGI interface. Implements __call__ to be usable as an ASGI application.

Can be created empty and configured via set_header/set_result before sending.

body

Encoded response body as bytes.

status_code

HTTP status code.

media_type

Content-Type media type (may include charset).

Example

>>> response = Response(content="Hello", media_type="text/plain")
>>> await response(scope, receive, send)

# Or create empty and configure: >>> response = Response() >>> response.set_header(“X-Custom”, “value”) >>> response.set_result({“data”: 123}) # auto-detects JSON >>> await response(scope, receive, send)

ERROR_MAP: dict[str, int] = {'FileNotFoundError': 404, 'NotAuthorized': 403, 'NotFound': 404, 'PermissionError': 403, 'TypeError': 400, 'ValueError': 400}
__init__(content=None, status_code=200, headers=None, media_type=None, request=None)[source]

Initialize response.

Parameters:
  • content (bytes | str | None) – Response body (bytes, string, or None).

  • status_code (int) – HTTP status code (default 200).

  • headers (Mapping[str, str] | list[tuple[str, str]] | None) – Response headers as dict or list of tuples.

  • media_type (str | None) – Content-Type media type (overrides class default).

Note

HTTP status codes 204 (No Content) and 304 (Not Modified) must not have body content per RFC 7230. If you provide content with these status codes, the ASGI server may reject or truncate the response.

body
charset: str = 'utf-8'
media_type: str | None = None
request
set_error(error)[source]

Set response as error from exception.

Maps exception type to HTTP status code using ERROR_MAP. Unknown exceptions default to 500 and are logged.

Parameters:

error (Exception) – The exception to convert to error response.

Return type:

None

set_header(name, value)[source]

Set a response header. Can be called before set_result.

Return type:

None

set_result(result, metadata=None)[source]

Set response body from result.

Uses _guess_mime_type() to determine content type. Falls back to type-based defaults: - dict/list: application/json (or TYTX if request.tytx_mode) - Path: from extension - bytes: application/octet-stream - str: text/plain - None: text/plain (empty body) - other: text/plain (str conversion)

Parameters:
  • result (Any) – The handler result to set as response body.

  • metadata (dict[str, Any] | None) – Route metadata dict. Uses mime_type if present.

Return type:

None

status_code

Create a Set-Cookie header tuple.

This is a helper function for creating cookie headers without modifying the immutable Response object. The returned tuple can be passed directly to Response headers.

Note

Design Decision - Module-level function vs method

This is a module-level function (not a Response method) to preserve Response immutability. Response objects are “frozen” after construction - all headers must be provided at creation time. A response.set_cookie() method would violate this principle by modifying headers after construction.

Using make_cookie() the user creates cookie tuples BEFORE constructing the Response, keeping the Response immutable and predictable.

Parameters:
  • key (str) – Cookie name.

  • value (str) – Cookie value (will be URL-encoded).

  • max_age (int | None) – Max age in seconds. None means session cookie.

  • path (str) – Cookie path (default “/”).

  • domain (str | None) – Cookie domain. None means current domain only.

  • secure (bool) – If True, cookie only sent over HTTPS.

  • httponly (bool) – If True, cookie not accessible via JavaScript.

  • samesite (str | None) – SameSite policy (“strict”, “lax”, “none”, or None to omit).

Return type:

tuple[str, str]

Returns:

Tuple of (“set-cookie”, cookie_string) for use in Response headers.

Example

>>> from genro_asgi import Response, make_cookie
>>> response = Response(
...     content="OK",
...     headers=[
...         make_cookie("session", "abc123", httponly=True, secure=True),
...         make_cookie("prefs", "dark", max_age=31536000),
...     ]
... )