Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_newsfragments/1820.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added type annotations to the recipe snippets covering ``request_id_*`` middleware/context examples and the ``plain_text_main`` / ``pretty_json_main`` custom media handler examples (see :ref:`recipes`).
9 changes: 6 additions & 3 deletions examples/recipes/plain_text_main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import functools
from typing import IO

import falcon

Expand All @@ -8,13 +9,15 @@ class TextHandler(falcon.media.BaseHandler):

@classmethod
@functools.lru_cache
def _get_charset(cls, content_type):
def _get_charset(cls, content_type: str) -> str:
_, params = falcon.parse_header(content_type)
return params.get('charset') or cls.DEFAULT_CHARSET

def deserialize(self, stream, content_type, content_length):
def deserialize(
self, stream: IO[bytes], content_type: str, content_length: int
) -> str:
data = stream.read()
return data.decode(self._get_charset(content_type))

def serialize(self, media, content_type):
def serialize(self, media: str, content_type: str) -> bytes:
return media.encode(self._get_charset(content_type))
9 changes: 6 additions & 3 deletions examples/recipes/pretty_json_main.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import json
from typing import Any, IO, Optional

import falcon


class CustomJSONHandler(falcon.media.BaseHandler):
MAX_INDENT_LEVEL = 8

def deserialize(self, stream, content_type, content_length):
def deserialize(
self, stream: IO[bytes], content_type: str, content_length: int
) -> Any:
data = stream.read()
return json.loads(data.decode())

def serialize(self, media, content_type):
def serialize(self, media: Any, content_type: str) -> bytes:
_, params = falcon.parse_header(content_type)
indent = params.get('indent')
indent: Optional[int] = params.get('indent')
if indent is not None:
try:
indent = int(indent)
Expand Down
11 changes: 7 additions & 4 deletions examples/recipes/request_id_context.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import contextvars
from typing import Optional


class _Context:
def __init__(self):
self._request_id_var = contextvars.ContextVar('request_id', default=None)
def __init__(self) -> None:
self._request_id_var: contextvars.ContextVar[Optional[str]] = (
contextvars.ContextVar('request_id', default=None)
)

@property
def request_id(self):
def request_id(self) -> Optional[str]:
return self._request_id_var.get()

@request_id.setter
def request_id(self, value):
def request_id(self, value: str) -> None:
self._request_id_var.set(value)


Expand Down
2 changes: 1 addition & 1 deletion examples/recipes/request_id_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from my_app.context import ctx


def create_widget_object(name: str):
def create_widget_object(name: str) -> None:
request_id = f'request_id={ctx.request_id}'
logging.debug('%s going to create widget: %s', request_id, name)

Expand Down
12 changes: 10 additions & 2 deletions examples/recipes/request_id_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
# Import the above context.py
from my_app.context import ctx

import falcon


class RequestIDMiddleware:
def process_request(self, req, resp):
def process_request(self, req: falcon.Request, resp: falcon.Response) -> None:
request_id = str(uuid4())
ctx.request_id = request_id

# It may also be helpful to include the ID in the response
def process_response(self, req, resp, resource, req_succeeded):
def process_response(
self,
req: falcon.Request,
resp: falcon.Response,
resource: object,
req_succeeded: bool,
) -> None:
resp.set_header('X-Request-ID', ctx.request_id)
12 changes: 10 additions & 2 deletions examples/recipes/request_id_structlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Optional logging package (pip install structlog)
import structlog

import falcon


class RequestIDMiddleware:
def process_request(self, req, resp):
def process_request(self, req: falcon.Request, resp: falcon.Response) -> None:
request_id = str(uuid4())

# Using Falcon 2.0+ context style
Expand All @@ -15,5 +17,11 @@ def process_request(self, req, resp):
req.context.log = structlog.get_logger(request_id=request_id)

# It may also be helpful to include the ID in the response
def process_response(self, req, resp, resource, req_succeeded):
def process_response(
self,
req: falcon.Request,
resp: falcon.Response,
resource: object,
req_succeeded: bool,
) -> None:
resp.set_header('X-Request-ID', req.context.request_id)