Skip to content

Handler Response

This section explains how to manage an HTTP response in Rapidy when returning a Python object from an HTTP handler.

Attributes

Handler response attributes are used to control how a response is generated when returning any Python object from a handler.

Rapidy supports attribute management in all types of handlers, including those written in the aiohttp style.

# aiohttp style
from rapidy import web

async def handler() -> dict[str, str]:
    return {'hello': 'rapidy'}

app = web.Application()
app.add_routes([
    web.post(
        '/',
        handler,
        status_code=200,
        response_content_type='application/json',
    ),
])

path

path: str | None = None — the path to the handler on the web server.

from rapidy.http import get

@get(
    '/',
)
async def handler() -> ...:
    ...

allow_head

allow_head: bool = True — a flag indicating whether to add the head method to an existing get handler.

from rapidy.http import get

@get(
    '/',
    allow_head=True,
)
async def handler() -> ...:
    ...

status_code

status_code: int | HTTPStatus = 200 — the default status code used for the response.

from http import HTTPStatus
from rapidy.http import get

@get(
    '/',
    status_code=201,
)
async def handler() -> ...:
    ...

@get(
    '/',
    status_code=HTTPStatus.CREATED,
)
async def handler() -> ...:
    ...

response_validate

response_validate: bool = True — a flag indicating whether the handler response should be validated.

from rapidy.http import get

@get(
    '/',
    response_validate=False,
)
async def handler() -> str:  # <-- `str` will be ignored
    return {'hello': 'rapidy'}

response_type

response_type: Type[Any] | None = ... — defines the response type of the handler. (If specified, this attribute will be used to create a Pydantic response model instead of the handler's return annotation.)

from rapidy.http import get

@get(
    '/',
    # `dict[str, str]` will be used for validate and serialize body response data
    response_type=dict[str, str],
)
async def handler() -> str:  # <-- `str` will be ignored
    return {'hello': 'rapidy'}

This flag adds flexibility to response body serialization and validation, but in most cases, you won't need to modify it.


response_content_type

response_content_type: str = 'application/json' — defines the Content-Type header and manages response post-processing.

response_content_type="application/json"

When set to "application/json", data is converted to JSON using jsonify(dumps=True) and encoded according to the charset.

from rapidy.http import get, ContentType

@get(
    '/',
    response_content_type=ContentType.json,
)
async def handler() -> dict[str, str]:
    return {'hello': 'rapidy!'}  # {"hello": "rapidy!"}

If the provided object is a string (Response(body="string")), then according to the JSON standard, the string will be double-escaped:

from rapidy.http import get, ContentType

@get(
    '/',
    response_content_type=ContentType.json,
)
async def handler() -> str:
    return 'hello rapidy!'  # "'hello rapidy!'"

content_type="text/*"

When set to "text/*" (e.g., text/plain, text/html, etc.):

  • If the data is of type str, it is sent as is.
  • Otherwise, it is converted to a string using jsonify(dumps=False).
from rapidy.http import get, ContentType

@get(
    '/',
    response_content_type=ContentType.text_any,
)
async def handler() -> str:
    return 'hello rapidy!'  # "hello rapidy!"

If the object is not a string after jsonify(dumps=False), it is additionally encoded using json_encoder to avoid double escaping.

content_type="*"

For any other types (*):

  • If the data is of type bytes, it is sent as is.
  • Otherwise, it is converted to a string using jsonify(dumps=True) and encoded according to the charset.

If content_type is not specified, it is set automatically based on the return type annotation:

  • body: dict | BaseModel | dataclasscontent_type="application/json"
  • body: str | Enum | int | float | Decimal | boolcontent_type="text/plain"
  • body: Anycontent_type="application/octet-stream"

response_charset

response_charset: str = 'utf-8' — the character set used for encoding and decoding data.

from rapidy.http import get, Charset

@get(
    '/',
    response_charset=Charset.utf32,
)
async def handler() -> ...:
    ...

response_zlib_executor

response_zlib_executor: Callable | None = None — a function used for response compression with zlib.

More about zlib_executor

zlib_executor is a feature of aiohttp. Learn more here.


response_zlib_executor_size

response_zlib_executor_size: int | None = None — the response body size (in bytes) at which zlib compression is applied.


response_include_fields

response_include_fields: set[str] | dict[str, Any] | None = None — the Pydantic include parameter, specifying which fields to include in the response.

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')
    another_value: str = Field('another_data', alias='someAnotherValue')

@get(
    '/',
    response_include_fields={'value'},
)
async def handler() -> Result:
    return Result()  # {'someValue': 'data'}

response_exclude_fields

response_exclude_fields: set[str] | dict[str, Any] | None = None — the Pydantic exclude parameter, specifying which fields to exclude from the response.

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')
    another_value: str = Field('another_data', alias='someAnotherValue')

@get(
    '/',
    response_exclude_fields={'value'},
)
async def handler() -> Result:
    return Result()  # {'someAnotherValue': 'another_data'}

response_by_alias

response_by_alias: bool = True — the Pydantic by_alias parameter, determining whether to use field aliases instead of their original names.

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')

@get(
    '/',
    response_by_alias=True,  # <-- default
)
async def handler() -> Result:
    return Result()  # {"someValue": "data"}
...
@get(
    '/',
    response_by_alias=False,
)
async def handler() -> Result:
    return Result()  # {"value": "data"}


response_exclude_unset

response_exclude_unset: bool = False — the Pydantic exclude_unset parameter, excluding fields from the response that were not explicitly set (and only have default values).

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')
    another_value: str = Field('another_data', alias='someAnotherValue')

@get(
    '/',
    response_exclude_unset=False,  # <-- default
)
async def handler() -> Result:
    return Result(someAnotherValue='new_data')  # {"someValue": "data", "someAnotherValue": "new_data"}
...
@get(
    '/',
    response_exclude_unset=True,
)
async def handler() -> Result:
    return Result(someAnotherValue='new_data')  # {"someAnotherValue": "new_data"}


response_exclude_defaults

response_exclude_defaults: bool = False — the Pydantic exclude_defaults parameter, excluding fields from the response if their values match the default values, even if explicitly set.

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')

@get(
    '/',
    response_exclude_defaults=False,  # <-- default
)
async def handler() -> Result:
    return Result()  # {"value": "data"}
...
@get(
    '/',
    response_exclude_defaults=True,
)
async def handler() -> Result:
    return Result()  # {}


response_exclude_none

response_exclude_none: bool = False — the Pydantic exclude_none parameter, excluding fields from the response if they have a value of None.

from pydantic import BaseModel, Field
from rapidy.http import get

class Result(BaseModel):
    value: str = Field('data', alias='someValue')
    none_value: None = None

@get(
    '/',
    response_exclude_none=False,  # <-- default
)
async def handler() -> Result:
    return Result()  # {"someValue": "data", "none_value": null}
...
@get(
    '/',
    response_exclude_none=True,
)
async def handler() -> Result:
    return Result()  # {"someValue": "data"}


response_custom_encoder

response_custom_encoder: Callable | None = None — the Pydantic custom_encoder parameter, specifying a custom data encoder.


response_json_encoder

response_json_encoder: Callable = json.dumps — a callable that takes an object and returns its JSON string representation. Used when json_response(dumps=True, ...) is applied.

from typing import Any
from rapidy.http import get

def custom_encoder(obj: Any) -> str:
    ...

@get(
    '/',
    response_json_encoder=custom_encoder,
)
async def handler() -> dict[str, str]:
    return {'hello': 'rapidy!'}  # will be converted to a string by Rapidy's internal tools