Browse Source

🌐 Update translations for zh (update-outdated)

pull/15177/head
github-actions[bot] 4 months ago
committed by Yurii Motov
parent
commit
0230e26077
  1. 4
      docs/zh/docs/advanced/additional-responses.md
  2. 4
      docs/zh/docs/advanced/advanced-dependencies.md
  3. 8
      docs/zh/docs/advanced/async-tests.md
  4. 26
      docs/zh/docs/advanced/behind-a-proxy.md
  5. 116
      docs/zh/docs/advanced/custom-response.md
  6. 8
      docs/zh/docs/advanced/dataclasses.md
  7. 6
      docs/zh/docs/advanced/events.md
  8. 6
      docs/zh/docs/advanced/index.md
  9. 12
      docs/zh/docs/advanced/middleware.md
  10. 14
      docs/zh/docs/advanced/openapi-callbacks.md
  11. 4
      docs/zh/docs/advanced/openapi-webhooks.md
  12. 6
      docs/zh/docs/advanced/path-operation-advanced-configuration.md
  13. 2
      docs/zh/docs/advanced/response-change-status-code.md
  14. 6
      docs/zh/docs/advanced/response-headers.md
  15. 16
      docs/zh/docs/advanced/settings.md
  16. 10
      docs/zh/docs/advanced/sub-applications.md
  17. 8
      docs/zh/docs/advanced/templates.md
  18. 2
      docs/zh/docs/advanced/testing-websockets.md
  19. 26
      docs/zh/docs/advanced/websockets.md
  20. 6
      docs/zh/docs/advanced/wsgi.md
  21. 6
      docs/zh/docs/tutorial/background-tasks.md
  22. 2
      docs/zh/docs/tutorial/body-nested-models.md
  23. 12
      docs/zh/docs/tutorial/body.md
  24. 4
      docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
  25. 18
      docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
  26. 6
      docs/zh/docs/tutorial/dependencies/global-dependencies.md
  27. 4
      docs/zh/docs/tutorial/dependencies/index.md
  28. 2
      docs/zh/docs/tutorial/metadata.md
  29. 2
      docs/zh/docs/tutorial/path-operation-configuration.md
  30. 6
      docs/zh/docs/tutorial/path-params-numeric-validations.md
  31. 24
      docs/zh/docs/tutorial/request-files.md
  32. 4
      docs/zh/docs/tutorial/request-form-models.md
  33. 4
      docs/zh/docs/tutorial/request-forms-and-files.md
  34. 8
      docs/zh/docs/tutorial/schema-extra-example.md
  35. 10
      docs/zh/docs/tutorial/security/first-steps.md
  36. 10
      docs/zh/docs/tutorial/security/oauth2-jwt.md
  37. 4
      docs/zh/docs/tutorial/security/simple-oauth2.md
  38. 22
      docs/zh/docs/tutorial/sql-databases.md
  39. 4
      docs/zh/docs/tutorial/static-files.md
  40. 24
      docs/zh/docs/tutorial/testing.md

4
docs/zh/docs/advanced/additional-responses.md

@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
要查看响应中究竟可以包含什么,你可以查看 OpenAPI 规范中的以下部分:
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">OpenAPI Responses 对象</a>,它包含 `Response Object`
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">OpenAPI Response 对象</a>,你可以把这里的任何内容直接包含到 `responses` 参数中的每个响应里。包括 `description`、`headers`、`content`(在这里声明不同的媒体类型和 JSON Schemas),以及 `links`
* [OpenAPI Responses 对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object),它包含 `Response Object`
* [OpenAPI Response 对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object),你可以把这里的任何内容直接包含到 `responses` 参数中的每个响应里。包括 `description`、`headers`、`content`(在这里声明不同的媒体类型和 JSON Schemas),以及 `links`

4
docs/zh/docs/advanced/advanced-dependencies.md

@ -132,7 +132,7 @@ checker(q="somequery")
这样会话会释放数据库连接,让其他请求可以使用。
如果你还有其他需要在 `yield` 依赖项中提前退出的用例,请创建一个 <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub 讨论问题</a>,说明你的具体用例以及为何提前关闭会对你有帮助。
如果你还有其他需要在 `yield` 依赖项中提前退出的用例,请创建一个 [GitHub 讨论问题](https://github.com/fastapi/fastapi/discussions/new?category=questions),说明你的具体用例以及为何提前关闭会对你有帮助。
如果确有有力的用例需要提前关闭,我会考虑新增一种选择性启用提前关闭的方式。
@ -144,7 +144,7 @@ checker(q="somequery")
### 后台任务与带 `yield` 的依赖项(技术细节) { #background-tasks-and-dependencies-with-yield-technical-details }
在 FastAPI 0.106.0 之前,`yield` 之后抛出异常是不可行的,因为带 `yield` 的依赖项中的退出代码会在响应发送之后才执行,此时[异常处理器](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}已经运行完毕。
在 FastAPI 0.106.0 之前,`yield` 之后抛出异常是不可行的,因为带 `yield` 的依赖项中的退出代码会在响应发送之后才执行,此时[异常处理器](../tutorial/handling-errors.md#install-custom-exception-handlers)已经运行完毕。
之所以这样设计,主要是为了允许在后台任务中继续使用依赖项通过 `yield`“产出”的对象,因为退出代码会在后台任务完成之后才执行。

8
docs/zh/docs/advanced/async-tests.md

@ -16,11 +16,11 @@
`TestClient` 在内部通过一些“魔法”操作,使得您可以在普通的 `def` 测试函数中调用异步的 FastAPI 应用程序,并使用标准的 pytest。但当我们在异步函数中使用它时,这种“魔法”就不再生效了。由于测试以异步方式运行,我们无法在测试函数中继续使用 `TestClient`
`TestClient` 是基于 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> 的。幸运的是,我们可以直接使用它来测试API。
`TestClient` 是基于 [HTTPX](https://www.python-httpx.org) 的。幸运的是,我们可以直接使用它来测试 API。
## 示例 { #example }
举个简单的例子,让我们来看一个[更大的应用](../tutorial/bigger-applications.md){.internal-link target=_blank}和[测试](../tutorial/testing.md){.internal-link target=_blank}中描述的类似文件结构:
举个简单的例子,让我们来看一个[更大的应用](../tutorial/bigger-applications.md)和[测试](../tutorial/testing.md)中描述的类似文件结构:
```
.
@ -84,7 +84,7 @@ response = client.get('/')
/// warning | 警告
如果您的应用程序依赖于生命周期事件, `AsyncClient` 将不会触发这些事件。为了确保它们被触发,请使用 <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a> 中的 `LifespanManager`
如果您的应用程序依赖于生命周期事件, `AsyncClient` 将不会触发这些事件。为了确保它们被触发,请使用 [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage) 中的 `LifespanManager`
///
@ -94,6 +94,6 @@ response = client.get('/')
/// tip | 提示
如果您在测试程序中集成异步函数调用的时候遇到一个 `RuntimeError: Task attached to a different loop` 的报错(例如,使用 <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB 的 MotorClient</a> 时),请记住,只能在异步函数中实例化需要事件循环的对象,例如在 `@app.on_event("startup")` 回调中初始化。
如果您在测试程序中集成异步函数调用的时候遇到一个 `RuntimeError: Task attached to a different loop` 的报错(例如,使用 [MongoDB 的 MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop) 时),请记住,只能在异步函数中实例化需要事件循环的对象,例如在 `@app.on_event("startup")` 回调中初始化。
///

26
docs/zh/docs/advanced/behind-a-proxy.md

@ -16,9 +16,9 @@
这些代理相关的请求头包括:
- <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
- <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
- <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
@ -60,7 +60,7 @@ https://mysuperapp.com/items/
/// tip | 提示
如果你想了解更多关于 HTTPS 的内容,查看指南:[关于 HTTPS](../deployment/https.md){.internal-link target=_blank}
如果你想了解更多关于 HTTPS 的内容,查看指南:[关于 HTTPS](../deployment/https.md)。
///
@ -228,7 +228,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
请注意,服务器(Uvicorn)不会用这个 `root_path` 做别的事情,只会把它传给应用。
但是,如果你用浏览器打开 <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>,你会看到正常的响应:
但是,如果你用浏览器打开 [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app),你会看到正常的响应:
```JSON
{
@ -251,9 +251,9 @@ Uvicorn 会期望代理以 `http://127.0.0.1:8000/app` 访问 Uvicorn,而在
## 使用 Traefik 进行本地测试 { #testing-locally-with-traefik }
你可以很容易地使用 <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a> 在本地运行一个移除路径前缀的实验。
你可以很容易地使用 [Traefik](https://docs.traefik.io/) 在本地运行一个移除路径前缀的实验。
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">下载 Traefik</a>,它是一个单独的二进制文件,你可以解压压缩包并直接在终端中运行。
[下载 Traefik](https://github.com/containous/traefik/releases),它是一个单独的二进制文件,你可以解压压缩包并直接在终端中运行。
然后创建一个 `traefik.toml` 文件,内容如下:
@ -330,7 +330,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
### 查看响应 { #check-the-responses }
现在,如果你访问 Uvicorn 端口对应的 URL:<a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>,你会看到正常响应:
现在,如果你访问 Uvicorn 端口对应的 URL:[http://127.0.0.1:8000/app](http://127.0.0.1:8000/app),你会看到正常响应:
```JSON
{
@ -345,7 +345,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
///
现在打开包含路径前缀、使用 Traefik 端口的 URL:<a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>
现在打开包含路径前缀、使用 Traefik 端口的 URL:[http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app)
我们得到相同的响应:
@ -370,13 +370,13 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
访问应用的“官方”方式应该是通过我们定义的带有路径前缀的代理。因此,正如预期的那样,如果你尝试不带路径前缀、直接由 Uvicorn 提供的文档界面,它将无法工作,因为它期望通过代理访问。
你可以在 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> 查看:
你可以在 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) 查看:
<img src="/img/tutorial/behind-a-proxy/image01.png">
但如果我们在“官方”URL(代理端口为 `9999`)的 `/api/v1/docs` 访问文档界面,它就能正常工作!🎉
你可以在 <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> 查看:
你可以在 [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) 查看:
<img src="/img/tutorial/behind-a-proxy/image02.png">
@ -433,7 +433,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
///
<a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> 的文档界面中,它看起来是这样的:
文档界面 [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) 中,它看起来是这样的:
<img src="/img/tutorial/behind-a-proxy/image03.png">
@ -461,6 +461,6 @@ OpenAPI 规范中的 `servers` 属性是可选的。
## 挂载子应用 { #mounting-a-sub-application }
如果你需要在使用带有 `root_path` 的代理时挂载一个子应用(参见 [子应用 - 挂载](sub-applications.md){.internal-link target=_blank}),你可以像预期的那样正常操作。
如果你需要在使用带有 `root_path` 的代理时挂载一个子应用(参见 [子应用 - 挂载](sub-applications.md)),你可以像预期的那样正常操作。
FastAPI 会在内部智能地使用 `root_path`,因此它可以直接正常工作。✨

116
docs/zh/docs/advanced/custom-response.md

@ -1,52 +1,36 @@
# 自定义响应 - HTML、流、文件等 { #custom-response-html-stream-file-others }
**FastAPI** 默认会使用 `JSONResponse` 返回响应。
默认情况下,**FastAPI** 会返回 JSON 响应。
你可以通过直接返回 `Response` 来重载它,参见 [直接返回响应](response-directly.md){.internal-link target=_blank}
你可以像在 [直接返回响应](response-directly.md) 中那样,直接返回 `Response` 来重载它
但如果你直接返回一个 `Response`(或其任意子类,比如 `JSONResponse`),返回数据不会自动转换(即使你声明了 `response_model`),也不会自动生成文档(例如,在生成的 OpenAPI 中,HTTP 头 `Content-Type` 里的特定「媒体类型」不会被包含)。
但如果你直接返回一个 `Response`(或其任意子类,比如 `JSONResponse`),返回数据不会自动转换(即使你声明了 `response_model`),也不会自动生成文档(例如,在生成的 OpenAPI 中,HTTP 头 `Content-Type` 里的特定「媒体类型」不会被包含)。
你还可以在 *路径操作装饰器* 中通过 `response_class` 参数声明要使用的 `Response`(例如任意 `Response` 子类)。
你从 *路径操作函数* 中返回的内容将被放在该 `Response` 中。
并且如果该 `Response` 有一个 JSON 媒体类型(`application/json`),比如使用 `JSONResponse``UJSONResponse` 的时候,返回的数据将使用你在路径操作装饰器中声明的任何 Pydantic 的 `response_model` 自动转换(和过滤)。
/// note | 注意
如果你使用不带有任何媒体类型的响应类,FastAPI 会认为你的响应没有任何内容,所以不会在生成的 OpenAPI 文档中记录响应格式。
如果你使用不带有媒体类型的响应类,FastAPI 会认为你的响应没有任何内容,所以不会在生成的 OpenAPI 文档中记录响应格式。
///
## 使用 `ORJSONResponse` { #use-orjsonresponse }
例如,如果你需要压榨性能,你可以安装并使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> 并将响应设置为 `ORJSONResponse`
导入你想要使用的 `Response` 类(子类)然后在 *路径操作装饰器* 中声明它。
对于较大的响应,直接返回一个 `Response` 会比返回一个字典快得多。
这是因为默认情况下,FastAPI 会检查其中的每一项并确保它可以被序列化为 JSON,使用教程中解释的相同 [JSON 兼容编码器](../tutorial/encoder.md){.internal-link target=_blank}。这正是它允许你返回「任意对象」的原因,例如数据库模型。
但如果你确定你返回的内容是「可以用 JSON 序列化」的,你可以将它直接传给响应类,从而避免在传给响应类之前先通过 `jsonable_encoder` 带来的额外开销。
## JSON 响应 { #json-responses }
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
默认情况下 FastAPI 返回 JSON 响应。
/// info | 信息
参数 `response_class` 也会用来定义响应的「媒体类型」。
如果你声明了一个[响应模型](../tutorial/response-model.md),FastAPI 会使用 Pydantic 将数据序列化为 JSON。
在这个例子中,HTTP 头的 `Content-Type` 会被设置成 `application/json`
如果你没有声明响应模型,FastAPI 会使用 [JSON 兼容编码器](../tutorial/encoder.md) 中解释的 `jsonable_encoder`,并把结果放进一个 `JSONResponse`
并且在 OpenAPI 文档中也会这样记录
如果你在 `response_class` 中声明了一个 JSON 媒体类型(`application/json`)的类(比如 `JSONResponse`),你返回的数据会使用你在 *路径操作装饰器* 中声明的任意 Pydantic `response_model` 自动转换(和过滤)。但数据不会由 Pydantic 序列化为 JSON 字节;而是先用 `jsonable_encoder` 转换后传给 `JSONResponse`,由它使用 Python 标准 JSON 库序列化为字节。
///
### JSON 性能 { #json-performance }
/// tip | 提示
简而言之,如果你想要获得最大性能,请使用[响应模型](../tutorial/response-model.md),并且不要在 *路径操作装饰器* 中声明 `response_class`
`ORJSONResponse` 目前只在 FastAPI 中可用,而在 Starlette 中不可用。
///
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML 响应 { #html-response }
@ -69,7 +53,7 @@
### 返回一个 `Response` { #return-a-response }
正如你在 [直接返回响应](response-directly.md){.internal-link target=_blank} 中了解到的,你也可以通过直接返回响应在 *路径操作* 中直接重载响应。
正如你在 [直接返回响应](response-directly.md) 中了解到的,你也可以通过直接返回响应在 *路径操作* 中直接重载响应。
和上面一样的例子,返回一个 `HTMLResponse` 看起来可能是这样:
@ -154,37 +138,11 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
如上文所述,这是 **FastAPI** 中使用的默认响应。
### `ORJSONResponse` { #orjsonresponse }
如上文所述,`ORJSONResponse` 是一个使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> 的快速的可选 JSON 响应。
/// info | 信息
这需要先安装 `orjson`,例如使用 `pip install orjson`
///
### `UJSONResponse` { #ujsonresponse }
`UJSONResponse` 是一个使用 <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a> 的可选 JSON 响应。
/// info | 信息
这需要先安装 `ujson`,例如使用 `pip install ujson`
///
/// warning | 警告
在处理某些边缘情况时,`ujson` 不如 Python 的内置实现那么谨慎。
///
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// note | 技术细节
/// tip | 提示
但如果你声明了响应模型或返回类型,将直接使用它来把数据序列化为 JSON,并直接返回一个具备正确 JSON 媒体类型的响应,而不会使用 `JSONResponse` 类。
`ORJSONResponse` 可能是一个更快的选择
这是获得最佳性能的理想方式。
///
@ -214,31 +172,25 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
### `StreamingResponse` { #streamingresponse }
采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### 对类似文件的对象使用 `StreamingResponse` { #using-streamingresponse-with-file-like-objects }
采用异步生成器或普通生成器/迭代器(带有 `yield` 的函数),然后流式传输响应主体。
如果您有一个<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">类文件</a>对象(例如由 `open()` 返回的对象),你可以创建一个生成器函数来迭代该类文件对象。
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
这样,你就不必先把它全部读入内存,可以将该生成器函数传给 `StreamingResponse` 并返回它。
这也包括许多与云存储、视频处理等交互的库。
/// note | 技术细节
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
一个 `async` 任务只有在到达 `await` 时才能被取消。如果没有 `await`,生成器(带有 `yield` 的函数)无法被正确取消,即使已请求取消也可能继续运行。
1. 这是生成器函数。之所以是「生成器函数」,是因为它内部包含 `yield` 语句。
2. 通过使用 `with` 代码块,我们可以确保在生成器函数完成后关闭类文件对象。因此,在它完成发送响应之后会被关闭。
3. 这个 `yield from` 告诉函数去迭代名为 `file_like` 的那个对象。然后,对于每个被迭代出来的部分,都把该部分作为来自这个生成器函数(`iterfile`)的值再 `yield` 出去。
由于这个小示例不需要任何 `await` 语句,我们添加 `await anyio.sleep(0)`,给事件循环一个处理取消的机会。
因此,它是一个把「生成」工作内部转交给其他东西的生成器函数
对于大型或无限流,这一点更为重要。
通过这种方式,我们可以把它放在 `with` 代码块中,从而确保类文件对象在结束后被关闭。
///
/// tip | 提示
注意在这里,因为我们使用的是不支持 `async``await` 的标准 `open()`,我们使用普通的 `def` 声明了路径操作。
与其直接返回 `StreamingResponse`,更推荐遵循 [流式数据](./stream-data.md) 的写法,它更方便并在幕后为你处理取消。
如果你在流式传输 JSON Lines,请参阅教程:[流式传输 JSON Lines](../tutorial/stream-json-lines.md)。
///
@ -267,11 +219,11 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
你可以创建你自己的自定义响应类,继承自 `Response` 并使用它。
例如,假设你想使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>,但要使用内置 `ORJSONResponse` 类没有启用的一些自定义设置
例如,假设你想用一些设置来使用 [`orjson`](https://github.com/ijl/orjson)
假设你想让它返回带缩进、格式化的 JSON,因此你想使用 orjson 选项 `orjson.OPT_INDENT_2`
你可以创建一个 `CustomORJSONResponse`。你需要做的主要事情是实现一个返回 `bytes` `Response.render(content)` 方法:
你可以创建一个 `CustomORJSONResponse`。你需要做的主要事情是实现一个 `Response.render(content)` 方法,并返回 `bytes`
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
@ -291,13 +243,21 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
当然,你很可能会找到比格式化 JSON 更好的方式来利用这一点。😉
### `orjson` 或响应模型 { #orjson-or-response-model }
如果你追求的是性能,使用[响应模型](../tutorial/response-model.md) 往往比返回 `orjson` 响应更好。
使用响应模型时,FastAPI 会使用 Pydantic 直接把数据序列化为 JSON,不需要诸如通过 `jsonable_encoder` 转换这样的中间步骤(其他情况下会发生)。
并且在底层,Pydantic 使用与 `orjson` 相同的 Rust 机制来序列化 JSON,所以使用响应模型你已经可以获得最佳性能。
## 默认响应类 { #default-response-class }
在创建 **FastAPI** 类实例或 `APIRouter` 时,你可以指定默认要使用的响应类。
用于定义它的参数是 `default_response_class`
在下面的示例中,**FastAPI** 会在所有 *路径操作* 中默认使用 `ORJSONResponse`,而不是 `JSONResponse`
在下面的示例中,**FastAPI** 会在所有 *路径操作* 中默认使用 `HTMLResponse`,而不是 JSON
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
@ -309,4 +269,4 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
## 额外文档 { #additional-documentation }
你还可以使用 `responses` 在 OpenAPI 中声明媒体类型和许多其他详细信息:[OpenAPI 中的额外文档](additional-responses.md){.internal-link target=_blank}
你还可以使用 `responses` 在 OpenAPI 中声明媒体类型和许多其他详细信息:[OpenAPI 中的额外响应](additional-responses.md)

8
docs/zh/docs/advanced/dataclasses.md

@ -2,11 +2,11 @@
FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydantic 模型声明请求与响应。
但 FastAPI 也支持以相同方式使用 <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>
但 FastAPI 也支持以相同方式使用 [`dataclasses`](https://docs.python.org/3/library/dataclasses.html)
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
这仍然得益于 **Pydantic**,因为它对 <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` 的内置支持</a>
这仍然得益于 **Pydantic**,因为它对 [`dataclasses` 的内置支持](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel)
因此,即便上面的代码没有显式使用 Pydantic,FastAPI 也会使用 Pydantic 将那些标准数据类转换为 Pydantic 风格的 dataclasses。
@ -67,7 +67,7 @@ FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydant
一如既往,在 FastAPI 中你可以按需组合 `def``async def`
如果需要回顾何时用哪一个,请查看关于 [`async` 和 `await`](../async.md#in-a-hurry){.internal-link target=_blank} 的文档中的 _“急不可待?”_ 一节。
如果需要回顾何时用哪一个,请查看关于 [`async` 和 `await`](../async.md#in-a-hurry) 的文档中的 _“急不可待?”_ 一节。
9. 这个 *路径操作函数* 返回的不是数据类(当然也可以返回数据类),而是包含内部数据的字典列表。
FastAPI 会使用(包含数据类的)`response_model` 参数来转换响应。
@ -80,7 +80,7 @@ FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydant
你还可以把 `dataclasses` 与其它 Pydantic 模型组合、从它们继承、把它们包含到你自己的模型中等。
想了解更多,请查看 <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">Pydantic 关于 dataclasses 的文档</a>
想了解更多,请查看 [Pydantic 关于 dataclasses 的文档](https://docs.pydantic.dev/latest/concepts/dataclasses/)
## 版本 { #version }

6
docs/zh/docs/advanced/events.md

@ -150,11 +150,11 @@ async with lifespan(app):
只是为好奇者提供的技术细节。🤓
在底层,这部分是 ASGI 技术规范中的 <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan 协议</a>的一部分,定义了称为 `startup``shutdown` 的事件。
在底层,这部分是 ASGI 技术规范中的 [Lifespan 协议](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)的一部分,定义了称为 `startup``shutdown` 的事件。
/// info | 信息
你可以在 <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlette 的 Lifespan 文档</a> 中阅读更多关于 `lifespan` 处理器的内容。
你可以在 [Starlette 的 Lifespan 文档](https://www.starlette.dev/lifespan/) 中阅读更多关于 `lifespan` 处理器的内容。
包括如何处理生命周期状态,以便在代码的其他部分使用。
@ -162,4 +162,4 @@ async with lifespan(app):
## 子应用 { #sub-applications }
🚨 请注意,这些生命周期事件(startup 和 shutdown)只会在主应用上执行,不会在[子应用 - 挂载](sub-applications.md){.internal-link target=_blank}上执行。
🚨 请注意,这些生命周期事件(startup 和 shutdown)只会在主应用上执行,不会在[子应用 - 挂载](sub-applications.md)上执行。

6
docs/zh/docs/advanced/index.md

@ -2,13 +2,13 @@
## 附加功能 { #additional-features }
主要的[教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank}足以带你了解 **FastAPI** 的所有主要特性。
主要的[教程 - 用户指南](../tutorial/index.md)足以带你了解 **FastAPI** 的所有主要特性。
在接下来的章节中,你将看到其他选项、配置和附加功能。
/// tip | 提示
接下来的章节不一定是“高级”的。
接下来的章节**不一定是“高级”的**
对于你的用例,解决方案很可能就在其中之一。
@ -16,6 +16,6 @@
## 先阅读教程 { #read-the-tutorial-first }
仅凭主要[教程 - 用户指南](../tutorial/index.md){.internal-link target=_blank}中的知识,你已经可以使用 **FastAPI** 的大多数功能。
仅凭主要[教程 - 用户指南](../tutorial/index.md)中的知识,你已经可以使用 **FastAPI** 的大多数功能。
接下来的章节默认你已经读过它,并理解其中的核心概念。

12
docs/zh/docs/advanced/middleware.md

@ -1,8 +1,8 @@
# 高级中间件 { #advanced-middleware }
用户指南介绍了如何为应用添加[自定义中间件](../tutorial/middleware.md){.internal-link target=_blank}
用户指南介绍了如何为应用添加[自定义中间件](../tutorial/middleware.md)。
以及如何[使用 `CORSMiddleware` 处理 CORS](../tutorial/cors.md){.internal-link target=_blank}
以及如何[使用 `CORSMiddleware` 处理 CORS](../tutorial/cors.md)。
本章学习如何使用其它中间件。
@ -87,11 +87,11 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
## 其它中间件 { #other-middlewares }
除了上述中间件外,FastAPI 还支持其它ASGI 中间件。
除了上述中间件外,FastAPI 还支持其它 ASGI 中间件。
例如:
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn 的 `ProxyHeadersMiddleware`</a>
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
* [Uvicorn 的 `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
其它可用中间件详见 <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">Starlette 官档 - 中间件</a><a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI Awesome 列表</a>
其它可用中间件详见 [Starlette 官档 - 中间件](https://www.starlette.dev/middleware/) 及 [ASGI Awesome 列表](https://github.com/florimondmanca/awesome-asgi)

14
docs/zh/docs/advanced/openapi-callbacks.md

@ -35,7 +35,7 @@ API 的用户(外部开发者)要在您的 API 内使用 POST 请求创建
/// tip | 提示
`callback_url` 查询参数使用 Pydantic 的 <a href="https://docs.pydantic.dev/latest/api/networks/" class="external-link" target="_blank">Url</a> 类型。
`callback_url` 查询参数使用 Pydantic 的 [Url](https://docs.pydantic.dev/latest/api/networks/) 类型。
///
@ -66,7 +66,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
实际的回调只是 HTTP 请求。
实现回调时,要使用 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a><a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a>
实现回调时,要使用 [HTTPX](https://www.python-httpx.org) 或 [Requests](https://requests.readthedocs.io/)
///
@ -106,13 +106,13 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
回调*路径操作*与常规*路径操作*有两点主要区别:
* 它不需要任何实际的代码,因为应用不会调用这段代码。它只是用于存档*外部 API*。因此,函数的内容只需要 `pass` 就可以了
* *路径*可以包含 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 表达式</a>(详见下文),可以使用带参数的变量,以及发送至您的 API 的原始请求的部分
* *路径*可以包含 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(详见下文),可以使用带参数的变量,以及发送至您的 API 的原始请求的部分
### 回调路径表达式 { #the-callback-path-expression }
回调*路径*支持包含发送给您的 API 的原始请求的部分的 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 表达式</a>
回调*路径*支持包含发送给您的 API 的原始请求的部分的 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)
本例中是**字符串**
本例中是 `str`
```Python
"{$callback_url}/invoices/{$request.body.id}"
@ -173,13 +173,13 @@ JSON 请求体包含如下内容:
/// tip | 提示
注意,不能把路由本身(`invoices_callback_router`)传递给 `callback=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。
注意,不能把路由本身(`invoices_callback_router`)传递给 `callbacks=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。
///
### 查看文档 { #check-the-docs }
现在,启动应用并打开 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
现在,启动应用并打开 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
就能看到文档的*路径操作*已经包含了**回调**的内容以及*外部 API*:

4
docs/zh/docs/advanced/openapi-webhooks.md

@ -2,7 +2,7 @@
有些情况下,您可能想告诉您的 API **用户**,您的应用程序可以携带一些数据调用*他们的*应用程序(给它们发送请求),通常是为了**通知**某种**事件**。
这意味着,除了您的用户向您的 API 发送请求的一般情况,**您的 API**(或您的应用)也可以向**他们的系统**(他们的 API、他们的应用)**发送请求**。
这意味着,与通常由您的用户向您的 API 发送请求的流程相反,是**您的 API**(或您的应用)可以**向他们的系统**(他们的 API、他们的应用)**发送请求**。
这通常被称为**网络钩子**(Webhook)。
@ -48,7 +48,7 @@
### 查看文档 { #check-the-docs }
现在您可以启动您的应用程序并访问 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
现在您可以启动您的应用程序并访问 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
您会看到您的文档不仅有正常的*路径操作*显示,现在还多了一些**网络钩子**:

6
docs/zh/docs/advanced/path-operation-advanced-configuration.md

@ -60,7 +60,7 @@
你也可以为它声明带有各自模型、状态码等的附加响应。
文档中有一个完整章节,你可以阅读这里的[OpenAPI 中的附加响应](additional-responses.md){.internal-link target=_blank}
文档中有一个完整章节,你可以阅读这里的[OpenAPI 中的附加响应](additional-responses.md)。
## OpenAPI Extra { #openapi-extra }
@ -68,7 +68,7 @@
/// note | 技术细节
在 OpenAPI 规范中,这被称为 <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation 对象</a>
在 OpenAPI 规范中,这被称为 [Operation 对象](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object)
///
@ -82,7 +82,7 @@
这是一个较低层级的扩展点。
如果你只需要声明附加响应,更方便的方式是使用[OpenAPI 中的附加响应](additional-responses.md){.internal-link target=_blank}
如果你只需要声明附加响应,更方便的方式是使用[OpenAPI 中的附加响应](additional-responses.md)。
///

2
docs/zh/docs/advanced/response-change-status-code.md

@ -1,6 +1,6 @@
# 响应 - 更改状态码 { #response-change-status-code }
你可能之前已经了解到,你可以设置默认的[响应状态码](../tutorial/response-status-code.md){.internal-link target=_blank}
你可能之前已经了解到,你可以设置默认的[响应状态码](../tutorial/response-status-code.md)。
但在某些情况下,你需要返回一个不同于默认值的状态码。

6
docs/zh/docs/advanced/response-headers.md

@ -20,7 +20,7 @@
你也可以在直接返回 `Response` 时添加头部。
按照[直接返回响应](response-directly.md){.internal-link target=_blank}中所述创建响应,并将头部作为附加参数传递:
按照[直接返回响应](response-directly.md)中所述创建响应,并将头部作为附加参数传递:
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
@ -36,6 +36,6 @@
## 自定义头部 { #custom-headers }
请注意,可以通过<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">使用 `X-` 前缀</a>添加自定义专有头部。
请注意,可以通过[使用 `X-` 前缀](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)添加自定义专有头部。
但是,如果你有自定义头部,并希望浏览器中的客户端能够看到它们,你需要将它们添加到你的 CORS 配置中(在 [CORS(跨源资源共享)](../tutorial/cors.md){.internal-link target=_blank} 中阅读更多),使用在 <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette 的 CORS 文档</a>中记录的 `expose_headers` 参数。
但是,如果你有自定义头部,并希望浏览器中的客户端能够看到它们,你需要将它们添加到你的 CORS 配置中(在 [CORS(跨源资源共享)](../tutorial/cors.md) 中阅读更多),使用在 [Starlette 的 CORS 文档](https://www.starlette.dev/middleware/#corsmiddleware)中记录的 `expose_headers` 参数。

16
docs/zh/docs/advanced/settings.md

@ -8,7 +8,7 @@
/// tip | 提示
要理解环境变量,你可以阅读[环境变量](../environment-variables.md){.internal-link target=_blank}
要理解环境变量,你可以阅读[环境变量](../environment-variables.md)。
///
@ -20,11 +20,11 @@
## Pydantic 的 `Settings` { #pydantic-settings }
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:<a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:[Pydantic:Settings 管理](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)
### 安装 `pydantic-settings` { #install-pydantic-settings }
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后安装 `pydantic-settings` 包:
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md),然后安装 `pydantic-settings` 包:
<div class="termy">
@ -100,7 +100,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
## 在另一个模块中放置设置 { #settings-in-another-module }
你可以把这些设置放在另一个模块文件中,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。
你可以把这些设置放在另一个模块文件中,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md)中看到的那样。
例如,可以有一个 `config.py` 文件:
@ -112,7 +112,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
/// tip | 提示
你还需要一个 `__init__.py` 文件,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。
你还需要一个 `__init__.py` 文件,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md)中看到的那样。
///
@ -172,7 +172,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
///
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: Dotenv (.env) support</a> 中阅读更多信息。
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 [Pydantic Settings:Dotenv(.env)支持](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support) 中阅读更多信息。
/// tip | 提示
@ -197,7 +197,7 @@ APP_NAME="ChimichangApp"
/// tip | 提示
`model_config` 属性仅用于 Pydantic 配置。你可以在 <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a> 中阅读更多信息。
`model_config` 属性仅用于 Pydantic 配置。你可以在 [Pydantic:概念:配置](https://docs.pydantic.dev/latest/concepts/config/) 中阅读更多信息。
///
@ -291,7 +291,7 @@ participant execute as Execute function
这样,它的行为几乎就像是一个全局变量。但由于它使用了依赖项函数,我们可以在测试时很容易地覆盖它。
`@lru_cache``functools` 的一部分,它属于 Python 标准库。你可以在 <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">Python 文档中关于 `@lru_cache` 的章节</a>阅读更多信息。
`@lru_cache``functools` 的一部分,它属于 Python 标准库。你可以在 [Python 文档中关于 `@lru_cache` 的章节](https://docs.python.org/3/library/functools.html#functools.lru_cache)阅读更多信息。
## 小结 { #recap }

10
docs/zh/docs/advanced/sub-applications.md

@ -30,25 +30,25 @@
### 查看自动 API 文档 { #check-the-automatic-api-docs }
现在,使用你的文件运行 `fastapi` 命令:
现在,运行 `fastapi` 命令:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
然后在 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> 打开文档。
然后在 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) 打开文档。
下图显示的是主应用 API 文档,只包括其自有的*路径操作*。
<img src="/img/tutorial/sub-applications/image01.png">
然后查看子应用文档 <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>
然后查看子应用文档 [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs)
下图显示的是子应用的 API 文档,也是只包括其自有的*路径操作*,所有这些路径操作都在 `/subapi` 子路径前缀下。
@ -64,4 +64,4 @@ $ fastapi dev main.py
并且子应用还可以再挂载子应用,一切都会正常运行,FastAPI 可以自动处理所有 `root_path`
关于 `root_path` 及如何显式使用 `root_path` 的内容,详见[使用代理](behind-a-proxy.md){.internal-link target=_blank}一章。
关于 `root_path` 及如何显式使用 `root_path` 的内容,详见[使用代理](behind-a-proxy.md)一章。

8
docs/zh/docs/advanced/templates.md

@ -8,7 +8,7 @@ Flask 等工具使用的 Jinja2 是最用的模板引擎。
## 安装依赖项 { #install-dependencies }
确保你创建一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},激活它,并安装 `jinja2`
确保你创建一个[虚拟环境](../virtual-environments.md),激活它,并安装 `jinja2`
<div class="termy">
@ -29,14 +29,14 @@ $ pip install jinja2
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note
/// note | 注意
在 FastAPI 0.108.0,Starlette 0.29.0 之前,`name` 是第一个参数。
并且,在此之前,`request` 对象是作为 context 的一部分以键值对的形式传递的。
///
/// tip
/// tip | 提示
通过声明 `response_class=HTMLResponse`,API 文档就能识别响应的对象是 HTML。
@ -122,4 +122,4 @@ Item ID: 42
## 更多说明 { #more-details }
包括测试模板等更多详情,请参阅 <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">Starlette 官方文档 - 模板</a>
包括如何测试模板在内的更多详情,请查看 [Starlette 的模板文档](https://www.starlette.dev/templates/)

2
docs/zh/docs/advanced/testing-websockets.md

@ -8,6 +8,6 @@
/// note | 注意
更多细节请查看 Starlette 的文档:<a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">测试 WebSockets</a>
更多细节请查看 Starlette 的文档:[测试 WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions)
///

26
docs/zh/docs/advanced/websockets.md

@ -1,10 +1,10 @@
# WebSockets { #websockets }
您可以在 **FastAPI** 中使用 <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a>
您可以在 **FastAPI** 中使用 [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
## 安装 `websockets` { #install-websockets }
请确保您创建一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank}、激活它,并安装 `websockets`(一个让使用“WebSocket”协议更容易的 Python 库):
请确保您创建一个[虚拟环境](../virtual-environments.md)、激活它,并安装 `websockets`(一个让使用“WebSocket”协议更容易的 Python 库):
<div class="termy">
@ -64,19 +64,19 @@ $ pip install websockets
## 尝试一下 { #try-it }
如果您的文件名为 `main.py`,请使用以下命令运行应用程序:
将代码放在 `main.py`,然后运行你的应用程序:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
在浏览器中打开 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>
在浏览器中打开 [http://127.0.0.1:8000](http://127.0.0.1:8000)
您将看到一个简单的页面,如下所示:
@ -86,7 +86,7 @@ $ fastapi dev main.py
<img src="/img/tutorial/websockets/image02.png">
您的 **FastAPI** 应用程序将回复:
您的 **FastAPI** 应用程序将通过 WebSockets 回复:
<img src="/img/tutorial/websockets/image03.png">
@ -115,25 +115,25 @@ $ fastapi dev main.py
由于这是一个 WebSocket,抛出 `HTTPException` 并不是很合理,而是抛出 `WebSocketException`
您可以使用<a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">规范中定义的有效代码</a>
您可以使用[规范中定义的有效代码](https://tools.ietf.org/html/rfc6455#section-7.4.1)
///
### 尝试带有依赖项的 WebSockets { #try-the-websockets-with-dependencies }
如果您的文件名为 `main.py`,请使用以下命令运行应用程序:
运行你的应用程序:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
在浏览器中打开 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>
在浏览器中打开 [http://127.0.0.1:8000](http://127.0.0.1:8000)
在页面中,您可以设置:
@ -174,7 +174,7 @@ Client #1596980209979 left the chat
但请记住,由于所有内容都在内存中以单个列表的形式处理,因此它只能在进程运行时工作,并且只能使用单个进程。
如果您需要与 FastAPI 集成更简单但更强大的功能,支持 Redis、PostgreSQL 或其他功能,请查看 <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>
如果您需要与 FastAPI 集成更简单但更强大的功能,支持 Redis、PostgreSQL 或其他功能,请查看 [encode/broadcaster](https://github.com/encode/broadcaster)
///
@ -182,5 +182,5 @@ Client #1596980209979 left the chat
要了解更多选项,请查看 Starlette 的文档:
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">`WebSocket` 类</a>
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">基于类的 WebSocket 处理</a>
* [`WebSocket` 类](https://www.starlette.dev/websockets/)
* [基于类的 WebSocket 处理](https://www.starlette.dev/endpoints/#websocketendpoint)

6
docs/zh/docs/advanced/wsgi.md

@ -1,6 +1,6 @@
# 包含 WSGI - Flask,Django,其它 { #including-wsgi-flask-django-others }
您可以挂载 WSGI 应用,正如您在 [子应用 - 挂载](sub-applications.md){.internal-link target=_blank}、[在代理之后](behind-a-proxy.md){.internal-link target=_blank} 中所看到的那样。
您可以挂载 WSGI 应用,正如您在 [子应用 - 挂载](sub-applications.md)、[在代理之后](behind-a-proxy.md) 中所看到的那样。
为此, 您可以使用 `WSGIMiddleware` 来包装你的 WSGI 应用,如:Flask,Django,等等。
@ -36,13 +36,13 @@
其余的请求则会被 **FastAPI** 处理。
如果你运行它并访问 <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a>,你将会看到由 Flask 返回的响应:
如果你运行它并访问 [http://localhost:8000/v1/](http://localhost:8000/v1/),你将会看到由 Flask 返回的响应:
```txt
Hello, World from Flask!
```
如果你访问 <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a>,你将会看到由 FastAPI 返回的响应:
如果你访问 [http://localhost:8000/v2](http://localhost:8000/v2),你将会看到由 FastAPI 返回的响应:
```JSON
{

6
docs/zh/docs/tutorial/background-tasks.md

@ -61,7 +61,7 @@
## 技术细节 { #technical-details }
`BackgroundTasks` 类直接来自 <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>
`BackgroundTasks` 类直接来自 [`starlette.background`](https://www.starlette.dev/background/)
它被直接导入/包含到FastAPI以便你可以从 `fastapi` 导入,并避免意外从 `starlette.background` 导入备用的 `BackgroundTask` (后面没有 `s`)。
@ -69,11 +69,11 @@
在FastAPI中仍然可以单独使用 `BackgroundTask`,但您必须在代码中创建对象,并返回包含它的Starlette `Response`
更多细节查看 <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">Starlette 后台任务的官方文档</a>.
更多细节查看 [Starlette 后台任务的官方文档](https://www.starlette.dev/background/)。
## 告诫 { #caveat }
如果您需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,您不需要共享内存、变量等),那么使用其他更大的工具(如 <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>)可能更好。
如果您需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,您不需要共享内存、变量等),那么使用其他更大的工具(如 [Celery](https://docs.celeryq.dev))可能更好。
它们往往需要更复杂的配置,即消息/作业队列管理器,如RabbitMQ或Redis,但它们允许您在多个进程中运行后台任务,甚至是在多个服务器中。

2
docs/zh/docs/tutorial/body-nested-models.md

@ -95,7 +95,7 @@ Pydantic 模型的每个属性都具有类型。
除了普通的单一值类型(如 `str`、`int`、`float` 等)外,你还可以使用从 `str` 继承的更复杂的单一值类型。
要了解所有的可用选项,请查看 <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydantic 的类型概览</a>。你将在下一章节中看到一些示例。
要了解所有的可用选项,请查看 [Pydantic 的类型概览](https://docs.pydantic.dev/latest/concepts/types/)。你将在下一章节中看到一些示例。
例如,在 `Image` 模型中我们有一个 `url` 字段,我们可以把它声明为 Pydantic 的 `HttpUrl`,而不是 `str`

12
docs/zh/docs/tutorial/body.md

@ -6,7 +6,7 @@
你的 API 几乎总是需要发送**响应体**。但客户端不一定总是要发送**请求体**,有时它们只请求某个路径,可能带一些查询参数,但不会发送请求体。
使用 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> 模型来声明**请求体**,能充分利用它的功能和优点。
使用 [Pydantic](https://docs.pydantic.dev/) 模型来声明**请求体**,能充分利用它的功能和优点。
/// info | 信息
@ -72,7 +72,7 @@
* 数据无效时返回清晰的错误信息,并指出错误数据的确切位置和内容。
* 把接收的数据赋值给参数 `item`
* 因为你把函数中的参数类型声明为 `Item`,所以还能获得所有属性及其类型的编辑器支持(补全等)。
* 为你的模型生成 <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> 定义,如果对你的项目有意义,还可以在其他地方使用它们。
* 为你的模型生成 [JSON Schema](https://json-schema.org) 定义,如果对你的项目有意义,还可以在其他地方使用它们。
* 这些 schema 会成为生成的 OpenAPI Schema 的一部分,并被自动文档的 <abbr title="User Interfaces - 用户界面">UIs</abbr> 使用。
## 自动文档 { #automatic-docs }
@ -101,15 +101,15 @@
我们甚至对 Pydantic 本身做了一些改动以支持这些功能。
上面的截图来自 <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>
上面的截图来自 [Visual Studio Code](https://code.visualstudio.com)
但使用 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 和大多数其他 Python 编辑器,你也会获得相同的编辑器支持:
但使用 [PyCharm](https://www.jetbrains.com/pycharm/) 和大多数其他 Python 编辑器,你也会获得相同的编辑器支持:
<img src="/img/tutorial/body/image05.png">
/// tip | 提示
如果你使用 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 作为编辑器,可以使用 <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm 插件</a>
如果你使用 [PyCharm](https://www.jetbrains.com/pycharm/) 作为编辑器,可以使用 [Pydantic PyCharm 插件](https://github.com/koxudaxi/pydantic-pycharm-plugin/)
它能改进对 Pydantic 模型的编辑器支持,包括:
@ -161,4 +161,4 @@ FastAPI 会根据默认值 `= None` 知道 `q` 的值不是必填的。
## 不使用 Pydantic { #without-pydantic }
即便不使用 Pydantic 模型也能使用 **Body** 参数。详见[请求体 - 多参数:请求体中的单值](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}
即便不使用 Pydantic 模型也能使用 **Body** 参数。详见[请求体 - 多参数:请求体中的单值](body-multiple-params.md#singular-values-in-body)。

4
docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md

@ -32,7 +32,7 @@
本例中,使用的是自定义响应头 `X-Key``X-Token`
但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的[安全工具](../security/index.md){.internal-link target=_blank}(详见下一章)
但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的[安全工具(下一章)](../security/index.md)。
///
@ -62,7 +62,7 @@
## 为一组路径操作定义依赖项 { #dependencies-for-a-group-of-path-operations }
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md){.internal-link target=_blank}一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md)一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。
## 全局依赖项 { #global-dependencies }

18
docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md

@ -14,8 +14,8 @@ FastAPI 支持那些在完成后执行一些<dfn title="有时也称为:“退
任何可以与以下装饰器一起使用的函数:
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a>
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager)
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
都可以作为 **FastAPI** 的依赖项。
@ -87,7 +87,7 @@ FastAPI 支持那些在完成后执行一些<dfn title="有时也称为:“退
/// note | 技术细节
这要归功于 Python 的<a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">上下文管理器</a>
这要归功于 Python 的[上下文管理器](https://docs.python.org/3/library/contextlib.html)
**FastAPI** 在内部使用它们来实现这一点。
@ -111,7 +111,7 @@ FastAPI 支持那些在完成后执行一些<dfn title="有时也称为:“退
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
如果你想捕获异常并基于它创建一个自定义响应,请创建一个[自定义异常处理器](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}
如果你想捕获异常并基于它创建一个自定义响应,请创建一个[自定义异常处理器](../handling-errors.md#install-custom-exception-handlers)。
## 同时使用 `yield``except` 的依赖项 { #dependencies-with-yield-and-except }
@ -233,7 +233,7 @@ participant operation as Path Operation
带有 `yield` 的依赖项随着时间演进以涵盖不同的用例并修复了一些问题。
如果你想了解在不同 FastAPI 版本中发生了哪些变化,可以在进阶指南中阅读更多:[高级依赖项 —— 包含 `yield`、`HTTPException`、`except` 和后台任务的依赖项](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}
如果你想了解在不同 FastAPI 版本中发生了哪些变化,可以在进阶指南中阅读更多:[高级依赖项 —— 包含 `yield`、`HTTPException`、`except` 和后台任务的依赖项](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks)。
## 上下文管理器 { #context-managers }
@ -241,7 +241,7 @@ participant operation as Path Operation
“上下文管理器”是你可以在 `with` 语句中使用的任意 Python 对象。
例如,<a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files" class="external-link" target="_blank">你可以用 `with` 来读取文件</a>
例如,[你可以用 `with` 来读取文件](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files)
```Python
with open("./somefile.txt") as f:
@ -265,7 +265,7 @@ with open("./somefile.txt") as f:
///
在 Python 中,你可以通过<a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank">创建一个带有 `__enter__()``__exit__()` 方法的类</a>来创建上下文管理器。
在 Python 中,你可以通过[创建一个带有 `__enter__()``__exit__()` 方法的类](https://docs.python.org/3/reference/datamodel.html#context-managers)来创建上下文管理器。
你也可以在 **FastAPI** 的带有 `yield` 的依赖中,使用依赖函数内部的 `with``async with` 语句来使用它们:
@ -275,8 +275,8 @@ with open("./somefile.txt") as f:
另一种创建上下文管理器的方式是:
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a>
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager)
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
用它们去装饰一个只包含单个 `yield` 的函数。

6
docs/zh/docs/tutorial/dependencies/global-dependencies.md

@ -2,14 +2,14 @@
有时,我们要为整个应用添加依赖项。
通过与[将 `dependencies` 添加到*路径操作装饰器*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 类似的方式,可以把依赖项添加至整个 `FastAPI` 应用。
通过与[将 `dependencies` 添加到*路径操作装饰器*](dependencies-in-path-operation-decorators.md) 类似的方式,可以把依赖项添加至整个 `FastAPI` 应用。
这样一来,就可以为所有*路径操作*应用该依赖项:
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
[将 `dependencies` 添加到*路径操作装饰器*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 一章的思路均适用于全局依赖项, 在本例中,这些依赖项可以用于应用中的所有*路径操作*。
[将 `dependencies` 添加到*路径操作装饰器*](dependencies-in-path-operation-decorators.md) 一章的思路均适用于全局依赖项, 在本例中,这些依赖项可以用于应用中的所有*路径操作*。
## 为一组路径操作定义依赖项 { #dependencies-for-groups-of-path-operations }
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md){.internal-link target=_blank}一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。
稍后,[大型应用 - 多文件](../../tutorial/bigger-applications.md)一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,将了解到如何为一组*路径操作*声明单个 `dependencies` 参数。

4
docs/zh/docs/tutorial/dependencies/index.md

@ -57,7 +57,7 @@ FastAPI 在 0.95.0 版本中新增了对 `Annotated` 的支持(并开始推荐
如果你的版本较旧,尝试使用 `Annotated` 会报错。
在使用 `Annotated` 之前,请确保[升级 FastAPI 版本](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}到至少 0.95.1。
在使用 `Annotated` 之前,请确保[升级 FastAPI 版本](../../deployment/versions.md#upgrading-the-fastapi-versions)到至少 0.95.1。
///
@ -152,7 +152,7 @@ commons: Annotated[dict, Depends(common_parameters)]
/// note | 注意
如果不了解异步,请参阅文档中关于 `async``await` 的章节:[异步:*“着急了?”*](../../async.md#in-a-hurry){.internal-link target=_blank}
如果不了解异步,请参阅文档中关于 `async``await` 的章节:[异步:*“着急了?”*](../../async.md#in-a-hurry)。
///

2
docs/zh/docs/tutorial/metadata.md

@ -14,7 +14,7 @@
| `version` | `string` | API 的版本。这是您自己的应用程序的版本,而不是 OpenAPI 的版本。例如 `2.5.0`。 |
| `terms_of_service` | `str` | API 服务条款的 URL。如果提供,则必须是 URL。 |
| `contact` | `dict` | 公开的 API 的联系信息。它可以包含多个字段。<details><summary><code>contact</code> 字段</summary><table><thead><tr><th>参数</th><th>类型</th><th>描述</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>联系人/组织的识别名称。</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>指向联系信息的 URL。必须采用 URL 格式。</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>联系人/组织的电子邮件地址。必须采用电子邮件地址的格式。</td></tr></tbody></table></details> |
| `license_info` | `dict` | 公开的 API 的许可证信息。它可以包含多个字段。<details><summary><code>license_info</code> 字段</summary><table><thead><tr><th>参数</th><th>类型</th><th>描述</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>必须</strong>(如果设置了 <code>license_info</code>)。用于 API 的许可证名称。</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API 的 <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> 许可证表达式。字段 <code>identifier</code> 与字段 <code>url</code> 互斥。<small>自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>用于 API 的许可证的 URL。必须采用 URL 格式。</td></tr></tbody></table></details> |
| `license_info` | `dict` | 公开的 API 的许可证信息。它可以包含多个字段。<details><summary><code>license_info</code> 字段</summary><table><thead><tr><th>参数</th><th>类型</th><th>描述</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>必须</strong>(如果设置了 <code>license_info</code>)。用于 API 的许可证名称。</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API 的 [SPDX](https://spdx.org/licenses/) 许可证表达式。字段 <code>identifier</code> 与字段 <code>url</code> 互斥。<small>自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>用于 API 的许可证的 URL。必须采用 URL 格式。</td></tr></tbody></table></details> |
你可以按如下方式设置它们:

2
docs/zh/docs/tutorial/path-operation-configuration.md

@ -58,7 +58,7 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用:
描述内容比较长且占用多行时,可以在函数的 <dfn title="作为函数内部的第一个表达式(不赋给任何变量)的多行字符串,用于文档用途">docstring</dfn> 中声明*路径操作*的描述,**FastAPI** 会从中读取。
文档字符串支持 <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>,能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。
文档字符串支持 [Markdown](https://en.wikipedia.org/wiki/Markdown),能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。
{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}

6
docs/zh/docs/tutorial/path-params-numeric-validations.md

@ -14,7 +14,7 @@ FastAPI 在 0.95.0 版本添加了对 `Annotated` 的支持(并开始推荐使
如果你使用的是更旧的版本,尝试使用 `Annotated` 会报错。
请确保在使用 `Annotated` 之前,将 FastAPI 版本[升级](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}到至少 0.95.1。
请确保在使用 `Annotated` 之前,将 FastAPI 版本[升级](../deployment/versions.md#upgrading-the-fastapi-versions)到至少 0.95.1。
///
@ -122,7 +122,7 @@ Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数
## 总结 { #recap }
你能够以与[查询参数和字符串校验](query-params-str-validations.md){.internal-link target=_blank}相同的方式使用 `Query`、`Path`(以及其他你还没见过的类)声明元数据和字符串校验。
你能够以与[查询参数和字符串校验](query-params-str-validations.md)相同的方式使用 `Query`、`Path`(以及其他你还没见过的类)声明元数据和字符串校验。
而且你还可以声明数值校验:
@ -139,7 +139,7 @@ Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数
///
/// note | 技术细节
/// note | 注意
当你从 `fastapi` 导入 `Query`、`Path` 和其他对象时,它们实际上是函数。

24
docs/zh/docs/tutorial/request-files.md

@ -4,9 +4,9 @@
/// info | 信息
要接收上传的文件,请先安装 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>
要接收上传的文件,请先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)
请确保你创建一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank}、激活它,然后安装,例如:
请确保你创建一个[虚拟环境](../virtual-environments.md)、激活它,然后安装,例如:
```console
$ pip install python-multipart
@ -63,8 +63,8 @@ $ pip install python-multipart
* 文件会先存储在内存中,直到达到最大上限,超过该上限后会写入磁盘。
* 因此,非常适合处理图像、视频、大型二进制等大文件,而不会占用所有内存。
* 你可以获取上传文件的元数据。
* 它提供 <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a>`async` 接口。
* 它暴露了一个实际的 Python <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> 对象,你可以直接传给期望「file-like」对象的其他库。
* 它提供 [file-like](https://docs.python.org/3/glossary.html#term-file-like-object)`async` 接口。
* 它暴露了一个实际的 Python [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) 对象,你可以直接传给期望「file-like」对象的其他库。
### `UploadFile` { #uploadfile }
@ -72,7 +72,7 @@ $ pip install python-multipart
* `filename`:上传的原始文件名字符串(`str`),例如 `myimage.jpg`
* `content_type`:内容类型(MIME 类型 / 媒体类型)的字符串(`str`),例如 `image/jpeg`
* `file`<a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a>(一个 <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> 对象)。这是实际的 Python 文件对象,你可以直接传递给其他期望「file-like」对象的函数或库。
* `file`[`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile)(一个 [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) 对象)。这是实际的 Python 文件对象,你可以直接传递给其他期望「file-like」对象的函数或库。
`UploadFile` 具有以下 `async` 方法。它们都会在底层调用对应的文件方法(使用内部的 `SpooledTemporaryFile`)。
@ -97,13 +97,13 @@ contents = await myfile.read()
contents = myfile.file.read()
```
/// note | 注意
/// note | `async` 技术细节
当你使用这些 `async` 方法时,**FastAPI** 会在线程池中运行相应的文件方法并等待其完成。
///
/// note | 注意
/// note | Starlette 技术细节
**FastAPI** 的 `UploadFile` 直接继承自 **Starlette**`UploadFile`,但添加了一些必要的部分,使其与 **Pydantic** 以及 FastAPI 的其他部分兼容。
@ -115,13 +115,13 @@ HTML 表单(`<form></form>`)向服务器发送数据的方式通常会对数
**FastAPI** 会确保从正确的位置读取这些数据,而不是从 JSON 中读取。
/// note | 注意
/// note | 技术细节
当不包含文件时,来自表单的数据通常使用「媒体类型」`application/x-www-form-urlencoded` 编码。
但当表单包含文件时,会编码为 `multipart/form-data`。如果你使用 `File`,**FastAPI** 会知道需要从请求体的正确位置获取文件。
如果你想进一步了解这些编码和表单字段,请参阅 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 开发者网络">MDN</abbr> 关于 <code>POST</code> 的 Web 文档</a>
如果你想进一步了解这些编码和表单字段,请参阅 [<abbr title="Mozilla Developer Network - Mozilla 开发者网络">MDN</abbr> 关于 `POST` 的 Web 文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)
///
@ -135,13 +135,13 @@ HTML 表单(`<form></form>`)向服务器发送数据的方式通常会对数
## 可选文件上传 { #optional-file-upload }
可以通过使用标准类型注解并将 `None` 作为默认值的方式将一个文件参数设为可选:
可以通过使用标准类型注解并将 `None` 作为默认值的方式将一个文件参数设为可选:
{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
## 带有额外元数据的 `UploadFile` { #uploadfile-with-additional-metadata }
也可以将 `File()``UploadFile` 一起使用,例如,设置额外的元数据:
也可以将 `File()``UploadFile` 一起使用,例如,设置额外的元数据:
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
@ -157,7 +157,7 @@ FastAPI 支持同时上传多个文件。
接收的也是含 `bytes``UploadFile` 的列表(`list`)。
/// note | 注意
/// note | 技术细节
也可以使用 `from starlette.responses import HTMLResponse`

4
docs/zh/docs/tutorial/request-form-models.md

@ -4,9 +4,9 @@
/// info | 信息
要使用表单,首先安装 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>
要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)
确保你创建一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},激活它,然后再安装,例如:
确保你创建一个[虚拟环境](../virtual-environments.md),激活它,然后再安装,例如:
```console
$ pip install python-multipart

4
docs/zh/docs/tutorial/request-forms-and-files.md

@ -4,9 +4,9 @@ FastAPI 支持同时使用 `File` 和 `Form` 定义文件和表单字段。
/// info | 信息
接收上传的文件和/或表单数据,首先安装 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>
接收上传的文件和/或表单数据,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)
请先创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装,例如:
请先创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
```console
$ pip install python-multipart

8
docs/zh/docs/tutorial/schema-extra-example.md

@ -12,7 +12,7 @@
这些额外信息会原样添加到该模型输出的 JSON Schema 中,并会在 API 文档中使用。
你可以使用属性 `model_config`,它接收一个 `dict`,详见 <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic 文档:配置</a>
你可以使用属性 `model_config`,它接收一个 `dict`,详见 [Pydantic 文档:配置](https://docs.pydantic.dev/latest/api/config/)
你可以设置 `"json_schema_extra"`,其值为一个 `dict`,包含你希望出现在生成 JSON Schema 中的任意附加数据,包括 `examples`
@ -145,12 +145,12 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持
OpenAPI 还在规范的其他部分添加了 `example``examples` 字段:
- <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object`(规范中)</a>,被 FastAPI 的以下内容使用:
- [`Parameter Object`(规范中)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object),被 FastAPI 的以下内容使用:
- `Path()`
- `Query()`
- `Header()`
- `Cookie()`
- <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object` 中的 `content` 字段里的 `Media Type Object`(规范中)</a>,被 FastAPI 的以下内容使用:
- [`Request Body Object` 中的 `content` 字段里的 `Media Type Object`(规范中)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object),被 FastAPI 的以下内容使用:
- `Body()`
- `File()`
- `Form()`
@ -163,7 +163,7 @@ OpenAPI 还在规范的其他部分添加了 `example` 和 `examples` 字段:
### JSON Schema 的 `examples` 字段 { #json-schemas-examples-field }
后来,JSON Schema 在新版本的规范中添加了 <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a> 字段。
后来,JSON Schema 在新版本的规范中添加了 [`examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5) 字段。
随后新的 OpenAPI 3.1.0 基于最新版本(JSON Schema 2020-12),其中包含了这个新的 `examples` 字段。

10
docs/zh/docs/tutorial/security/first-steps.md

@ -26,11 +26,11 @@
/// info | 信息
当你使用命令 `pip install "fastapi[standard]"` 安装 **FastAPI** 时,<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> 包会自动安装。
当你使用命令 `pip install "fastapi[standard]"` 安装 **FastAPI** 时,[`python-multipart`](https://github.com/Kludex/python-multipart) 包会自动安装。
但是,如果你使用 `pip install fastapi`,默认不会包含 `python-multipart` 包。
如需手动安装,请先创建并激活[虚拟环境](../../virtual-environments.md){.internal-link target=_blank},然后执行:
如需手动安装,请先创建并激活[虚拟环境](../../virtual-environments.md),然后执行:
```console
$ pip install python-multipart
@ -45,7 +45,7 @@ $ pip install python-multipart
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@ -54,7 +54,7 @@ $ fastapi dev main.py
## 查看 { #check-it }
打开交互式文档:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
打开交互式文档:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
你会看到类似这样的界面:
@ -140,7 +140,7 @@ OAuth2 的设计目标是让后端或 API 与负责用户认证的服务器解
因为使用的是相对 URL,若你的 API 位于 `https://example.com/`,它将指向 `https://example.com/token`;若你的 API 位于 `https://example.com/api/v1/`,它将指向 `https://example.com/api/v1/token`
使用相对 URL 很重要,这能确保你的应用在诸如[使用代理](../../advanced/behind-a-proxy.md){.internal-link target=_blank}等高级用例中依然正常工作。
使用相对 URL 很重要,这能确保你的应用在诸如[使用代理](../../advanced/behind-a-proxy.md)等高级用例中依然正常工作。
///

10
docs/zh/docs/tutorial/security/oauth2-jwt.md

@ -24,13 +24,13 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
一周后令牌过期,用户将不再被授权,需要重新登录以获取新令牌。而如果用户(或第三方)尝试修改令牌来更改过期时间,你也能发现,因为签名将不匹配。
如果你想动手体验 JWT 令牌并了解它的工作方式,请访问 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>
如果你想动手体验 JWT 令牌并了解它的工作方式,请访问 [https://jwt.io](https://jwt.io/)
## 安装 `PyJWT` { #install-pyjwt }
我们需要安装 `PyJWT`,以便在 Python 中生成和校验 JWT 令牌。
请确保创建并激活一个[虚拟环境](../../virtual-environments.md){.internal-link target=_blank},然后安装 `pyjwt`
请确保创建并激活一个[虚拟环境](../../virtual-environments.md),然后安装 `pyjwt`
<div class="termy">
@ -46,7 +46,7 @@ $ pip install pyjwt
如果你计划使用类似 RSA 或 ECDSA 的数字签名算法,你应该安装加密库依赖项 `pyjwt[crypto]`
可以在 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT 安装文档</a>中了解更多。
可以在 [PyJWT 安装文档](https://pyjwt.readthedocs.io/en/latest/installation.html)中了解更多。
///
@ -72,7 +72,7 @@ pwdlib 是一个用于处理密码哈希的优秀 Python 包。
推荐的算法是 “Argon2”。
请确保创建并激活一个[虚拟环境](../../virtual-environments.md){.internal-link target=_blank},然后安装带 Argon2 的 pwdlib:
请确保创建并激活一个[虚拟环境](../../virtual-environments.md),然后安装带 Argon2 的 pwdlib:
<div class="termy">
@ -200,7 +200,7 @@ JWT 除了用于识别用户并允许其直接在你的 API 上执行操作之
## 检查 { #check-it }
运行服务器并打开文档:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
运行服务器并打开文档:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
你会看到这样的用户界面:

4
docs/zh/docs/tutorial/security/simple-oauth2.md

@ -146,7 +146,7 @@ UserInDB(
/// info | 信息
`user_dict` 的说明,详见[**更多模型**一章](../extra-models.md#about-user-in-dict){.internal-link target=_blank}
`user_dict` 的说明,详见[**更多模型**一章](../extra-models.md#about-user-in-dict)。
///
@ -216,7 +216,7 @@ UserInDB(
## 实际效果 { #see-it-in-action }
打开 API 文档:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>
打开交互式文档:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
### 身份验证 { #authenticate }

22
docs/zh/docs/tutorial/sql-databases.md

@ -2,9 +2,9 @@
**FastAPI** 并不要求你使用 SQL(关系型)数据库。你可以使用你想用的**任何数据库**。
这里,我们来看一个使用 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a> 的示例。
这里,我们来看一个使用 [SQLModel](https://sqlmodel.tiangolo.com/) 的示例。
**SQLModel** 基于 <a href="https://www.sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a> 和 Pydantic 构建。它由 **FastAPI** 的同一作者制作,旨在完美匹配需要使用**SQL 数据库**的 FastAPI 应用程序。
**SQLModel** 基于 [SQLAlchemy](https://www.sqlalchemy.org/) 和 Pydantic 构建。它由 **FastAPI** 的同一作者制作,旨在完美匹配需要使用**SQL 数据库**的 FastAPI 应用程序。
/// tip | 提示
@ -26,15 +26,15 @@
/// tip | 提示
有一个使用 **FastAPI****PostgreSQL** 的官方项目生成器,其中包括了前端和更多工具: <a href="https://github.com/fastapi/full-stack-fastapi-template" class="external-link" target="_blank">https://github.com/fastapi/full-stack-fastapi-template</a>
有一个使用 **FastAPI****PostgreSQL** 的官方项目生成器,其中包括了前端和更多工具: [https://github.com/fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)
///
这是一个非常简单和简短的教程。如果你想了解一般的数据库、SQL 或更高级的功能,请查看 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel 文档</a>
这是一个非常简单和简短的教程。如果你想了解一般的数据库、SQL 或更高级的功能,请查看 [SQLModel 文档](https://sqlmodel.tiangolo.com/)
## 安装 `SQLModel` { #install-sqlmodel }
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后安装 `sqlmodel`
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md),然后安装 `sqlmodel`
<div class="termy">
@ -65,7 +65,7 @@ $ pip install sqlmodel
* `Field(primary_key=True)` 会告诉 SQLModel `id` 是 SQL 数据库中的**主键**(你可以在 SQLModel 文档中了解更多关于 SQL 主键的信息)。
**注意:** 我们为主键字段使用 `int | None`,这样在 Python 代码中我们可以在没有 `id`(`id=None`)的情况下创建对象,并假定数据库在保存时会生成它。SQLModel 会理解数据库会提供 `id`,并在数据库模式中将该列定义为非空的 `INTEGER`。详见 <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">SQLModel 关于主键的文档</a>
**注意:** 我们为主键字段使用 `int | None`,这样在 Python 代码中我们可以在没有 `id`(`id=None`)的情况下创建对象,并假定数据库在保存时会生成它。SQLModel 会理解数据库会提供 `id`,并在数据库模式中将该列定义为非空的 `INTEGER`。详见 [SQLModel 关于主键的文档](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id)
* `Field(index=True)` 会告诉 SQLModel 应该为此列创建一个 **SQL 索引**,这样在读取按此列过滤的数据时,程序能在数据库中进行更快的查找。
@ -111,7 +111,7 @@ SQLModel 的 `engine`(实际上它是一个 SQLAlchemy 的 `engine`)是用
/// tip | 提示
SQLModel 将会拥有封装 Alembic 的迁移工具,但目前你可以直接使用 <a href="https://alembic.sqlalchemy.org/en/latest/" class="external-link" target="_blank">Alembic</a>
SQLModel 将会拥有封装 Alembic 的迁移工具,但目前你可以直接使用 [Alembic](https://alembic.sqlalchemy.org/en/latest/)
///
@ -152,7 +152,7 @@ SQLModel 将会拥有封装 Alembic 的迁移工具,但目前你可以直接
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@ -337,7 +337,7 @@ $ fastapi dev main.py
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@ -352,6 +352,6 @@ $ fastapi dev main.py
## 总结 { #recap }
你可以使用 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">**SQLModel**</a> 与 SQL 数据库进行交互,并通过*数据模型*和*表模型*简化代码。
你可以使用 [**SQLModel**](https://sqlmodel.tiangolo.com/) 与 SQL 数据库进行交互,并通过*数据模型*和*表模型*简化代码。
你可以在 **SQLModel** 文档中学习到更多内容,其中有一个更详细的<a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">将 SQLModel 与 **FastAPI** 一起使用的迷你教程</a>。🚀
你可以在 **SQLModel** 文档中学习到更多内容,其中有一个更详细的[将 SQLModel 与 **FastAPI** 一起使用的迷你教程](https://sqlmodel.tiangolo.com/tutorial/fastapi/)。🚀

4
docs/zh/docs/tutorial/static-files.md

@ -23,7 +23,7 @@
这与使用 `APIRouter` 不同,因为挂载的应用是完全独立的。主应用的 OpenAPI 和文档不会包含已挂载应用的任何内容,等等。
你可以在[高级用户指南](../advanced/index.md){.internal-link target=_blank}中了解更多。
你可以在[高级用户指南](../advanced/index.md)中了解更多。
## 细节 { #details }
@ -37,4 +37,4 @@
## 更多信息 { #more-info }
更多细节和选项请查阅 <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Starlette 的静态文件文档</a>
更多细节和选项请查阅 [Starlette 的静态文件文档](https://www.starlette.dev/staticfiles/)

24
docs/zh/docs/tutorial/testing.md

@ -1,18 +1,18 @@
# 测试 { #testing }
感谢 <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>,测试**FastAPI** 应用轻松又愉快。
感谢 [Starlette](https://www.starlette.dev/testclient/),测试**FastAPI** 应用轻松又愉快。
它基于 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>而HTTPX又是基于Requests设计的,所以很相似且易懂。
它基于 [HTTPX](https://www.python-httpx.org),而HTTPX又是基于Requests设计的,所以很相似且易懂。
有了它,你可以直接与**FastAPI**一起使用 <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a>
有了它,你可以直接与**FastAPI**一起使用 [pytest](https://docs.pytest.org/)
## 使用 `TestClient` { #using-testclient }
/// info | 信息
要使用 `TestClient`,先要安装 <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>
要使用 `TestClient`,先要安装 [`httpx`](https://www.python-httpx.org)
确保你创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装,例如:
确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
```console
$ pip install httpx
@ -52,7 +52,7 @@ $ pip install httpx
/// tip | 提示
除了发送请求之外,如果你还想测试时在FastAPI应用中调用 `async` 函数(例如异步数据库函数), 可以在高级教程中看下 [Async Tests](../advanced/async-tests.md){.internal-link target=_blank}
除了发送请求之外,如果你还想测试时在FastAPI应用中调用 `async` 函数(例如异步数据库函数), 可以在高级教程中看下 [Async Tests](../advanced/async-tests.md) 。
///
@ -64,7 +64,7 @@ $ pip install httpx
### **FastAPI** app 文件 { #fastapi-app-file }
假设你有一个像 [更大的应用](bigger-applications.md){.internal-link target=_blank} 中所描述的文件结构:
假设你有一个像[更大的应用](bigger-applications.md)中所描述的文件结构:
```
.
@ -112,7 +112,7 @@ $ pip install httpx
│   └── test_main.py
```
假设现在包含**FastAPI** app的文件 `main.py` 有些其他**路径操作**。
假设现在包含**FastAPI** app的文件 `main.py` 有些其他**路径操作**。
有个 `GET` 操作会返回错误。
@ -128,7 +128,7 @@ $ pip install httpx
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
每当你需要客户端在请求中传递信息,但你不知道如何传递时,你可以通过搜索(谷歌)如何用 `httpx`做,或者是用 `requests` 做,毕竟HTTPX的设计是基于Requests的设计的。
每当你需要客户端在请求中传递信息,但你不知道如何传递时,你可以通过搜索(谷歌)如何用 `httpx` 做,或者是用 `requests` 做,毕竟HTTPX的设计是基于Requests的设计的。
接着只需在测试中同样操作。
@ -140,13 +140,13 @@ $ pip install httpx
* 要发送 *headers*,传 `dict``headers` 参数。
* 对于 *cookies*,传 `dict``cookies` 参数。
关于如何传数据给后端的更多信息 (使用`httpx` 或 `TestClient`),请查阅 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX 文档</a>.
关于如何传数据给后端的更多信息(使用 `httpx``TestClient`),请查阅 [HTTPX 文档](https://www.python-httpx.org)。
/// info | 信息
注意 `TestClient` 接收可以被转化为JSON的数据,而不是Pydantic模型。
如果你在测试中有一个Pydantic模型,并且你想在测试时发送它的数据给应用,你可以使用在[JSON Compatible Encoder](encoder.md){.internal-link target=_blank}介绍的`jsonable_encoder` 。
如果你在测试中有一个Pydantic模型,并且你想在测试时发送它的数据给应用,你可以使用在[JSON Compatible Encoder](encoder.md)介绍的`jsonable_encoder` 。
///
@ -154,7 +154,7 @@ $ pip install httpx
之后,你只需要安装 `pytest`
确保你创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装,例如:
确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
<div class="termy">

Loading…
Cancel
Save