The ultra-reliable, fast ASGI+WSGI framework for building data plane APIs at scale.
—
Comprehensive HTTP request and response objects that provide extensive properties and methods for accessing headers, parameters, media content, and managing response data.
Represents an HTTP request with comprehensive access to all request data including headers, parameters, body content, and metadata.
class Request:
def __init__(self, env: dict, options: RequestOptions = None):
"""
Create a Request object from WSGI environment.
Args:
env: WSGI environment dictionary
options: Request processing options
"""
# Core Properties
method: str # HTTP method (GET, POST, etc.)
uri: str # Full request URI
relative_uri: str # URI relative to app
forwarded_uri: str # URI from Forwarded header
scheme: str # URI scheme (http/https)
forwarded_scheme: str # Scheme from Forwarded header
host: str # Host header value
forwarded_host: str # Host from Forwarded header
path: str # URI path component
query_string: str # Query string
headers: dict # Case-insensitive headers dict
params: dict # Query parameters dict
cookies: dict # Request cookies
content_length: int # Content-Length header value
content_type: str # Content-Type header value
media: object # Parsed request body (JSON, form data, etc.)
bounded_stream: object # Raw request body stream
context: object # User data storage
# Accept header properties
accept: str # Accept header value
accept_charset: str # Accept-Charset header
accept_encoding: str # Accept-Encoding header
accept_language: str # Accept-Language header
# Conditional request headers
date: datetime # Date header as datetime
if_match: str # If-Match header value
if_none_match: str # If-None-Match header value
if_modified_since: datetime # If-Modified-Since as datetime
if_unmodified_since: datetime # If-Unmodified-Since as datetime
if_range: str # If-Range header value
# Range request properties
range: tuple # Range header as (start, end) tuple
range_unit: str # Range unit (usually 'bytes')
# Forwarded header information
forwarded: list # Parsed Forwarded headers
# Authentication
auth: str # Authorization header value
# Client information
user_agent: str # User-Agent header
referer: str # Referer header
remote_addr: str # Client IP address
# Methods
def get_header(self, name: str, default: str = None) -> str:
"""
Get header value by name.
Args:
name: Header name (case-insensitive)
default: Default value if header not found
Returns:
Header value or default
"""
def get_param(self, name: str, default: str = None) -> str:
"""
Get query parameter value by name.
Args:
name: Parameter name
default: Default value if parameter not found
Returns:
Parameter value or default
"""
def get_param_as_bool(self, name: str, default: bool = None) -> bool:
"""Get query parameter as boolean value."""
def get_param_as_int(self, name: str, default: int = None) -> int:
"""Get query parameter as integer value."""
def get_param_as_float(self, name: str, default: float = None) -> float:
"""Get query parameter as float value."""
def get_param_as_date(self, name: str, format_string: str = '%Y-%m-%d', default: datetime = None) -> datetime:
"""Get query parameter as date value."""
def get_param_as_list(self, name: str, transform: callable = None, default: list = None) -> list:
"""Get query parameter as list of values."""
def client_accepts_json(self) -> bool:
"""Check if client accepts JSON responses."""
def client_accepts_msgpack(self) -> bool:
"""Check if client accepts MessagePack responses."""
def client_accepts_xml(self) -> bool:
"""Check if client accepts XML responses."""
def client_prefers(self, media_types: list) -> str:
"""
Determine client's preferred media type from a list.
Args:
media_types: List of media types to choose from
Returns:
Preferred media type or None
"""class UserResource:
def on_get(self, req, resp):
# Access request properties
user_id = req.get_param('user_id')
page = req.get_param_as_int('page', default=1)
include_deleted = req.get_param_as_bool('include_deleted', default=False)
# Check headers
api_key = req.get_header('X-API-Key')
if not api_key:
raise falcon.HTTPUnauthorized(title='API key required')
# Content negotiation
if req.client_accepts_json():
resp.content_type = falcon.MEDIA_JSON
elif req.client_accepts_xml():
resp.content_type = falcon.MEDIA_XML
# Use context for request-scoped data
req.context.current_user = authenticate_user(api_key)
resp.media = {'users': get_users(page, include_deleted)}
def on_post(self, req, resp):
# Access parsed request body
user_data = req.media
# Validate content type
if req.content_type != falcon.MEDIA_JSON:
raise falcon.HTTPUnsupportedMediaType(
description='This endpoint only accepts JSON'
)
# Create user
new_user = create_user(user_data)
resp.status = falcon.HTTP_201
resp.media = new_userRepresents an HTTP response with methods for setting headers, status codes, body content, and managing output data.
class Response:
def __init__(self, options: ResponseOptions = None):
"""
Create a Response object.
Args:
options: Response processing options
"""
# Core Properties
status: str # HTTP status line
status_code: int # HTTP status code as integer
headers: dict # Response headers dict
data: bytes # Raw response body bytes
media: object # Structured response data (auto-serialized)
text: str # Response body as text
content_type: str # Content-Type header value
content_length: int # Content-Length header value
context: object # User data storage
# Caching headers
cache_control: list # Cache-Control directives
etag: str # ETag header value
last_modified: datetime # Last-Modified as datetime
expires: datetime # Expires as datetime
vary: list # Vary header values
# Methods
def set_header(self, name: str, value: str):
"""
Set response header.
Args:
name: Header name
value: Header value
"""
def append_header(self, name: str, value: str):
"""
Append value to response header.
Args:
name: Header name
value: Value to append
"""
def get_header(self, name: str, default: str = None) -> str:
"""
Get response header value.
Args:
name: Header name
default: Default if not found
Returns:
Header value or default
"""
def delete_header(self, name: str):
"""
Delete response header.
Args:
name: Header name to delete
"""
def set_cookie(
self,
name: str,
value: str,
expires: datetime = None,
max_age: int = None,
domain: str = None,
path: str = None,
secure: bool = None,
http_only: bool = None,
same_site: str = None
):
"""
Set response cookie.
Args:
name: Cookie name
value: Cookie value
expires: Expiration datetime
max_age: Max age in seconds
domain: Cookie domain
path: Cookie path
secure: Secure flag
http_only: HttpOnly flag
same_site: SameSite attribute
"""
def unset_cookie(self, name: str, domain: str = None, path: str = None):
"""
Unset/delete a cookie.
Args:
name: Cookie name
domain: Cookie domain
path: Cookie path
"""
def set_stream(self, stream: object, content_length: int, content_type: str = None):
"""
Set streaming response body.
Args:
stream: File-like object or iterable
content_length: Content length in bytes
content_type: Content type
"""
def render_body(self) -> bytes:
"""
Render response body to bytes.
Returns:
Response body as bytes
"""
def append_link(self, target: str, rel: str, title: str = None, **kwargs):
"""
Add Link header for resource relationships.
Args:
target: Link target URI
rel: Link relationship
title: Optional link title
**kwargs: Additional link parameters
"""class FileResource:
def on_get(self, req, resp, file_id):
# Get file info
file_info = get_file_info(file_id)
if not file_info:
raise falcon.HTTPNotFound()
# Set response headers
resp.status = falcon.HTTP_200
resp.content_type = file_info['content_type']
resp.set_header('X-File-Size', str(file_info['size']))
# Set caching headers
resp.etag = file_info['etag']
resp.last_modified = file_info['modified_date']
resp.cache_control = ['public', 'max-age=3600']
# Handle conditional requests
if req.if_none_match == resp.etag:
resp.status = falcon.HTTP_304
return
# Stream file content
file_stream = open_file(file_id)
resp.set_stream(file_stream, file_info['size'])
class APIResource:
def on_post(self, req, resp):
# Process data
result = process_data(req.media)
# Set structured response
resp.status = falcon.HTTP_201
resp.media = {
'success': True,
'data': result,
'timestamp': datetime.utcnow().isoformat()
}
# Add custom headers
resp.set_header('X-Processing-Time', '150ms')
resp.append_link('/api/status', 'status')
# Set cookie
resp.set_cookie(
'session_id',
'abc123',
secure=True,
http_only=True,
same_site='Strict'
)Specialized request and response classes for ASGI applications with async support.
class falcon.asgi.Request(Request):
"""
ASGI Request class with async-specific features.
Inherits all methods and properties from WSGI Request.
"""
async def get_media(self) -> object:
"""
Asynchronously parse request media.
Returns:
Parsed request body
"""
async def bounded_stream(self) -> object:
"""
Get async stream for request body.
Returns:
Async stream object
"""
class falcon.asgi.Response(Response):
"""
ASGI Response class with async-specific features.
Inherits all methods and properties from WSGI Response.
"""
async def render_body(self) -> bytes:
"""
Asynchronously render response body.
Returns:
Response body as bytes
"""Support for RFC 7239 Forwarded headers and proxy information.
class Forwarded:
def __init__(self, forwarded_header: str):
"""
Parse Forwarded header.
Args:
forwarded_header: Raw Forwarded header value
"""
# Properties
src: str # Source IP address
host: str # Host value
proto: str # Protocol (http/https)
for_: str # For parameter value
# Class methods
@classmethod
def parse(cls, forwarded_header: str) -> list:
"""
Parse Forwarded header into list of Forwarded objects.
Args:
forwarded_header: Raw header value
Returns:
List of Forwarded objects
"""# Main request/response types
Request: type # WSGI request class
Response: type # WSGI response class
falcon.asgi.Request: type # ASGI request class
falcon.asgi.Response: type # ASGI response class
# Configuration types
RequestOptions: type # Request configuration
ResponseOptions: type # Response configuration
# Support types
Forwarded: type # Forwarded header parserInstall with Tessl CLI
npx tessl i tessl/pypi-falcon