前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >FastAPI后台开发基础(8):Cookie的使用

FastAPI后台开发基础(8):Cookie的使用

原创
作者头像
bowenerchen
修改2024-10-15 17:01:48
修改2024-10-15 17:01:48
21800
代码可运行
举报
文章被收录于专栏:编码视界编码视界
运行总次数:0
代码可运行

在FastAPI中使用Cookie

示例代码

服务器向客户端写入Cookie数据

代码语言:python
代码运行次数:0
复制
@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_idcookie,并返回当前的时间戳。

使用 curl 命令作为客户端,向服务器发送请求并接收服务端设置的 cookie 数据:

代码语言:shell
复制
curl -c test_cookies -X 'GET' \
  'http://127.0.0.1:18081/async_set_cookie' \
  -H 'accept: application/json'

查看 cookie 数据:cat test_cookies

代码语言:python
代码运行次数:0
复制
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

服务端接收客户端传入的Cookie数据

代码语言:python
代码运行次数:0
复制
@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,并发送给服务器:

代码语言:shell
复制
curl -b test_cookies -X 'GET' \
'http://127.0.0.1:18081/async_with_cookie' \
-H 'accept: application/json'

服务端的打印日志:

代码语言:python
代码运行次数:0
复制
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
服务端日志
服务端日志

使用 Pydantic Model 定义 Cookie

代码语言:python
代码运行次数:0
复制
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 生成有问题:

Issue

填入测试参数
填入测试参数
错误的执行参数
错误的执行参数

使用 Curl 正确执行:

多个键值对
多个键值对

Request 参数与显式的 Path、Query、Body、Cookie、Header 参数的使用场景划分

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.

推荐使用显式的 Path、Query、Body、Cookie、Header 参数的原因

  • Type safety: FastAPI performs type checking and conversion automatically.
  • Validation: Pydantic models used for body parameters provide built-in validation.
  • Auto-documentation: FastAPI generates OpenAPI (Swagger) documentation automatically based on your function signatures.
  • Performance: FastAPI optimizes the parameter extraction process.
  • Clarity: The function signature clearly shows what parameters are expected.

适合使用 Request 的场景

Summary

  • When you need to access raw request data.
  • For debugging or logging purposes.
  • When building middleware or plugins that need to inspect the raw request.
  • When dealing with non-standard or dynamic parameter structures.

Dynamic or Unknown Parameter Structure

When you're dealing with requests where the structure or names of parameters are not known in advance or can vary significantly.

代码语言:python
代码运行次数:0
复制
@app.post("/dynamic")
async def handle_dynamic(request: Request):
    data = await request.json()

Raw Data Access

When you need access to the raw request data, such as for custom parsing or when dealing with non-standard content types.

代码语言:python
代码运行次数:0
复制
@app.post("/raw")
async def handle_raw(request: Request):
    raw_body = await request.body()

Custom Middleware or Plugins

When building middleware or plugins that need to inspect or modify the raw request.

代码语言:python
代码运行次数:0
复制
@app.middleware("http")
async def custom_middleware(request: Request, call_next):
    # Inspect or modify request
    response = await call_next(request)
    return response

Debugging or Logging

When you need to log or debug the entire request, including headers, body, and other metadata.

代码语言:python
代码运行次数:0
复制
@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}")

Working with WebSockets

When handling WebSocket connections, you often need the Request object for the initial connection setup.

代码语言:python
代码运行次数:0
复制
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()

Accessing Multiple Aspects of the Request

When you need to access various parts of the request that don't fit neatly into the standard parameter types.

代码语言:python
代码运行次数:0
复制
@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

File Uploads with Additional Metadata

When handling file uploads where you need access to both the file and additional form data.

代码语言:python
代码运行次数:0
复制
@app.post("/upload")
async def upload_file(request: Request):
    form = await request.form()
    file = form["file"]
    metadata = form["metadata"]

Custom Content Types:

When dealing with custom or non-standard content types that FastAPI doesn't handle out of the box.

代码语言:python
代码运行次数:0
复制
@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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在FastAPI中使用Cookie
    • 示例代码
      • 服务器向客户端写入Cookie数据
      • 服务端接收客户端传入的Cookie数据
    • 使用 Pydantic Model 定义 Cookie
  • Request 参数与显式的 Path、Query、Body、Cookie、Header 参数的使用场景划分
    • 推荐使用显式的 Path、Query、Body、Cookie、Header 参数的原因
    • 适合使用 Request 的场景
      • Summary
      • Dynamic or Unknown Parameter Structure
      • Raw Data Access
      • Custom Middleware or Plugins
      • Debugging or Logging
      • Working with WebSockets
      • Accessing Multiple Aspects of the Request
      • File Uploads with Additional Metadata
      • Custom Content Types:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档