Skip to content

Requests

The request object and the parsed containers it exposes.

Request

Incoming HTTP request with lazy attribute parsing.

All expensive operations (JSON parsing, cookie parsing, URL construction, form/multipart parsing) are deferred until accessed — zero overhead for properties you don't use.

Usage::

@app.get("/users/{user_id}")
async def show(request: Request, user_id: str):
    data = await request.json()
    agent = request.headers.get("user-agent", "")
    return {"id": user_id, "agent": agent, "body": data}

query_params property

query_params: QueryParams

Parse query string lazily - only when accessed.

Repeated keys are preserved: params.getlist("tag") returns every value; params["tag"] returns the first.

args property

Alias for query_params — the parsed URL query string.

path_params property writable

path_params: dict[str, str]

Path parameters captured by the matched route pattern.

view_args property

view_args: dict[str, Any]

Alias for path_params — the matched route's path params.

request.view_args and request.path_params are two names for the dict of URL-captured values; both point at the same dict.

headers property writable

headers: Headers

Return the parsed request headers, materializing from raw ASGI tuples on first access.

user_agent property

user_agent: str

Return the User-Agent header value.

referrer property

referrer: str

Value of the Referer request header.

Spelling preserved from the original RFC misprint (RFC 7231 Sec. 5.5.2 documents Referer, not Referrer). The accessor uses the corrected spelling so callers don't have to remember.

origin property

origin: str | None

The Origin header - RFC 6454. None when absent.

Set by browsers on cross-origin requests (and all CORS preflights). CORS middleware matches the allow-list against it.

date property

date: datetime | None

The request Date header as a tz-aware UTC datetime.

RFC 9110 Sec. 6.6.1 - the originator's timestamp for the message. Returns None when the header is missing or unparseable.

pragma property

pragma: str

Value of the legacy Pragma header - RFC 9111 Sec. 5.4.

Almost always no-cache from HTTP/1.0 clients. Returns the empty string when absent. Prefer cache_control for HTTP/1.1.

max_forwards property

max_forwards: int | None

The Max-Forwards header as an int - RFC 9110 Sec. 7.6.2.

Bounds how many proxies a TRACE/OPTIONS request may traverse. None when absent or non-numeric.

is_xhr property

is_xhr: bool

Detect XMLHttpRequest-style AJAX calls.

The convention is X-Requested-With: XMLHttpRequest, set by jQuery, fetch wrappers, and similar libraries. It's a hint, not a guarantee (the client controls the header), but it's the traditional signal application code uses to switch between full HTML responses and partial / JSON ones.

content_type property

content_type: str

Return the Content-Type header value, or an empty string.

mimetype property

mimetype: str

Content-Type without parameters.

application/json; charset=utf-8 -> application/json. Lower-cased and stripped - per RFC 9110 Sec. 8.3 the media type is case-insensitive.

mimetype_params property

mimetype_params: dict[str, str]

Parameters from Content-Type (e.g. {"charset": "utf-8"}).

Each parameter is key=value; quoted values have their surrounding double-quotes stripped. Keys are lower-cased; values preserve case.

content_length property

content_length: int | None

Return the Content-Length as an integer, or None.

content_encoding property

content_encoding: str

Value of the Content-Encoding header.

Returns the lowercased encoding name ("gzip", "br", etc.) or the empty string when the header is missing.

content_language property

content_language: str

Value of the Content-Language header - RFC 9110 Sec. 8.5.

Returns the raw header value (a comma-separated list of language tags) or the empty string when the header is absent.

charset property

charset: str

Request body charset, decoded from Content-Type.

Defaults to utf-8 when no charset is declared (the modern default; the also moved off ISO-8859-1).

is_json property

is_json: bool

True for application/json or any application/*+json subtype.

Per RFC 6839 Sec. 3.1 the structured-suffix +json (e.g. application/vnd.api+json, application/problem+json) marks the body as JSON-encoded.

is_multipart property

is_multipart: bool

True when the request body is multipart/*.

is_form property

is_form: bool

True when the body is application/x-www-form-urlencoded or multipart/form-data.

accept property

accept: str

Return the raw Accept header value.

accept_mimetypes property

accept_mimetypes: AcceptHeader

Parsed Accept header with MIME wildcard matching.

accept_languages property

accept_languages: AcceptHeader

Parsed Accept-Language header. q-value ordered.

accept_encodings property

accept_encodings: AcceptHeader

Parsed Accept-Encoding header (e.g. gzip, br).

accept_charsets property

accept_charsets: AcceptHeader

Parsed Accept-Charset header.

authorization property

authorization: str | None

Return the parsed Authorization header.

auth property

auth: Authorization | None

Lazy-parse the Authorization: header into a typed object.

Returns None when the header is missing. Basic and Bearer schemes populate .username/.password and .token respectively; other schemes carry their key=value parameters in .params.

access_control_request_method property

access_control_request_method: str | None

CORS preflight Access-Control-Request-Method - RFC 6454.

On an OPTIONS preflight, names the method the real request will use. None outside a preflight.

access_control_request_headers property

access_control_request_headers: list[str]

CORS preflight Access-Control-Request-Headers - header list.

The headers the real request intends to send, lower-cased and whitespace-trimmed. Empty list when the header is absent.

if_modified_since property

if_modified_since: float | None

Parse If-Modified-Since (RFC 9110 Sec. 13.1.3) to a Unix timestamp.

Accepts IMF-fixdate, obsolete RFC 850, and ANSI C asctime() forms. Returns None when the header is missing or unparseable - never raises, so callers can use it in a single branch.

if_unmodified_since property

if_unmodified_since: float | None

Parse If-Unmodified-Since (RFC 9110 Sec. 13.1.4) to a Unix timestamp.

Returns None when the header is missing or unparseable. Write-side companion to If-Modified-Since: precondition that fails with 412 when the resource has been modified since the given date.

if_match property

if_match: tuple[str, ...]

Parse If-Match (RFC 9110 Sec. 13.1.1) into a tuple of ETags.

Returns ("*",) for the wildcard, an empty tuple when the header is absent, otherwise a tuple of quoted ETags (quotes and any W/ weak prefix preserved verbatim).

If-Match is the write-side companion to If-None-Match: precondition that fails the request with 412 Precondition Failed when none of the listed ETags matches the resource's current ETag. Standard guard against the lost-update problem.

if_none_match property

if_none_match: tuple[str, ...]

Parse If-None-Match (RFC 9110 Sec. 13.1.4) into a tuple of ETags.

Returns ("*",) when the header is the literal * (matches any existing representation), an empty tuple when the header is missing, or a tuple of one or more quoted ETags (the quotes are preserved so callers can compare them verbatim against an ETag header on the response).

if_range property

if_range: tuple[str, float | None]

Parse If-Range: (RFC 9110 Sec. 13.1.5).

The header carries either an ETag or an HTTP-date - never both. Returns (etag, None) when the value is an ETag (quoted, possibly weak-prefixed) and ("", timestamp) when it parses as a date. Returns ("", None) when the header is absent or unparseable. Caller picks the relevant slot.

Used by GET with Range: to convert a partial-content request into a full 200 when the cached resource is stale.

range property

range: RangeSpec | None

Parse Range: header per RFC 9110 Sec. 14.2. Returns None when absent or unparseable.

cache_control property

cache_control: Any

Parsed Cache-Control header.

Returns a CacheControl view: req.cache_control.no_cache (bool), req.cache_control.max_age (int or None), etc. Always returns a fresh parse to reflect any header mutation.

cookies property

cookies: Cookies

Parse cookies from the Cookie header - lazy, MultiDict-shaped.

Returns a Cookies (MultiDict). cookies["name"] gives the first value; cookies.getlist("name") gives every value when a name repeats (rare but valid per RFC 6265).

url property

url: Any

Full URL object - lazy construction.

base_url property

base_url: str

Base URL (scheme + host).

full_path property

full_path: str

Path + ? + query string. Always contains a ? even when the query string is empty.

url_root property

url_root: str

Root URL of the request: scheme://host/ (with trailing slash, no path or query string).

host_url property

host_url: str

Alias for url_root - Veloce exposes both names.

is_secure property

is_secure: bool

Return True if the request uses HTTPS.

scheme property

scheme: str

Request scheme - "http" or "https".

Sourced from the ASGI scope["scheme"] when present, then from the X-Forwarded-Proto header (only meaningful behind a trusted proxy), then default http.

host property

host: str

Value of the Host request header.

Mirrors Request.url.netloc for the common case but pulls directly from the header to remain cheap (no full URL parse). Returns the empty string when the header is absent.

root_path property

root_path: str

ASGI scope["root_path"] - the URL prefix the app is mounted under.

Comes from the ASGI server (e.g. uvicorn --root-path /api) or from app.mount("/sub", inner_app). Used so an app behind a prefix can generate correct external URLs without knowing the prefix at code-time.

Returns the empty string when the app is at root.

script_root property

script_root: str

Alias for root_path — also called script_root.

ProxyFix-style middleware may also set _state["proxy_fix_prefix"]; that wins over the ASGI scope because it represents the trusted outer-edge prefix when the ASGI server is behind a reverse proxy that strips the prefix.

subdomain property

subdomain: str

Leftmost host label minus app.config["SERVER_NAME"].

Returns the empty string when the request host equals SERVER_NAME exactly (apex), or when SERVER_NAME isn't configured and the host has no dots. With SERVER_NAME set, the returned value is the prefix that wouldn't match the configured apex; without it, the leftmost label.

environ property

environ: dict[str, Any]

Alias for the ASGI scope dict.

Third-party code paths reach for request.environ (WSGI); ASGI scope is the analogue. Returns the live dict so middleware can introspect (mutation goes through framework APIs, not this).

url_rule property

url_rule: str | None

Return the matched route's template (e.g. /users/{id}).

Returns the raw path template the radix tree used for the match — i.e. path_params placeholders are unsubstituted. None for synthetic requests that never went through dispatch.

is_mcp property

is_mcp: bool

Return whether this request is a replayed MCP tool / resource call.

True when the request was synthesised by the MCP integration to replay a route through Depends / middleware for an agent call, rather than a real HTTP request. Authentication middleware that checks a browser credential (a session cookie, an Authorization header) should return early on these - the MCP transport authenticates the agent separately. The transport request itself (POST /mcp) opts such middleware out via mount_mcp(..., exclude_middleware=[...]).

blueprint property

blueprint: str | None

Return the name of the blueprint that owns the matched route.

Veloce stores the endpoint as <bp>.<name> for blueprint routes. Returns the bit before the dot, or None if the endpoint is unset or is a top-level (no-dot) name.

blueprints property

blueprints: list[str]

Return every blueprint in the matched endpoint's parent chain.

For an endpoint a.b.c.view, returns ["a.b.c", "a.b", "a"] (innermost first). Empty list when the route is top-level or the endpoint is unset.

client_host property

client_host: str | None

Return the client's IP address, or None when the peer is unknown.

client_port property

client_port: int | None

Return the client's port number, or None when the peer is unknown.

client property

client: Address | None

The connecting peer as an Address(host, port).

request.client.host / request.client.port work, and tuple unpacking (host, port = request.client) works too. Returns None when the peer is unknown (e.g. synthetic requests). Honours ProxyFix - client.host reflects the trusted client IP.

remote_addr property

remote_addr: str | None

Alias for client_host — the connecting client's IP.

Honours ProxyFix-style middleware: when the trusted hop has set _state["proxy_fix_client"], that value wins over the raw TCP peer (the ASGI/uvicorn client[0] may be the load balancer).

access_route property

access_route: list[str]

Forwarded-for chain.

Returns the comma-separated X-Forwarded-For values (client -> proxy chain order), with the connecting peer (remote_addr) appended at the end. With no X-Forwarded-For header, returns [remote_addr] when the peer is known, else [].

RFC 7239 Sec. 5.2 defines the IP-order convention: leftmost is the originating client, rightmost is the closest proxy. Production code should consume the leftmost trusted entry, not blindly the leftmost value.

state property

state: State

Per-request scratch namespace - ASGI shape.

Supports attribute access (request.state.user = ...) and dict access (request.state["user"], request.state.get(...)).

session property

session: dict[str, Any]

Access to the session dict.

SessionMiddleware writes the parsed session into _state["session"] during process_request. This property surfaces it under the a convenience accessor. Raises RuntimeError when the middleware hasn't run - keeps "I forgot to add SessionMiddleware" from showing up as a confusing silent empty-dict.

data property

data: bytes

Raw request body bytes - request.data shape.

The sync-property form of body(). Returns the body exactly as received, with no decoding or form parsing. Requires the body to already be buffered; raises RuntimeError otherwise (use await request.body() for the async path).

max_content_length property

max_content_length: int | None

The body-size cap for this request.

Reads app.config["MAX_CONTENT_LENGTH"] from the bound app (the dispatcher enforces it, returning 413 on overflow). None - no limit - when unset or no app is bound.

url_for

url_for(name: str, /, **path_params: Any) -> str

Reverse-resolve a route URL - ASGI shape.

request.url_for("route_name", id=7) delegates to the bound app's url_for. Raises RuntimeError when the request has no app bound (synthetic requests built outside dispatch).

With _external=True the absolute URL is built from this request's origin - the scheme, host and port a trusted ProxyFix recovered - and carries script_root, so a link generated behind a proxy that terminates TLS on another port and mounts the app under a prefix points at the public URL rather than the internal one. app.url_for has no request to read and falls back to SERVER_NAME. An explicit _scheme or _host still wins.

get_json

get_json(force: bool = False, silent: bool = False, cache: bool = True) -> Any

Parse the request body as JSON.

  • force=True skips the is_json content-type check; useful when the client sends JSON without setting Content-Type (e.g. some XHR libraries). Default is to honour the content type and return None for non-JSON requests.
  • silent=True swallows orjson.JSONDecodeError and returns None. Default raises so caller code can distinguish malformed JSON from missing JSON.
  • cache=False forces a re-parse on every call. Default caches the parsed value (one parse per request); cache invalidation is the caller's job when cache=False.

Returns None for empty bodies regardless of force / silent.

This is the synchronous accessor: it requires the body to already be buffered (the in-memory path), and raises RuntimeError otherwise - reach for await request.json() when the body has not yet been drained.

on_json_loading_failed

on_json_loading_failed(error: Exception) -> Any

Hook invoked when JSON parsing fails on a non-silent body.

Raises BadRequest (400) with a stable, body-independent message so a malformed body cannot leak decoder internals (byte offsets derived from attacker-controlled input) into the production response. The verbose decoder reason is always logged and attached as BadRequest.debug_detail for operators, and is surfaced in the response only when debug mode or the JSON_ERRORS_VERBOSE config flag is set. Override on a Request subclass to customise.

body async

body() -> bytes

Return the full request body as bytes, draining the source once.

Async to match the ASGI convention. Veloce buffers the body before dispatch, so no I/O happens inside the await - the coroutine resolves immediately with the cached bytes.

json async

json() -> Any

Parse the request body as JSON, async to match the ASGI convention.

Veloce buffers the body at construction time, so no I/O actually happens inside the await - the coroutine resolves immediately with the cached parse. The async signature exists so the await request.json() idiom does not blow up at runtime.

The synchronous request.get_json() accessor is available for callers that prefer a sync API.

get_data async

get_data(as_text: bool = False, cache: bool = True) -> bytes | str

Return the raw request body, draining the source once.

Async to match body() / json() / form().

  • as_text=True decodes via the Content-Type charset (default UTF-8). Falls back to latin-1 when the declared charset is unrecognised - a defensive fallback, since latin-1 round-trips arbitrary bytes without raising.
  • cache is accepted and ignored. A non-streaming route has its body buffered before the handler runs, so there is nothing to decide; a stream=True route is consumed through request.stream() rather than here. The parameter is kept so callers passing cache=False for cross-framework compatibility keep working.

Returns bytes (default) or str (with as_text=True).

form async

form() -> Any

Parse form data including file uploads.

files async

files() -> Any

View of uploaded files only - a FormData subset.

Parses the form (via form()) and returns a FormData containing just the entries whose value is an UploadFile. Non-file form fields are excluded. Empty FormData for non-multipart requests. Result is cached after first parse.

values async

values() -> Any

Merged query string + form body - request.values shape.

Returns a fresh MultiDict with query-string entries first, then form-body entries appended. Both source MultiDicts preserve repeated keys; merging preserves the order across both sources. Form parsing is async (multipart may need executor reads), so this is an awaitable rather than a property.

text async

text() -> str

Return body as text, draining the source once.

is_disconnected async

is_disconnected() -> bool

Whether the client has disconnected.

A non-streaming route has its body drained before the handler runs, so the body is already received and the answer is always False. On a stream=True route the client can genuinely go away mid-handler, and this reports it once the consumer has seen the disconnect - reading the flag the body source records rather than probing the transport.

stream async

stream() -> Any

Async-iterate the request body in chunks - ASGI shape.

Streamed requests (raw HTTP/1.1) yield each chunk as the socket delivers it, so async for chunk in request.stream(): ... processes a large body incrementally without ever buffering it whole. For in-memory requests (TestClient / ASGI), or once a streamed body has already been drained and cached, the buffered bytes are sliced into 64 KiB chunks instead.

URL

Parsed URL with component access - lazily constructed.

netloc property

netloc: str

Return the network location (host:port).

from_request classmethod

from_request(headers: Mapping[str, str], path: str, query_string: str, scope_scheme: str | None = None, forwarded_port: int | None = None, trust_forwarded_proto: bool = True) -> URL

Construct a URL from request headers and path components.

trust_forwarded_proto is False once ProxyFix has run: it writes the scheme it trusted into the scope, so reading the raw header afterwards would let a hop it deliberately refused set the scheme anyway - which is the trust depth being bypassed. With no ProxyFix installed the header remains a convenience default.

forwarded_port is the public port a trusted reverse proxy supplied (via ProxyFix reading X-Forwarded-Port / Forwarded host=...:port). A port embedded in the Host header always wins; forwarded_port only fills in the port when the Host header carries none, so a proxy on a non-default port (e.g. 8443) survives into netloc / absolute URLs.

replace

replace(**kwargs: Any) -> URL

Return a new URL with the specified components replaced.

Headers

Bases: _GetListMixin, CIMultiDict

Case-insensitive, multi-value header collection.

Backed by multidict.CIMultiDict. Existing single-value access via headers["X"] returns the first value (multidict semantics); use headers.getlist("X") to get all values. Construction from a plain dict, a list of tuples, or another multidict all work - the underlying constructor handles each shape.

getlist

getlist(key: str) -> list[str]

Return all values for the given key as a list. Empty list if absent.

to_wsgi_list

to_wsgi_list() -> list[tuple[str, str]]

Return headers as a list of (name, value) tuples.

Preserves insertion order and every duplicate. Useful for emitting to a WSGI/ASGI layer or for round-tripping.

copy

copy() -> Headers

Return a shallow copy - a fresh Headers with the same entries.

add

add(key: str, value: str, **params: str) -> None

Append a header, with optional key=value parameters.

headers.add("Content-Disposition", "attachment", filename="x.txt") emits attachment; filename="x.txt". Parameter values containing whitespace or punctuation are double-quoted. Underscores in parameter names map to hyphens.

QueryParams

Bases: _GetListMixin, MultiDict

Multi-value, case-sensitive query parameter collection.

Backed by multidict.MultiDict. Repeated query keys (?x=1&x=2) preserve every value; getlist("x") returns ["1", "2"] while params["x"] returns "1" (the first).

getlist

getlist(key: str) -> list[str]

Return all values for the given key as a list. Empty list if absent.

from_query_string classmethod

from_query_string(query_string: str) -> QueryParams

Parse a=1&b=2&a=3 into a multi-value mapping.

Keeps blank values (a=) and decodes percent-escapes. The ordering of repeated keys reflects the order in the URL.

Cookies

Bases: _GetListMixin, MultiDict

Cookie collection parsed from the Cookie header.

Built on multidict.MultiDict. Parsing delegates to iter_cookies (RFC 6265 section 5.4) so values are percent-decoded. Duplicate names collapse to the first occurrence per the spec.

getlist

getlist(key: str) -> list[str]

Return all values for the given key as a list. Empty list if absent.

from_cookie_header(header_value: str) -> Cookies

Parse a Cookie: header value into a Cookies mapping.

Delegates to iter_cookies for RFC 6265-compliant parsing (percent-decoding, quote-stripping). Duplicate names collapse to the first occurrence per RFC 6265 section 5.4.

State

Bases: dict

Per-request scratch namespace - supports both styles.

ASGI servers expose request.state for attribute-style storage (request.state.user = ...). Veloce's dispatcher also stashes framework internals (session, url_rule, ...) here by key. State is a dict subclass whose attribute access maps to items, so state.user and state["user"] / state.get("user") are interchangeable - neither call site needs to know the other.

Address

Bases: NamedTuple

Client/server address - ASGI shape.

A two-field named tuple so request.client.host / request.client.port work, while host, port = request.client unpacking also works (tuple semantics).

FormData

Bases: _GetListMixin, MultiDict

Multi-value form-field collection (text fields + file uploads).

Backed by multidict.MultiDict. Repeated form fields (<input name="a"> submitted twice, or repeated multipart parts with the same name) preserve every value; single-value access form["a"] returns the first. getlist("a") returns the full list.

getlist

getlist(key: str) -> list[str]

Return all values for the given key as a list. Empty list if absent.

get_upload

get_upload(key: str) -> UploadFile | None

Return the first value if it is an UploadFile, else None.

UploadFile

Uploaded file with an async read/write interface.

content property

content: bytes

Return the full file content as bytes.

Warning: this is a synchronous property. For large uploads that have been spooled to disk (i.e. _file_is_in_memory() returns False), the underlying read() call performs blocking I/O. Prefer await read() in async contexts for spooled files.

save

save(destination: str | BinaryIO, buffer_size: int = 16384) -> None

Stream this upload into destination.

  • destination is either a filesystem path (str) or an already-open binary file object. With a path, the file is opened in "wb" mode and closed afterwards; with a file object, the caller stays responsible for closing it.
  • buffer_size controls the chunk size used while streaming - keeps memory bounded for large uploads without loading them fully into RAM.

The upload's read cursor is reset to 0 before reading and restored to its prior position afterwards so the upload remains available for re-inspection.

This opens and writes on the calling thread. In an async handler use save_async, which is the same work hopped to a thread.

save_async async

save_async(destination: str | BinaryIO, buffer_size: int = 16384) -> None

Stream this upload into destination without blocking the event loop.

The async counterpart of save, with identical behaviour: handlers are async, so opening and writing on the calling thread would block the loop for the length of the upload.

read async

read(size: int = -1) -> bytes

Read up to size bytes from the upload.

write async

write(data: bytes) -> int

Write data to the upload's spool file.

seek async

seek(offset: int) -> None

Seek to a position in the upload's spool file.

close async

close() -> None

Close the upload's underlying spool file.

AcceptHeader

Parsed Accept-* header with RFC 9110 Sec. 12.5 q-value semantics.

Construction is via AcceptHeader.parse(raw, mime=False). mime=True enables MIME-style wildcard matching (text/*, */*) used by Accept; defaults to plain string equality used by Accept-Language, Accept-Encoding, Accept-Charset.

values property

values: list[str]

All accepted values in the order the client sent them.

parse classmethod

parse(raw: str, mime: bool = False) -> AcceptHeader

Parse a comma-separated header into (value, q) tuples.

Q-values missing or unparseable default to 1.0 (RFC 9110 Sec. 12.4.2). Entries with q=0 are kept - best_match treats them as explicit rejections of that option. For MIME headers, media-type parameters (e.g. application/json;profile="x") are retained and participate in matching (RFC 9110 Sec. 12.5.1); the q parameter separates the q-value from the media-type parameters.

quality

quality(value: str) -> float

Return the q-value the client assigned to value.

For MIME headers, matches */* and type/* wildcards as well as parameterized media ranges (e.g. application/json;profile=x); the MOST SPECIFIC matching client range wins (RFC 9110 Sec. 12.5.1), with ties broken by the higher q-value. Returns 0 when the value is rejected or not mentioned (callers usually special-case this).

quality_explicit

quality_explicit(value: str) -> float

Return the q-value for value, with explicit tokens overriding *.

RFC 9110 Sec. 12.5.3: an explicit q=0 means "not acceptable" and must override a more permissive wildcard. quality() returns the MAX across an exact match and a * match, so for br;q=0, *;q=1 it reports 1.0 for br - serving a rejected coding. This variant prefers an EXACT token match (so an explicit q=0 excludes the coding) and only falls back to the * wildcard q when value is not explicitly listed. Used by precompressed static selection where honoring an explicit rejection matters; non-MIME (Accept-Encoding) semantics.

accepts_identity

accepts_identity() -> bool

Whether the identity (no-encoding) coding is acceptable per RFC 9110.

RFC 9110 Sec. 12.5.3: identity is acceptable by default unless it is explicitly excluded. It is UNacceptable only when an explicit identity entry carries q=0, OR when identity is not explicitly listed and a * wildcard entry carries q=0 (the wildcard rejects every coding not named, including identity). A missing header, or any header that does not exclude identity, leaves identity acceptable. Token comparison is case-insensitive (Sec. 8.4.1). Used by precompressed static selection to decide between serving the uncompressed asset and returning 406.

best_match

best_match(options: list[str], default: str | None = None) -> str | None

Return the option the client accepts with the highest q-value.

Among candidates the client accepts (q>0), the one whose best matching client range has the highest (q, specificity) wins, so a parameterized exact match beats a bare wildcard (RFC 9110 Sec. 12.5.1). Ties on both go to the order in options (caller's preference). Returns default when no option has q>0. When the header is empty (no preference expressed), returns options[0] - a missing Accept means "accept anything".

Authorization

Parsed Authorization header.

Two common shapes are first-class: - Basic (RFC 7617): .type == "basic", .username + .password set. - Bearer (RFC 6750): .type == "bearer", .token set.

Other schemes (Digest per RFC 7616, Negotiate, custom) populate .params with the comma-separated key="value" parameters parsed from the credentials portion; .type is the scheme name lower-cased.

Construction is via Authorization.from_header(value) which returns None for empty / malformed inputs rather than raising.

from_header classmethod

from_header(header_value: str) -> Authorization | None

Parse an Authorization: header value. Returns None on miss.

RangeSpec

Parsed Range: header (RFC 9110 Sec. 14.2).

  • unit is the range unit, e.g. "bytes" (the only commonly-used one).
  • ranges is a list of (start, end) tuples, with None standing in for an open endpoint:
    • 0-499 -> (0, 499)
    • 1000- -> (1000, None) (open at the right)
    • -500 -> (None, 500) (suffix-range - last 500 bytes)

parse classmethod

parse(header_value: str) -> RangeSpec | None

Parse a Range: header, returning None for a missing or unparseable value.

The remaining header helpers are reached through the veloce.http gateway: they parse or build a header value rather than describing a Request attribute.

CacheControl

Parsed view of a Cache-Control header.

to_header

to_header() -> str

Serialise back to a Cache-Control header value.

Bool-True directives emit just the directive name; numeric and string directives emit name=value. Preserves source-observed order; user-set directives append in set order.

HeaderSet

Ordered, case-insensitive set of header tokens.

Used for headers like Vary and Allow that carry a comma-joined token list:

  • __contains__ is case-insensitive.
  • add / discard / remove mutate in place.
  • to_header() round-trips to a comma-separated header value.
  • Iteration yields items in insertion order.

add

add(header: str) -> None

Add header to the set. No-op if already present (case-insensitive).

discard

discard(header: str) -> None

Remove header if present. Never raises (set semantics).

remove

remove(header: str) -> None

Remove header; raise KeyError if absent.

update

update(headers: Iterable[str]) -> None

Add every header in headers, ignoring ones already present.

clear

clear() -> None

Remove every header.

to_header

to_header() -> str

Serialise as a comma-separated header value (insertion order).

parse_multipart_form

parse_multipart_form(body: bytes, content_type: str, *, max_parts: int = DEFAULT_MAX_MULTIPART_PARTS, max_files: int | None = None, max_fields: int | None = None, max_part_size: int = DEFAULT_MAX_MULTIPART_PART_SIZE, max_file_size: int | None = None, max_field_size: int | None = None, max_field_memory: int | None = None, charset_fallback: str | None = None) -> FormData

Parse multipart/form-data into FormData with UploadFile support.

max_parts caps the total number of parts. max_files and max_fields, when set, additionally cap file parts and text-field parts independently, so a form may allow many small fields while permitting only a few uploads (or vice versa).

max_part_size caps each part's body size. max_file_size and max_field_size, when set, override it for file parts and text fields respectively, expressing the common "small fields, large files" policy. max_field_memory, when set, caps the cumulative resident bytes of all text fields (value bytes plus field-name bytes), a ceiling that max_field_size alone cannot express.

Exceeding any limit raises RequestEntityTooLarge (413), so a maliciously structured form cannot exhaust memory or CPU even when its total size is within MAX_CONTENT_LENGTH.

A missing boundary parameter, or one violating the RFC 2046 boundary grammar, raises BadRequest (400) rather than silently yielding an empty form.

charset_fallback controls how non-UTF-8 field bytes are handled when a part declares no charset of its own. The default (None) rejects them with BadRequest (400). Pass "replace" to substitute U+FFFD (the pre-0.1.4 behaviour) or "latin-1" to decode as ISO-8859-1 for legacy clients. A part that declares its own Content-Type charset (RFC 7578 §5.1.2) is decoded with that charset instead, provided it is one of ascii, us-ascii, utf-8, or iso-8859-1. A declared charset is decoded strictly: bytes that are invalid in it raise BadRequest (400) rather than being corrupted with U+FFFD, since the part asserted its own encoding.

header_key

header_key(headers: Mapping[str, str], name: str) -> str | None

Return the actual stored key matching name case-insensitively, or None.

name should be passed in its canonical casing; the common case (the header is stored under that exact key) returns without scanning. Use the returned key to rewrite a value in place under whatever casing the caller originally stored.

header_get

header_get(headers: Mapping[str, str], name: str) -> str | None

Return the value stored under name case-insensitively, or None.

header_present

header_present(headers: Mapping[str, str], name: str) -> bool

Return True when a header named name exists under any casing.