FastAPI - 如何在中间件中获取响应正文

2023-12-14

有没有办法在中间件中获取响应内容? 以下代码是从here.

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()

    response = await call_next(request)

    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

The responsebody 是一个迭代器,一旦迭代完成,就无法再次迭代。因此,您要么必须将所有迭代数据保存到list (or bytes变量)并使用它返回自定义Response,或者再次启动迭代器。下面的选项演示了这两种方法。如果您想获得request身体里面的middleware另外,请看一下这个答案.

Option 1

将数据保存到list并使用iterate_in_threadpool再次初始化迭代器,如上所述here- 这是什么StreamingResponse使用,如图here.

from starlette.concurrency import iterate_in_threadpool

@app.middleware("http")
async def some_middleware(request: Request, call_next):
    response = await call_next(request)
    response_body = [chunk async for chunk in response.body_iterator]
    response.body_iterator = iterate_in_threadpool(iter(response_body))
    print(f"response_body={response_body[0].decode()}")
    return response

Note 1:如果您的代码使用StreamingResponse, response_body[0]只会返回第一个chunk of the response。为了得到整个responsebody,您应该加入该字节(块)列表,如下所示(.decode()返回的字符串表示形式bytes目的):

print(f"response_body={(b''.join(response_body)).decode()}")

Note 2:如果你有一个StreamingResponse流式传输不适合服务器 RAM 的主体(例如 30GB 的响应),您可能会在迭代时遇到内存错误response.body_iterator(这适用于本答案中列出的两个选项),unless你循环遍历response.body_iterator(如选项 2 所示),但不是将块存储在内存变量中,而是将其存储在磁盘上的某个位置。然而,您随后需要从该磁盘位置检索整个响应数据并将其加载到 RAM 中,以便将其发送回客户端(这可能会进一步延长响应客户端的延迟),在这种情况下,您可以将内容分块加载到 RAM 中并使用StreamingResponse,类似于已经证明的here, here, 也here, here and here(在选项 1 中,您可以将迭代器/生成器函数传递给iterate_in_threadpool)。但是,我不建议遵循这种方法,而是让此类端点返回从中间件中排除的大型流响应,如中所述这个答案.

Option 2

下面演示了另一种方法,其中响应正文存储在bytes对象(而不是列表,如上所示),用于返回自定义Response直接(连同status_code, headers and media_type原始响应)。

@app.middleware("http")
async def some_middleware(request: Request, call_next):
    response = await call_next(request)
    response_body = b""
    async for chunk in response.body_iterator:
        response_body += chunk
    print(f"response_body={response_body.decode()}")
    return Response(content=response_body, status_code=response.status_code, 
        headers=dict(response.headers), media_type=response.media_type)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastAPI - 如何在中间件中获取响应正文 的相关文章

随机推荐

  • 双向重复测量ANOVA python函数

    预先感谢您的任何答复 我想在 python 中进行 2 路重复测量方差分析 其中一个 IV 有 5 个级别 其他 4 个级别 有一个 DV 我尝试查看 scipy 文档和一些在线博客 但似乎找不到任何东西 您可以使用rm anovaPino
  • 我希望能够通过网络从 BIOS 提取错误日志

    我希望能够通过网络从 BIOS 提取错误日志 查看 MSDN 中的 Win32 BIOS 我没有看到任何定义错误日志的内容 很乐意在 C 中使用 WMI 来完成此操作 但我愿意接受建议 是否可以 Win32 BIOS 没有包含 BIOS 错
  • 为什么在 PHP 中使用 ORM?

    最近开始学习ORM 突然想到一个问题 PHP 应用程序主要使用 MySql 和 Sqlite 几乎所有 PHP 服务器都安装了它们 那么是否值得在 PHP 中使用 ORM 来独立于数据库呢 性能怎么样 数据库独立性并不是使用 ORM 的主要
  • Jquery 自动完成 - 无结果消息

    我希望自动完成在下拉列表中显示 无结果 如果没有找到结果 则列出 我的情况就像 JQuery 默认示例 function var availableTags ActionScript AppleScript Asp BASIC C C Cl
  • R Shiny:Vtree 图未使用 Shiny 渲染

    如何在闪亮中使用 vtree 包 尝试从服务器端渲染时 没有出现所需的绘图 我的代码 library shiny library vtree Define UI ui lt pageWithSidebar App title headerP
  • ColdFusion、MS Word 文档和希腊字符

    我正在尝试从数据库动态构建 Word 文档 我使用 CFC 进行查询处理 我的努力是成功的 但我只能复制英语文档 但是 我的应用程序使用希腊语 当我尝试构建包含希腊字符的文档时 输出如下所示 我尝试了很多事情但没有任何效果 这里奇怪的是 当
  • 以天:小时:分钟:秒格式计算 SQL 中的 DateDiff

    我目前正在使用 SQL 脚本来计算两个日期之间的差异 这将为我提供 DD HH MI SEC 格式的结果 例子 日期 1 2012 年 7 月 30 日 下午 4 00 日期 2 2012 年 5 月 4 日上午 10 31 结果应该是 8
  • 当 puppet-rspec 存在时,为什么我会收到“类不存在”?

    我设置了一个新的木偶demo模块具有以下内容Gemfile当我运行一个简单的 puppet rspec 测试时 它按预期工作 Gemfile source https rubygems org if puppetversion ENV PU
  • 如何通过纯javascript中的每次点击来选择循环中下一个特定数量的元素?

    我试图为每次单击 下一步 按钮选择接下来的 3 个项目 nextElementSiblings 项目长度为 14 直到项目 12 为止它都工作正常 在项目 12 之后 它检查接下来的 3 个项目 但循环中只剩下 2 个项目 十三个 13 十
  • C++ 中重载运算符->

    我有一个智能指针类 我想重载operator gt 提供它是为了方便 这样我就可以直接访问智能指针中包含的类的成员 我正在研究 Boost 在其中实现该运算符的方式shared ptr模板 我注意到他们添加了一个断言 在返回指针之前检查指针
  • 将绘图映射到 FacetGrid 时的图例问题

    我还在seaborn git repo 中提出了一个问题here 然而 我很可能犯了一些基本错误 而不是错误 但我还没有弄清楚 问题 相同的颜色被分配给图例中的两个不同的值 当我扩展到更多仅包含分配给 色调 的值的子集的图形时 如何防止这种
  • 从检测方法调用自己的类时出现 Java NoClassDefFoundError

    我正在开发一套简单的 Java 代理工具包 以帮助我 也希望其他人 排除 Java 应用程序的故障 我想创建的代理之一是 JComponent getToolTipText 方法 只需将鼠标光标悬停在任何 GUI 类上即可快速识别该类 您可
  • Jackson XML:如何将空/空集合序列化为空节点

    我正在使用 Jackson XML 2 8 9 不幸的是我找不到任何方法将空 空集合序列化为空节点 负责序列化为 XML 的方法 protected byte toXml final Collection
  • 将 Base64 编码的图像上传到 Node.js 服务器不起作用

    我正在使用 MEAN io 并且正在尝试上传 Base64 编码的图像 客户端 AngularJS Image we re going to send it out var base64Image files i var file imag
  • 在应用程序商店中转让 iPhone 应用程序的所有权

    我和我的团队有一个应用程序 我们很快就会将其提交到商店 但我们知道我们将在不久的将来将该应用程序出售给另一家公司 有人有将应用程序的所有权转移到另一个帐户的经验吗 具体来说 当我将应用程序出售给另一家公司时 我们如何将应用程序移至他们的帐户
  • 使用交替和分组结构

    最初我想要一个正则表达式来解析月份数字 首先我想出了以下正则表达式 1 9 1 1 012 它匹配任何正数 表示它匹配该数字的高位数字 即 1 gt 1 2 gt 2 9 gt 9 10 gt 1 19 gt 1 20 gt 2 为什么会这
  • 如何在代码中复制 android:editable="false" ?

    在布局中您可以设置EditText小部件不可通过android editable attribute 我怎样才能在代码中做到这一点 我需要做EditText小部件可根据条件进行编辑 editText setFocusable false e
  • 使用 DomDocument 将实体添加到 DOCTYPE

    我正在尝试创建一个类似于这样的 XML 文档
  • 禁用按钮时更改按钮的样式 ( IsEnabled=False )

    我有一个 UWP 问题 当按钮禁用时 IsEnabled False 如何更改按钮的样式 Microsoft added the VisualStateManager known from Silverlight to the Window
  • FastAPI - 如何在中间件中获取响应正文

    有没有办法在中间件中获取响应内容 以下代码是从here app middleware http async def add process time header request Request call next start time t