英文:
How to update/modify request headers and query parameters in a FastAPI middleware?
问题
I'm trying to write a middleware for a FastAPI project that manipulates the request headers
and / or query
parameters in some special cases.
I've managed to capture and modify the request object in the middleware, but it seems that even if I modify the request object that is passed to the middleware, the function that serves the endpoint receives the original, unmodified request.
Here is a simplified version of my implementation:
from fastapi import FastAPI, Request
from starlette.datastructures import MutableHeaders, QueryParams
from starlette.middleware.base import BaseHTTPMiddleware
class TestMiddleware(BaseHTTPMiddleware):
def __init__(self, app: FastAPI):
super().__init__(app)
def get_modified_query_params(request: Request) -> QueryParams:
pass # Create and return new query params
async def dispatch(
self, request: Request, call_next, *args, **kwargs
) -> None:
# Check and manipulate the X-DEVICE-TOKEN if required
header_key = "X-DEVICE-INFo"
new_header_value = "new device info"
new_header = MutableHeaders(request._headers)
new_header[header_key] = new_header_value
request._headers = new_header
request._query_params = self.get_modified_query_params(request)
print("modified headers =>", request.headers)
print("modified params =>", request.query_params)
return await call_next(request)
Even though I see the updated values in the print statements above, when I try to print request object in the function that serves the endpoint, I see original values of the request.
What am I missing?
英文:
I'm trying to write a middleware for a FastAPI project that manipulates the request headers
and / or query
parameters in some special cases.
I've managed to capture and modify the request object in the middleware, but it seems that even if I modify the request object that is passed to the middleware, the function that serves the endpoint receives the original, unmodified request.
Here is a simplified version of my implementation:
from fastapi import FastAPI, Request
from starlette.datastructures import MutableHeaders, QueryParams
from starlette.middleware.base import BaseHTTPMiddleware
class TestMiddleware(BaseHTTPMiddleware):
def __init__(self, app: FastAPI):
super().__init__(app)
def get_modified_query_params(request: Request) -> QueryParams:
pass ## Create and return new query params
async def dispatch(
self, request: Request, call_next, *args, **kwargs
) -> None:
# Check and manipulate the X-DEVICE-TOKEN if required
header_key = "X-DEVICE-INFo"
new_header_value = "new device info"
new_header = MutableHeaders(request._headers)
new_header[header_key] = new_header_value
request._headers = new_header
request._query_params = self.get_modified_query_params(request)
print("modified headers =>", request.headers)
print("modified params =>", request.query_params)
return await call_next(request)
Even though I see the updated values in the print statements above, when I try to print request object in the function that serves the endpoint, I see original values of the request.
What am I missing?
答案1
得分: 2
以下是翻译好的部分:
要更新或修改请求的头部(headers),您需要更新request.scope['headers']
,如此答案所描述的那样。通过这种方式,您可以添加新的自定义头部,以及修改现有的头部。类似地,通过更新request.scope['query_string']
,您可以修改现有的查询参数(query parameters),以及添加新的参数。下面是一个工作示例。
工作示例
from fastapi import FastAPI, Request
from urllib.parse import urlencode
app = FastAPI()
@app.middleware('http')
async def some_middleware(request: Request, call_next):
# 更新请求头部
headers = dict(request.scope['headers'])
headers[b'custom-header'] = b'my custom header'
request.scope['headers'] = [(k, v) for k, v in headers.items()]
# 更新请求查询参数
q_params = dict(request.query_params)
q_params['custom-q-param'] = 'my custom query param'
request.scope['query_string'] = urlencode(q_params).encode('utf-8')
return await call_next(request)
@app.get('/')
async def main(request: Request):
return {'headers': request.headers, 'q_params': request.query_params}
英文:
To update or modify the request headers, you would need to update request.scope['headers']
, as described in this answer. In that way, you could add new custom headers, as well as modify existing ones. In a similar way, by updating request.scope['query_string']
, you could modify existing query parameters, as well as add new ones. A working example is given below.
Working Example
from fastapi import FastAPI, Request
from urllib.parse import urlencode
app = FastAPI()
@app.middleware('http')
async def some_middleware(request: Request, call_next):
# update request headers
headers = dict(request.scope['headers'])
headers[b'custom-header'] = b'my custom header'
request.scope['headers'] = [(k, v) for k, v in headers.items()]
# update request query parameters
q_params = dict(request.query_params)
q_params['custom-q-param'] = 'my custom query param'
request.scope['query_string'] = urlencode(q_params).encode('utf-8')
return await call_next(request)
@app.get('/')
async def main(request: Request):
return {'headers': request.headers, 'q_params': request.query_params}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论