Here is a complete solution based on sub-classing the Request object, which according to the internal Quart comments is the preferred method.
https://pgjones.gitlab.io/quart/reference/source/quart.html
https://github.com/pgjones/quart/blob/main/src/quart/wrappers/request.py
In this implementation a "correlation_id" needs to be taken from the request.args or generated on the fly, and should be attached to the request context for general use throughout the request in code or error handling etc.
(NOTE: the "ABC" import avoids some issues some Python abstract classes & not having to reimplement abstract methods.)
QuartUtilities.py:
from abc import ABC
from typing import cast
from uuid import uuid4
# Subclass of Request so we can add our own custom properties to the request context
class CorrelatedRequest(Request, ABC):
correlation_id: str = ""
def correlate_requests(app: Quart):
app.request_class = CorrelatedRequest
@app.before_request
def ensure_correlation_id_present():
correlated_request = cast(CorrelatedRequest, request)
if correlated_request.correlation_id != "":
return
if 'correlation_id' in request.args:
correlated_request.correlation_id = request.args["correlation_id"]
else:
correlated_request.correlation_id = uuid4()
def get_request_correlation_id() -> str:
return cast(CorrelatedRequest, request).correlation_id
QuartPI.py:
from quart import Quart
from werkzeug.exceptions import InternalServerError
from QuartUtilities import correlate_requests
app = Quart(__name__)
correlate_requests(app)
@app.errorhandler(InternalServerError)
def handle_error(error):
correlation_id = get_or_create_correlation_id()