The ultra-reliable, fast ASGI+WSGI framework for building data plane APIs at scale.
npx @tessl/cli install tessl/pypi-falcon@4.1.0A minimalist Python web framework specifically designed for building high-performance REST APIs and microservices at scale. Falcon supports both ASGI and WSGI protocols, making it suitable for modern asynchronous applications as well as traditional synchronous web services.
pip install falconimport falconFor ASGI applications:
import falcon.asgiimport falcon
class ThingsResource:
def on_get(self, req, resp):
"""Handles GET requests"""
resp.status = falcon.HTTP_200
resp.content_type = falcon.MEDIA_JSON
resp.media = {'message': 'Hello, World!'}
def on_post(self, req, resp):
"""Handles POST requests"""
try:
data = req.media
# Process the data
resp.status = falcon.HTTP_201
resp.media = {'created': True, 'data': data}
except Exception as e:
raise falcon.HTTPBadRequest(
title='Invalid request',
description=str(e)
)
# Create WSGI application
app = falcon.App()
app.add_route('/things', ThingsResource())
# Or create ASGI application
# app = falcon.asgi.App()
# app.add_route('/things', ThingsResource())Falcon's architecture emphasizes performance and simplicity:
This design provides minimal abstractions over HTTP while maintaining excellent performance, making it ideal for building data plane APIs and microservices.
Core WSGI and ASGI application classes for building web APIs, with routing, middleware support, and comprehensive configuration options.
class App:
def __init__(
self,
media_type: str = 'application/json',
request_type: type = None,
response_type: type = None,
middleware: object = None,
router: object = None,
independent_middleware: bool = True,
cors_enable: bool = False,
sink_before_static_route: bool = True
): ...
def add_route(self, uri_template: str, resource: object, **kwargs): ...
def add_static_route(self, prefix: str, directory: str, **kwargs): ...
def add_sink(self, sink: callable, prefix: str = '/'): ...
def add_middleware(self, middleware: object): ...
def add_error_handler(self, exception_type: type, handler: callable): ...# ASGI Application
class falcon.asgi.App:
def __init__(self, **kwargs): ...
# Same methods as WSGI AppComprehensive HTTP request and response objects with extensive properties and methods for headers, parameters, media processing, and content negotiation.
class Request:
# Core properties
method: str
uri: str
relative_uri: str
headers: dict
params: dict
cookies: dict
media: object # Parsed request body
context: object # User data storage
# Methods
def get_header(self, name: str, default: str = None) -> str: ...
def get_param(self, name: str, default: str = None) -> str: ...
def client_accepts_json(self) -> bool: ...
def client_accepts_msgpack(self) -> bool: ...class Response:
# Core properties
status: str
headers: dict
media: object # Auto-serialized response data
data: bytes # Raw response body
content_type: str
context: object
# Methods
def set_header(self, name: str, value: str): ...
def set_cookie(self, name: str, value: str, **kwargs): ...
def set_stream(self, stream: object, content_length: int, content_type: str = None): ...Comprehensive HTTP exception hierarchy and error handling mechanisms for building robust APIs with proper status codes and error responses.
class HTTPError(Exception):
def __init__(
self,
status: str,
title: str = None,
description: str = None,
headers: dict = None,
href: str = None,
href_text: str = None,
code: int = None
): ...
def to_dict(self) -> dict: ...
def to_json(self) -> str: ...
# Common HTTP exceptions
class HTTPBadRequest(HTTPError): ...
class HTTPUnauthorized(HTTPError): ...
class HTTPForbidden(HTTPError): ...
class HTTPNotFound(HTTPError): ...
class HTTPMethodNotAllowed(HTTPError): ...
class HTTPInternalServerError(HTTPError): ...Advanced routing capabilities with URI templates, path converters, static file serving, and high-performance compiled routing.
# Route converters for path parameters
class IntConverter: ...
class FloatConverter: ...
class DateTimeConverter: ...
class UUIDConverter: ...
class PathConverter: ...
# Static file serving
class StaticRoute:
def __init__(self, prefix: str, directory: str, **kwargs): ...
class StaticRouteAsync: # ASGI version
def __init__(self, prefix: str, directory: str, **kwargs): ...Modern asynchronous application support with WebSocket handling, Server-Sent Events, and full ASGI 3.0 compatibility.
class WebSocket:
# Properties
ready_state: int
client_address: tuple
context: object
# Methods
async def accept(self, subprotocol: str = None, headers: dict = None): ...
async def receive_text(self) -> str: ...
async def receive_data(self) -> bytes: ...
async def send_text(self, payload: str): ...
async def send_data(self, payload: bytes): ...
async def close(self, code: int = 1000, reason: str = None): ...
class SSEvent:
def __init__(self, data: str, event_type: str = None, event_id: str = None, retry: int = None): ...Pluggable media handling system supporting JSON, MessagePack, multipart forms, URL-encoded data, and custom media types.
class BaseHandler:
def serialize(self, media: object, content_type: str) -> bytes: ...
def deserialize(self, stream: object, content_type: str, content_length: int) -> object: ...
class JSONHandler(BaseHandler): ...
class MessagePackHandler(BaseHandler): ...
class MultipartFormHandler(BaseHandler): ...
class URLEncodedFormHandler(BaseHandler): ...
class Handlers:
def __init__(self, initial: dict = None): ...
def find_by_media_type(self, media_type: str, default: object = None) -> BaseHandler: ...Comprehensive testing utilities with request simulation, ASGI testing support, and mock objects for building robust test suites.
class TestClient:
def __init__(self, app: object, headers: dict = None): ...
def simulate_get(self, path: str, **kwargs) -> Result: ...
def simulate_post(self, path: str, **kwargs) -> Result: ...
def simulate_put(self, path: str, **kwargs) -> Result: ...
def simulate_delete(self, path: str, **kwargs) -> Result: ...
class Result:
status: str
headers: dict
text: str
json: object
cookies: listMiddleware system for cross-cutting concerns and hook decorators for before/after request processing.
class CORSMiddleware:
def __init__(
self,
allow_origins: str = '*',
expose_headers: list = None,
allow_credentials: bool = None,
allow_private_network: bool = False
): ...
# Hook decorators
def before(action: callable, *args, **kwargs): ...
def after(action: callable, *args, **kwargs): ...Extensive utility functions for HTTP dates, URI handling, async/sync conversion, data structures, and common web development tasks.
# HTTP utilities
def http_now() -> str: ...
def http_date_to_dt(http_date: str) -> datetime: ...
def dt_to_http(dt: datetime) -> str: ...
def secure_filename(filename: str) -> str: ...
# Async utilities
def async_to_sync(coroutine_func: callable) -> callable: ...
def sync_to_async(sync_func: callable) -> callable: ...
# Data structures
class CaseInsensitiveDict(dict): ...
class Context: ...
class ETag: ...# Request/Response Options
class RequestOptions:
auto_parse_form_urlencoded: bool
auto_parse_qs_csv: bool
default_media_type: str
media_handlers: Handlers
strip_url_path_trailing_slash: bool
class ResponseOptions:
default_media_type: str
media_handlers: Handlers
secure_cookies_by_default: bool
static_media_types: dict
# WebSocket payload types
class WebSocketPayloadType:
TEXT: int
BINARY: int# HTTP Methods
HTTP_METHODS: list # Standard HTTP methods
WEBDAV_METHODS: list # WebDAV methods
COMBINED_METHODS: list # All supported methods
# Media Types
DEFAULT_MEDIA_TYPE: str # 'application/json'
MEDIA_JSON: str # 'application/json'
MEDIA_XML: str # 'application/xml'
MEDIA_HTML: str # 'text/html'
MEDIA_TEXT: str # 'text/plain'
MEDIA_URLENCODED: str # 'application/x-www-form-urlencoded'
MEDIA_MULTIPART: str # 'multipart/form-data'
MEDIA_MSGPACK: str # 'application/msgpack'
# HTTP Status Codes
## Numeric Status Codes
### 1xx Informational
HTTP_100: str # '100 Continue'
HTTP_101: str # '101 Switching Protocols'
HTTP_102: str # '102 Processing'
HTTP_103: str # '103 Early Hints'
### 2xx Success
HTTP_200: str # '200 OK'
HTTP_201: str # '201 Created'
HTTP_202: str # '202 Accepted'
HTTP_203: str # '203 Non-Authoritative Information'
HTTP_204: str # '204 No Content'
HTTP_205: str # '205 Reset Content'
HTTP_206: str # '206 Partial Content'
HTTP_207: str # '207 Multi-Status'
HTTP_208: str # '208 Already Reported'
HTTP_226: str # '226 IM Used'
### 3xx Redirection
HTTP_300: str # '300 Multiple Choices'
HTTP_301: str # '301 Moved Permanently'
HTTP_302: str # '302 Found'
HTTP_303: str # '303 See Other'
HTTP_304: str # '304 Not Modified'
HTTP_305: str # '305 Use Proxy'
HTTP_307: str # '307 Temporary Redirect'
HTTP_308: str # '308 Permanent Redirect'
### 4xx Client Error
HTTP_400: str # '400 Bad Request'
HTTP_401: str # '401 Unauthorized'
HTTP_402: str # '402 Payment Required'
HTTP_403: str # '403 Forbidden'
HTTP_404: str # '404 Not Found'
HTTP_405: str # '405 Method Not Allowed'
HTTP_406: str # '406 Not Acceptable'
HTTP_407: str # '407 Proxy Authentication Required'
HTTP_408: str # '408 Request Timeout'
HTTP_409: str # '409 Conflict'
HTTP_410: str # '410 Gone'
HTTP_411: str # '411 Length Required'
HTTP_412: str # '412 Precondition Failed'
HTTP_413: str # '413 Content Too Large'
HTTP_414: str # '414 URI Too Long'
HTTP_415: str # '415 Unsupported Media Type'
HTTP_416: str # '416 Range Not Satisfiable'
HTTP_417: str # '417 Expectation Failed'
HTTP_418: str # '418 I\'m a Teapot'
HTTP_421: str # '421 Misdirected Request'
HTTP_422: str # '422 Unprocessable Entity'
HTTP_423: str # '423 Locked'
HTTP_424: str # '424 Failed Dependency'
HTTP_425: str # '425 Too Early'
HTTP_426: str # '426 Upgrade Required'
HTTP_428: str # '428 Precondition Required'
HTTP_429: str # '429 Too Many Requests'
HTTP_431: str # '431 Request Header Fields Too Large'
HTTP_451: str # '451 Unavailable For Legal Reasons'
### 5xx Server Error
HTTP_500: str # '500 Internal Server Error'
HTTP_501: str # '501 Not Implemented'
HTTP_502: str # '502 Bad Gateway'
HTTP_503: str # '503 Service Unavailable'
HTTP_504: str # '504 Gateway Timeout'
HTTP_505: str # '505 HTTP Version Not Supported'
HTTP_506: str # '506 Variant Also Negotiates'
HTTP_507: str # '507 Insufficient Storage'
HTTP_508: str # '508 Loop Detected'
HTTP_510: str # '510 Not Extended'
HTTP_511: str # '511 Network Authentication Required'
### 7xx Custom Error Codes (Falcon Extensions)
HTTP_701: str # '701 Meh'
HTTP_702: str # '702 Emacs'
HTTP_703: str # '703 Explosion'
HTTP_710: str # '710 PHP'
HTTP_711: str # '711 Convenience Store'
HTTP_712: str # '712 NoSQL'
HTTP_719: str # '719 I am not a teapot'
HTTP_720: str # '720 Unpossible'
HTTP_721: str # '721 Known Unknowns'
HTTP_722: str # '722 Unknown Unknowns'
HTTP_723: str # '723 Tricky'
HTTP_724: str # '724 This line should be unreachable'
HTTP_725: str # '725 It works on my machine'
HTTP_726: str # '726 It\'s a feature, not a bug'
HTTP_727: str # '727 32 bits is plenty'
HTTP_740: str # '740 Computer says no'
HTTP_741: str # '741 Compiling'
HTTP_742: str # '742 A kitten dies'
HTTP_743: str # '743 RTFM'
HTTP_744: str # '744 Nothing to see here'
HTTP_745: str # '745 Not implemented'
HTTP_748: str # '748 Confounded by ponies'
HTTP_749: str # '749 Reserved for Chuck Norris'
HTTP_750: str # '750 Didn\'t bother to compile it'
HTTP_753: str # '753 Syntax Error'
HTTP_754: str # '754 Too many semi-colons'
HTTP_755: str # '755 Not enough cowbell'
HTTP_759: str # '759 Unexpected T_PAAMAYIM_NEKUDOTAYIM'
HTTP_771: str # '771 Version mismatch'
HTTP_772: str # '772 Incompatible dependencies'
HTTP_773: str # '773 Missing dependency'
HTTP_774: str # '774 Shit happens'
HTTP_776: str # '776 Coincidence'
HTTP_777: str # '777 Coincidence'
HTTP_778: str # '778 Coincidence'
HTTP_779: str # '779 Off by one error'
HTTP_780: str # '780 Project owner not responding'
HTTP_781: str # '781 Operations'
HTTP_782: str # '782 QA'
HTTP_783: str # '783 It was DNS'
HTTP_784: str # '784 It was a race condition'
HTTP_785: str # '785 It was a cache issue'
HTTP_786: str # '786 Cached for too long'
HTTP_791: str # '791 The Internet shut down due to copyright restrictions'
HTTP_792: str # '792 Climate change driven catastrophic weather event'
HTTP_797: str # '797 We are no longer Amazon\'s ELB'
HTTP_799: str # '799 End of the world'
## Named Status Codes (Aliases)
HTTP_ACCEPTED: str # Alias for HTTP_202
HTTP_ALREADY_REPORTED: str # Alias for HTTP_208
HTTP_BAD_GATEWAY: str # Alias for HTTP_502
HTTP_BAD_REQUEST: str # Alias for HTTP_400
HTTP_CONFLICT: str # Alias for HTTP_409
HTTP_CONTENT_TOO_LARGE: str # Alias for HTTP_413
HTTP_CONTINUE: str # Alias for HTTP_100
HTTP_CREATED: str # Alias for HTTP_201
HTTP_EARLY_HINTS: str # Alias for HTTP_103
HTTP_EXPECTATION_FAILED: str # Alias for HTTP_417
HTTP_FAILED_DEPENDENCY: str # Alias for HTTP_424
HTTP_FORBIDDEN: str # Alias for HTTP_403
HTTP_FOUND: str # Alias for HTTP_302
HTTP_GATEWAY_TIMEOUT: str # Alias for HTTP_504
HTTP_GONE: str # Alias for HTTP_410
HTTP_HTTP_VERSION_NOT_SUPPORTED: str # Alias for HTTP_505
HTTP_IM_A_TEAPOT: str # Alias for HTTP_418
HTTP_IM_USED: str # Alias for HTTP_226
HTTP_INSUFFICIENT_STORAGE: str # Alias for HTTP_507
HTTP_INTERNAL_SERVER_ERROR: str # Alias for HTTP_500
HTTP_LENGTH_REQUIRED: str # Alias for HTTP_411
HTTP_LOCKED: str # Alias for HTTP_423
HTTP_LOOP_DETECTED: str # Alias for HTTP_508
HTTP_METHOD_NOT_ALLOWED: str # Alias for HTTP_405
HTTP_MISDIRECTED_REQUEST: str # Alias for HTTP_421
HTTP_MOVED_PERMANENTLY: str # Alias for HTTP_301
HTTP_MULTI_STATUS: str # Alias for HTTP_207
HTTP_MULTIPLE_CHOICES: str # Alias for HTTP_300
HTTP_NETWORK_AUTHENTICATION_REQUIRED: str # Alias for HTTP_511
HTTP_NON_AUTHORITATIVE_INFORMATION: str # Alias for HTTP_203
HTTP_NOT_ACCEPTABLE: str # Alias for HTTP_406
HTTP_NOT_EXTENDED: str # Alias for HTTP_510
HTTP_NOT_FOUND: str # Alias for HTTP_404
HTTP_NOT_IMPLEMENTED: str # Alias for HTTP_501
HTTP_NOT_MODIFIED: str # Alias for HTTP_304
HTTP_NO_CONTENT: str # Alias for HTTP_204
HTTP_OK: str # Alias for HTTP_200
HTTP_PARTIAL_CONTENT: str # Alias for HTTP_206
HTTP_PAYMENT_REQUIRED: str # Alias for HTTP_402
HTTP_PERMANENT_REDIRECT: str # Alias for HTTP_308
HTTP_PRECONDITION_FAILED: str # Alias for HTTP_412
HTTP_PRECONDITION_REQUIRED: str # Alias for HTTP_428
HTTP_PROCESSING: str # Alias for HTTP_102
HTTP_PROXY_AUTHENTICATION_REQUIRED: str # Alias for HTTP_407
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE: str # Alias for HTTP_416
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE: str # Alias for HTTP_431
HTTP_REQUEST_TIMEOUT: str # Alias for HTTP_408
HTTP_REQUEST_URI_TOO_LONG: str # Alias for HTTP_414
HTTP_RESET_CONTENT: str # Alias for HTTP_205
HTTP_SEE_OTHER: str # Alias for HTTP_303
HTTP_SERVICE_UNAVAILABLE: str # Alias for HTTP_503
HTTP_SWITCHING_PROTOCOLS: str # Alias for HTTP_101
HTTP_TEMPORARY_REDIRECT: str # Alias for HTTP_307
HTTP_TOO_EARLY: str # Alias for HTTP_425
HTTP_TOO_MANY_REQUESTS: str # Alias for HTTP_429
HTTP_UNAUTHORIZED: str # Alias for HTTP_401
HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: str # Alias for HTTP_451
HTTP_UNPROCESSABLE_ENTITY: str # Alias for HTTP_422
HTTP_UNSUPPORTED_MEDIA_TYPE: str # Alias for HTTP_415
HTTP_UPGRADE_REQUIRED: str # Alias for HTTP_426
HTTP_USE_PROXY: str # Alias for HTTP_305
HTTP_VARIANT_ALSO_NEGOTIATES: str # Alias for HTTP_506