Module

http.forms

Form data parsing and binding — URL-encoded and multipart.

ImplementsMultiValueMappingfor consistent access across Headers, QueryParams, and FormData.

form_from()provides lightweight dataclass binding: define a frozen dataclass, pass it toform_from(request, MyForm), and get a populated instance. No magic validation — just binding with type coercion forstr, int, float, and bool.

python-multipart is an optional dependency (pip install chirp[forms]). URL-encoded forms use stdliburllib.parse— no extra dependency.

Classes

UploadFile 7
An uploaded file from a multipart form submission. Immutable metadata with lazy content access. Th…

An uploaded file from a multipart form submission.

Immutable metadata with lazy content access. The file content is held in memory as bytes (suitable for typical web uploads).

For large file handling, read the raw body viarequest.stream().

Attributes

Name Type Description
filename str
content_type str
size int
_content bytes

Methods

read 0 bytes
Return the file content as bytes.
async
async def read(self) -> bytes
Returns
bytes
save 1
Write the file content to disk.
async
async def save(self, path: Path) -> None
Parameters
Name Type Description
path

Destination file path. Parent directories must exist.

Internal Methods 1
__repr__ 0 str
def __repr__(self) -> str
Returns
str
FormData 9
Immutable parsed form data. Implements ``Mapping[str, str]`` and the ``MultiValueMapping`` protoco…

Immutable parsed form data.

ImplementsMapping[str, str] and the MultiValueMappingprotocol. Holds both string field values and uploaded files.

__getitem__returns the first value for a key (string fields only). get_listreturns all values for a key. filesprovides access to uploaded files by field name.

Usage::

form = await request.form()
username = form["username"]
avatar = form.files.get("avatar")  # UploadFile or None

Methods

files 0 Mapping[str, UploadFile]
Uploaded files by field name.
property
def files(self) -> Mapping[str, UploadFile]
Returns
Mapping[str, UploadFile]
get 2 str | None
Return the first value for *key*, or *default* if missing.
def get(self, key: str, default: str | None = None) -> str | None
Parameters
Name Type Description
key
default Default:None
Returns
str | None
get_list 1 list[str]
Return all values for *key* (checkboxes, multi-selects).
def get_list(self, key: str) -> list[str]
Parameters
Name Type Description
key
Returns
list[str]
Internal Methods 6
__init__ 2
def __init__(self, data: dict[str, list[str]], files: dict[str, UploadFile] | None = None) -> None
Parameters
Name Type Description
data
files Default:None
__getitem__ 1 str
def __getitem__(self, key: str) -> str
Parameters
Name Type Description
key
Returns
str
__contains__ 1 bool
def __contains__(self, key: object) -> bool
Parameters
Name Type Description
key
Returns
bool
__iter__ 0 Iterator[str]
def __iter__(self) -> Iterator[str]
Returns
Iterator[str]
__len__ 0 int
def __len__(self) -> int
Returns
int
__repr__ 0 str
def __repr__(self) -> str
Returns
str
FormBindingError 2
Raised when form data cannot be bound to a dataclass.

Raised when form data cannot be bound to a dataclass.

Attributes

Name Type Description
errors

Dict mapping field names to lists of error messages.

Methods

Internal Methods 1
__init__ 1
def __init__(self, errors: dict[str, list[str]]) -> None
Parameters
Name Type Description
errors

Functions

form_from 2 T
Bind form data from a request to a dataclass instance. Reads ``request.form()`…
async
async def form_from(request: Any, datacls: type[T]) -> T

Bind form data from a request to a dataclass instance.

Readsrequest.form()and populates the given dataclass. Fields with defaults are optional; fields without defaults are required. String fields are stripped of whitespace by default.

Supportsstr, int, float, and booltype coercion. RaisesFormBindingErrorwith a dict of errors for missing or invalid fields.

Usage::

@dataclass(frozen=True, slots=True)
class TaskForm:
    title: str
    description: str = ""
    priority: str = "medium"

@app.route("/tasks", methods=["POST"])
async def add_task(request: Request):
    form = await form_from(request, TaskForm)
    # form.title, form.description, form.priority are populated
Parameters
Name Type Description
request Any

A Chirp Request object (anything with an async.form()method).

datacls type[T]

A dataclass class to bind form data into.

Returns
T
form_or_errors 6 T | ValidationError
Bind form data or return a ValidationError for re-rendering. Combines ``form_f…
async
async def form_or_errors(request: Any, datacls: type[T], template_name: str, block_name: str, /, *, retarget: str | None = None, **extra_context: Any) -> T | ValidationError

Bind form data or return a ValidationError for re-rendering.

Combinesform_from() and ValidationErrorinto a single call. On success, returns the populated dataclass. On binding failure, returns aValidationErrorwith the errors and the raw form values for re-population.

Usage::

result = await form_or_errors(request, TaskForm, "tasks.html", "form")
if isinstance(result, ValidationError):
    return result
# result is TaskForm — proceed with validated data
Parameters
Name Type Description
request Any

A Chirp Request object (anything with an async.form()method).

datacls type[T]

A dataclass class to bind form data into.

template_name str

Template name for the error response.

block_name str

Block name for the error response.

retarget str | None

OptionalHX-Retarget header value. **extra_context: Additional template context passed to ValidationError.

Default:None
**extra_context Any
Returns
T | ValidationError
form_values 1 dict[str, str]
Extract form field values as strings for template re-population. Accepts a dat…
def form_values(form: Any) -> dict[str, str]

Extract form field values as strings for template re-population.

Accepts a dataclass instance or aMapping. Returns a flat dict[str, str] suitable for passing as form=...context toValidationError.

Parameters
Name Type Description
form Any

A dataclass instance or aMapping.

Returns
dict[str, str]
_unwrap_optional 1 type
Extract the base type from ``X | None`` or plain ``X``.
def _unwrap_optional(hint: Any) -> type
Parameters
Name Type Description
hint Any
Returns
type
parse_form_data 2 FormData
Parse form body into FormData. **Supports:** - ``application/x-www-form-urlenc…
async
async def parse_form_data(body: bytes, content_type: str) -> FormData

Parse form body into FormData.

Supports:

  • application/x-www-form-urlencoded(stdlib, no extra dependency)
  • multipart/form-data (requires python-multipart)
Parameters
Name Type Description
body bytes

Raw request body bytes.

content_type str

The Content-Type header value.

Returns
FormData
_parse_urlencoded 1 FormData
Parse URL-encoded form data using stdlib.
def _parse_urlencoded(body: bytes) -> FormData
Parameters
Name Type Description
body bytes
Returns
FormData
_parse_multipart 2 FormData
Parse multipart form data using python-multipart. Raises ``ConfigurationError`…
async
async def _parse_multipart(body: bytes, content_type: str) -> FormData

Parse multipart form data using python-multipart.

RaisesConfigurationError if python-multipartis not installed.

Parameters
Name Type Description
body bytes
content_type str
Returns
FormData