@app.get("/async_set_cookie")
async def set_cookie_to_client(response: Response):
"""
将 cookie 写入到本地文件: test_cookies
curl -c test_cookies -X 'GET' \
'http://127.0.0.1:18081/async_set_cookie' \
-H 'accept: application/json'
cat test_cookies
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 test_cookie_user_id test_cookie_user_value
"""
response.set_cookie(key = 'test_cookie_user_id', value = 'test_cookie_user_value')
return {"set_cookie": datetime.datetime.now().isoformat(sep = ' ')}
向客户端设置一个名为 test_cookie_user_id
的 cookie
,并返回当前的时间戳。
使用 curl
命令作为客户端,向服务器发送请求并接收服务端设置的 cookie 数据:
curl -c test_cookies -X 'GET' \
'http://127.0.0.1:18081/async_set_cookie' \
-H 'accept: application/json'
查看 cookie 数据:cat test_cookies
cat test_cookies
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 test_cookie_user_id test_cookie_user_value
@app.get('/async_with_cookie')
async def request_with_cookie(req: Request):
"""
从本地缓存文件中读取 cookie,并发送给服务器
curl -b test_cookies -X 'GET' \
'http://127.0.0.1:18081/async_with_cookie' \
-H 'accept: application/json'
it's generally recommended and more common to use cookies for storing simple string values rather than complex data structures
Cookie Parameters:
These are used to extract data from HTTP cookies sent by the client.
Cookies are small pieces of data stored on the client-side and sent with every request to the server.
They're often used for maintaining session information, user preferences, or tracking.
Path Parameters:
These are part of the URL path itself.
They're typically used for identifying specific resources or entities.
Example: /users/{user_id} where user_id is a path parameter.
Query Parameters:
These are appended to the URL after a question mark.
They're used for filtering, sorting, or passing optional data.
Example: /users?age=30&city=NewYork
Body Parameters:
These are sent in the request body, typically with POST, PUT, or PATCH methods.
They're used for sending larger amounts of data or complex structures.
Often used for form submissions or API payloads.
The key differences and use cases:
Data Source:
Cookies come from the browser's cookie storage.
Path and query parameters come from the URL.
Body parameters come from the request body.
Persistence:
Cookies can persist across multiple requests and even browser sessions.
Path, query, and body parameters are typically single-request.
Visibility:
Path and query parameters are visible in the URL.
Cookies and body parameters are not visible in the URL.
Size Limitations:
Cookies and URL parameters (path and query) have size limitations.
Body parameters can handle much larger data sets.
Use Cases:
Cookies: Session management, remembering user preferences.
Path Parameters: Identifying resources (e.g., user IDs, post IDs).
Query Parameters: Filtering, sorting, pagination.
Body Parameters: Submitting forms, complex data structures.
"""
print('received cookies:', req.cookies)
return {"cookies": req.cookies}
使用 curl 客户端从本地缓存文件中读取 cookie,并发送给服务器:
curl -b test_cookies -X 'GET' \
'http://127.0.0.1:18081/async_with_cookie' \
-H 'accept: application/json'
服务端的打印日志:
received cookies: {'test_cookie_user_id': 'test_cookie_user_value'}
INFO: 127.0.0.1:53670 - "GET /async_with_cookie HTTP/1.1" 200 OK
class Cookies(BaseModel):
session_id: str
fatebook_tracker: str | None = None
googall_tracker: str | None = None
class Config:
title = 'test cookie model'
extra = "forbid"
@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
"""
curl -X 'GET' \
'http://127.0.0.1:18081/items/' \
-H 'accept: application/json' \
-H 'Cookie: googall_tracker=123; session_id=test; fatebook_tracker=HelloWorld;'
"""
return cookies
注意:生成的 Swagger 文档进行测试时无法正常执行,这应该是文档的测试 case 生成有问题:
使用 Curl 正确执行:
FastAPI's Path
, Query
, Body
, Cookie
, and Header
parameters are generally preferred for their type safety, validation, and auto-documentation features, there are specific scenarios where using the Request object directly can be beneficial.
When you're dealing with requests where the structure or names of parameters are not known in advance or can vary significantly.
@app.post("/dynamic")
async def handle_dynamic(request: Request):
data = await request.json()
When you need access to the raw request data, such as for custom parsing or when dealing with non-standard content types.
@app.post("/raw")
async def handle_raw(request: Request):
raw_body = await request.body()
When building middleware or plugins that need to inspect or modify the raw request.
@app.middleware("http")
async def custom_middleware(request: Request, call_next):
# Inspect or modify request
response = await call_next(request)
return response
When you need to log or debug the entire request, including headers, body, and other metadata.
@app.get("/debug")
async def debug_request(request: Request):
log_data = {
"method": request.method,
"url": str(request.url),
"headers": dict(request.headers),
"query_params": dict(request.query_params),
"client": request.client.host
}
logger.debug(f"Request data: {log_data}")
When handling WebSocket connections, you often need the Request object for the initial connection setup.
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
When you need to access various parts of the request that don't fit neatly into the standard parameter types.
@app.post("/complex")
async def handle_complex(request: Request):
body = await request.json()
headers = request.headers
query_params = request.query_params
client_host = request.client.host
When handling file uploads where you need access to both the file and additional form data.
@app.post("/upload")
async def upload_file(request: Request):
form = await request.form()
file = form["file"]
metadata = form["metadata"]
When dealing with custom or non-standard content types that FastAPI doesn't handle out of the box.
@app.post("/custom-type")
async def handle_custom_type(request: Request):
if request.headers.get("content-type") == "application/custom-type":
data = await request.body()
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。