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 [email protected].
To unsubscribe, please send an email to: [email protected]