You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fastapi-cache时如何同时获取FastAPI请求状态与请求体参数

问题描述

我有一个FastAPI POST接口,接收请求体中的参数,全局通过FastAPI的Depends设置了Request状态值,需要在接口方法中获取该值。

以下代码运行正常:

from pydantic import BaseModel
from fastapi import APIRouter, Request


class MyPydanticValue(BaseModel):
    # some properties here


router = APIRouter()

@router.post("/foo")
def perform_action(
  my_val: MyPydanticValue,
  request: Request
):
  # do something with my_val
  ...

  # and also reference a state value that was set globally elsewhere
  print(request.state.x_some_value) 

FastAPI会自动识别my_val为Pydantic模型并从请求体解析数据。

但添加fastapi-cache的@cache装饰器后出现异常:

@router.post("/foo")
@cache(expire=300)
def perform_action(
  my_val: MyPydanticValue,
  request: Request
):
  # do something with my_val
  ...

  #and also reference a state value that was set globally elsewhere
  print(request.state.x_some_value) 

异常信息:

TypeError: perform_action() got multiple values for argument 'my_val'

根据fastapi-cache文档说明:

The cache decorator injects dependencies for the Request and Response objects, so that it can add cache control headers to the outgoing response, and return a 304 Not Modified response when the incoming request has a matching If-Non-Match header. This only happens if the decorated endpoint doesn't already list these dependencies already.

我本以为自己已经声明了Request参数,缓存装饰器就不会再注入该依赖,但查看源码后发现,fastapi-cache和FastAPI都注入了request参数,导致参数冲突。

想知道哪里操作有误?有没有解决方法?如何在接口函数中同时获取请求状态值并解析请求体中的Pydantic模型?

解决方法

方法1:通过Depends声明Request参数

将直接声明的request: Request改为通过Depends()注入,这样fastapi-cache能正确识别你已声明该依赖,不会重复注入:

from fastapi import Depends, Request

@router.post("/foo")
@cache(expire=300)
def perform_action(
  my_val: MyPydanticValue,
  request: Request = Depends()
):
  # 业务逻辑
  print(request.state.x_some_value)

方法2:关闭装饰器的自动注入(版本兼容)

若你使用的fastapi-cache版本支持,可通过inject_request_response=False参数关闭装饰器自动注入Request/Response的逻辑,避免冲突:

@cache(expire=300, inject_request_response=False)

注意:该参数需确认是否存在于你使用的v0.2.1版本中,若不存在则优先使用方法1。

原理说明

fastapi-cache的装饰器对直接声明的Request参数检测逻辑存在缺陷,无法正确识别已声明的依赖,而通过Depends()声明的依赖能被装饰器正确检测到,从而避免重复注入,解决参数冲突问题。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:10:13