news 2026/9/7 1:46:56

FastAPI 响应类参考:fastapi.responses 中 FileResponse、StreamingResponse 等九类 Response 详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastAPI 响应类参考:fastapi.responses 中 FileResponse、StreamingResponse 等九类 Response 详解

FastAPI 响应类参考:fastapi.responses 中 FileResponse、StreamingResponse 等九类 Response 详解

【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi

本文是fastapi.responses模块的完整参考指南,系统梳理 FastAPI 提供的全部 9 个响应类(ResponseJSONResponseHTMLResponsePlainTextResponseFileResponseStreamingResponseRedirectResponseUJSONResponseORJSONResponse)、它们的成员属性与使用方式。读完本文,你能够直接在路径操作函数中返回自定义响应、通过response_class/default_response_class控制响应行为,并理解 FastAPI 自研 JSON 响应类被弃用后 Pydantic 序列化的性能替代方案。

fastapi.responses导入响应类

FastAPI 允许在路径操作函数中直接创建并返回响应类实例,以此覆盖默认的 JSON 序列化行为。所有可用的响应类都可以直接从fastapi.responses导入:

from fastapi.responses import ( FileResponse, HTMLResponse, JSONResponse, ORJSONResponse, PlainTextResponse, RedirectResponse, Response, StreamingResponse, UJSONResponse, )

从源码结构看,fastapi/responses.pyFileResponseHTMLResponseJSONResponsePlainTextResponseRedirectResponseResponseStreamingResponse这 7 个类全部是从 Starlette 直接重导出的(from starlette.responses import ...),FastAPI 只是将它们以fastapi.responses的名义再次暴露,方便开发者统一从 FastAPI 包中导入;而UJSONResponseORJSONResponse则是 FastAPI 自己定义的类,目前已被弃用。

已弃用的 FastAPI 响应类:UJSONResponse 与 ORJSONResponse

fastapi.responses中曾有 2 个 FastAPI 自研的响应类,设计初衷是优化 JSON 序列化性能:

  • UJSONResponse—— 使用ujson库把数据序列化为 JSON。
  • ORJSONResponse—— 使用orjson库把数据序列化为 JSON。

这两个类如今均已弃用。当前更推荐的做法是声明响应模型(Response Model)/ 返回类型,让 FastAPI 通过 Pydantic 把数据直接序列化为 JSON 字节,Pydantic 在 Rust 层完成序列化,性能优于这些自定义 JSON 响应类,且不再需要安装额外的第三方库。

源码中的弃用证据

在 fastapi/responses.py 中可以看到:

  • 两个类都使用了typing_extensions.deprecated装饰器,弃用消息为 "FastAPI now serializes data directly to JSON bytes via Pydantic when a return type or response model is set, which is faster and doesn't need a custom response class",警告类别是FastAPIDeprecationWarning
  • UJSONResponse.render()的实现是ujson.dumps(content, ensure_ascii=False).encode("utf-8")
  • ORJSONResponse.render()的实现是orjson.dumps(content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY),即同时启用了「允许非字符串键」与「序列化 NumPy 数据」两个 orjson 选项;
  • 两个类都依赖可选依赖:ujsonorjson不包含在 FastAPI 中,需要单独安装(例如pip install ujson/pip install orjson)。如果对应库未安装,模块加载时静默置为None,真正调用render()时才会触发assert ... is not None断言失败。

tests/test_orjson_response_class.py 用pytest.importorskip("orjson")守卫了可选依赖,并通过warnings.catch_warnings()忽略FastAPIDeprecationWarning后,验证了ORJSONResponse对非字符串键(SQLAlchemy 的quoted_name对象、整数键1)也能正确序列化为{"msg": "Hello World", "1": 1}。这正是OPT_NON_STR_KEYS选项在实际中的体现。

两个弃用响应类的成员

弃用响应类继承自JSONResponse,其参考成员包括:

  • charset—— 响应字符集
  • status_code—— HTTP 状态码
  • media_type—— 媒体类型(两者均为application/json
  • body—— 响应体
  • background—— 后台任务(Background Task)
  • raw_headers—— 原始请求头字节
  • render—— 把内容渲染为bytes的序列化方法(两者各自重写的核心)
  • init_headers—— 响应头初始化
  • headers—— 响应头
  • set_cookie—— 设置 Cookie
  • delete_cookie—— 删除 Cookie

docs_src/custom_response/tutorial001_py310.py 展示了UJSONResponse作为response_class的传统用法(现已不推荐):

from fastapi import FastAPI from fastapi.responses import UJSONResponse app = FastAPI() @app.get("/items/", response_class=UJSONResponse) async def read_items(): return [{"item_id": "Foo"}]

Starlette 响应类参考

除 2 个弃用类外,fastapi.responses提供的其余响应类直接来自 Starlette。它们都继承自Response,可以逐个查看其成员。

Response(基类)

所有其他响应类的基类,可以直接返回。参考成员:

  • charset—— 响应字符集
  • status_code——int型 HTTP 状态码
  • media_type—— 媒体类型字符串,如"text/html"
  • body—— 响应体
  • background—— 后台任务
  • raw_headers—— 原始响应头字节
  • render—— 序列化钩子,返回bytes
  • init_headers—— 响应头初始化
  • headers—— 响应头
  • set_cookie/delete_cookie—— Cookie 操作

直接返回Response的构造参数包括:contentstrbytes)、status_codeint)、headers(字符串字典)、media_type(如"text/html")。FastAPI(实际是 Starlette)会自动附加Content-Length头,并基于media_type附加Content-Type头(文本类型会追加 charset)。

FileResponse

以流式方式异步发送文件作为响应。除Response的全部成员外,额外提供:

  • chunk_size—— 分块读取文件的大小参数

构造参数与别的响应类不同:

  • path—— 要流式传输的文件路径
  • headers—— 自定义响应头字典
  • media_type—— 媒体类型字符串;未设置时会根据文件名/路径自动推断
  • filename—— 若设置,会写入响应的Content-Disposition

文件响应会自动包含Content-LengthLast-ModifiedETag头。

from fastapi import FastAPI from fastapi.responses import FileResponse some_file_path = "large-video-file.mp4" app = FastAPI() @app.get("/") async def main(): return FileResponse(some_file_path)

也可以放在response_class参数中,此时路径操作函数直接返回文件路径字符串即可(见 docs_src/custom_response/tutorial009b_py310.py)。

HTMLResponse

接收文本或字节,返回 HTML 响应(text/html)。

PlainTextResponse

接收文本或字节,返回纯文本响应(text/plain)。

JSONResponse

接收任意数据,返回application/json编码响应,是 FastAPI 的默认响应类型。

RedirectResponse

返回 HTTP 重定向,默认使用307(Temporary Redirect)状态码。

StreamingResponse

接收异步生成器或普通生成器/迭代器(含yield的函数),流式发送响应体。除Response全部成员外额外提供:

  • body_iterator—— 提供响应体字节的迭代器
import anyio from fastapi import FastAPI from fastapi.responses import StreamingResponse app = FastAPI() async def fake_video_streamer(): for i in range(10): yield b"some fake video bytes" await anyio.sleep(0) @app.get("/") async def main(): return StreamingResponse(fake_video_streamer())

技术细节:异步任务只有在到达await时才能被取消;生成器中如果没有await,即使请求取消后生成器也可能继续运行。上面的示例特意加入了await anyio.sleep(0)给事件循环一个处理取消的机会——对大型或无限流式响应这一点尤为关键。

更推荐使用 FastAPI 内置的流式返回风格(见 docs_src/stream_data 与 docs_src/stream_json_lines 相关文档),它更便捷且会自动在幕后处理取消逻辑。

实战:三种使用方式

方式一:直接返回Response实例

在路径操作函数中直接return一个响应实例(如RedirectResponse):

from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get("/typer") async def redirect_typer(): return RedirectResponse("https://typer.tiangolo.com")

注意:直接返回的Response不会写入 OpenAPI 文档(例如Content-Type不会被记录),也不会显示在自动交互文档中;实际的Content-Type、状态码等来自你返回的Response对象本身。

方式二:response_class参数

在路径操作装饰器中声明response_class,函数只需返回原始数据(字符串、字典等),FastAPI 会把数据装进该响应类:

@app.get("/", response_class=FileResponse) async def main(): return some_file_path

response_class同时决定了响应在 OpenAPI 中的媒体类型。如果声明的响应类没有媒体类型,FastAPI 会认为该响应没有内容,从而不在 OpenAPI 文档中记录响应格式。

方式三:default_response_class全局默认

创建FastAPI实例或APIRouter时,可以用default_response_class指定默认响应类,单个路径操作仍可用response_class覆盖:

from fastapi import FastAPI from fastapi.responses import HTMLResponse app = FastAPI(default_response_class=HTMLResponse) @app.get("/items/") async def read_items(): return "<h1>Items</h1><p>This is a list of items.</p>"

自定义响应类:重写render()

继承Response即可创建自定义响应类,核心是重写render(content)方法并返回bytes(见 docs_src/custom_response/tutorial009c_py310.py):

from typing import Any import orjson from fastapi import FastAPI, Response app = FastAPI() class CustomORJSONResponse(Response): media_type = "application/json" def render(self, content: Any) -> bytes: assert orjson is not None, "orjson must be installed" return orjson.dumps(content, option=orjson.OPT_INDENT_2) @app.get("/", response_class=CustomORJSONResponse) async def main(): return {"message": "Hello World"}

这个响应会把{"message": "Hello World"}渲染为带两空格缩进的格式化 JSON。

性能提示:Response Model 优于自定义 JSON 响应

如果你的目标是 JSON 序列化性能,声明响应模型比写orjson自定义响应更优:FastAPI 会用 Pydantic 直接把数据序列化为 JSON 字节,省去了jsonable_encoder这类中间转换;而 Pydantic 底层使用的 Rust 序列化机制与orjson同源,因此响应模型已经能获得最佳性能——这也是UJSONResponse/ORJSONResponse被弃用的根本原因。若确实需要response_class且媒体类型为application/json,返回数据会先经过response_model过滤、再由jsonable_encoder转换、最后由标准 JSON 库序列化为字节,性能不如纯 Pydantic 路径。

小结

  • fastapi.responses提供 9 个响应类:7 个重导出自 Starlette(ResponseJSONResponseHTMLResponsePlainTextResponseFileResponseStreamingResponseRedirectResponse),2 个 FastAPI 自研且已弃用(UJSONResponseORJSONResponse,见 fastapi/responses.py);
  • 所有响应类共享charsetstatus_codemedia_typebodybackgroundraw_headersrenderinit_headersheadersset_cookiedelete_cookie等成员;FileResponse额外提供chunk_sizeStreamingResponse额外提供body_iterator
  • 使用上支持三种路径:直接返回Response实例、装饰器response_class参数、应用级default_response_class
  • JSON 性能优化请优先采用响应模型/返回类型,而不是自定义 JSON 响应类。

【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 1:45:31

滑环与无线遥测信号质量实测对比:旋转机械测试到底选谁

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 1:44:20

STM32实战:Y01-3IN1空气质量传感器与OLED显示完整教程

1. 项目到底要做什么&#xff1a;Y01-3IN1和OLED的搭配逻辑手里有一块Y01-3IN1空气质量模块&#xff0c;又有一块0.96寸OLED&#xff0c;想把两者接到STM32上&#xff0c;让屏幕实时显示PM2.5、温湿度和甲醛浓度。这个需求听起来简单&#xff0c;但实际做的时候&#xff0c;串口…

作者头像 李华
网站建设 2026/9/7 1:43:50

大模型蒸馏实战指南:从原理到部署的关键技术解析

简介&#xff1a;大模型&#xff08;LLMs&#xff09;蒸馏面.pdf 是一份聚焦大模型知识蒸馏的面试梳理笔记&#xff0c;主要面向备战 AI 算法岗位的求职者&#xff0c;以及对模型压缩、高效部署感兴趣的工程师和研究者。全篇以问答形式整理知识蒸馏的核心脉络&#xff1a;教师-…

作者头像 李华
网站建设 2026/9/7 1:42:37

通信技术基础课件全解析:知识框架与PPTX使用指南

简介&#xff1a;《通信技术基础&#xff08;第二版&#xff09;》全书电子讲义以PPT课件形式&#xff0c;面向通信技术初学者、高职院校师生及备考人员&#xff0c;系统讲解通信系统从信号产生、传输到接收的核心知识&#xff0c;帮助读者理清模拟通信与数字通信、基带传输与频…

作者头像 李华
网站建设 2026/9/7 1:42:34

图像镜像处理工具部署与测试全攻略:从环境配置到批量应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 1:42:13

Java选择题PDF高效刷法:从知识自检到面试迁移

简介&#xff1a;面向Java初学者和备考者的一份PDF练习题&#xff0c;内含100道选择题及答案解析&#xff0c;内容覆盖标识符规则、源文件命名、整型数据类型内存占用、类作为类型定义与数据封装机制、对象创建初始化、方法参数按值/引用传递、单继承特性、多线程并行机制、Cha…

作者头像 李华