+7
−2
Loading
## Motivation and Context
* Customers want to be able to implement simple middleware directly in Python. This PR aims to add the initial support for it.
* Improve the idiomatic experience of logging by exposing a handler compatible with Python's standard library `logging` module.
## Description
### Middleware
A middleware is defined as a sync or async Python function that can return multiple values, following these rules:
* Middleware not returning will let the execution continue without changing the original request.
* Middleware returning a modified Request will update the original request before continuing the execution.
* Middleware returning a Response will immediately terminate the request handling and return the response constructed from Python.
* Middleware raising MiddlewareException will immediately terminate the request handling and return a protocol specific error, with the option of setting the HTTP return code.
* Middleware raising any other exception will immediately terminate the request handling and return a protocol specific error, with HTTP status code 500.
Middlewares are registered into the Python application and executed in order of registration.
Example:
from sdk import App
from sdk.middleware import Request, MiddlewareException
app = App()
@app.request_middleware
def inject_header(request: Request):
request.set_header("x-amzn-answer", "42")
return request
@app.request_middleare
def check_header(request: Request):
if request.get_header("x-amzn-answer") != "42":
raise MiddlewareException("Wrong answer", 404)
@app.request_middleware
def dump_headers(request: Request):
logging.debug(f"Request headers after middlewares: {request.headers()}")
**NOTE: this PR only adds support for request middlewares, which are executed before the operation handler. Response middlewares, executed after the operation are tracked here: https://github.com/awslabs/smithy-rs/issues/1754.**
### Logging
To improve the idiomatic experience, now logging need to be configured from the Python side by using the standard `logging` module. This allows customers to opt-out of our `tracing` based logging implementation and use their own and logging level is now driven by Python.
import logging
from sdk.logging import TracingHandler
logging.basicConfig(level=logging.INFO, handlers=[TracingHandler.handle()])
Signed-off-by:
Bigo <1781140+crisidev@users.noreply.github.com>
Co-authored-by:
Burak <burakvar@amazon.co.uk>