GitHub user asukaminato0721 added a comment to the discussion: Do we have better names for opendal python's Layer?
> a more in-depth study on how python users use middleware Basically define a class -> define special method, usually `__call__` or `dispatch` -> put them into a list/builder pattern api ### 1. Django Middleware ``` django_mw_project/ ├── myapp/ │ ├── __init__.py │ ├── middleware.py # <--- │ ├── views.py │ └── urls.py ├── django_mw_project/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py ``` **`myapp/middleware.py`:** ```python import time class TimingMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): ... response = self.get_response(request) ... return response class LoggingMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): ... response = self.get_response(request) ... return response ``` ```py MIDDLEWARE = [ ... # require seq: LoggingMiddleware -> TimingMiddleware -> ... -> View # respond seq: View -> ... -> TimingMiddleware -> LoggingMiddleware 'myapp.middleware.LoggingMiddleware', 'myapp.middleware.TimingMiddleware', ] ``` --- ### 2. Flask Middleware (use WSGI Middleware) **`flask_app.py`:** ```python from flask import Flask, Response import time class TimingMiddleware: def __init__(self, wsgi_app): self.wsgi_app = wsgi_app def __call__(self, environ, start_response): response_iterable = self.wsgi_app(environ, custom_start_response) return response_iterable class LoggingMiddleware: def __init__(self, wsgi_app): self.wsgi_app = wsgi_app def __call__(self, environ, start_response): request = Request(environ) def custom_start_response(status, headers, exc_info=None): ... response_iterable = self.wsgi_app(environ, custom_start_response) return response_iterable app = Flask(__name__) @app.route('/') def hello(): time.sleep(0.1) return Response("Hello from Flask with WSGI Middleware!", mimetype='text/plain') # req seq: Logging -> Timing -> Flask App # res seq: Flask App -> Timing -> Logging app.wsgi_app = LoggingMiddleware(app.wsgi_app) app.wsgi_app = TimingMiddleware(app.wsgi_app) # Timing in Logging if __name__ == '__main__': app.run(debug=True, port=5000) ``` --- ### 3. FastAPI Middleware **`fastapi_app.py`:** ```python from fastapi import FastAPI, Request, Response import time from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint from starlette.types import ASGIApp, Receive, Scope, Send class TimingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: response = await call_next(request) return response class LoggingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: response = await call_next(request) return response app = FastAPI() # use add_middleware # req seq: Logging -> Timing -> Route # res seq: Route -> Timing -> Logging app.add_middleware(LoggingMiddleware) # most outside app.add_middleware(TimingMiddleware) # inner side @app.get("/") async def read_root(): await asyncio.sleep(0.1) return {"message": "Hello from FastAPI with Middleware!"} ``` --- GitHub link: https://github.com/apache/opendal/discussions/6074#discussioncomment-12945572 ---- This is an automatically sent email for dev@opendal.apache.org. To unsubscribe, please send an email to: dev-unsubscr...@opendal.apache.org