FastAPI 响应类参考:fastapi.responses 中 FileResponse、StreamingResponse 等九类 Response 详解
本文是 fastapi.responses 模块的完整参考指南,系统梳理 FastAPI 提供的全部 9 个响应类(Response、JSONResponse、HTMLResponse、PlainTextResponse、FileResponse、StreamingResponse、RedirectResponse、UJSONResponse、ORJSONResponse)、它们的成员属性与使用方式。读完本文,你能够直接在路径操作函数中返回自定义响应、通过 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.py 中 FileResponse、HTMLResponse、JSONResponse、PlainTextResponse、RedirectResponse、Response、StreamingResponse 这 7 个类全部是从 Starlette 直接重导出的(from starlette.responses import ...),FastAPI 只是将它们以 fastapi.responses 的名义再次暴露,方便开发者统一从 FastAPI 包中导入;而 UJSONResponse 和 ORJSONResponse 则是 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 选项;- 两个类都依赖可选依赖:
ujson和orjson均不包含在 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—— 设置 Cookiedelete_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—— 序列化钩子,返回bytesinit_headers—— 响应头初始化headers—— 响应头set_cookie/delete_cookie—— Cookie 操作
直接返回 Response 的构造参数包括:content(str 或 bytes)、status_code(int)、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-Length、Last-Modified 和 ETag 头。
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(Response、JSONResponse、HTMLResponse、PlainTextResponse、FileResponse、StreamingResponse、RedirectResponse),2 个 FastAPI 自研且已弃用(UJSONResponse、ORJSONResponse,见 fastapi/responses.py);- 所有响应类共享
charset、status_code、media_type、body、background、raw_headers、render、init_headers、headers、set_cookie、delete_cookie等成员;FileResponse额外提供chunk_size,StreamingResponse额外提供body_iterator; - 使用上支持三种路径:直接返回
Response实例、装饰器response_class参数、应用级default_response_class; - JSON 性能优化请优先采用响应模型/返回类型,而不是自定义 JSON 响应类。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00