From 8af0b136b1718625f1a371831b532350e4c6cc31 Mon Sep 17 00:00:00 2001 From: Ikkyu <31848542+RunningIkkyu@users.noreply.github.com> Date: Thu, 26 Nov 2020 01:27:34 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translation=20fo?= =?UTF-8?q?r=20Advanced=20-=20Custom=20Response=20(#1459)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sebastián Ramírez --- docs/zh/docs/advanced/custom-response.md | 212 +++++++++++++++++++++++ docs/zh/mkdocs.yml | 1 + 2 files changed, 213 insertions(+) create mode 100644 docs/zh/docs/advanced/custom-response.md diff --git a/docs/zh/docs/advanced/custom-response.md b/docs/zh/docs/advanced/custom-response.md new file mode 100644 index 000000000..b67ef6c2e --- /dev/null +++ b/docs/zh/docs/advanced/custom-response.md @@ -0,0 +1,212 @@ +# 自定义响应 - HTML,流,文件和其他 + +**FastAPI** 默认会使用 `JSONResponse` 返回响应。 + +你可以通过直接返回 `Response` 来重载它,参见 [直接返回响应](response-directly.md){.internal-link target=_blank}。 + +但如果你直接返回 `Response`,返回数据不会自动转换,也不会自动生成文档(例如,在 HTTP 头 `Content-Type` 中包含特定的「媒体类型」作为生成的 OpenAPI 的一部分)。 + +你还可以在 *路径操作装饰器* 中声明你想用的 `Response`。 + +你从 *路径操作函数* 中返回的内容将被放在该 `Response` 中。 + +并且如果该 `Response` 有一个 JSON 媒体类型(`application/json`),比如使用 `JSONResponse` 或者 `UJSONResponse` 的时候,返回的数据将使用你在路径操作装饰器中声明的任何 Pydantic 的 `response_model` 自动转换(和过滤)。 + +!!! note "说明" + 如果你使用不带有任何媒体类型的响应类,FastAPI 认为你的响应没有任何内容,所以不会在生成的OpenAPI文档中记录响应格式。 + +## 使用 `ORJSONResponse` + +例如,如果你需要压榨性能,你可以安装并使用 `orjson` 并将响应设置为 `ORJSONResponse`。 + +导入你想要使用的 `Response` 类(子类)然后在 *路径操作装饰器* 中声明它。 + +```Python hl_lines="2 7" +{!../../../docs_src/custom_response/tutorial001b.py!} +``` + +!!! info "提示" + 参数 `response_class` 也会用来定义响应的「媒体类型」。 + + 在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `application/json`。 + + 并且在 OpenAPI 文档中也会这样记录。 + +!!! tip "小贴士" + `ORJSONResponse` 目前只在 FastAPI 中可用,而在 Starlette 中不可用。 + + + +## HTML 响应 + +使用 `HTMLResponse` 来从 **FastAPI** 中直接返回一个 HTML 响应。 + +* 导入 `HTMLResponse`。 +* 将 `HTMLResponse` 作为你的 *路径操作* 的 `response_class` 参数传入。 + +```Python hl_lines="2 7" +{!../../../docs_src/custom_response/tutorial002.py!} +``` + +!!! info "提示" + 参数 `response_class` 也会用来定义响应的「媒体类型」。 + + 在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `text/html`。 + + 并且在 OpenAPI 文档中也会这样记录。 + +### 返回一个 `Response` + +正如你在 [直接返回响应](response-directly.md){.internal-link target=_blank} 中了解到的,你也可以通过直接返回响应在 *路径操作* 中直接重载响应。 + +和上面一样的例子,返回一个 `HTMLResponse` 看起来可能是这样: + +```Python hl_lines="2 7 19" +{!../../../docs_src/custom_response/tutorial003.py!} +``` + +!!! warning "警告" + *路径操作函数* 直接返回的 `Response` 不会被 OpenAPI 的文档记录(比如,`Content-Type` 不会被文档记录),并且在自动化交互文档中也是不可见的。 + +!!! info "提示" + 当然,实际的 `Content-Type` 头,状态码等等,将来自于你返回的 `Response` 对象。 + +### OpenAPI 中的文档和重载 `Response` + +如果你想要在函数内重载响应,但是同时在 OpenAPI 中文档化「媒体类型」,你可以使用 `response_class` 参数并返回一个 `Response` 对象。 + +接着 `response_class` 参数只会被用来文档化 OpenAPI 的 *路径操作*,你的 `Response` 用来返回响应。 + +### 直接返回 `HTMLResponse` + +比如像这样: + +```Python hl_lines="7 23 21" +{!../../../docs_src/custom_response/tutorial004.py!} +``` + +在这个例子中,函数 `generate_html_response()` 已经生成并返回 `Response` 对象而不是在 `str` 中返回 HTML。 + +通过返回函数 `generate_html_response()` 的调用结果,你已经返回一个重载 **FastAPI** 默认行为的 `Response` 对象, + +但如果你在 `response_class` 中也传入了 `HTMLResponse`,**FastAPI** 会知道如何在 OpenAPI 和交互式文档中使用 `text/html` 将其文档化为 HTML。 + + + +## 可用响应 + +这里有一些可用的响应。 + +要记得你可以使用 `Response` 来返回任何其他东西,甚至创建一个自定义的子类。 + +!!! note "技术细节" + 你也可以使用 `from starlette.responses import HTMLResponse`。 + + **FastAPI** 提供了同 `fastapi.responses` 相同的 `starlette.responses` 只是为了方便开发者。但大多数可用的响应都直接来自 Starlette。 + +### `Response` + +其他全部的响应都继承自主类 `Response`。 + +你可以直接返回它。 + +`Response` 类接受如下参数: + +* `content` - 一个 `str` 或者 `bytes`。 +* `status_code` - 一个 `int` 类型的 HTTP 状态码。 +* `headers` - 一个由字符串组成的 `dict`。 +* `media_type` - 一个给出媒体类型的 `str`,比如 `"text/html"`。 + +FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它还将包含一个基于 media_type 的 Content-Type 头,并为文本类型附加一个字符集。 + + +```Python hl_lines="1 18" +{!../../../docs_src/response_directly/tutorial002.py!} +``` + +### `HTMLResponse` + +如上文所述,接受文本或字节并返回 HTML 响应。 + +### `PlainTextResponse` + +接受文本或字节并返回纯文本响应。 + +```Python hl_lines="2 7 9" +{!../../../docs_src/custom_response/tutorial005.py!} +``` + +### `JSONResponse` + +接受数据并返回一个 `application/json` 编码的响应。 + +如上文所述,这是 **FastAPI** 中使用的默认响应。 + +### `ORJSONResponse` + +如上文所述,`ORJSONResponse` 是一个使用 `orjson` 的快速的可选 JSON 响应。 + + +### `UJSONResponse` + +`UJSONResponse` 是一个使用 `ujson` 的可选 JSON 响应。 + +!!! warning "警告" + 在处理某些边缘情况时,`ujson` 不如 Python 的内置实现那么谨慎。 + +```Python hl_lines="2 7" +{!../../../docs_src/custom_response/tutorial001.py!} +``` + +!!! tip "小贴士" + `ORJSONResponse` 可能是一个更快的选择。 + +### `RedirectResponse` + +返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。 + +```Python hl_lines="2 9" +{!../../../docs_src/custom_response/tutorial006.py!} +``` + +### `StreamingResponse` + +采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。 + +```Python hl_lines="2 14" +{!../../../docs_src/custom_response/tutorial007.py!} +``` + +#### 对类似文件的对象使用 `StreamingResponse` + +如果您有类似文件的对象(例如,由 `open()` 返回的对象),则可以在 `StreamingResponse` 中将其返回。 + +包括许多与云存储,视频处理等交互的库。 + +```Python hl_lines="2 10 11" +{!../../../docs_src/custom_response/tutorial008.py!} +``` + +!!! tip "小贴士" + 注意在这里,因为我们使用的是不支持 `async` 和 `await` 的标准 `open()`,我们使用普通的 `def` 声明了路径操作。 + +### `FileResponse` + +异步传输文件作为响应。 + +与其他响应类型相比,接受不同的参数集进行实例化: + +* `path` - 要流式传输的文件的文件路径。 +* `headers` - 任何自定义响应头,传入字典类型。 +* `media_type` - 给出媒体类型的字符串。如果未设置,则文件名或路径将用于推断媒体类型。 +* `filename` - 如果给出,它将包含在响应的 `Content-Disposition` 中。 + +文件响应将包含适当的 `Content-Length`,`Last-Modified` 和 `ETag` 的响应头。 + +```Python hl_lines="2 10" +{!../../../docs_src/custom_response/tutorial009.py!} +``` + +## 额外文档 + +您还可以使用 `response` 在 OpenAPI 中声明媒体类型和许多其他详细信息:[OpenAPI 中的额外文档](additional-responses.md){.internal-link target=_blank}。 diff --git a/docs/zh/mkdocs.yml b/docs/zh/mkdocs.yml index d279c4030..fa040f7c2 100644 --- a/docs/zh/mkdocs.yml +++ b/docs/zh/mkdocs.yml @@ -65,6 +65,7 @@ nav: - advanced/path-operation-advanced-configuration.md - advanced/additional-status-codes.md - advanced/response-directly.md + - advanced/custom-response.md - deployment.md - contributing.md - help-fastapi.md