Headers
This section covers how to extract and validate headers using Rapidy.
You can validate the data using any type supported by pydantic.
Description
HTTP headers allow the client and server to exchange additional information in HTTP requests and responses.
Extracting a Single Header
Header allows you to retrieve a specific header.
from rapidy.http import get, Header
@get('/')
async def handler(
host: str = Header(alias='Host'),
) -> ...:
from rapidy.http import get, Header
@get('/')
async def handler(
host: str = Header(alias='Host'),
keep_alive: str = Header(alias='Keep-Alive'),
) -> ...:
Extracting All Headers
Headers allows you to extract all headers at once.
Extracting into a Predefined Schema
pydantic.BaseModel
from pydantic import BaseModel, Field
from rapidy.http import get, Headers
class HeadersData(BaseModel):
host: str = Field(alias='Host')
keep_alive: str = Field(alias='Keep-Alive')
@get('/')
async def handler(
headers_data: HeadersData = Headers(),
) -> ...:
dataclasses.dataclass
dataclasses.dataclass is supported as a model type, but you cannot set an alias using standard dataclasses tools.
from dataclasses import dataclass
from rapidy.http import get, Headers
@dataclass
class HeadersData:
host: str
keep_alive: str # cannot extract if header name is 'Keep-Alive'
@get('/')
async def handler(
headers_data: HeadersData = Headers(),
) -> ...:
# {"errors": [{"type": "missing", "loc": ["header", "keep_alive" ], "msg": "Field required"}]}
Extracting into a Dictionary
from rapidy.http import get, Headers
@get('/')
async def handler(
headers_data: dict[str, str] = Headers(),
) -> ...:
# {Host': '0.0.0.0:8080', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': '...'}
Extracting Without Validation
Disabling validation is not recommended.
If validation is disabled, the parameter will return the basic aiohttp structure:
Header→strHeaders→CIMultiDictProxy[str]
Ways to Disable Validation
Explicit Disabling
from multidict import CIMultiDictProxy
from rapidy.http import get, Header, Headers
@get('/')
async def handler_1(
header_host: str = Header(alias='Host', validate=False)
) -> ...:
# "0.0.0.0:8080"
@get('/')
async def handler_2(
headers_data: CIMultiDictProxy[str] = Headers(validate=False)
) -> ...:
# <CIMultiDictProxy('Host': '0.0.0.0:8080', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': '...')>
Using Any
from typing import Any
@get('/')
async def handler_1(
header_host: Any = Header(alias='Host')
) -> ...:
# "0.0.0.0:8080"
@get('/')
async def handler_2(
headers_data: Any = Headers()
) -> ...:
# <CIMultiDictProxy('Host': '0.0.0.0:8080', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': '...')>
No Type Annotation
If the type is not specified, it defaults to Any.
from typing import Any
@get('/')
async def handler_1(
header_host=Header(alias='Host')
) -> ...:
# "0.0.0.0:8080"
@get('/')
async def handler_2(
headers_data=Headers()
) -> ...:
# <CIMultiDictProxy('Host': '0.0.0.0:8080', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': '...')>
Default Values
The default value for Header is used if the request does not contain a header with the specified name.
The default value for Headers is used if the request contains no headers at all.
A default value for Headers is practically never used.
Any HTTP client will always send basic headers, making this case nearly impossible. However, if it ever happens, it will work as expected.
Using default
@get('/')
async def handler(
some_header: str = Header(alias='Some-Header', default='SomeValue'),
) -> ...:
from typing import Annotated
@get('/')
async def handler(
some_header: Annotated[str, Header(alias='Some-Header', default='SomeValue')],
) -> ...:
from typing import Annotated
@get('/')
async def handler(
some_header: Annotated[str, Header(alias='Some-Header')] = 'SomeValue',
) -> ...:
Using default_factory
@get('/')
async def handler(
some_header: str = Header(alias='Some-Header', default_factory=lambda: 'SomeValue'),
) -> ...:
from typing import Annotated
@get('/')
async def handler(
some_header: Annotated[str, Header(alias='Some-Header', default_factory=lambda:'SomeValue')],
) -> ...:
You cannot use default and default_factory at the same time.
Attempting to specify both will raise a pydantic exception:
Warnings and Considerations
Using Header and Headers together
You cannot use Header and Headers in the same handler.
@get('/')
async def handler(
host: str = Header(alias='Host'),
headers_data: HeadersData = Headers(),
) -> ...:
When the application starts, an AnotherDataExtractionTypeAlreadyExistsError exception will be raised.
------------------------------
Attribute with this data extraction type cannot be added to the handler - another data extraction type is already use in handler.
Handler path: `main.py`
Handler name: `handler`
Attribute name: `headers_data`
------------------------------
The alias Attribute in Headers
The alias attribute does not work in the Headers() parameter.
@get('/')
async def handler(
headers_data: HeadersData = Headers(alias='SomeName'), # <-- alias not working
) -> ...:
How Raw Data is Extracted
Rapidy uses the headers method of the Request object and then passes the retrieved data to a pydantic model for validation.
How data extraction works in Rapidy
Rapidy uses built-in aiohttp mechanisms.
For more details on the aiohttp.Request object and data extraction methods, see
here.