Перейти к содержанию

Text

Чтение тела запроса в качестве строки.

Описание

Text (MIME-type: text/*) — это тип данных, представляющий собой строку.

Rapidy работает с любым текстом, независимо от его subtype.

Например: text/plain, text/html, text/css, text/xml, ..., text/*.

Определение кодировки

Для декодирования текста используется параметр charset заголовка Content-Type. Если charset не указан клиентом, текст будет декодирован в кодировке utf-8.

from rapidy.http import post, Body, ContentType

@post('/')
async def handler(
    text_data: str = Body(content_type=ContentType.text_plain),
    # or
    text_data: str = Body(content_type=ContentType.text_html),
    # or any mime-type with type `text`
    text_data: str = Body(content_type=ContentType.text_any),
) -> ...:
Отправка с помощью curl
curl -X POST \
-H "Content-Type: text/plain" \
-d 'SomeString' \
http://127.0.0.1:8080

Извлечение без валидации

Отключение валидации не рекомендуется.

Если валидация отключена, параметр будет содержать базовую структуру aiohttp:

  • Body(content_type=ContentType.text_plain)str

Способы отключения валидации

Явное отключение

from enum import Enum
from rapidy.http import post, Body, ContentType

class DataEnum(Enum):
    test = 'test'

@post('/')
async def handler(
    data: DataEnum = Body(validate=False, content_type=ContentType.text_plain),
) -> ...:

Использование Any

@post('/')
async def handler(
    data: Any = Body(content_type=ContentType.text_plain),
) -> ...:

Отсутствие аннотации типа

@post('/')
async def handler(
    data = Body(content_type=ContentType.text_plain),
) -> ...:

Значения по умолчанию

Если HTTP-запрос не содержит тела, параметр получит указанное значение по умолчанию (если оно задано).

Примеры использования

Указано значение по умолчанию

from enum import Enum
from rapidy.http import post, Body, ContentType

class DataEnum(Enum):
    test = 'test'

@post('/')
async def handler(
    data: DataEnum = Body('some_data', content_type=ContentType.text_plain),
    # or
    data: DataEnum = Body(default_factory=lambda: 'some_data', content_type=ContentType.text_plain),
) -> ...:

Опциональное тело запроса

from enum import Enum
from rapidy.http import post, Body, ContentType

class DataEnum(Enum):
    test = 'test'

@post('/')
async def handler(
    data: DataEnum | None = Body(content_type=ContentType.text_plain),
    # or
    data: Optional[DataEnum] = Body(content_type=ContentType.text_plain),
    # or
    data: Union[DataEnum, None] = Body(content_type=ContentType.text_plain),
) -> ...:

Извлечение сырых данных

Rapidy использует метод text объекта Request для получения данных и передает их в Pydantic для валидации.

Как происходит извлечение внутри Rapidy
async def extract_body_text(request: Request) -> Optional[str]:
    if not request.body_exists:
        return None

    return await request.text()

Rapidy использует встроенные механизмы aiohttp

Подробнее об объекте aiohttp.Request и методах извлечения данных можно узнать здесь.

Однако если параметр аннотирован как bytes или StreamReader, данные извлекаются иначе.

Подробнее об объекте StreamReader можно узнать здесь.

bytes

@post('/')
async def handler(
    user_data: bytes = Body(content_type=ContentType.text_plain),
    # also you can use pydantic validation
    user_data: bytes = Body(content_type=ContentType.text_plain, min_length=1),
) -> ...:
Внутренний код Rapidy
async def extract_body_bytes(request: Request) -> Optional[bytes]:
    if not request.body_exists:
        return None

    return await request.read()

StreamReader

from rapidy import StreamReader

@post('/')
async def handler(
    user_data: StreamReader = Body(content_type=ContentType.text_plain),
) -> ...:
Внутренний код Rapidy
async def extract_body_stream(request: Request) -> Optional[StreamReader]:
    if not request.body_exists:
        return None

    return request.content

Валидация Pydantic для StreamReader не поддерживается.

Значение по умолчанию для StreamReader задать нельзя.

Если попытаться установить значение по умолчанию для Body с аннотацией StreamReader через default или default_factory, будет вызвана ошибка ParameterCannotUseDefaultError.

from rapidy import StreamReader

@post('/')
async def handler(
    user_data: StreamReader = Body(default='SomeDefault', content_type=ContentType.text_plain),
) -> ...:
------------------------------
Handler attribute with Type `Body` cannot have a default value.

Handler path: `<full_path>/main.py`
Handler name: `handler`
Attribute name: `data`
------------------------------