///
-/// info | 信息
+/// note | 注意
`model` 键不是 OpenAPI 的一部分。
///
-/// info | 信息
+/// note | 注意
除非你在 `responses` 参数中明确指定不同的媒体类型,否则 FastAPI 会假设响应与主响应类具有相同的媒体类型(默认是 `application/json`)。
在 0.118.0 中,这一行为被回退为:让 `yield` 之后的退出代码在响应发送之后再执行。
-/// info | 信息
+/// note | 注意
如你在下文所见,这与 0.106.0 之前的行为非常相似,但对若干边界情况做了改进和修复。
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
-/// info | 信息
+/// note | 注意
参数 `response_class` 也会用来定义响应的「媒体类型」。
///
-/// info | 信息
+/// note | 注意
当然,实际的 `Content-Type` 头、状态码等等,将来自于你返回的 `Response` 对象。
这与使用 Pydantic 模型时的工作方式相同。而且底层实际上也是借助 Pydantic 实现的。
-/// info | 信息
+/// note | 注意
请注意,数据类不能完成 Pydantic 模型能做的所有事情。
此处,`shutdown` 事件处理器函数会向文件 `log.txt` 写入一行文本 `"Application shutdown"`。
-/// info | 信息
+/// note | 注意
在 `open()` 函数中,`mode="a"` 指的是“追加”。因此这行文本会添加在文件已有内容之后,不会覆盖之前的内容。
在底层,这部分是 ASGI 技术规范中的 [Lifespan 协议](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)的一部分,定义了称为 `startup` 和 `shutdown` 的事件。
-/// info | 信息
+/// note | 注意
你可以在 [Starlette 的 Lifespan 文档](https://www.starlette.dev/lifespan/) 中阅读更多关于 `lifespan` 处理器的内容。
例如,你可以尝试:
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
-* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
其中一些方案也可能是开源的或提供免费层级,你可以不花钱就先试用。其他商业 SDK 生成器也可在网上找到。🤓
///
-你发送的数据如果不符合要求,会在编辑器中显示内联错误:
+你发送的数据会有**内联错误**:
<img src="/img/tutorial/generate-clients/image04.png">
/// tip | 提示
-注意,不能把路由本身(`invoices_callback_router`)传递给 `callbacks=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。
+注意,不能把路由本身(`invoices_callback_router`)传递给 `callbacks=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。FastAPI 会使用这些路由来生成回调的 OpenAPI 文档。
///
这能让您的用户更轻松地**实现他们的 API** 来接收您的**网络钩子**请求,他们甚至可能能够自动生成一些自己的 API 代码。
-/// info | 信息
+/// note | 注意
网络钩子在 OpenAPI 3.1.0 及以上版本中可用,FastAPI `0.99.0` 及以上版本支持。
您定义的网络钩子将被包含在 `OpenAPI` 的架构中,并出现在自动生成的**文档 UI** 中。
-/// info | 信息
+/// note | 注意
`app.webhooks` 对象实际上只是一个 `APIRouter` ,与您在使用多个文件来构建应用程序时所使用的类型相同。
### 使用 *路径操作函数* 的函数名作为 operationId { #using-the-path-operation-function-name-as-the-operationid }
-如果你想用 API 的函数名作为 `operationId`,你可以遍历所有路径操作,并使用它们的 `APIRoute.name` 重写每个 *路径操作* 的 `operation_id`。
+如果你想用 API 的函数名作为 `operationId`,你可以向 `FastAPI` 传入自定义的 `generate_unique_id_function`。
-你应该在添加了所有 *路径操作* 之后执行此操作。
+该函数会接收每个 `APIRoute`,并返回用于该路径操作的 `operationId`。
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
-
-/// tip
-
-如果你手动调用 `app.openapi()`,你应该在此之前更新 `operationId`。
-
-///
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}
/// warning
如果你声明了 [响应模型](../tutorial/response-model.md),FastAPI 会使用它通过 Pydantic 将数据序列化为 JSON。
如果你没有声明响应模型,**FastAPI** 会使用在 [JSON 兼容编码器](../tutorial/encoder.md) 中阐述的 `jsonable_encoder`。
-ç\84¶å\90\8eï¼\8c**FastAPI** ä¼\9aå\9c¨å\90\8eå\8f°å°\86è¿\99äº\9bå\85¼å®¹ JSON ç\9a\84æ\95°æ\8d®ï¼\88æ¯\94å¦\82å\97å\85¸ï¼\89æ\94¾å\88°ä¸\80个 `JSONResponse` ä¸ï¼\8c该 `JSONResponse` ä¼\9aç\94¨æ\9d¥å\8f\91é\80\81å\93\8dåº\94ç»\99客æ\88·ç«¯。
+ç\84¶å\90\8eï¼\8c**FastAPI** ä¼\9aå°\86å\85¶æ\94¾å\85¥ä¸\80个 `JSONResponse` ä¸。
-ä½\86æ\98¯ä½ å\8f¯ä»¥å\9c¨ä½ ç\9a\84 *è·¯å¾\84æ\93\8dä½\9c* ä¸ç\9b´æ\8e¥è¿\94å\9b\9eä¸\80个 `JSONResponse`。
+ä½ ä¹\9få\8f¯ä»¥ç\9b´æ\8e¥å\88\9b建ä¸\80个 `JSONResponse` å¹¶è¿\94å\9b\9eå®\83。
/// tip | 提示
## 返回 `Response` { #return-a-response }
-äº\8bå®\9eä¸\8aï¼\8cä½ å\8f¯ä»¥è¿\94å\9b\9eä»»æ\84\8f `Response` æ\88\96è\80\85ä»»æ\84\8f `Response` ç\9a\84子类。
+ä½ å\8f¯ä»¥è¿\94å\9b\9eä¸\80个 `Response` æ\88\96å\85¶ä»»æ\84\8f子类。
-/// info | 信息
+/// note | 注意
`JSONResponse` 本身是一个 `Response` 的子类。
* Facebook / Instagram 使用 `instagram_basic`
* Google 使用 `https://www.googleapis.com/auth/drive`
-/// info | 信息
+/// note | 注意
在 OAuth2 中,“作用域”只是一个声明所需特定权限的字符串。
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
-/// info | 技术细节
+/// note | 技术细节
`Security` 实际上是 `Depends` 的子类,它只多了一个我们稍后会看到的参数。
但如果你想流式传输纯二进制数据或字符串,可以按下面的方法操作。
-/// info | 信息
+/// note | 注意
自 FastAPI 0.134.0 起新增。
而且很多情况下,读取它们是一个阻塞操作(可能会阻塞事件循环),因为数据来自磁盘或网络。
-/// info | 信息
+/// note | 注意
上面的示例其实是个例外,因为 `io.BytesIO` 对象已经在内存中,所以读取它不会阻塞。
启用该设置后,缺少 `Content-Type` 头的请求其请求体也会按 JSON 解析,这与旧版本 FastAPI 的行为一致。
-/// info | 信息
+/// note | 注意
此行为和配置在 FastAPI 0.132.0 中新增。
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
-/// info
+/// note | 注意
由于这是一个 WebSocket,抛出 `HTTPException` 并不是很合理,而是抛出 `WebSocketException`。
-您可以使用[规范中定义的有效代码](https://tools.ietf.org/html/rfc6455#section-7.4.1)。
+您可以使用[规范中定义的有效关闭代码](https://tools.ietf.org/html/rfc6455#section-7.4.1)。
///
* "Item ID",用于路径。
* "Token",作为查询参数。
-/// tip
+/// tip | 提示
注意,查询参数 `token` 将由依赖项处理。
Client #1596980209979 left the chat
```
-/// tip
+/// tip | 提示
上面的应用程序是一个最小和简单的示例,用于演示如何处理和向多个 WebSocket 连接广播消息。
但请记住,由于所有内容都在内存中以单个列表的形式处理,因此它只能在进程运行时工作,并且只能使用单个进程。
-å¦\82æ\9e\9cæ\82¨é\9c\80è¦\81ä¸\8e FastAPI é\9b\86æ\88\90æ\9b´ç®\80å\8d\95ä½\86æ\9b´å¼ºå¤§ç\9a\84å\8a\9fè\83½ï¼\8cæ\94¯æ\8c\81 Redisã\80\81PostgreSQL æ\88\96å\85¶ä»\96å\8a\9fè\83½,请查看 [encode/broadcaster](https://github.com/encode/broadcaster)。
+å¦\82æ\9e\9cæ\82¨é\9c\80è¦\81ä¸\8e FastAPI é\9b\86æ\88\90æ\9b´ç®\80å\8d\95ä½\86æ\9b´å\81¥å£®ç\9a\84æ\96¹æ¡\88ï¼\8cæ\94¯æ\8c\81 Redisã\80\81PostgreSQL æ\88\96å\85¶ä»\96,请查看 [encode/broadcaster](https://github.com/encode/broadcaster)。
///
## 使用 `WSGIMiddleware` { #using-wsgimiddleware }
-/// info | 信息
+/// note | 注意
需要安装 `a2wsgi`,例如使用 `pip install a2wsgi`。
</div>
-/// info | 信息
+/// note | 注意
还有其他格式和工具可以定义并安装包依赖。
如果你有**多个容器**,可能每个容器运行一个**单独进程**(例如在 **Kubernetes** 集群中),那么你可能希望使用一个**单独的容器**来执行**前置步骤**,在一个容器中运行一个进程,**在**启动那些复制的 worker 容器**之前**完成。
-/// info | 信息
+/// note | 注意
如果你使用 Kubernetes,这通常会是一个 [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)。
# FastAPI Cloud { #fastapi-cloud }
-你可以用**一条命令**将你的 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com),如果还没有,去加入候补名单吧。🚀
-
-## 登录 { #login }
-
-请确保你已有 **FastAPI Cloud** 账号(我们已从候补名单向你发出邀请 😉)。
-
-然后登录:
-
-<div class="termy">
-
-```console
-$ fastapi login
-
-You are logged in to FastAPI Cloud 🚀
-```
-
-</div>
-
-## 部署 { #deploy }
-
-现在用**一条命令**部署你的应用:
+你可以用**一条命令**将你的 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com)。🚀
<div class="termy">
</div>
+CLI 会自动检测你的 FastAPI 应用并将其部署到云端。如果你尚未登录,浏览器会自动打开以完成认证流程。
+
就这样!现在你可以通过该 URL 访问你的应用。✨
## 关于 FastAPI Cloud { #about-fastapi-cloud }
* [Hypercorn](https://hypercorn.readthedocs.io/): 与 HTTP/2 和 Trio 等兼容的 ASGI 服务器。
* [Daphne](https://github.com/django/daphne): 为 Django Channels 构建的 ASGI 服务器。
* [Granian](https://github.com/emmett-framework/granian): 基于 Rust 的 HTTP 服务器,专为 Python 应用设计。
-* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit 是一个轻量级且灵活的 Web 应用运行时环境。
## 服务器主机和服务器程序 { #server-machine-and-server-program }
在本章节中,我将向您展示如何使用 `fastapi` 命令或直接使用 `uvicorn` 命令以**多工作进程模式**运行 **Uvicorn**。
-/// info | 信息
+/// note | 注意
如果您正在使用容器,例如 Docker 或 Kubernetes,我将在下一章中告诉您更多相关信息:[容器中的 FastAPI - Docker](docker.md)。
- `openapi_version`:使用的 OpenAPI 规范版本。默认是最新的 `3.1.0`。
- `summary`:API 的简短摘要。
- `description`:API 的描述,可包含 Markdown,并会展示在文档中。
-- `routes`:路由列表,即已注册的每个路径操作。来自 `app.routes`。
+- `routes`:应用的路由,来自 `app.routes`。FastAPI 使用它们来收集已注册的路径操作,包括来自已包含路由器的那些。
-/// info | 信息
+/// tip | 技术细节
+
+`app.routes` 是一个更底层的路由树。它可能包含 FastAPI 在内部用于包含的路由器的候选路由,而不仅仅是最终的 `APIRoute` 对象。
+
+你仍然可以把 `app.routes` 传给 `get_openapi()`。FastAPI 会遍历这棵路由树来收集实际生效的路径操作。
+
+///
+
+/// note | 注意
参数 `summary` 仅在 OpenAPI 3.1.0 及更高版本中可用,FastAPI 0.99.0 及以上版本支持。
你可以把 `.openapi_schema` 属性当作“缓存”,用来存储已生成的架构。
-这样一来,用户每次打开 API 文档时,应用就不必重新生成架构。
+这样一来,应用每次打开 API 文档时就不必重新生成架构。
它只会生成一次,后续请求都会使用同一份缓存的架构。
这种情况下,你可以在 **FastAPI** 中通过参数 `separate_input_output_schemas=False` 禁用该特性。
-/// info | 信息
+/// note | 注意
对 `separate_input_output_schemas` 的支持是在 FastAPI `0.102.0` 中添加的。🤓
### 部署你的应用(可选) { #deploy-your-app-optional }
-你可以选择把 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com),如果还没有的话去加入候补名单吧。🚀
-
-如果你已经有 **FastAPI Cloud** 账号(我们从候补名单邀请了你 😉),你可以用一个命令部署你的应用。
+你可以选择用一条命令将 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com)。🚀
<div class="termy">
</div>
+CLI 会自动检测你的 FastAPI 应用并将其部署到云端。如果你尚未登录,浏览器会打开以完成认证流程。
+
就这样!现在你可以通过该 URL 访问你的应用了。✨
#### 关于 FastAPI Cloud { #about-fastapi-cloud }
/// note | 技术细节
-å®\9eé\99\85ä¸\8aï¼\8cå®\83å°\86å\9c¨å\86\85é\83¨ä¸ºå£°æ\98\8eå\9c¨ `APIRouter` ä¸ç\9a\84æ¯\8f个*è·¯å¾\84æ\93\8dä½\9c*å\88\9b建ä¸\80个*è·¯å¾\84æ\93\8dä½\9c*。
+å½\93å\9c¨ä¸»åº\94ç\94¨ä¸å\8c\85å\90«è·¯ç\94±å\99¨æ\97¶ï¼\8cFastAPI ä¼\9aä¿\9dç\95\99å\8e\9få§\8bç\9a\84 `APIRouter` å\8f\8aå\85¶ `APIRoute` å¤\84äº\8eæ´»å\8a¨ç\8a¶æ\80\81。
-所以,在幕后,它实际上会像所有的东西都是同一个应用程序一样工作。
+这意味着自定义的 `APIRouter` 和 `APIRoute` 子类在被包含之后仍然能够参与工作。
///
包含路由器时,你不必担心性能问题。
-这将花费几微秒时间,并且只会在启动时发生。
+这被设计为轻量级的,并且避免给每个请求增加开销。
因此,它不会影响性能。⚡
---
-`APIRouter` 没有被「挂载」,它们与应用程序的其余部分没有隔离。
+`APIRouter` 并不是「挂载」的,它们并没有和应用程序的其余部分隔离。
-这是因为我们想要在 OpenAPI 模式和用户界面中包含它们的*路径操作*。
+这是因为我们希望在 OpenAPI 模式和用户界面中包含它们的*路径操作*。
-由于我们不能仅仅隔离它们并独立于其余部分来「挂载」它们,因此*路径操作*是被「克隆的」(重新创建),而不是直接包含。
+FastAPI 会保留原始的路由器和路径操作处于活动状态,并在处理请求和生成 OpenAPI 时组合路由器的前缀、依赖项、标签、响应以及其他元数据。
///
router.include_router(other_router)
```
-请确保在你将 `router` 包含到 `FastAPI` 应用程序之前进行此操作,以便 `other_router` 中的*路径操作*也能被包含进来。
+你可以在将 `router` 包含到 `FastAPI` 应用之前或之后执行此操作。FastAPI 仍然会在路由和 OpenAPI 中包含 `other_router` 中的*路径操作*。
+
+同样适用于之后添加到这些路由器的*路径操作*。它们也会通过先前的包含可见。
+
+/// warning | 技术细节
+
+在包含路由器之后,避免直接修改 `router.routes`。FastAPI 将路由器的包含视为「实时」的,因此原始路由器及其路由会继续参与路由和 OpenAPI 生成。
+
+使用文档化的 API(例如路径操作装饰器和 `.include_router()`)来添加路由和路由器。
+
+将 `router.routes` 视为较低层级的路由树,它可以包含路由定义和被包含的路由器;避免把它当作最终路径操作的扁平列表来依赖。
+
+///
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
-/// info | 信息
+/// note | 注意
`Body` 同样具有与 `Query`、`Path` 以及其他后面将看到的类完全相同的额外校验和元数据参数。
但是,如果你希望它期望一个拥有 `item` 键并在值中包含模型内容的 JSON,就像在声明额外的请求体参数时所做的那样,则可以使用一个特殊的 `Body` 参数 `embed`:
```Python
-item: Item = Body(embed=True)
+item: Annotated[Item, Body(embed=True)]
```
比如:
}
```
-/// info | 信息
+/// note | 注意
请注意 `images` 键现在具有一组 image 对象是如何发生的。
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
-/// info | 信息
+/// note | 注意
-请注æ\84\8f `Offer` æ\8b¥æ\9c\89ä¸\80ç»\84 `Item` è\80\8cå\8f\8dè¿\87æ\9d¥ `Item` å\8f\88æ\98¯一个可选的 `Image` 列表是如何发生的。
+请注æ\84\8f `Offer` æ\8b¥æ\9c\89ä¸\80ç»\84 `Item` è\80\8cå\8f\8dè¿\87æ\9d¥ `Item` å\8f\88æ\9c\89一个可选的 `Image` 列表是如何发生的。
///
使用 [Pydantic](https://docs.pydantic.dev/) 模型来声明**请求体**,能充分利用它的功能和优点。
-/// info | 信息
+/// note | 注意
发送数据应使用以下之一:`POST`(最常见)、`PUT`、`DELETE` 或 `PATCH`。
# Cookie 参数模型 { #cookie-parameter-models }
-如果您有一组相关的 **cookie**,您可以创建一个 **Pydantic 模型**来声明它们。🍪
+如果你有一组相关的 **cookie**,你可以创建一个 **Pydantic 模型**来声明它们。🍪
-这将允许您在**多个地方**能够**重用模型**,并且可以一次性声明所有参数的验证方式和元数据。😎
+这将允许你在**多个地方**能够**重用模型**,并且可以一次性声明所有参数的验证方式和元数据。😎
/// note | 注意
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
-**FastAPI** 将从请求中接收到的 **cookie** 中**提取**出**每个字段**的数据,并提供您定义的 Pydantic 模型。
+**FastAPI** 将从请求中接收到的 **cookie** 中**提取**出**每个字段**的数据,并提供你定义的 Pydantic 模型。
## 查看文档 { #check-the-docs }
-您可以在文档 UI 的 `/docs` 中查看定义的 cookie:
+你可以在文档 UI 的 `/docs` 中查看定义的 cookie:
<div class="screenshot">
<img src="/img/tutorial/cookie-param-models/image01.png">
</div>
-/// info | 信息
+/// note | 注意
请记住,由于**浏览器**以特殊方式**处理 cookie**,并在后台进行操作,因此它们**不会**轻易允许 **JavaScript** 访问这些 cookie。
-如果您访问 `/docs` 的 **API 文档 UI**,您将能够查看您*路径操作*的 cookie **文档**。
+如果你访问 `/docs` 的 **API 文档 UI**,你将能够查看你*路径操作*的 cookie **文档**。
-但是即使您**填写数据**并点击“执行”,由于文档界面使用 **JavaScript**,cookie 将不会被发送。而您会看到一条**错误**消息,就好像您没有输入任何值一样。
+但是即使你**填写数据**并点击“执行”,由于文档界面使用 **JavaScript**,cookie 将不会被发送。而你会看到一条**错误**消息,就好像你没有输入任何值一样。
///
## 禁止额外的 Cookie { #forbid-extra-cookies }
-在某些特殊使用情况下(可能并不常见),您可能希望**限制**您想要接收的 cookie。
+在某些特殊使用情况下(可能并不常见),你可能希望**限制**你想要接收的 cookie。
-您的 API 现在可以控制自己的 <dfn title="只是个玩笑,别当真。和 cookie 同意无关,不过连 API 现在都能拒绝可怜的 cookie,挺好玩的。来,吃块小饼干吧。🍪">cookie 同意</dfn>。🤪🍪
+你的 API 现在可以控制自己的 <dfn title="只是个玩笑,别当真。和 cookie 同意无关,不过连 API 现在都能拒绝可怜的 cookie,挺好玩的。来,吃块小饼干吧。🍪">cookie 同意</dfn>。🤪🍪
-您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
+你可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
如果客户端尝试发送一些**额外的 cookie**,他们将收到**错误**响应。
-可怜的 cookie 通知条,费尽心思为了获得您的同意,却被<dfn title="又是个玩笑,别理我。给你的小饼干配点咖啡吧。☕">API 拒绝了</dfn>。🍪
+可怜的 cookie 通知条,费尽心思为了获得你的同意,却被<dfn title="又是个玩笑,别理我。给你的小饼干配点咖啡吧。☕">API 拒绝了</dfn>。🍪
例如,如果客户端尝试发送一个值为 `good-list-please` 的 `santa_tracker` cookie,客户端将收到一个**错误**响应,告知他们 `santa_tracker` <dfn title="圣诞老人不赞成没有小饼干。🎅 好吧,不再讲 cookie 的笑话了。">cookie 是不允许的</dfn>:
## 总结 { #summary }
-您可以使用 **Pydantic 模型**在 **FastAPI** 中声明 <dfn title="临走前再吃一块小饼干吧。🍪">**cookie**</dfn>。😎
+你可以使用 **Pydantic 模型**在 **FastAPI** 中声明 <dfn title="临走前再吃一块小饼干吧。🍪">**cookie**</dfn>。😎
声明 `Cookie` 参数的方式与声明 `Query` 和 `Path` 参数相同。
-第一个值是默认值,还可以传递所有验证参数或注释参数:
+你可以定义默认值,以及所有额外的验证或注解参数:
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
///
-/// info | 信息
+/// note | 注意
必须使用 `Cookie` 声明 cookie 参数,否则该参数会被解释为查询参数。
///
-/// info | 信息
+/// note | 注意
请注意,由于**浏览器会以特殊方式并在幕后处理 cookies**,它们**不会**轻易允许**JavaScript**访问它们。
那么文件中由 Python 自动创建的内部变量 `__name__`,会将字符串 `"__main__"` 作为值。
-所以,下面这部分代码才会运行:
+所以,这一段:
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
+会运行。
+
---
如果你是导入这个模块(文件)就不会这样。
在这种情况下,`myapp.py` 内部的自动变量不会有值为 `"__main__"` 的变量 `__name__`。
-所以,下面这一行不会被执行:
+所以,这一行:
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
-/// info | 信息
+不会被执行。
+
+/// note | 注意
更多信息请检查 [Python 官方文档](https://docs.python.org/3/library/__main__.html).
///
-/// info | 信息
+/// note | 注意
本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。
end
```
-/// info | 信息
+/// note | 注意
只会向客户端发送**一次响应**。它可能是某个错误响应,或者是来自 *路径操作* 的响应。
然后它只需返回一个包含这些值的 `dict`。
-/// info | 信息
+/// note | 注意
FastAPI 在 0.95.0 版本中新增了对 `Annotated` 的支持(并开始推荐使用)。
这样,你只需编写一次共享代码,**FastAPI** 会在你的*路径操作*中为你调用它。
-/// check | 检查
+/// tip | 提示
注意,无需创建专门的类并传给 **FastAPI** 去“注册”之类的操作。
<img src="/img/tutorial/dependencies/image01.png">
-## ç®\80单用法 { #simple-usage }
+## ç°¡单用法 { #simple-usage }
观察一下就会发现,只要*路径*和*操作*匹配,就会使用声明的*路径操作函数*。随后,**FastAPI** 会用正确的参数调用该函数,并从请求中提取数据。
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
-/// info | 信息
+/// note | 注意
注意,这里在*路径操作函数*中只声明了一个依赖项,即 `query_or_cookie_extractor` 。
from backend.main import app
```
-### `fastapi dev` 带路径 { #fastapi-dev-with-path }
+### 带路径或使用 `--entrypoint` CLI 选项的 `fastapi dev` { #fastapi-dev-with-path-or-with-entrypoint-cli-option }
你也可以把文件路径传给 `fastapi dev` 命令,它会尝试推断要使用的 FastAPI 应用对象:
$ fastapi dev main.py
```
-但这样每次调用 `fastapi` 命令时都需要记得传入正确的路径。
-
-另外,其他工具可能无法找到它,例如 [VS Code 扩展](../editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此推荐在 `pyproject.toml` 中使用 `entrypoint`。
-
-### 部署你的应用(可选) { #deploy-your-app-optional }
-
-你可以选择将 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com),如果还没有,先去加入候补名单。🚀
-
-如果你已经拥有 **FastAPI Cloud** 账户(我们从候补名单邀请了你 😉),你可以用一条命令部署应用。
-
-部署前,先确保已登录:
-
-<div class="termy">
+或者,你也可以给 `fastapi dev` 命令传入 `--entrypoint` 选项:
```console
-$ fastapi login
-
-You are logged in to FastAPI Cloud 🚀
+$ fastapi dev --entrypoint main:app
```
-</div>
+但这样每次调用 `fastapi` 命令时都需要记得传入正确的路径/entrypoint。
+
+另外,其他工具可能无法找到它,例如 [VS Code 扩展](../editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此推荐在 `pyproject.toml` 中使用 `entrypoint`。
+
+### 部署你的应用(可选) { #deploy-your-app-optional }
-然后部署你的应用:
+你可以选择用一条命令将 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com)。🚀
<div class="termy">
</div>
+CLI 会自动检测你的 FastAPI 应用并将其部署到云端。如果你尚未登录,浏览器会打开以完成认证流程。
+
就这些!现在你可以通过该 URL 访问你的应用了。✨
## 分步概括 { #recap-step-by-step }
/items/foo
```
-/// info
+/// note | 注意
「路径」也通常被称为「端点」或「路由」。
* 请求路径为 `/`
* 使用 <dfn title="一种 HTTP GET 方法"><code>get</code> 操作</dfn>
-/// info | `@decorator` 信息
+/// note | `@decorator` 信息
`@something` 语法在 Python 中被称为「装饰器」。
* `@app.patch()`
* `@app.trace()`
-/// tip
+/// tip | 提示
你可以随意使用任何一个操作(HTTP方法)。
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
-/// note
+/// note | 注意
如果你不知道两者的区别,请查阅 [并发: *赶时间吗?*](../async.md#in-a-hurry)。
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
-/// info | 信息
+/// note | 注意
阅读更多关于标签的信息[路径操作配置](path-operation-configuration.md#tags)。
## 从 docstring 获取描述 { #description-from-docstring }
-描述内容比较长且占用多行时,可以在函数的 <dfn title="作为函数内部的第一个表达式(不赋给任何变量)的多行字符串,用于文档用途">docstring</dfn> 中声明*路径操作*的描述,**FastAPI** 会从中读取。
+描述内容比较长且占用多行时,可以在函数的 <dfn title="作为函数内部的第一个表达式(不赋给任何变量)的多行字符串,用于文档用途">文档字符串</dfn> 中声明*路径操作*的描述,**FastAPI** 会从中读取。
文档字符串支持 [Markdown](https://en.wikipedia.org/wiki/Markdown),能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
-/// info | 信息
+/// note | 注意
注意,`response_description` 只用于描述响应,`description` 一般则用于描述*路径操作*。
///
-/// check | 检查
+/// tip | 提示
OpenAPI 规定每个*路径操作*都要有响应描述。
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
-/// info | 信息
+/// note | 注意
FastAPI 在 0.95.0 版本添加了对 `Annotated` 的支持(并开始推荐使用它)。
* `lt`:小于(`l`ess `t`han)
* `le`:小于等于(`l`ess than or `e`qual)
-/// info | 信息
+/// note | 注意
`Query`、`Path` 以及你后面会看到的其他类,都是一个通用 `Param` 类的子类。
///
-/// note | 注æ\84\8f
+/// note | æ\8a\80æ\9c¯ç»\86è\8a\82
当你从 `fastapi` 导入 `Query`、`Path` 和其他对象时,它们实际上是函数。
本例把 `item_id` 的类型声明为 `int`。
-/// check | 检查
+/// tip | 提示
类型声明将为函数提供错误检查、代码补全等编辑器支持。
{"item_id":3}
```
-/// check | 检查
+/// tip | 提示
注意,函数接收并返回的值是 `3`( `int`),不是 `"3"`(`str`)。
值的类型不是 `int` 而是浮点数(`float`)时也会显示同样的错误,比如: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
-/// check | 检查
+/// tip | 提示
**FastAPI** 使用同样的 Python 类型声明实现了数据校验。
<img src="/img/tutorial/path-params/image01.png">
-/// check | 检查
+/// tip | 提示
还是使用 Python 类型声明,**FastAPI** 提供了(集成 Swagger UI 的)自动交互式文档。
## Pydantic { #pydantic }
-FastAPI 充分地利用了 [Pydantic](https://docs.pydantic.dev/) 的优势,用它在后台校验数据。众所周知,Pydantic 擅长的就是数据校验。
+所有数据校验都由 [Pydantic](https://docs.pydantic.dev/) 在幕后完成,因此你能从中获得所有好处。而且你可以放心。
同样,`str`、`float`、`bool` 以及很多复合数据类型都可以使用类型声明。
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
-/// info | 信息
+/// note | 注意
FastAPI 在 0.95.0 版本中添加了对 `Annotated` 的支持(并开始推荐使用)。
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
-/// info | 信息
+/// note | 注意
这在 Pydantic 2 或更高版本中可用。😎
本例中,查询参数 `q` 是可选的,默认值为 `None`。
-/// check | 检查
+/// tip | 提示
注意,**FastAPI** 可以识别出 `item_id` 是路径参数,`q` 不是路径参数,而是查询参数。
你可以使用 `File` 定义由客户端上传的文件。
-/// info | 信息
+/// note | 注意
要接收上传的文件,请先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
-/// info | 信息
+/// note | 注意
`File` 是直接继承自 `Form` 的类。
你可以在 FastAPI 中使用 **Pydantic 模型**声明**表单字段**。
-/// info | 信息
+/// note | 注意
要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
FastAPI 支持同时使用 `File` 和 `Form` 定义文件和表单字段。
-/// info | 信息
+/// note | 注意
接收上传的文件和/或表单数据,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
当你需要接收表单字段而不是 JSON 时,可以使用 `Form`。
-/// info
+/// note
要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
使用 `Form` 可以像使用 `Body`(以及 `Query`、`Path`、`Cookie`)一样声明相同的配置,包括校验、示例、别名(例如将 `username` 写成 `user-name`)等。
-/// info
+/// note
`Form` 是直接继承自 `Body` 的类。
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
-/// info | 信息
+/// note | 注意
要使用 `EmailStr`,首先安装 [`email-validator`](https://github.com/JoshData/python-email-validator)。
{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
-……我们仍将 `response_model` 声明为不包含密码的 `UserOut` 模型:
+...我们仍将 `response_model` 声明为不包含密码的 `UserOut` 模型:
{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
这就是为什么在这个例子里我们必须在 `response_model` 参数中声明它。
-……但继续往下读,看看如何更好地处理这种情况。
+...但继续往下读,看看如何更好地处理这种情况。
## 返回类型与数据过滤 { #return-type-and-data-filtering }
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
-……它失败是因为该类型注解不是 Pydantic 类型,也不只是单个 `Response` 类或其子类,而是 `Response` 与 `dict` 的联合类型(任意其一)。
+...它失败是因为该类型注解不是 Pydantic 类型,也不只是单个 `Response` 类或其子类,而是 `Response` 与 `dict` 的联合类型(任意其一)。
### 禁用响应模型 { #disable-response-model }
}
```
-/// info | 信息
+/// note | 注意
你还可以使用:
`status_code` 参数接收表示 HTTP 状态码的数字。
-/// info | 信息
+/// note | 注意
`status_code` 还能接收 `IntEnum` 类型,比如 Python 的 [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus)。
///
-/// info | 信息
+/// note | 注意
OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持,它是 JSON Schema 标准的一部分。
- `File()`
- `Form()`
-/// info | 信息
+/// note | 注意
这个旧的、OpenAPI 特定的 `examples` 参数,自 FastAPI `0.103.0` 起改名为 `openapi_examples`。
JSON Schema 中这个新的 `examples` 字段只是一个由示例组成的 `list`,而不是像上面提到的 OpenAPI 其他位置那样带有额外元数据的 `dict`。
-/// info | 信息
+/// note | 注意
即使在 OpenAPI 3.1.0 发布、并与 JSON Schema 有了这种更简单的集成之后,有一段时间里,提供自动文档的 Swagger UI 并不支持 OpenAPI 3.1.0(它自 5.0.0 版本起已支持 🎉)。
## 运行 { #run-it }
-/// info | 信息
+/// note | 注意
当你使用命令 `pip install "fastapi[standard]"` 安装 **FastAPI** 时,[`python-multipart`](https://github.com/Kludex/python-multipart) 包会自动安装。
但是,如果你使用 `pip install fastapi`,默认不会包含 `python-multipart` 包。
-如需手动安装,请先创建并激活[虚拟环境](../../virtual-environments.md),然后执行:
+如需手动安装,请先创建[虚拟环境](../../virtual-environments.md)、激活它,然后执行:
```console
$ pip install python-multipart
<img src="/img/tutorial/security/image01.png">
-/// check | Authorize 按钮!
+/// tip | Authorize 按钮!
页面右上角已经有一个崭新的“Authorize”按钮。
本示例将使用 **OAuth2** 的 **Password** 流程并配合 **Bearer** 令牌,通过 `OAuth2PasswordBearer` 类来实现。
-/// info | 信息
+/// note | 注意
“Bearer” 令牌并非唯一选项。
我们很快也会创建对应的实际路径操作。
-/// info | 信息
+/// note | 注意
如果你是非常严格的 “Pythonista”,可能不喜欢使用参数名 `tokenUrl` 而不是 `token_url`。
**FastAPI** 会据此在 OpenAPI 架构(以及自动生成的 API 文档)中定义一个“安全方案”。
-/// info | 技术细节
+/// note | 技术细节
**FastAPI** 之所以知道可以使用(在依赖中声明的)`OAuth2PasswordBearer` 在 OpenAPI 中定义安全方案,是因为它继承自 `fastapi.security.oauth2.OAuth2`,而后者又继承自 `fastapi.security.base.SecurityBase`。
///
-/// check | 检查
+/// tip | 提示
依赖系统的这种设计方式可以支持不同的依赖项返回同一个 `User` 模型。
</div>
-/// info | 信息
+/// note | 注意
如果你计划使用类似 RSA 或 ECDSA 的数字签名算法,你应该安装加密库依赖项 `pyjwt[crypto]`。
用户名: `johndoe`
密码: `secret`
-/// check | 检查
+/// tip | 提示
注意,代码中的任何地方都没有明文密码 “`secret`”,我们只有它的哈希版本。
* 脸书和 Instagram 使用 `instagram_basic`
* 谷歌使用 `https://www.googleapis.com/auth/drive`
-/// info | 信息
+/// note | 注意
OAuth2 中,**作用域**只是声明指定权限的字符串。
* 可选的 `client_id`(本例未使用)
* 可选的 `client_secret`(本例未使用)
-/// info | 信息
+/// note | 注意
`OAuth2PasswordRequestForm` 并不像 `OAuth2PasswordBearer` 那样是 **FastAPI** 的特殊类。
)
```
-/// info | 信息
+/// note | 注意
`user_dict` 的说明,详见[**更多模型**一章](../extra-models.md#about-user-in-dict)。
{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
-/// info | 信息
+/// note | 注意
此处返回值为 `Bearer` 的响应头 `WWW-Authenticate` 也是规范的一部分。
这类似于[流式传输 JSON Lines](stream-json-lines.md),但使用 `text/event-stream` 格式,浏览器原生通过 [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) 支持。
-/// info | 信息
+/// note | 注意
新增于 FastAPI 0.135.0。
当你想以“流”的方式发送一系列数据时,可以使用 JSON Lines。
-/// info | 信息
+/// note | 注意
新增于 FastAPI 0.134.0。
它与 JSON 数组(相当于 Python 的 list)非常相似,但不是用 `[]` 包裹、并在各项之间使用 `,` 分隔,而是每行一个 JSON 对象,彼此以换行符分隔。
-/// info | 信息
+/// note | 注意
关键在于你的应用可以逐行生成数据,而客户端在消费前面的行。
## 使用 `TestClient` { #using-testclient }
-/// info | 信息
+/// note | 注意
要使用 `TestClient`,先要安装 [`httpx`](https://www.python-httpx.org)。
关于如何传数据给后端的更多信息(使用 `httpx` 或 `TestClient`),请查阅 [HTTPX 文档](https://www.python-httpx.org)。
-/// info | 信息
+/// note | 注意
注意 `TestClient` 接收可以被转化为JSON的数据,而不是Pydantic模型。