From 2ecbf4b31ff56cdf23badb28f2ba7fe6d7625e5b Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Fri, 13 Feb 2026 13:40:51 +0100 Subject: [PATCH] Update all --- docs/zh/docs/advanced/additional-responses.md | 4 +- .../docs/advanced/additional-status-codes.md | 4 +- .../zh/docs/advanced/advanced-dependencies.md | 8 +- docs/zh/docs/advanced/async-tests.md | 10 +- docs/zh/docs/advanced/behind-a-proxy.md | 12 +- docs/zh/docs/advanced/custom-response.md | 34 ++-- docs/zh/docs/advanced/dataclasses.md | 2 +- docs/zh/docs/advanced/events.md | 12 +- docs/zh/docs/advanced/generate-clients.md | 10 +- docs/zh/docs/advanced/middleware.md | 8 +- docs/zh/docs/advanced/openapi-callbacks.md | 2 +- docs/zh/docs/advanced/openapi-webhooks.md | 2 +- .../path-operation-advanced-configuration.md | 16 +- .../advanced/response-change-status-code.md | 6 +- docs/zh/docs/advanced/response-cookies.md | 6 +- docs/zh/docs/advanced/response-directly.md | 4 +- docs/zh/docs/advanced/response-headers.md | 6 +- .../docs/advanced/security/http-basic-auth.md | 6 +- docs/zh/docs/advanced/settings.md | 26 +-- docs/zh/docs/advanced/sub-applications.md | 6 +- docs/zh/docs/advanced/templates.md | 2 +- docs/zh/docs/advanced/testing-dependencies.md | 1 - docs/zh/docs/advanced/testing-events.md | 4 +- docs/zh/docs/advanced/testing-websockets.md | 2 +- .../docs/advanced/using-request-directly.md | 2 +- docs/zh/docs/advanced/websockets.md | 8 +- docs/zh/docs/advanced/wsgi.md | 2 +- docs/zh/docs/async.md | 4 +- docs/zh/docs/benchmarks.md | 2 +- docs/zh/docs/deployment/concepts.md | 2 +- docs/zh/docs/deployment/docker.md | 10 +- docs/zh/docs/deployment/https.md | 8 +- docs/zh/docs/deployment/manually.md | 6 +- docs/zh/docs/deployment/server-workers.md | 20 +- docs/zh/docs/features.md | 12 +- docs/zh/docs/help-fastapi.md | 2 +- docs/zh/docs/how-to/configure-swagger-ui.md | 6 +- docs/zh/docs/how-to/general.md | 2 +- docs/zh/docs/index.md | 10 +- docs/zh/docs/python-types.md | 188 ++++-------------- docs/zh/docs/tutorial/background-tasks.md | 8 +- docs/zh/docs/tutorial/bigger-applications.md | 28 +-- docs/zh/docs/tutorial/body-multiple-params.md | 6 - docs/zh/docs/tutorial/body-nested-models.md | 4 +- docs/zh/docs/tutorial/body.md | 2 +- docs/zh/docs/tutorial/cookie-param-models.md | 10 +- docs/zh/docs/tutorial/cors.md | 4 +- docs/zh/docs/tutorial/debugging.md | 4 +- .../dependencies/classes-as-dependencies.md | 28 +-- ...pendencies-in-path-operation-decorators.md | 12 +- .../dependencies/dependencies-with-yield.md | 24 +-- .../dependencies/global-dependencies.md | 2 +- docs/zh/docs/tutorial/dependencies/index.md | 6 +- .../tutorial/dependencies/sub-dependencies.md | 6 +- docs/zh/docs/tutorial/encoder.md | 4 +- docs/zh/docs/tutorial/extra-models.md | 14 +- docs/zh/docs/tutorial/first-steps.md | 22 +- docs/zh/docs/tutorial/handling-errors.md | 16 +- docs/zh/docs/tutorial/metadata.md | 12 +- docs/zh/docs/tutorial/middleware.md | 4 +- .../tutorial/path-operation-configuration.md | 12 +- .../path-params-numeric-validations.md | 14 +- docs/zh/docs/tutorial/path-params.md | 30 +-- .../tutorial/query-params-str-validations.md | 42 +--- docs/zh/docs/tutorial/query-params.md | 13 +- docs/zh/docs/tutorial/request-files.md | 22 +- docs/zh/docs/tutorial/request-form-models.md | 4 +- .../docs/tutorial/request-forms-and-files.md | 6 +- docs/zh/docs/tutorial/request-forms.md | 6 +- docs/zh/docs/tutorial/response-model.md | 6 +- docs/zh/docs/tutorial/response-status-code.md | 6 +- docs/zh/docs/tutorial/schema-extra-example.md | 2 +- docs/zh/docs/tutorial/security/first-steps.md | 6 +- .../tutorial/security/get-current-user.md | 2 +- docs/zh/docs/tutorial/security/index.md | 2 +- docs/zh/docs/tutorial/security/oauth2-jwt.md | 12 +- .../docs/tutorial/security/simple-oauth2.md | 12 +- docs/zh/docs/tutorial/sql-databases.md | 2 +- docs/zh/docs/tutorial/static-files.md | 4 +- docs/zh/docs/tutorial/testing.md | 6 +- docs/zh/docs/virtual-environments.md | 10 +- 81 files changed, 385 insertions(+), 527 deletions(-) diff --git a/docs/zh/docs/advanced/additional-responses.md b/docs/zh/docs/advanced/additional-responses.md index bc197280a..aa3d22d1c 100644 --- a/docs/zh/docs/advanced/additional-responses.md +++ b/docs/zh/docs/advanced/additional-responses.md @@ -26,7 +26,7 @@ 例如,要声明另一个状态码为 `404` 且具有 Pydantic 模型 `Message` 的响应,你可以这样写: -{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *} +{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *} /// note | 注意 @@ -203,7 +203,7 @@ 以及一个状态码为 `200` 的响应,它使用你的 `response_model`,但包含自定义的 `example`: -{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *} +{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *} 所有这些都会被合并并包含到你的 OpenAPI 中,并显示在 API 文档里: diff --git a/docs/zh/docs/advanced/additional-status-codes.md b/docs/zh/docs/advanced/additional-status-codes.md index 23ceab4e8..7eeffaf53 100644 --- a/docs/zh/docs/advanced/additional-status-codes.md +++ b/docs/zh/docs/advanced/additional-status-codes.md @@ -16,7 +16,7 @@ {* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} -/// warning +/// warning | 警告 当你直接返回一个像上面例子中的 `Response` 对象时,它会直接返回。 @@ -26,7 +26,7 @@ /// -/// note | 技术细节 +/// note | 注意 你也可以使用 `from starlette.responses import JSONResponse`。  diff --git a/docs/zh/docs/advanced/advanced-dependencies.md b/docs/zh/docs/advanced/advanced-dependencies.md index 3efca8944..a547e8881 100644 --- a/docs/zh/docs/advanced/advanced-dependencies.md +++ b/docs/zh/docs/advanced/advanced-dependencies.md @@ -18,7 +18,7 @@ 为此,声明一个 `__call__` 方法: -{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *} +{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *} 在这种情况下,**FastAPI** 会使用这个 `__call__` 来检查附加参数和子依赖,并且稍后会调用它,把返回值传递给你的*路径操作函数*中的参数。 @@ -26,7 +26,7 @@ 现在,我们可以用 `__init__` 声明实例的参数,用来“参数化”这个依赖项: -{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *} +{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *} 在本例中,**FastAPI** 不会接触或关心 `__init__`,我们会在自己的代码中直接使用它。 @@ -34,7 +34,7 @@ 我们可以这样创建该类的实例: -{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *} +{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *} 这样就把依赖项“参数化”了,现在它内部带有属性 `checker.fixed_content` 的值 `"bar"`。 @@ -50,7 +50,7 @@ checker(q="somequery") ...并将其返回值作为依赖项的值,传给我们的*路径操作函数*中的参数 `fixed_content_included`: -{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *} +{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *} /// tip | 提示 diff --git a/docs/zh/docs/advanced/async-tests.md b/docs/zh/docs/advanced/async-tests.md index 6803358d2..16b8a8c81 100644 --- a/docs/zh/docs/advanced/async-tests.md +++ b/docs/zh/docs/advanced/async-tests.md @@ -32,11 +32,11 @@ 文件 `main.py` 将包含: -{* ../../docs_src/async_tests/app_a_py39/main.py *} +{* ../../docs_src/async_tests/app_a_py310/main.py *} 文件 `test_main.py` 将包含针对 `main.py` 的测试,现在它可能看起来如下: -{* ../../docs_src/async_tests/app_a_py39/test_main.py *} +{* ../../docs_src/async_tests/app_a_py310/test_main.py *} ## 运行测试 { #run-it } @@ -56,7 +56,7 @@ $ pytest 这个标记 `@pytest.mark.anyio` 会告诉 pytest 该测试函数应该被异步调用: -{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *} +{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *} /// tip | 提示 @@ -66,7 +66,7 @@ $ pytest 我们现在可以使用应用程序创建一个 `AsyncClient` ,并使用 `await` 向其发送异步请求。 -{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *} +{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *} 这相当于: @@ -74,7 +74,7 @@ $ pytest response = client.get('/') ``` -我们曾经通过它向 `TestClient` 发出请求。 +...我们曾经通过它向 `TestClient` 发出请求。 /// tip | 提示 diff --git a/docs/zh/docs/advanced/behind-a-proxy.md b/docs/zh/docs/advanced/behind-a-proxy.md index b44b0b5ac..3ccc65f29 100644 --- a/docs/zh/docs/advanced/behind-a-proxy.md +++ b/docs/zh/docs/advanced/behind-a-proxy.md @@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*" 例如,假设你定义了一个*路径操作* `/items/`: -{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *} 如果客户端尝试访问 `/items`,默认会被重定向到 `/items/`。 @@ -115,7 +115,7 @@ sequenceDiagram 即使你的所有代码都假设只有 `/app`。 -{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *} 代理会在将请求传递给应用服务器(可能是通过 FastAPI CLI 运行的 Uvicorn)之前,实时**“移除”**这个**路径前缀**,让你的应用认为它是在 `/app` 被服务,这样你就不需要更新所有代码去包含 `/api/v1` 前缀。 @@ -193,7 +193,7 @@ ASGI 规范为这种用例定义了 `root_path`。 这里我们把它包含在响应消息中仅用于演示。 -{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *} 然后,如果你这样启动 Uvicorn: @@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 或者,如果你无法提供类似 `--root-path` 的命令行选项,你可以在创建 FastAPI 应用时设置参数 `root_path`: -{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *} +{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *} 把 `root_path` 传给 `FastAPI` 等同于把命令行选项 `--root-path` 传给 Uvicorn 或 Hypercorn。 @@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 例如: -{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *} +{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *} 会生成如下的 OpenAPI 模式: @@ -455,7 +455,7 @@ OpenAPI 规范中的 `servers` 属性是可选的。 如果你不希望 **FastAPI** 包含一个使用 `root_path` 的自动服务器,可以使用参数 `root_path_in_servers=False`: -{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *} +{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *} 这样它就不会被包含到 OpenAPI 模式中。 diff --git a/docs/zh/docs/advanced/custom-response.md b/docs/zh/docs/advanced/custom-response.md index f5bec5fdc..7c19b73fb 100644 --- a/docs/zh/docs/advanced/custom-response.md +++ b/docs/zh/docs/advanced/custom-response.md @@ -30,7 +30,7 @@ 但如果你确定你返回的内容是「可以用 JSON 序列化」的,你可以将它直接传给响应类,从而避免在传给响应类之前先通过 `jsonable_encoder` 带来的额外开销。 -{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *} /// info | 信息 @@ -55,7 +55,7 @@ * 导入 `HTMLResponse`。 * 将 `HTMLResponse` 作为你的 *路径操作* 的 `response_class` 参数传入。 -{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *} /// info | 信息 @@ -73,7 +73,7 @@ 和上面一样的例子,返回一个 `HTMLResponse` 看起来可能是这样: -{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *} +{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *} /// warning | 警告 @@ -97,7 +97,7 @@ 比如像这样: -{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *} +{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *} 在这个例子中,函数 `generate_html_response()` 已经生成并返回 `Response` 对象而不是在 `str` 中返回 HTML。 @@ -136,7 +136,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它还将包含一个基于 `media_type` 的 Content-Type 头,并为文本类型附加一个字符集。 -{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *} ### `HTMLResponse` { #htmlresponse } @@ -146,7 +146,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 接受文本或字节并返回纯文本响应。 -{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *} ### `JSONResponse` { #jsonresponse } @@ -180,7 +180,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 /// -{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *} /// tip | 提示 @@ -194,13 +194,13 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 你可以直接返回一个 `RedirectResponse`: -{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *} +{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *} --- 或者你可以把它用于 `response_class` 参数: -{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *} 如果你这么做,那么你可以在 *路径操作* 函数中直接返回 URL。 @@ -210,13 +210,13 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 你也可以将 `status_code` 参数和 `response_class` 参数结合使用: -{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *} ### `StreamingResponse` { #streamingresponse } 采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。 -{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *} +{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *} #### 对类似文件的对象使用 `StreamingResponse` { #using-streamingresponse-with-file-like-objects } @@ -226,7 +226,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 这也包括许多与云存储、视频处理等交互的库。 -{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *} +{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *} 1. 这是生成器函数。之所以是「生成器函数」,是因为它内部包含 `yield` 语句。 2. 通过使用 `with` 代码块,我们可以确保在生成器函数完成后关闭类文件对象。因此,在它完成发送响应之后会被关闭。 @@ -255,11 +255,11 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 文件响应将包含适当的 `Content-Length`、`Last-Modified` 和 `ETag` 响应头。 -{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *} +{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *} 你也可以使用 `response_class` 参数: -{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *} +{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *} 在这种情况下,你可以在 *路径操作* 函数中直接返回文件路径。 @@ -273,7 +273,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 你可以创建一个 `CustomORJSONResponse`。你需要做的主要事情是实现一个返回 `bytes` 的 `Response.render(content)` 方法: -{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *} +{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *} 现在,不再是返回: @@ -281,7 +281,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 {"message": "Hello World"} ``` -…这个响应将返回: +...这个响应将返回: ```json { @@ -299,7 +299,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它 在下面的示例中,**FastAPI** 会在所有 *路径操作* 中默认使用 `ORJSONResponse`,而不是 `JSONResponse`。 -{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *} +{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *} /// tip | 提示 diff --git a/docs/zh/docs/advanced/dataclasses.md b/docs/zh/docs/advanced/dataclasses.md index d62aef8f3..f552d779f 100644 --- a/docs/zh/docs/advanced/dataclasses.md +++ b/docs/zh/docs/advanced/dataclasses.md @@ -59,7 +59,7 @@ FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydant 在本例中,它是一个 `Item` 数据类列表。 6. 这里我们返回一个字典,里面的 `items` 是一个数据类列表。 - FastAPI 仍然能够将数据序列化为 JSON。 + FastAPI 仍然能够将数据序列化为 JSON。 7. 这里的 `response_model` 使用了 “`Author` 数据类列表” 的类型注解。 同样,你可以将 `dataclasses` 与标准类型注解组合使用。 diff --git a/docs/zh/docs/advanced/events.md b/docs/zh/docs/advanced/events.md index 7b49931a4..71ad1ae38 100644 --- a/docs/zh/docs/advanced/events.md +++ b/docs/zh/docs/advanced/events.md @@ -30,7 +30,7 @@ 我们使用 `yield` 创建了一个异步函数 `lifespan()` 像这样: -{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *} +{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *} 在这里,我们在 `yield` 之前将(虚拟的)模型函数放入机器学习模型的字典中,以此模拟加载模型的耗时**启动**操作。这段代码将在应用程序**开始处理请求之前**执行,即**启动**期间。 @@ -48,7 +48,7 @@ 首先要注意的是,我们定义了一个带有 `yield` 的异步函数。这与带有 `yield` 的依赖项非常相似。 -{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *} +{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *} 这个函数在 `yield` 之前的部分,会在应用启动前执行。 @@ -60,7 +60,7 @@ 它将函数转化为所谓的“**异步上下文管理器**”。 -{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *} +{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *} 在 Python 中,**上下文管理器**是一个你可以在 `with` 语句中使用的东西,例如,`open()` 可以作为上下文管理器使用。 @@ -82,7 +82,7 @@ async with lifespan(app): `FastAPI` 的 `lifespan` 参数接受一个**异步上下文管理器**,所以我们可以把我们新定义的异步上下文管理器 `lifespan` 传给它。 -{* ../../docs_src/events/tutorial003_py39.py hl[22] *} +{* ../../docs_src/events/tutorial003_py310.py hl[22] *} ## 替代事件(弃用) { #alternative-events-deprecated } @@ -104,7 +104,7 @@ async with lifespan(app): 使用事件 `"startup"` 声明一个在应用启动前运行的函数: -{* ../../docs_src/events/tutorial001_py39.py hl[8] *} +{* ../../docs_src/events/tutorial001_py310.py hl[8] *} 本例中,`startup` 事件处理器函数为项目“数据库”(只是一个 `dict`)提供了一些初始值。 @@ -116,7 +116,7 @@ async with lifespan(app): 使用事件 `"shutdown"` 声明一个在应用关闭时运行的函数: -{* ../../docs_src/events/tutorial002_py39.py hl[6] *} +{* ../../docs_src/events/tutorial002_py310.py hl[6] *} 此处,`shutdown` 事件处理器函数会向文件 `log.txt` 写入一行文本 `"Application shutdown"`。 diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md index 48a4ba07a..e8a3b2055 100644 --- a/docs/zh/docs/advanced/generate-clients.md +++ b/docs/zh/docs/advanced/generate-clients.md @@ -40,7 +40,7 @@ FastAPI 会自动生成 **OpenAPI 3.1** 规范,因此你使用的任何工具 先从一个简单的 FastAPI 应用开始: -{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *} +{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *} 请注意,这些*路径操作*使用 `Item` 和 `ResponseMessage` 模型来定义它们的请求载荷和响应载荷。 @@ -98,7 +98,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client 例如,你可以有一个 **items** 相关的部分和另一个 **users** 相关的部分,它们可以用标签来分隔: -{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *} +{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *} ### 生成带标签的 TypeScript 客户端 { #generate-a-typescript-client-with-tags } @@ -121,7 +121,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) ``` -……这是因为客户端生成器会把每个*路径操作*的 OpenAPI 内部**操作 ID(operation ID)**用作方法名的一部分。 +...这是因为客户端生成器会把每个*路径操作*的 OpenAPI 内部**操作 ID(operation ID)**用作方法名的一部分。 OpenAPI 要求每个操作 ID 在所有*路径操作*中都是唯一的,因此 FastAPI 会使用**函数名**、**路径**和**HTTP 方法/操作**来生成操作 ID,以确保其唯一性。 @@ -145,7 +145,7 @@ FastAPI 为每个*路径操作*使用一个**唯一 ID**,它既用于**操作 然后你可以把这个自定义函数通过 `generate_unique_id_function` 参数传给 **FastAPI**: -{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *} +{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *} ### 使用自定义操作 ID 生成 TypeScript 客户端 { #generate-a-typescript-client-with-custom-operation-ids } @@ -167,7 +167,7 @@ FastAPI 为每个*路径操作*使用一个**唯一 ID**,它既用于**操作 我们可以把 OpenAPI JSON 下载到 `openapi.json` 文件中,然后用如下脚本**移除这个标签前缀**: -{* ../../docs_src/generate_clients/tutorial004_py39.py *} +{* ../../docs_src/generate_clients/tutorial004_py310.py *} //// tab | Node.js diff --git a/docs/zh/docs/advanced/middleware.md b/docs/zh/docs/advanced/middleware.md index 108bbbb5c..de4a3fcb1 100644 --- a/docs/zh/docs/advanced/middleware.md +++ b/docs/zh/docs/advanced/middleware.md @@ -43,7 +43,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") **FastAPI** 为常见用例提供了一些中间件,下面介绍怎么使用这些中间件。 -/// note | 注意 +/// note | 技术细节 以下几个示例中也可以使用 `from starlette.middleware.something import SomethingMiddleware`。 @@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") 任何传向 `http` 或 `ws` 的请求都会被重定向至安全方案。 -{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *} ## `TrustedHostMiddleware` { #trustedhostmiddleware } 强制所有传入请求都必须正确设置 `Host` 请求头,以防 HTTP 主机头攻击。 -{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *} +{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *} 支持以下参数: @@ -78,7 +78,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") 中间件会处理标准响应与流响应。 -{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *} 支持以下参数: diff --git a/docs/zh/docs/advanced/openapi-callbacks.md b/docs/zh/docs/advanced/openapi-callbacks.md index 6e8df68ae..cc9f5c28e 100644 --- a/docs/zh/docs/advanced/openapi-callbacks.md +++ b/docs/zh/docs/advanced/openapi-callbacks.md @@ -179,7 +179,7 @@ JSON 请求体包含如下内容: ### 查看文档 { #check-the-docs } -现在,使用 Uvicorn 启动应用,打开 http://127.0.0.1:8000/docs。 +现在,启动应用并打开 http://127.0.0.1:8000/docs。 就能看到文档的*路径操作*已经包含了**回调**的内容以及*外部 API*: diff --git a/docs/zh/docs/advanced/openapi-webhooks.md b/docs/zh/docs/advanced/openapi-webhooks.md index 9e64ed4e3..d23fbcf88 100644 --- a/docs/zh/docs/advanced/openapi-webhooks.md +++ b/docs/zh/docs/advanced/openapi-webhooks.md @@ -32,7 +32,7 @@ 当您创建一个 **FastAPI** 应用程序时,有一个 `webhooks` 属性可以用来定义网络钩子,方式与您定义*路径操作*的时候相同,例如使用 `@app.webhooks.post()` 。 -{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *} +{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *} 您定义的网络钩子将被包含在 `OpenAPI` 的架构中,并出现在自动生成的**文档 UI** 中。 diff --git a/docs/zh/docs/advanced/path-operation-advanced-configuration.md b/docs/zh/docs/advanced/path-operation-advanced-configuration.md index 6c9928ffc..588d4f09c 100644 --- a/docs/zh/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/zh/docs/advanced/path-operation-advanced-configuration.md @@ -12,7 +12,7 @@ 务必确保每个操作的 `operation_id` 都是唯一的。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *} ### 使用 *路径操作函数* 的函数名作为 operationId { #using-the-path-operation-function-name-as-the-operationid } @@ -20,7 +20,7 @@ 你应该在添加了所有 *路径操作* 之后执行此操作。 -{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *} /// tip @@ -40,7 +40,7 @@ 使用参数 `include_in_schema` 并将其设置为 `False`,来从生成的 OpenAPI 方案中排除一个 *路径操作*(这样一来,就从自动化文档系统中排除掉了): -{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *} ## 来自 docstring 的高级描述 { #advanced-description-from-docstring } @@ -92,7 +92,7 @@ 例如,这个 `openapi_extra` 可用于声明 [OpenAPI 扩展](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): -{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *} 当你打开自动 API 文档时,你的扩展会显示在该 *路径操作* 的底部。 @@ -139,9 +139,9 @@ 你可以用 `openapi_extra` 来做到: -{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *} -在这个示例中,我们没有声明任何 Pydantic 模型。事实上,请求体甚至没有被 解析 为 JSON,而是直接以 `bytes` 读取,并由函数 `magic_data_reader()` 以某种方式负责解析。 +在这个示例中,我们没有声明任何 Pydantic 模型。事实上,请求体甚至没有被 解析 为 JSON,而是直接以 `bytes` 读取,并由函数 `magic_data_reader()` 以某种方式负责解析。 尽管如此,我们仍然可以声明请求体的预期方案。 @@ -153,7 +153,7 @@ 例如,在这个应用中我们不使用 FastAPI 集成的从 Pydantic 模型提取 JSON Schema 的功能,也不使用对 JSON 的自动校验。实际上,我们将请求的内容类型声明为 YAML,而不是 JSON: -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *} 尽管我们没有使用默认的集成功能,我们仍然使用 Pydantic 模型手动生成我们想以 YAML 接收的数据的 JSON Schema。 @@ -161,7 +161,7 @@ 接着在我们的代码中,我们直接解析该 YAML 内容,然后再次使用同一个 Pydantic 模型来验证该 YAML 内容: -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *} /// tip diff --git a/docs/zh/docs/advanced/response-change-status-code.md b/docs/zh/docs/advanced/response-change-status-code.md index cdcd39f50..0b004bf4e 100644 --- a/docs/zh/docs/advanced/response-change-status-code.md +++ b/docs/zh/docs/advanced/response-change-status-code.md @@ -20,9 +20,11 @@ 然后你可以在这个*临时*响应对象中设置`status_code`。 -{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *} -然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。 +然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。 + +如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。 **FastAPI**将使用这个*临时*响应来提取状态码(也包括cookies和头部),并将它们放入包含你返回的值的最终响应中,该响应由任何`response_model`过滤。 diff --git a/docs/zh/docs/advanced/response-cookies.md b/docs/zh/docs/advanced/response-cookies.md index cc311a270..c618cd0f0 100644 --- a/docs/zh/docs/advanced/response-cookies.md +++ b/docs/zh/docs/advanced/response-cookies.md @@ -4,7 +4,7 @@ 你可以在 *路径操作函数* 中定义一个类型为 `Response` 的参数,这样你就可以在这个临时响应对象中设置cookie了。 -{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *} 而且你还可以根据你的需要响应不同的对象,比如常用的 `dict`,数据库model等。 @@ -22,9 +22,9 @@ 然后设置Cookies,并返回: -{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *} -/// tip +/// tip | 提示 需要注意,如果你直接反馈一个response对象,而不是使用`Response`入参,FastAPI则会直接反馈你封装的response对象。 diff --git a/docs/zh/docs/advanced/response-directly.md b/docs/zh/docs/advanced/response-directly.md index 8a9cf6ab8..a97992d24 100644 --- a/docs/zh/docs/advanced/response-directly.md +++ b/docs/zh/docs/advanced/response-directly.md @@ -36,7 +36,7 @@ {* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *} -/// note | 注意 +/// note | 技术细节 你也可以使用 `from starlette.responses import JSONResponse`。 @@ -54,7 +54,7 @@ 你可以把你的 XML 内容放到一个字符串中,放到一个 `Response` 中,然后返回: -{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *} ## 说明 { #notes } diff --git a/docs/zh/docs/advanced/response-headers.md b/docs/zh/docs/advanced/response-headers.md index fa02f53be..01bde56d2 100644 --- a/docs/zh/docs/advanced/response-headers.md +++ b/docs/zh/docs/advanced/response-headers.md @@ -6,13 +6,13 @@ 然后你可以在这个*临时*响应对象中设置头部。 -{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *} +{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *} 然后你可以像平常一样返回任何你需要的对象(例如一个 `dict` 或者一个数据库模型)。 如果你声明了一个 `response_model`,它仍然会被用来过滤和转换你返回的对象。 -**FastAPI** 将使用这个临时响应来提取头部(也包括 cookies 和状态码),并将它们放入包含你返回的值的最终响应中,该响应由任何 `response_model` 过滤。 +**FastAPI** 将使用这个*临时*响应来提取头部(也包括 cookies 和状态码),并将它们放入包含你返回的值的最终响应中,该响应由任何 `response_model` 过滤。 你也可以在依赖项中声明 `Response` 参数,并在其中设置头部(和 cookies)。 @@ -22,7 +22,7 @@ 按照[直接返回响应](response-directly.md){.internal-link target=_blank}中所述创建响应,并将头部作为附加参数传递: -{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *} +{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *} /// note | 技术细节 diff --git a/docs/zh/docs/advanced/security/http-basic-auth.md b/docs/zh/docs/advanced/security/http-basic-auth.md index 55479d8e3..9128a4975 100644 --- a/docs/zh/docs/advanced/security/http-basic-auth.md +++ b/docs/zh/docs/advanced/security/http-basic-auth.md @@ -20,7 +20,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。 * 返回类型为 `HTTPBasicCredentials` 的对象: * 包含发送的 `username` 与 `password` -{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *} +{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *} 第一次打开 URL(或在 API 文档中点击 **Execute** 按钮)时,浏览器要求输入用户名与密码: @@ -40,7 +40,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。 然后我们可以使用 `secrets.compare_digest()` 来确保 `credentials.username` 是 `"stanleyjobson"`,且 `credentials.password` 是`"swordfish"`。 -{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *} +{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *} 这类似于: @@ -104,4 +104,4 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": 检测到凭证不正确后,返回 `HTTPException` 及状态码 401(与无凭证时返回的内容一样),并添加响应头 `WWW-Authenticate`,让浏览器再次显示登录提示: -{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *} +{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *} diff --git a/docs/zh/docs/advanced/settings.md b/docs/zh/docs/advanced/settings.md index adf264491..b4def73eb 100644 --- a/docs/zh/docs/advanced/settings.md +++ b/docs/zh/docs/advanced/settings.md @@ -54,7 +54,7 @@ $ pip install "fastapi[all]" 你可以使用与 Pydantic 模型相同的验证功能和工具,例如不同的数据类型,以及使用 `Field()` 进行附加验证。 -{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *} +{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *} /// tip | 提示 @@ -70,7 +70,7 @@ $ pip install "fastapi[all]" 然后你可以在应用中使用新的 `settings` 对象: -{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *} +{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *} ### 运行服务器 { #run-the-server } @@ -100,19 +100,19 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p ## 在另一个模块中放置设置 { #settings-in-another-module } -你可以把这些设置放在另一个模块文件中,就像你在[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。 +你可以把这些设置放在另一个模块文件中,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。 例如,可以有一个 `config.py` 文件: -{* ../../docs_src/settings/app01_py39/config.py *} +{* ../../docs_src/settings/app01_py310/config.py *} 然后在 `main.py` 文件中使用它: -{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *} +{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *} /// tip | 提示 -你还需要一个 `__init__.py` 文件,就像你在[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。 +你还需要一个 `__init__.py` 文件,就像你在[更大的应用 - 多个文件](../tutorial/bigger-applications.md){.internal-link target=_blank}中看到的那样。 /// @@ -126,7 +126,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p 延续上一个示例,你的 `config.py` 文件可能如下所示: -{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *} +{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *} 注意,现在我们不再创建默认实例 `settings = Settings()`。 @@ -134,7 +134,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p 现在我们创建一个依赖项,返回一个新的 `config.Settings()`。 -{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *} +{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *} /// tip | 提示 @@ -144,15 +144,15 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p /// -然后我们可以在“路径操作函数”中将其作为依赖项引入,并在需要的任何地方使用它。 +然后我们可以在路径操作函数中将其作为依赖项引入,并在需要的任何地方使用它。 -{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *} +{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *} ### 设置与测试 { #settings-and-testing } 接着,在测试期间,通过为 `get_settings` 创建依赖项覆盖,就可以很容易地提供一个不同的设置对象: -{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *} +{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *} 在依赖项覆盖中,我们在创建新的 `Settings` 对象时为 `admin_email` 设置了一个新值,然后返回该新对象。 @@ -193,7 +193,7 @@ APP_NAME="ChimichangApp" 然后更新 `config.py`: -{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *} +{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *} /// tip | 提示 @@ -226,7 +226,7 @@ def get_settings(): 但由于我们在顶部使用了 `@lru_cache` 装饰器,`Settings` 对象只会在第一次调用时创建一次。 ✔️ -{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *} +{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *} 接着,对于后续请求中依赖项里对 `get_settings()` 的任何调用,它不会再次执行 `get_settings()` 的内部代码并创建新的 `Settings` 对象,而是会一遍又一遍地返回第一次调用时返回的那个相同对象。 diff --git a/docs/zh/docs/advanced/sub-applications.md b/docs/zh/docs/advanced/sub-applications.md index fe1fcd121..3e61610a3 100644 --- a/docs/zh/docs/advanced/sub-applications.md +++ b/docs/zh/docs/advanced/sub-applications.md @@ -10,7 +10,7 @@ 首先,创建主(顶层)**FastAPI** 应用及其*路径操作*: -{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *} +{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *} ### 子应用 { #sub-application } @@ -18,7 +18,7 @@ 子应用只是另一个标准 FastAPI 应用,但这个应用是被**挂载**的应用: -{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *} +{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *} ### 挂载子应用 { #mount-the-sub-application } @@ -26,7 +26,7 @@ 本例的子应用挂载在 `/subapi` 路径下: -{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *} +{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *} ### 查看自动 API 文档 { #check-the-automatic-api-docs } diff --git a/docs/zh/docs/advanced/templates.md b/docs/zh/docs/advanced/templates.md index f2e5c21cf..37575aff2 100644 --- a/docs/zh/docs/advanced/templates.md +++ b/docs/zh/docs/advanced/templates.md @@ -27,7 +27,7 @@ $ pip install jinja2 * 在返回模板的*路径操作*中声明 `Request` 参数 * 使用 `templates` 渲染并返回 `TemplateResponse`,传递模板的名称、request 对象以及一个包含多个键值对(用于 Jinja2 模板)的 "context" 字典。 -{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *} +{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *} /// note diff --git a/docs/zh/docs/advanced/testing-dependencies.md b/docs/zh/docs/advanced/testing-dependencies.md index db0b39483..3291cfc25 100644 --- a/docs/zh/docs/advanced/testing-dependencies.md +++ b/docs/zh/docs/advanced/testing-dependencies.md @@ -46,7 +46,6 @@ FastAPI 可以覆盖这些位置的依赖项。 app.dependency_overrides = {} ``` - /// tip | 提示 如果只在某些测试时覆盖依赖项,您可以在测试开始时(在测试函数内)设置覆盖依赖项,并在结束时(在测试函数结尾)重置覆盖依赖项。 diff --git a/docs/zh/docs/advanced/testing-events.md b/docs/zh/docs/advanced/testing-events.md index 221984e90..90cbbda13 100644 --- a/docs/zh/docs/advanced/testing-events.md +++ b/docs/zh/docs/advanced/testing-events.md @@ -2,10 +2,10 @@ 当你需要在测试中运行 `lifespan` 时,可以将 `TestClient` 与 `with` 语句一起使用: -{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *} +{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *} 你可以在[官方 Starlette 文档站点的“在测试中运行 lifespan”](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)阅读更多细节。 对于已弃用的 `startup` 和 `shutdown` 事件,可以按如下方式使用 `TestClient`: -{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *} +{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *} diff --git a/docs/zh/docs/advanced/testing-websockets.md b/docs/zh/docs/advanced/testing-websockets.md index 64e1d3005..e435e41e2 100644 --- a/docs/zh/docs/advanced/testing-websockets.md +++ b/docs/zh/docs/advanced/testing-websockets.md @@ -4,7 +4,7 @@ 为此,在 `with` 语句中使用 `TestClient` 连接到 WebSocket: -{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *} +{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *} /// note | 注意 diff --git a/docs/zh/docs/advanced/using-request-directly.md b/docs/zh/docs/advanced/using-request-directly.md index 64ba8da1b..8cfad4203 100644 --- a/docs/zh/docs/advanced/using-request-directly.md +++ b/docs/zh/docs/advanced/using-request-directly.md @@ -29,7 +29,7 @@ 此时,需要直接访问请求。 -{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *} +{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *} 把*路径操作函数*的参数类型声明为 `Request`,**FastAPI** 就能把 `Request` 传递到参数里。 diff --git a/docs/zh/docs/advanced/websockets.md b/docs/zh/docs/advanced/websockets.md index 4486a2e69..513e1aaec 100644 --- a/docs/zh/docs/advanced/websockets.md +++ b/docs/zh/docs/advanced/websockets.md @@ -38,13 +38,13 @@ $ pip install websockets 但这是一种专注于 WebSockets 的服务器端并提供一个工作示例的最简单方式: -{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *} +{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *} ## 创建 `websocket` { #create-a-websocket } 在您的 **FastAPI** 应用程序中,创建一个 `websocket`: -{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *} +{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *} /// note | 技术细节 @@ -58,7 +58,7 @@ $ pip install websockets 在您的 WebSocket 路由中,您可以使用 `await` 等待消息并发送消息。 -{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *} +{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *} 您可以接收和发送二进制、文本和 JSON 数据。 @@ -154,7 +154,7 @@ $ fastapi dev main.py 当 WebSocket 连接关闭时,`await websocket.receive_text()` 将引发 `WebSocketDisconnect` 异常,您可以捕获并处理该异常,就像本示例中的示例一样。 -{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *} +{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *} 尝试以下操作: diff --git a/docs/zh/docs/advanced/wsgi.md b/docs/zh/docs/advanced/wsgi.md index 73fcb3219..487fbf8dd 100644 --- a/docs/zh/docs/advanced/wsgi.md +++ b/docs/zh/docs/advanced/wsgi.md @@ -18,7 +18,7 @@ 之后将其挂载到某一个路径下。 -{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *} +{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *} /// note | 注意 diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md index c94c90787..36d875f51 100644 --- a/docs/zh/docs/async.md +++ b/docs/zh/docs/async.md @@ -298,7 +298,7 @@ CPU 密集型操作的常见示例是需要复杂的数学处理。 这一点,再加上 Python 是**数据科学**、机器学习(尤其是深度学习)的主要语言这一简单事实,使得 **FastAPI** 与数据科学/机器学习 Web API 和应用程序(以及其他许多应用程序)非常匹配。 -了解如何在生产环境中实现这种并行性,可查看此文 [Deployment](deployment/index.md){.internal-link target=_blank}。 +了解如何在生产环境中实现这种并行性,可查看此文 [部署](deployment/index.md){.internal-link target=_blank}。 ## `async` 和 `await` { #async-and-await } @@ -369,7 +369,7 @@ Starlette (和 **FastAPI**) 是基于 AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。 -我(指原作者 —— 译者注)基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的**自动补全**、**内联错误提示**等功能。这个库还附带了一个友好的入门指南和教程,能帮助你**理解**并编写**自己的异步代码**:Asyncer。如果你有**结合使用异步代码和常规**(阻塞/同步)代码的需求,这个库会特别有用。 +我基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的**自动补全**、**内联错误提示**等功能。这个库还附带了一个友好的入门指南和教程,能帮助你**理解**并编写**自己的异步代码**:Asyncer。如果你有**结合使用异步代码和常规**(阻塞/同步)代码的需求,这个库会特别有用。 ### 其他形式的异步代码 { #other-forms-of-asynchronous-code } diff --git a/docs/zh/docs/benchmarks.md b/docs/zh/docs/benchmarks.md index 1a4b4a3de..a6e706dfa 100644 --- a/docs/zh/docs/benchmarks.md +++ b/docs/zh/docs/benchmarks.md @@ -23,7 +23,7 @@ * 你不会直接在 Uvicorn 中编写应用程序。这意味着你的代码至少必须包含 Starlette(或 **FastAPI**)提供的代码。如果你这样做了(即直接在 Uvicorn 中编写应用程序),最终的应用程序会和使用了框架并且最小化了应用代码和 bug 的情况具有相同的性能损耗。 * 如果你要对比 Uvicorn,请将其与 Daphne,Hypercorn,uWSGI 等应用服务器进行比较。 * **Starlette**: - * 在 Uvicorn 后使用 Starlette,性能会略有下降。实际上,Starlette 使用 Uvicorn 运行。因此,由于必须执行更多的代码,它只会比 Uvicorn 更慢。 + * 性能仅次于 Uvicorn。实际上,Starlette 使用 Uvicorn 运行。因此,由于必须执行更多的代码,它只会比 Uvicorn 更慢。 * 但它为你提供了构建简单的网络程序的工具,并具有基于路径的路由等功能。 * 如果想对比与 Starlette 对标的开发框架,请将其与 Sanic,Flask,Django 等网络框架(或微框架)进行比较。 * **FastAPI**: diff --git a/docs/zh/docs/deployment/concepts.md b/docs/zh/docs/deployment/concepts.md index 66d32629c..76e967d7d 100644 --- a/docs/zh/docs/deployment/concepts.md +++ b/docs/zh/docs/deployment/concepts.md @@ -190,7 +190,7 @@ ### 工作进程和端口 { #worker-processes-and-ports } -还记得文档 [About HTTPS](https.md){.internal-link target=_blank} 中只有一个进程可以侦听服务器中的端口和 IP 地址的一种组合吗? +还记得文档 [关于 HTTPS](https.md){.internal-link target=_blank} 中只有一个进程可以侦听服务器中的端口和 IP 地址的一种组合吗? 现在仍然是对的。 diff --git a/docs/zh/docs/deployment/docker.md b/docs/zh/docs/deployment/docker.md index 3d0c19903..4e7410587 100644 --- a/docs/zh/docs/deployment/docker.md +++ b/docs/zh/docs/deployment/docker.md @@ -14,7 +14,7 @@ Dockerfile 预览 👀 ```Dockerfile -FROM python:3.9 +FROM python:3.14 WORKDIR /code @@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None): ```{ .dockerfile .annotate } # (1)! -FROM python:3.9 +FROM python:3.14 # (2)! WORKDIR /code @@ -390,7 +390,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage 然后你只需要在 `Dockerfile` 中修改相应路径来复制该文件: ```{ .dockerfile .annotate hl_lines="10 13" } -FROM python:3.9 +FROM python:3.14 WORKDIR /code @@ -454,7 +454,7 @@ Traefik 与 Docker、Kubernetes 等都有集成,因此为容器设置和配置 ## 复制 - 进程数 { #replication-number-of-processes } -如果你有一个由 **Kubernetes**、Docker Swarm Mode、Nomad 或其他类似的复杂系统管理的、在多台机器上运行的分布式容器集群,那么你很可能会希望在**集群层面**来**处理复制**,而不是在每个容器中使用**进程管理**(比如让 Uvicorn 运行多个 workers)。 +如果你有一个由 **Kubernetes**、Docker Swarm Mode、Nomad 或其他类似的复杂系统管理的、在多台机器上运行的分布式容器集群,那么你很可能会希望在**集群层面**来**处理复制**,而不是在每个容器中使用**进程管理**(比如让 Uvicorn 运行多个 workers)。 像 Kubernetes 这样的分布式容器管理系统通常都有某种内置方式来处理**容器复制**,同时对传入请求进行**负载均衡**。这一切都在**集群层面**完成。 @@ -499,7 +499,7 @@ Traefik 与 Docker、Kubernetes 等都有集成,因此为容器设置和配置 在这些情况下,你可以使用 `--workers` 命令行选项来设置要运行的 worker 数量: ```{ .dockerfile .annotate } -FROM python:3.9 +FROM python:3.14 WORKDIR /code diff --git a/docs/zh/docs/deployment/https.md b/docs/zh/docs/deployment/https.md index 4f60b7bca..591707f6d 100644 --- a/docs/zh/docs/deployment/https.md +++ b/docs/zh/docs/deployment/https.md @@ -65,13 +65,13 @@ 第一步我们要先**获取**一些**域名(Domain Name)**。 然后可以在 DNS 服务器(可能是你的同一家云服务商提供的)中配置它。 -你可能拥有一个云服务器(虚拟机)或类似的东西,并且它会有一个固定 **公共IP地址**。 +你可能拥有一个云服务器(虚拟机)或类似的东西,并且它会有一个固定 **公共IP地址**。 在 DNS 服务器中,你可以配置一条记录(“A 记录”)以将 **你的域名** 指向你服务器的公共 **IP 地址**。 这个操作一般只需要在最开始执行一次。 -/// tip +/// tip | 提示 域名这部分发生在 HTTPS 之前,由于这一切都依赖于域名和 IP 地址,所以先在这里提一下。 @@ -121,7 +121,7 @@ TLS 终止代理可以访问一个或多个 **TLS 证书**(HTTPS 证书)。 这就是 **HTTPS**,它只是 **安全 TLS 连接** 内的普通 **HTTP**,而不是纯粹的(未加密的)TCP 连接。 -/// tip +/// tip | 提示 请注意,通信加密发生在 **TCP 层**,而不是 HTTP 层。 @@ -217,7 +217,7 @@ TLS 终止代理将使用协商好的加密算法**解密请求**,并将**( 这在需要正确处理重定向等场景时很有用。 -/// tip +/// tip | 提示 你可以在文档中了解更多:[在代理之后 - 启用代理转发请求头](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} diff --git a/docs/zh/docs/deployment/manually.md b/docs/zh/docs/deployment/manually.md index 6f2ad27b2..f519c1e87 100644 --- a/docs/zh/docs/deployment/manually.md +++ b/docs/zh/docs/deployment/manually.md @@ -90,7 +90,7 @@ $ pip install "uvicorn[standard]" 类似的流程也适用于任何其他 ASGI 服务器程序。 -/// tip +/// tip | 提示 通过添加 `standard` 选项,Uvicorn 将安装并使用一些推荐的额外依赖项。 @@ -114,7 +114,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 80 -/// note +/// note | 注意 命令 `uvicorn main:app` 的含义如下: @@ -131,7 +131,7 @@ from main import app 每种 ASGI 服务器程序通常都会有类似的命令,您可以在它们的官方文档中找到更多信息。 -/// warning +/// warning | 警告 Uvicorn 和其他服务器支持 `--reload` 选项,该选项在开发过程中非常有用。 diff --git a/docs/zh/docs/deployment/server-workers.md b/docs/zh/docs/deployment/server-workers.md index 2bbd5d9b6..6f56bacda 100644 --- a/docs/zh/docs/deployment/server-workers.md +++ b/docs/zh/docs/deployment/server-workers.md @@ -60,16 +60,16 @@ $ fastapi run --workers 4 INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) - INFO Started parent process [27365] - INFO Started server process [27368] - INFO Started server process [27369] - INFO Started server process [27370] - INFO Started server process [27367] - INFO Waiting for application startup. - INFO Waiting for application startup. - INFO Waiting for application startup. - INFO Waiting for application startup. - INFO Application startup complete. + INFO Started parent process [27365] + INFO Started server process [27368] + INFO Started server process [27369] + INFO Started server process [27370] + INFO Started server process [27367] + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Application startup complete. INFO Application startup complete. INFO Application startup complete. INFO Application startup complete. diff --git a/docs/zh/docs/features.md b/docs/zh/docs/features.md index 7d7aa19c0..1414f7c6f 100644 --- a/docs/zh/docs/features.md +++ b/docs/zh/docs/features.md @@ -6,7 +6,7 @@ ### 基于开放标准 { #based-on-open-standards } -* 用于创建 API 的 OpenAPI,包含对路径 操作、参数、请求体、安全等的声明。 +* 用于创建 API 的 OpenAPI,包含对路径 操作、参数、请求体、安全等的声明。 * 使用 JSON Schema 自动生成数据模型文档(因为 OpenAPI 本身就是基于 JSON Schema 的)。 * 经过了缜密的研究后围绕这些标准而设计。并非狗尾续貂。 * 这也允许了在很多语言中自动**生成客户端代码**。 @@ -137,7 +137,7 @@ OpenAPI 中定义的安全模式,包括: ### 依赖注入 { #dependency-injection } -FastAPI 有一个使用非常简单,但是非常强大的依赖注入系统。 +FastAPI 有一个使用非常简单,但是非常强大的依赖注入系统。 * 甚至依赖也可以有依赖,创建一个层级或者**“图”依赖**。 * 所有**自动化处理**都由框架完成。 @@ -154,8 +154,8 @@ FastAPI 有一个使用非常简单,但是非常强大的IDE/linter/brain** 适配: +* 和你 **IDE/linter/brain** 适配: * 因为 pydantic 数据结构仅仅是你定义的类的实例;自动补全,linting,mypy 以及你的直觉应该可以和你验证的数据一起正常工作。 * 验证**复杂结构**: * 使用分层的 Pydantic 模型,Python `typing` 的 `List` 和 `Dict` 等等。 diff --git a/docs/zh/docs/help-fastapi.md b/docs/zh/docs/help-fastapi.md index 5a5157b5d..1be60d9d5 100644 --- a/docs/zh/docs/help-fastapi.md +++ b/docs/zh/docs/help-fastapi.md @@ -59,7 +59,7 @@ ## 发推谈谈 **FastAPI** { #tweet-about-fastapi } -Tweet about **FastAPI**,告诉我和大家你为什么喜欢它。🎉 +发推谈谈 **FastAPI**,告诉我和大家你为什么喜欢它。🎉 我很高兴听到 **FastAPI** 的使用情况、你喜欢它的哪些点、你在哪个项目/公司使用它,等等。 diff --git a/docs/zh/docs/how-to/configure-swagger-ui.md b/docs/zh/docs/how-to/configure-swagger-ui.md index 104baff4b..bf2624657 100644 --- a/docs/zh/docs/how-to/configure-swagger-ui.md +++ b/docs/zh/docs/how-to/configure-swagger-ui.md @@ -18,7 +18,7 @@ FastAPI会将这些配置转换为 **JSON**,使其与 JavaScript 兼容,因 但是你可以通过设置 `syntaxHighlight` 为 `False` 来禁用 Swagger UI 中的语法高亮: -{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *} ...在此之后,Swagger UI 将不会高亮代码: @@ -28,7 +28,7 @@ FastAPI会将这些配置转换为 **JSON**,使其与 JavaScript 兼容,因 同样地,你也可以通过设置键 `"syntaxHighlight.theme"` 来设置语法高亮主题(注意中间有一个点): -{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *} 这个配置会改变语法高亮主题: @@ -46,7 +46,7 @@ FastAPI 包含了一些默认配置参数,适用于大多数用例。 比如,如果要禁用 `deepLinking`,你可以像这样传递设置到 `swagger_ui_parameters` 中: -{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *} ## 其他 Swagger UI 参数 { #other-swagger-ui-parameters } diff --git a/docs/zh/docs/how-to/general.md b/docs/zh/docs/how-to/general.md index e75ad6c79..2c9f78179 100644 --- a/docs/zh/docs/how-to/general.md +++ b/docs/zh/docs/how-to/general.md @@ -36,4 +36,4 @@ ## OpenAPI 文档 URL { #openapi-docs-urls } -要更改用于自动生成文档的 URL,请阅读 [教程 - 元数据和文档 URL](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}。 +要更改自动生成的文档用户界面所使用的 URL,请阅读 [教程 - 元数据和文档 URL](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}。 diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md index 1c2aea328..38e128bf1 100644 --- a/docs/zh/docs/index.md +++ b/docs/zh/docs/index.md @@ -40,7 +40,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框 * **快速**:极高性能,可与 **NodeJS** 和 **Go** 并肩(归功于 Starlette 和 Pydantic)。[最快的 Python 框架之一](#performance)。 * **高效编码**:功能开发速度提升约 200% ~ 300%。* * **更少 bug**:人为(开发者)错误减少约 40%。* -* **直观**:极佳的编辑器支持。处处皆可自动补全。更少的调试时间。 +* **直观**:极佳的编辑器支持。处处皆可自动补全。更少的调试时间。 * **易用**:为易用和易学而设计。更少的文档阅读时间。 * **简短**:最小化代码重复。一次参数声明即可获得多种功能。更少的 bug。 * **健壮**:生产可用级代码。并带有自动生成的交互式文档。 @@ -368,7 +368,7 @@ item: Item * 数据校验: * 当数据无效时自动生成清晰的错误信息。 * 即便是多层嵌套的 JSON 对象也会进行校验。 -* 输入数据的转换:从网络读取到 Python 数据和类型。读取来源: +* 转换输入数据:从网络读取到 Python 数据和类型。读取来源: * JSON。 * 路径参数。 * 查询参数。 @@ -376,7 +376,7 @@ item: Item * Headers。 * Forms。 * Files。 -* 输出数据的转换:从 Python 数据和类型转换为网络数据(JSON): +* 转换输出数据:从 Python 数据和类型转换为网络数据(JSON): * 转换 Python 类型(`str`、`int`、`float`、`bool`、`list` 等)。 * `datetime` 对象。 * `UUID` 对象。 @@ -439,7 +439,7 @@ item: Item * 来自不同位置的**参数**声明:**headers**、**cookies**、**form 字段**和**文件**。 * 如何设置**校验约束**,如 `maximum_length` 或 `regex`。 -* 功能强大且易用的 **依赖注入** 系统。 +* 功能强大且易用的 **依赖注入** 系统。 * 安全与认证,包括对 **OAuth2**、**JWT tokens** 和 **HTTP Basic** 认证的支持。 * 更高级(但同样简单)的 **多层嵌套 JSON 模型** 声明技巧(得益于 Pydantic)。 * 通过 Strawberry 等库进行 **GraphQL** 集成。 @@ -524,7 +524,7 @@ Starlette 使用: * httpx - 使用 `TestClient` 时需要。 * jinja2 - 使用默认模板配置时需要。 -* python-multipart - 使用 `request.form()` 支持表单「解析」时需要。 +* python-multipart - 使用 `request.form()` 支持表单「解析」时需要。 FastAPI 使用: diff --git a/docs/zh/docs/python-types.md b/docs/zh/docs/python-types.md index 3e1c593c1..4824b7558 100644 --- a/docs/zh/docs/python-types.md +++ b/docs/zh/docs/python-types.md @@ -2,11 +2,11 @@ Python 支持可选的“类型提示”(也叫“类型注解”)。 -这些“类型提示”或注解是一种特殊语法,用来声明变量的类型。 +这些“类型提示”或注解是一种特殊语法,用来声明变量的类型。 通过为变量声明类型,编辑器和工具可以为你提供更好的支持。 -这只是一个关于 Python 类型提示的快速入门/复习。它只涵盖与 **FastAPI** 一起使用所需的最少部分……实际上非常少。 +这只是一个关于 Python 类型提示的快速入门/复习。它只涵盖与 **FastAPI** 一起使用所需的最少部分...实际上非常少。 **FastAPI** 完全基于这些类型提示构建,它们带来了许多优势和好处。 @@ -22,7 +22,7 @@ Python 支持可选的“类型提示”(也叫“类型注解”)。 让我们从一个简单的例子开始: -{* ../../docs_src/python_types/tutorial001_py39.py *} +{* ../../docs_src/python_types/tutorial001_py310.py *} 运行这个程序会输出: @@ -34,9 +34,9 @@ John Doe * 接收 `first_name` 和 `last_name`。 * 通过 `title()` 将每个参数的第一个字母转换为大写。 -* 用一个空格将它们拼接起来。 +* 用一个空格将它们拼接起来。 -{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *} ### 修改它 { #edit-it } @@ -78,7 +78,7 @@ John Doe 这些就是“类型提示”: -{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *} 这和声明默认值不同,比如: @@ -106,7 +106,7 @@ John Doe 看这个已经带有类型提示的函数: -{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *} 因为编辑器知道变量的类型,你不仅能得到补全,还能获得错误检查: @@ -114,7 +114,7 @@ John Doe 现在你知道需要修复它,用 `str(age)` 把 `age` 转成字符串: -{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *} ## 声明类型 { #declaring-types } @@ -133,29 +133,32 @@ John Doe * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *} -### 带类型参数的泛型类型 { #generic-types-with-type-parameters } +### typing 模块 { #typing-module } -有些数据结构可以包含其他值,比如 `dict`、`list`、`set` 和 `tuple`。而内部的值也会有自己的类型。 +在一些额外的用例中,你可能需要从标准库的 `typing` 模块导入内容。比如当你想声明“任意类型”时,可以使用 `typing` 中的 `Any`: -这些带有内部类型的类型称为“泛型”(generic)类型。可以把它们连同内部类型一起声明出来。 +```python +from typing import Any -要声明这些类型以及内部类型,你可以使用 Python 标准库模块 `typing`。它就是为支持这些类型提示而存在的。 -#### 更新的 Python 版本 { #newer-versions-of-python } +def some_function(data: Any): + print(data) +``` -使用 `typing` 的语法与所有版本兼容,从 Python 3.6 到最新版本(包括 Python 3.9、Python 3.10 等)。 +### 泛型类型 { #generic-types } -随着 Python 的发展,更新的版本对这些类型注解的支持更好,在很多情况下你甚至不需要导入和使用 `typing` 模块来声明类型注解。 +有些类型可以在方括号中接收“类型参数”(type parameters),用于声明其内部值的类型。比如“字符串列表”可以写为 `list[str]`。 -如果你可以为项目选择更高版本的 Python,你将能享受到这种额外的简化。 +这些能接收类型参数的类型称为“泛型类型”(Generic types)或“泛型”(Generics)。 -在整个文档中,会根据不同 Python 版本提供相应的示例(当存在差异时)。 +你可以把相同的内建类型作为泛型使用(带方括号和内部类型): -比如“Python 3.6+”表示兼容 Python 3.6 及以上(包括 3.7、3.8、3.9、3.10 等)。而“Python 3.9+”表示兼容 Python 3.9 及以上(包括 3.10 等)。 - -如果你可以使用最新的 Python 版本,请使用最新版本的示例,它们将拥有最简洁的语法,例如“Python 3.10+”。 +* `list` +* `tuple` +* `set` +* `dict` #### 列表 { #list } @@ -167,7 +170,7 @@ John Doe 因为 list 是一种包含内部类型的类型,把内部类型写在方括号里: -{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *} /// info | 信息 @@ -193,7 +196,7 @@ John Doe 声明 `tuple` 和 `set` 的方式类似: -{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *} 这表示: @@ -208,7 +211,7 @@ John Doe 第二个类型参数用于字典的值: -{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} +{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *} 这表示: @@ -220,44 +223,20 @@ John Doe 你可以声明一个变量可以是若干种类型中的任意一种,比如既可以是 `int` 也可以是 `str`。 -在 Python 3.6 及以上(包括 Python 3.10),你可以使用 `typing` 中的 `Union`,把可能的类型放到方括号里。 +定义时使用竖线(`|`)把两种类型分开。 -在 Python 3.10 中还有一种新的语法,可以用竖线(`|`)把可能的类型分隔开。 - -//// tab | Python 3.10+ +这称为“联合类型”(union),因为变量可以是这两类类型集合的并集中的任意一个。 ```Python hl_lines="1" {!> ../../docs_src/python_types/tutorial008b_py310.py!} ``` -//// - -//// tab | Python 3.9+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b_py39.py!} -``` - -//// - -两种方式的含义一致:`item` 可以是 `int` 或 `str`。 +这表示 `item` 可以是 `int` 或 `str`。 #### 可能为 `None` { #possibly-none } 你可以声明一个值的类型是某种类型(比如 `str`),但它也可能是 `None`。 -在 Python 3.6 及以上(包括 Python 3.10),你可以通过从 `typing` 模块导入并使用 `Optional` 来声明: - -```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009_py39.py!} -``` - -使用 `Optional[str]` 而不是仅仅 `str`,可以让编辑器帮助你发现把值当成总是 `str` 的错误(实际上它也可能是 `None`)。 - -`Optional[Something]` 实际上是 `Union[Something, None]` 的简写,它们等价。 - -这也意味着在 Python 3.10 中,你可以使用 `Something | None`: - //// tab | Python 3.10+ ```Python hl_lines="1" @@ -266,96 +245,7 @@ John Doe //// -//// tab | Python 3.9+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009_py39.py!} -``` - -//// - -//// tab | Python 3.9+ 另一种写法 - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b_py39.py!} -``` - -//// - -#### 使用 `Union` 或 `Optional` { #using-union-or-optional } - -如果你使用的是 3.10 以下的 Python 版本,这里有个来自我非常主观的建议: - -* 🚨 避免使用 `Optional[SomeType]` -* 改用 ✨**`Union[SomeType, None]`**✨ - -两者等价,底层相同,但我更推荐 `Union` 而不是 `Optional`,因为“optional(可选)”这个词看起来像是在说“参数可选”,而它实际上表示“它可以是 `None`”,即使它并不是可选的,仍然是必填的。 - -我认为 `Union[SomeType, None]` 更明确地表达了它的意思。 - -这只是关于词语和名字。但这些词会影响你和你的队友如何理解代码。 - -例如,看下面这个函数: - -{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *} - -参数 `name` 被定义为 `Optional[str]`,但它并不是“可选”的,你不能不传这个参数就调用函数: - -```Python -say_hi() # 哦不,这会抛错!😱 -``` - -参数 `name` 仍然是必填的(不是“可选”),因为它没有默认值。不过,`name` 接受 `None` 作为值: - -```Python -say_hi(name=None) # 这样可以,None 是有效值 🎉 -``` - -好消息是,一旦你使用 Python 3.10,就无需再为此操心,因为你可以直接用 `|` 来定义类型联合: - -{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} - -这样你就不必再考虑 `Optional` 和 `Union` 这些名字了。😎 - -#### 泛型类型 { #generic-types } - -这些在方括号中接收类型参数的类型称为“泛型类型”(Generic types)或“泛型”(Generics),例如: - -//// tab | Python 3.10+ - -你可以把同样的内建类型作为泛型使用(带方括号和内部类型): - -* `list` -* `tuple` -* `set` -* `dict` - -以及与之前的 Python 版本一样,来自 `typing` 模块的: - -* `Union` -* `Optional` -* ……以及其他。 - -在 Python 3.10 中,作为使用泛型 `Union` 和 `Optional` 的替代,你可以使用竖线(`|`)来声明类型联合,这更好也更简单。 - -//// - -//// tab | Python 3.9+ - -你可以把同样的内建类型作为泛型使用(带方括号和内部类型): - -* `list` -* `tuple` -* `set` -* `dict` - -以及来自 `typing` 模块的泛型: - -* `Union` -* `Optional` -* ……以及其他。 - -//// +使用 `str | None` 而不是仅仅 `str`,可以让编辑器帮助你发现把值当成总是 `str` 的错误(实际上它也可能是 `None`)。 ### 类作为类型 { #classes-as-types } @@ -363,11 +253,11 @@ say_hi(name=None) # 这样可以,None 是有效值 🎉 假设你有一个名为 `Person` 的类,带有 name: -{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *} 然后你可以声明一个变量是 `Person` 类型: -{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *} 接着,你会再次获得所有的编辑器支持: @@ -403,19 +293,13 @@ say_hi(name=None) # 这样可以,None 是有效值 🎉 你会在[教程 - 用户指南](tutorial/index.md){.internal-link target=_blank}中看到更多的实战示例。 -/// tip | 提示 - -当你在没有默认值的情况下使用 `Optional` 或 `Union[Something, None]` 时,Pydantic 有一个特殊行为,你可以在 Pydantic 文档的 必填的 Optional 字段 中了解更多。 - -/// - ## 带元数据注解的类型提示 { #type-hints-with-metadata-annotations } -Python 还提供了一个特性,可以使用 `Annotated` 在这些类型提示中放入额外的元数据。 +Python 还提供了一个特性,可以使用 `Annotated` 在这些类型提示中放入额外的元数据。 -从 Python 3.9 起,`Annotated` 是标准库的一部分,因此可以从 `typing` 导入。 +你可以从 `typing` 导入 `Annotated`。 -{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} +{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *} Python 本身不会对这个 `Annotated` 做任何处理。对于编辑器和其他工具,类型仍然是 `str`。 diff --git a/docs/zh/docs/tutorial/background-tasks.md b/docs/zh/docs/tutorial/background-tasks.md index 8398472c3..d73fee429 100644 --- a/docs/zh/docs/tutorial/background-tasks.md +++ b/docs/zh/docs/tutorial/background-tasks.md @@ -15,7 +15,7 @@ 首先导入 `BackgroundTasks` 并在 *路径操作函数* 中使用类型声明 `BackgroundTasks` 定义一个参数: -{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *} **FastAPI** 会创建一个 `BackgroundTasks` 类型的对象并作为该参数传入。 @@ -31,13 +31,13 @@ 由于写操作不使用 `async` 和 `await`,我们用普通的 `def` 定义函数: -{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *} ## 添加后台任务 { #add-the-background-task } 在你的 *路径操作函数* 里,用 `.add_task()` 方法将任务函数传到 *后台任务* 对象中: -{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *} `.add_task()` 接收以下参数: @@ -69,7 +69,7 @@ 在FastAPI中仍然可以单独使用 `BackgroundTask`,但您必须在代码中创建对象,并返回包含它的Starlette `Response`。 -更多细节查看 Starlette's official docs for Background Tasks. +更多细节查看 Starlette 后台任务的官方文档. ## 告诫 { #caveat } diff --git a/docs/zh/docs/tutorial/bigger-applications.md b/docs/zh/docs/tutorial/bigger-applications.md index 1ced002dc..a667d596f 100644 --- a/docs/zh/docs/tutorial/bigger-applications.md +++ b/docs/zh/docs/tutorial/bigger-applications.md @@ -85,7 +85,7 @@ from app.routers import items 你可以导入它并通过与 `FastAPI` 类相同的方式创建一个「实例」: -{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *} ### 使用 `APIRouter` 的*路径操作* { #path-operations-with-apirouter } @@ -93,7 +93,7 @@ from app.routers import items 使用方式与 `FastAPI` 类相同: -{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *} 你可以将 `APIRouter` 视为一个「迷你 `FastAPI`」类。 @@ -117,7 +117,7 @@ from app.routers import items 现在我们将使用一个简单的依赖项来读取一个自定义的 `X-Token` 请求首部: -{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *} /// tip | 提示 @@ -149,7 +149,7 @@ from app.routers import items 因此,我们可以将其添加到 `APIRouter` 中,而不是将其添加到每个路径操作中。 -{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *} 由于每个*路径操作*的路径都必须以 `/` 开头,例如: @@ -208,7 +208,7 @@ async def read_item(item_id: str): 因此,我们通过 `..` 对依赖项使用了相对导入: -{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *} #### 相对导入如何工作 { #how-relative-imports-work } @@ -279,11 +279,11 @@ from ...dependencies import get_token_header 但是我们仍然可以添加*更多*将会应用于特定的*路径操作*的 `tags`,以及一些特定于该*路径操作*的额外 `responses`: -{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *} /// tip | 提示 -最后的这个路径操作将包含标签的组合:`["items","custom"]`。 +最后的这个路径操作将包含标签的组合:`["items", "custom"]`。 并且在文档中也会有两个响应,一个用于 `404`,一个用于 `403`。 @@ -305,13 +305,13 @@ from ...dependencies import get_token_header 我们甚至可以声明[全局依赖项](dependencies/global-dependencies.md){.internal-link target=_blank},它会和每个 `APIRouter` 的依赖项组合在一起: -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *} ### 导入 `APIRouter` { #import-the-apirouter } 现在,我们导入具有 `APIRouter` 的其他子模块: -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *} 由于文件 `app/routers/users.py` 和 `app/routers/items.py` 是同一 Python 包 `app` 一个部分的子模块,因此我们可以使用单个点 ` .` 通过「相对导入」来导入它们。 @@ -374,13 +374,13 @@ from .routers.users import router 因此,为了能够在同一个文件中使用它们,我们直接导入子模块: -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *} ### 包含 `users` 和 `items` 的 `APIRouter` { #include-the-apirouters-for-users-and-items } 现在,让我们来包含来自 `users` 和 `items` 子模块的 `router`。 -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *} /// info | 信息 @@ -420,13 +420,13 @@ from .routers.users import router 对于此示例,它将非常简单。但是假设由于它是与组织中的其他项目所共享的,因此我们无法对其进行修改,以及直接在 `APIRouter` 中添加 `prefix`、`dependencies`、`tags` 等: -{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *} 但是我们仍然希望在包含 `APIRouter` 时设置一个自定义的 `prefix`,以便其所有*路径操作*以 `/admin` 开头,我们希望使用本项目已经有的 `dependencies` 保护它,并且我们希望它包含自定义的 `tags` 和 `responses`。 我们可以通过将这些参数传递给 `app.include_router()` 来完成所有的声明,而不必修改原始的 `APIRouter`: -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *} 这样,原始的 `APIRouter` 将保持不变,因此我们仍然可以与组织中的其他项目共享相同的 `app/internal/admin.py` 文件。 @@ -447,7 +447,7 @@ from .routers.users import router 这里我们这样做了...只是为了表明我们可以做到🤷: -{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *} +{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *} 它将与通过 `app.include_router()` 添加的所有其他*路径操作*一起正常运行。 diff --git a/docs/zh/docs/tutorial/body-multiple-params.md b/docs/zh/docs/tutorial/body-multiple-params.md index 7d0ddfc1e..39b84904f 100644 --- a/docs/zh/docs/tutorial/body-multiple-params.md +++ b/docs/zh/docs/tutorial/body-multiple-params.md @@ -104,12 +104,6 @@ q: str | None = None ``` -或者在 Python 3.9 中: - -```Python -q: Union[str, None] = None -``` - 比如: {* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *} diff --git a/docs/zh/docs/tutorial/body-nested-models.md b/docs/zh/docs/tutorial/body-nested-models.md index 242aa5822..fe6902e83 100644 --- a/docs/zh/docs/tutorial/body-nested-models.md +++ b/docs/zh/docs/tutorial/body-nested-models.md @@ -163,7 +163,7 @@ images: list[Image] 例如: -{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *} +{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *} ## 无处不在的编辑器支持 { #editor-support-everywhere } @@ -193,7 +193,7 @@ images: list[Image] 在下面的例子中,你将接受任意键为 `int` 类型并且值为 `float` 类型的 `dict`: -{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *} +{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *} /// tip | 提示 diff --git a/docs/zh/docs/tutorial/body.md b/docs/zh/docs/tutorial/body.md index 60088a048..4a72ba17c 100644 --- a/docs/zh/docs/tutorial/body.md +++ b/docs/zh/docs/tutorial/body.md @@ -153,7 +153,7 @@ FastAPI 会根据默认值 `= None` 知道 `q` 的值不是必填的。 -`str | None`(Python 3.10+)或 `Union[str, None]`(Python 3.9+ 中的 `Union`)并不是 FastAPI 用来判断是否必填的依据;是否必填由是否有默认值 `= None` 决定。 +`str | None` 并不是 FastAPI 用来判断是否必填的依据;是否必填由是否有默认值 `= None` 决定。 但添加这些类型注解可以让你的编辑器提供更好的支持并检测错误。 diff --git a/docs/zh/docs/tutorial/cookie-param-models.md b/docs/zh/docs/tutorial/cookie-param-models.md index 707a6a9c7..8e094c7d3 100644 --- a/docs/zh/docs/tutorial/cookie-param-models.md +++ b/docs/zh/docs/tutorial/cookie-param-models.md @@ -46,17 +46,17 @@ 在某些特殊使用情况下(可能并不常见),您可能希望**限制**您想要接收的 cookie。 -您的 API 现在可以控制自己的 cookie 同意。🤪🍪 +您的 API 现在可以控制自己的 cookie 同意。🤪🍪 您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段: {* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *} -如果客户尝试发送一些**额外的 cookie**,他们将收到**错误**响应。 +如果客户端尝试发送一些**额外的 cookie**,他们将收到**错误**响应。 -可怜的 cookie 通知条,费尽心思为了获得您的同意,却被API 拒绝了。🍪 +可怜的 cookie 通知条,费尽心思为了获得您的同意,却被API 拒绝了。🍪 -例如,如果客户端尝试发送一个值为 `good-list-please` 的 `santa_tracker` cookie,客户端将收到一个**错误**响应,告知他们 `santa_tracker` cookie 是不允许的: +例如,如果客户端尝试发送一个值为 `good-list-please` 的 `santa_tracker` cookie,客户端将收到一个**错误**响应,告知他们 `santa_tracker` cookie 是不允许的: ```json { @@ -73,4 +73,4 @@ ## 总结 { #summary } -您可以使用 **Pydantic 模型**在 **FastAPI** 中声明 **cookie**。😎 +您可以使用 **Pydantic 模型**在 **FastAPI** 中声明 **cookie**。😎 diff --git a/docs/zh/docs/tutorial/cors.md b/docs/zh/docs/tutorial/cors.md index 3a296ca72..2e271ec75 100644 --- a/docs/zh/docs/tutorial/cors.md +++ b/docs/zh/docs/tutorial/cors.md @@ -46,7 +46,7 @@ * 特定的 HTTP 方法(`POST`,`PUT`)或者使用通配符 `"*"` 允许所有方法。 * 特定的 HTTP 请求头或者使用通配符 `"*"` 允许所有请求头。 -{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *} 默认情况下,这个 `CORSMiddleware` 实现所使用的默认参数较为保守,所以你需要显式地启用特定的源、方法或者 headers,以便浏览器能够在跨域上下文中使用它们。 @@ -63,7 +63,7 @@ * `expose_headers` - 指示可以被浏览器访问的响应头。默认为 `[]`。 * `max_age` - 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为 `600`。 -中间件响应两种特定类型的 HTTP 请求…… +中间件响应两种特定类型的 HTTP 请求... ### CORS 预检请求 { #cors-preflight-requests } diff --git a/docs/zh/docs/tutorial/debugging.md b/docs/zh/docs/tutorial/debugging.md index 6e0cefe5b..1ff7d6127 100644 --- a/docs/zh/docs/tutorial/debugging.md +++ b/docs/zh/docs/tutorial/debugging.md @@ -6,7 +6,7 @@ 在你的 FastAPI 应用中直接导入 `uvicorn` 并运行: -{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *} ### 关于 `__name__ == "__main__"` { #about-name-main } @@ -68,7 +68,7 @@ from myapp import app uvicorn.run(app, host="0.0.0.0", port=8000) ``` -/// info +/// info | 信息 更多信息请检查 Python 官方文档. diff --git a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md index d83321ddd..43bd7a680 100644 --- a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md @@ -14,7 +14,7 @@ 对此,我们可以做的更好... -## 什么构成了依赖项? { #what-makes-a-dependency } +## 什么构成了依赖项 { #what-makes-a-dependency } 到目前为止,你看到的依赖项都被声明为函数。 @@ -101,7 +101,7 @@ fluffy = Cat(name="Mr Fluffy") 注意,我们在上面的代码中编写了两次`CommonQueryParams`: -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 @@ -129,7 +129,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ... Depends(CommonQueryParams) ``` -...实际上是 **Fastapi** 用来知道依赖项是什么的。 +...实际上是 **FastAPI** 用来知道依赖项是什么的。 FastAPI 将从依赖项中提取声明的参数,这才是 FastAPI 实际调用的。 @@ -137,7 +137,7 @@ FastAPI 将从依赖项中提取声明的参数,这才是 FastAPI 实际调用 在本例中,第一个 `CommonQueryParams` : -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 @@ -163,7 +163,7 @@ commons: CommonQueryParams ... 你实际上可以只这样编写: -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 @@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams) 但是你可以看到,我们在这里有一些代码重复了,编写了`CommonQueryParams`两次: -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 @@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) 不是写成这样: -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ...而是这样写: -//// tab | Python 3.9+ +//// tab | Python 3.10+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.9+ 未使用 Annotated +//// tab | Python 3.10+ 未使用 Annotated /// tip | 提示 diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md index 02fcf62a0..23412e465 100644 --- a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md +++ b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md @@ -14,7 +14,7 @@ 该参数的值是由 `Depends()` 组成的 `list`: -{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *} +{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *} 路径操作装饰器依赖项的执行或解析方式和普通依赖项一样,但就算这些依赖项会返回值,它们的值也不会传递给*路径操作函数*。 @@ -22,13 +22,13 @@ 有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。 -在*路径操作装饰器*中使用 `dependencies` 参数,可以确保在执行依赖项的同时,避免编辑器显示错误提示。 +在*路径操作装饰器*中使用 `dependencies` 参数,可以确保在执行依赖项的同时,避免编辑器/工具报错。 使用路径装饰器依赖项还可以避免开发新人误会代码中包含无用的未使用参数。 /// -/// info | 说明 +/// info | 信息 本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。 @@ -44,13 +44,13 @@ 路径装饰器依赖项可以声明请求的需求项(比如响应头)或其他子依赖项: -{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *} +{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *} ### 触发异常 { #raise-exceptions } 路径装饰器依赖项与正常的依赖项一样,可以 `raise` 异常: -{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *} +{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *} ### 返回值 { #return-values } @@ -58,7 +58,7 @@ 因此,可以复用在其他位置使用过的、(能返回值的)普通依赖项,即使没有使用这个值,也会执行该依赖项: -{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *} +{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *} ## 为一组路径操作定义依赖项 { #dependencies-for-a-group-of-path-operations } diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md index bf495c9f3..413dedb96 100644 --- a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md @@ -1,6 +1,6 @@ # 使用 yield 的依赖项 { #dependencies-with-yield } -FastAPI 支持那些在完成后执行一些额外步骤的依赖项。 +FastAPI 支持那些在完成后执行一些额外步骤的依赖项。 为此,使用 `yield` 而不是 `return`,并把这些额外步骤(代码)写在后面。 @@ -29,15 +29,15 @@ FastAPI 支持那些在完成后执行一些docstring 中声明*路径操作*的描述,**FastAPI** 会从中读取。 +描述内容比较长且占用多行时,可以在函数的 docstring 中声明*路径操作*的描述,**FastAPI** 会从中读取。 文档字符串支持 Markdown,能正确解析和显示 Markdown 的内容,但要注意文档字符串的缩进。 {* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *} -下图为 Markdown 文本在 API 文档中的显示效果: +它会在交互式文档中使用: @@ -72,7 +72,7 @@ OpenAPI 概图会自动添加标签,供 API 文档接口使用: {* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *} -/// info | 说明 +/// info | 信息 注意,`response_description` 只用于描述响应,`description` 一般则用于描述*路径操作*。 @@ -90,9 +90,9 @@ OpenAPI 规定每个*路径操作*都要有响应描述。 ## 弃用*路径操作* { #deprecate-a-path-operation } -`deprecated` 参数可以把*路径操作*标记为弃用,无需直接删除: +如果需要把*路径操作*标记为弃用,但不删除它,可以传入 `deprecated` 参数: -{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *} API 文档会把该路径操作标记为弃用: diff --git a/docs/zh/docs/tutorial/path-params-numeric-validations.md b/docs/zh/docs/tutorial/path-params-numeric-validations.md index ff8b1762c..608aa69a1 100644 --- a/docs/zh/docs/tutorial/path-params-numeric-validations.md +++ b/docs/zh/docs/tutorial/path-params-numeric-validations.md @@ -54,11 +54,11 @@ FastAPI 在 0.95.0 版本添加了对 `Annotated` 的支持(并开始推荐使 因此,你可以将函数声明为: -{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *} 但请记住,如果你使用 `Annotated`,你就不会遇到这个问题,因为你没有使用 `Query()` 或 `Path()` 作为函数参数的默认值。 -{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *} ## 按需对参数排序的技巧 { #order-the-parameters-as-you-need-tricks } @@ -83,13 +83,13 @@ FastAPI 在 0.95.0 版本添加了对 `Annotated` 的支持(并开始推荐使 Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数都应该作为关键字参数(键值对)来调用,也被称为 kwargs。即使它们没有默认值。 -{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *} ### 使用 `Annotated` 更好 { #better-with-annotated } 请记住,如果你使用 `Annotated`,因为你没有使用函数参数的默认值,所以你不会有这个问题,你大概率也不需要使用 `*`。 -{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *} ## 数值校验:大于等于 { #number-validations-greater-than-or-equal } @@ -97,7 +97,7 @@ Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数 在这里,使用 `ge=1` 后,`item_id` 必须是一个整数,值要「`g`reater than or `e`qual」1。 -{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *} +{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *} ## 数值校验:大于和小于等于 { #number-validations-greater-than-and-less-than-or-equal } @@ -106,7 +106,7 @@ Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数 * `gt`:大于(`g`reater `t`han) * `le`:小于等于(`l`ess than or `e`qual) -{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *} +{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *} ## 数值校验:浮点数、大于和小于 { #number-validations-floats-greater-than-and-less-than } @@ -118,7 +118,7 @@ Python 不会对这个 `*` 做任何事,但它会知道之后的所有参数 对于 lt 也是一样的。 -{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *} +{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *} ## 总结 { #recap } diff --git a/docs/zh/docs/tutorial/path-params.md b/docs/zh/docs/tutorial/path-params.md index fa4c9514a..06a9f1b44 100644 --- a/docs/zh/docs/tutorial/path-params.md +++ b/docs/zh/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ 你可以使用与 Python 字符串格式化相同的语法声明路径“参数”或“变量”: -{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *} 路径参数 `item_id` 的值会作为参数 `item_id` 传递给你的函数。 @@ -16,7 +16,7 @@ 使用 Python 标准类型注解,声明路径操作函数中路径参数的类型: -{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *} +{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *} 本例把 `item_id` 的类型声明为 `int`。 @@ -26,7 +26,7 @@ /// -## 数据转换 { #data-conversion } +## 数据转换 { #data-conversion } 运行示例并访问 http://127.0.0.1:8000/items/3,返回的响应如下: @@ -38,7 +38,7 @@ 注意,函数接收并返回的值是 `3`( `int`),不是 `"3"`(`str`)。 -**FastAPI** 通过类型声明自动**解析**请求中的数据。 +**FastAPI** 通过类型声明自动进行请求的解析。 /// @@ -118,19 +118,19 @@ FastAPI 充分地利用了 `Enum` 类型接收预设的路径参数。 +路径操作使用 Python 的 `Enum` 类型接收预设的路径参数。 ### 创建 `Enum` 类 { #create-an-enum-class } @@ -140,11 +140,11 @@ FastAPI 充分地利用了 模型的名字。 +**AlexNet**、**ResNet**、**LeNet** 是机器学习模型的名字。 /// @@ -152,7 +152,7 @@ FastAPI 充分地利用了 解析" +- 数据 "解析" - 数据校验 - API 注解和自动文档 diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md index 62552e6d0..d41f30226 100644 --- a/docs/zh/docs/tutorial/query-params-str-validations.md +++ b/docs/zh/docs/tutorial/query-params-str-validations.md @@ -47,40 +47,16 @@ FastAPI 在 0.95.0 版本中添加了对 `Annotated` 的支持(并开始推荐 我们之前的类型标注是: -//// tab | Python 3.10+ - ```Python q: str | None = None ``` -//// - -//// tab | Python 3.9+ - -```Python -q: Union[str, None] = None -``` - -//// - 我们要做的是用 `Annotated` 把它包起来,变成: -//// tab | Python 3.10+ - ```Python q: Annotated[str | None] = None ``` -//// - -//// tab | Python 3.9+ - -```Python -q: Annotated[Union[str, None]] = None -``` - -//// - 这两种写法含义相同,`q` 是一个可以是 `str` 或 `None` 的参数,默认是 `None`。 现在进入更有趣的部分。🎉 @@ -109,7 +85,7 @@ FastAPI 现在会: ## 另一种(旧的)方式:把 `Query` 作为默认值 { #alternative-old-query-as-the-default-value } -早期版本的 FastAPI(0.95.0 之前)要求你把 `Query` 作为参数的默认值,而不是放在 `Annotated` 里。你很可能会在别处看到这种写法,所以我也给你解释一下。 +早期版本的 FastAPI(0.95.0 之前)要求你把 `Query` 作为参数的默认值,而不是放在 `Annotated` 里。你很可能会在别处看到这种写法,所以我也给你解释一下。 /// tip | 提示 @@ -191,7 +167,7 @@ q: str = Query(default="rick") ## 添加正则表达式 { #add-regular-expressions } -你可以定义一个参数必须匹配的 正则表达式 `pattern`: +你可以定义一个参数必须匹配的 正则表达式 `pattern`: {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *} @@ -211,7 +187,7 @@ q: str = Query(default="rick") 假设你想要声明查询参数 `q` 的 `min_length` 为 `3`,并且默认值为 `"fixedquery"`: -{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *} +{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *} /// note | 注意 @@ -241,7 +217,7 @@ q: Annotated[str | None, Query(min_length=3)] = None 因此,在使用 `Query` 的同时需要把某个值声明为必填时,只需不声明默认值: -{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *} +{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *} ### 必填,但可以为 `None` { #required-can-be-none } @@ -292,7 +268,7 @@ http://localhost:8000/items/?q=foo&q=bar 你还可以定义在没有给定值时的默认 `list`: -{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *} +{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *} 如果你访问: @@ -315,7 +291,7 @@ http://localhost:8000/items/ 你也可以直接使用 `list`,而不是 `list[str]`: -{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *} +{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *} /// note | 注意 @@ -371,7 +347,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems 现在假设你不再喜欢这个参数了。 -由于还有客户端在使用它,你不得不保留一段时间,但你希望文档清楚地将其展示为已弃用。 +由于还有客户端在使用它,你不得不保留一段时间,但你希望文档清楚地将其展示为已弃用。 那么将参数 `deprecated=True` 传给 `Query`: @@ -401,7 +377,7 @@ Pydantic 还有 ISBN 书号)或 `imdb-`(用于 IMDB 电影 URL 的 ID)开头: +例如,这个自定义校验器会检查条目 ID 是否以 `isbn-`(用于 ISBN 书号)或 `imdb-`(用于 IMDB 电影 URL 的 ID)开头: {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *} @@ -435,7 +411,7 @@ Pydantic 还有 可迭代对象。 +使用 `data.items()` 我们会得到一个包含每个字典项键和值的元组的 可迭代对象。 我们用 `list(data.items())` 把这个可迭代对象转换成一个真正的 `list`。 diff --git a/docs/zh/docs/tutorial/query-params.md b/docs/zh/docs/tutorial/query-params.md index 9ef998731..4ea37d7e0 100644 --- a/docs/zh/docs/tutorial/query-params.md +++ b/docs/zh/docs/tutorial/query-params.md @@ -2,7 +2,7 @@ 声明的参数不是路径参数时,路径操作函数会把该参数自动解释为**查询**参数。 -{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *} +{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *} 查询字符串是键值对的集合,这些键值对位于 URL 的 `?` 之后,以 `&` 分隔。 @@ -12,7 +12,7 @@ http://127.0.0.1:8000/items/?skip=0&limit=10 ``` -……查询参数为: +...查询参数为: * `skip`:值为 `0` * `limit`:值为 `10` @@ -24,7 +24,7 @@ http://127.0.0.1:8000/items/?skip=0&limit=10 所有应用于路径参数的流程也适用于查询参数: * (显而易见的)编辑器支持 -* 数据**解析** +* 数据"解析" * 数据校验 * 自动文档 @@ -75,7 +75,6 @@ http://127.0.0.1:8000/items/?skip=20 参数还可以声明为 `bool` 类型,FastAPI 会自动转换参数类型: - {* ../../docs_src/query_params/tutorial003_py310.py hl[7] *} 本例中,访问: @@ -129,7 +128,7 @@ FastAPI 通过参数名进行检测: 如果要把查询参数设置为**必选**,就不要声明默认值: -{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *} +{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *} 这里的查询参数 `needy` 是类型为 `str` 的必选查询参数。 @@ -139,7 +138,7 @@ FastAPI 通过参数名进行检测: http://127.0.0.1:8000/items/foo-item ``` -……因为路径中没有必选参数 `needy`,返回的响应中会显示如下错误信息: +...因为路径中没有必选参数 `needy`,返回的响应中会显示如下错误信息: ```JSON { @@ -163,7 +162,7 @@ http://127.0.0.1:8000/items/foo-item http://127.0.0.1:8000/items/foo-item?needy=sooooneedy ``` -……这样就正常了: +...这样就正常了: ```JSON { diff --git a/docs/zh/docs/tutorial/request-files.md b/docs/zh/docs/tutorial/request-files.md index 927bd093b..e3b543539 100644 --- a/docs/zh/docs/tutorial/request-files.md +++ b/docs/zh/docs/tutorial/request-files.md @@ -20,13 +20,13 @@ $ pip install python-multipart 从 `fastapi` 导入 `File` 和 `UploadFile`: -{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *} +{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *} ## 定义 `File` 参数 { #define-file-parameters } 像为 `Body` 或 `Form` 一样创建文件参数: -{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *} +{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *} /// info | 信息 @@ -54,7 +54,7 @@ $ pip install python-multipart 将文件参数的类型声明为 `UploadFile`: -{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *} +{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *} 与 `bytes` 相比,使用 `UploadFile` 有多项优势: @@ -76,9 +76,9 @@ $ pip install python-multipart `UploadFile` 具有以下 `async` 方法。它们都会在底层调用对应的文件方法(使用内部的 `SpooledTemporaryFile`)。 -* `write(data)`:将 `data`(`str` 或 `bytes`)写入文件。 -* `read(size)`:读取文件中 `size`(`int`)个字节/字符。 -* `seek(offset)`:移动到文件中字节位置 `offset`(`int`)。 +* `write(data)`:将 `data` (`str` 或 `bytes`) 写入文件。 +* `read(size)`:读取文件中 `size` (`int`) 个字节/字符。 +* `seek(offset)`:移动到文件中字节位置 `offset` (`int`)。 * 例如,`await myfile.seek(0)` 会移动到文件开头。 * 如果你先运行过 `await myfile.read()`,然后需要再次读取内容时,这尤其有用。 * `close()`:关闭文件。 @@ -121,7 +121,7 @@ HTML 表单(`
`)向服务器发送数据的方式通常会对数 但当表单包含文件时,会编码为 `multipart/form-data`。如果你使用 `File`,**FastAPI** 会知道需要从请求体的正确位置获取文件。 -如果你想进一步了解这些编码和表单字段,请参阅
MDN web docs for POST。 +如果你想进一步了解这些编码和表单字段,请参阅 MDN 关于 POST 的 Web 文档。 /// @@ -135,7 +135,7 @@ HTML 表单(`
`)向服务器发送数据的方式通常会对数 ## 可选文件上传 { #optional-file-upload } -您可以通过使用标准类型注解并将 None 作为默认值的方式将一个文件参数设为可选: +您可以通过使用标准类型注解并将 `None` 作为默认值的方式将一个文件参数设为可选: {* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *} @@ -143,7 +143,7 @@ HTML 表单(`
`)向服务器发送数据的方式通常会对数 您也可以将 `File()` 与 `UploadFile` 一起使用,例如,设置额外的元数据: -{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *} +{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *} ## 多文件上传 { #multiple-file-uploads } @@ -153,7 +153,7 @@ FastAPI 支持同时上传多个文件。 要实现这一点,声明一个由 `bytes` 或 `UploadFile` 组成的列表(`List`): -{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *} +{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *} 接收的也是含 `bytes` 或 `UploadFile` 的列表(`list`)。 @@ -169,7 +169,7 @@ FastAPI 支持同时上传多个文件。 和之前的方式一样,你可以为 `File()` 设置额外参数,即使是 `UploadFile`: -{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *} +{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *} ## 小结 { #recap } diff --git a/docs/zh/docs/tutorial/request-form-models.md b/docs/zh/docs/tutorial/request-form-models.md index 4eb98ea22..63759df08 100644 --- a/docs/zh/docs/tutorial/request-form-models.md +++ b/docs/zh/docs/tutorial/request-form-models.md @@ -24,7 +24,7 @@ $ pip install python-multipart 你只需声明一个 **Pydantic 模型**,其中包含你希望接收的**表单字段**,然后将参数声明为 `Form`: -{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *} +{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *} **FastAPI** 将从请求中的**表单数据**中**提取**出**每个字段**的数据,并提供你定义的 Pydantic 模型。 @@ -48,7 +48,7 @@ $ pip install python-multipart 你可以使用 Pydantic 的模型配置来 `forbid` 任何 `extra` 字段: -{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *} +{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *} 如果客户端尝试发送一些额外的数据,他们将收到**错误**响应。 diff --git a/docs/zh/docs/tutorial/request-forms-and-files.md b/docs/zh/docs/tutorial/request-forms-and-files.md index 3c809868b..484fcd5d6 100644 --- a/docs/zh/docs/tutorial/request-forms-and-files.md +++ b/docs/zh/docs/tutorial/request-forms-and-files.md @@ -16,17 +16,17 @@ $ pip install python-multipart ## 导入 `File` 与 `Form` { #import-file-and-form } -{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *} +{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *} ## 定义 `File` 与 `Form` 参数 { #define-file-and-form-parameters } 创建文件和表单参数的方式与 `Body` 和 `Query` 一样: -{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *} +{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *} 文件和表单字段作为表单数据上传与接收。 -声明文件可以使用 `bytes` 或 `UploadFile` 。 +并且你可以将部分文件声明为 `bytes`,将部分文件声明为 `UploadFile`。 /// warning | 警告 diff --git a/docs/zh/docs/tutorial/request-forms.md b/docs/zh/docs/tutorial/request-forms.md index 70eb93a26..1fc305a69 100644 --- a/docs/zh/docs/tutorial/request-forms.md +++ b/docs/zh/docs/tutorial/request-forms.md @@ -18,17 +18,17 @@ $ pip install python-multipart 从 `fastapi` 导入 `Form`: -{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *} +{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *} ## 定义 `Form` 参数 { #define-form-parameters } 创建表单参数的方式与 `Body` 或 `Query` 相同: -{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *} +{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *} 例如,在 OAuth2 规范的一种使用方式(称为“密码流”)中,要求将 `username` 和 `password` 作为表单字段发送。 -spec 要求这些字段必须精确命名为 `username` 和 `password`,并且作为表单字段发送,而不是 JSON。 +规范 要求这些字段必须精确命名为 `username` 和 `password`,并且作为表单字段发送,而不是 JSON。 使用 `Form` 可以像使用 `Body`(以及 `Query`、`Path`、`Cookie`)一样声明相同的配置,包括校验、示例、别名(例如将 `username` 写成 `user-name`)等。 diff --git a/docs/zh/docs/tutorial/response-model.md b/docs/zh/docs/tutorial/response-model.md index 791eb66fb..df0afa66f 100644 --- a/docs/zh/docs/tutorial/response-model.md +++ b/docs/zh/docs/tutorial/response-model.md @@ -183,7 +183,7 @@ FastAPI 在内部配合 Pydantic 做了多项处理,确保不会把类继承 最常见的情况是[直接返回 Response,详见进阶文档](../advanced/response-directly.md){.internal-link target=_blank}。 -{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} +{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *} 这个简单场景 FastAPI 会自动处理,因为返回类型注解是 `Response`(或其子类)。 @@ -193,7 +193,7 @@ FastAPI 在内部配合 Pydantic 做了多项处理,确保不会把类继承 你也可以在类型注解中使用 `Response` 的子类: -{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} +{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *} 这同样可行,因为 `RedirectResponse` 是 `Response` 的子类,FastAPI 会自动处理这个简单场景。 @@ -201,7 +201,7 @@ FastAPI 在内部配合 Pydantic 做了多项处理,确保不会把类继承 但当你返回其他任意对象(如数据库对象)而它不是有效的 Pydantic 类型,并在函数中按此进行了注解时,FastAPI 会尝试基于该类型注解创建一个 Pydantic 响应模型,但会失败。 -如果你有一个在多个类型之间的联合类型,其中一个或多个不是有效的 Pydantic 类型,也会发生同样的情况,例如这个会失败 💥: +如果你有一个在多个类型之间的联合类型,其中一个或多个不是有效的 Pydantic 类型,也会发生同样的情况,例如这个会失败 💥: {* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *} diff --git a/docs/zh/docs/tutorial/response-status-code.md b/docs/zh/docs/tutorial/response-status-code.md index 3630de280..266f919ba 100644 --- a/docs/zh/docs/tutorial/response-status-code.md +++ b/docs/zh/docs/tutorial/response-status-code.md @@ -8,7 +8,7 @@ * `@app.delete()` * 等... -{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *} /// note | 注意 @@ -74,7 +74,7 @@ FastAPI 可以进行识别,并生成表明无响应体的 OpenAPI 文档。 再看下之前的例子: -{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *} `201` 表示“已创建”的状态码。 @@ -82,7 +82,7 @@ FastAPI 可以进行识别,并生成表明无响应体的 OpenAPI 文档。 可以使用 `fastapi.status` 中的快捷变量。 -{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *} +{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *} 这只是一种快捷方式,具有相同的数字代码,但它可以使用编辑器的自动补全功能: diff --git a/docs/zh/docs/tutorial/schema-extra-example.md b/docs/zh/docs/tutorial/schema-extra-example.md index 818ff5087..ec1fc29e5 100644 --- a/docs/zh/docs/tutorial/schema-extra-example.md +++ b/docs/zh/docs/tutorial/schema-extra-example.md @@ -74,7 +74,7 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持 这样做时,这些示例会成为该请求体数据内部 JSON Schema 的一部分。 -不过,在撰写本文时,用于展示文档 UI 的 Swagger UI 并不支持显示 JSON Schema 中数据的多个示例。但请继续阅读,下面有一种变通方法。 +不过,在撰写本文时,用于展示文档 UI 的 Swagger UI 并不支持显示 JSON Schema 中数据的多个示例。但请继续阅读,下面有一种变通方法。 ### OpenAPI 特定的 `examples` { #openapi-specific-examples } diff --git a/docs/zh/docs/tutorial/security/first-steps.md b/docs/zh/docs/tutorial/security/first-steps.md index 43b7c6657..8b1aeb70b 100644 --- a/docs/zh/docs/tutorial/security/first-steps.md +++ b/docs/zh/docs/tutorial/security/first-steps.md @@ -20,7 +20,7 @@ 把下面的示例代码复制到 `main.py`: -{* ../../docs_src/security/tutorial001_an_py39.py *} +{* ../../docs_src/security/tutorial001_an_py310.py *} ## 运行 { #run-it } @@ -132,7 +132,7 @@ OAuth2 的设计目标是让后端或 API 与负责用户认证的服务器解 创建 `OAuth2PasswordBearer` 类实例时,需要传入 `tokenUrl` 参数。该参数包含客户端(运行在用户浏览器中的前端)用来发送 `username` 和 `password` 以获取令牌的 URL。 -{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *} +{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *} /// tip | 提示 @@ -170,7 +170,7 @@ oauth2_scheme(some, parameters) 现在你可以通过 `Depends` 将 `oauth2_scheme` 作为依赖传入。 -{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *} +{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *} 该依赖会提供一个 `str`,赋值给*路径操作函数*的参数 `token`。 diff --git a/docs/zh/docs/tutorial/security/get-current-user.md b/docs/zh/docs/tutorial/security/get-current-user.md index c14bba28a..814ff2c82 100644 --- a/docs/zh/docs/tutorial/security/get-current-user.md +++ b/docs/zh/docs/tutorial/security/get-current-user.md @@ -2,7 +2,7 @@ 上一章中,(基于依赖注入系统的)安全系统向*路径操作函数*传递了 `str` 类型的 `token`: -{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *} +{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *} 但这并不实用。 diff --git a/docs/zh/docs/tutorial/security/index.md b/docs/zh/docs/tutorial/security/index.md index 589f93c3e..a4c352110 100644 --- a/docs/zh/docs/tutorial/security/index.md +++ b/docs/zh/docs/tutorial/security/index.md @@ -10,7 +10,7 @@ 但首先,让我们来看一些小的概念。 -## 没有时间? { #in-a-hurry } +## 赶时间 { #in-a-hurry } 如果你不关心这些术语,而只需要*立即*通过基于用户名和密码的身份认证来增加安全性,请跳转到接下来的章节。 diff --git a/docs/zh/docs/tutorial/security/oauth2-jwt.md b/docs/zh/docs/tutorial/security/oauth2-jwt.md index c7eb9bd90..b5ccfd3e3 100644 --- a/docs/zh/docs/tutorial/security/oauth2-jwt.md +++ b/docs/zh/docs/tutorial/security/oauth2-jwt.md @@ -116,7 +116,11 @@ pwdlib 也支持 bcrypt 哈希算法,但不包含遗留算法——如果需 再创建一个工具函数来进行身份验证并返回用户。 -{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *} + +当使用一个在数据库中不存在的用户名调用 `authenticate_user` 时,我们仍然会针对一个虚拟哈希运行 `verify_password`。 + +这可以确保无论用户名是否有效,端点的响应时间大致相同,从而防止可用于枚举已存在用户名的“时间攻击”(timing attacks)。 /// note | 注意 @@ -152,7 +156,7 @@ $ openssl rand -hex 32 创建一个生成新访问令牌的工具函数。 -{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *} ## 更新依赖项 { #update-the-dependencies } @@ -162,7 +166,7 @@ $ openssl rand -hex 32 如果令牌无效,立即返回一个 HTTP 错误。 -{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *} ## 更新 `/token` 路径操作 { #update-the-token-path-operation } @@ -170,7 +174,7 @@ $ openssl rand -hex 32 创建一个真正的 JWT 访问令牌并返回它。 -{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *} ### 关于 JWT “主题” `sub` 的技术细节 { #technical-details-about-the-jwt-subject-sub } diff --git a/docs/zh/docs/tutorial/security/simple-oauth2.md b/docs/zh/docs/tutorial/security/simple-oauth2.md index 3037a983b..95f708ae6 100644 --- a/docs/zh/docs/tutorial/security/simple-oauth2.md +++ b/docs/zh/docs/tutorial/security/simple-oauth2.md @@ -6,9 +6,9 @@ 首先,使用 **FastAPI** 安全工具获取 `username` 和 `password`。 -OAuth2 规范要求使用**密码流**时,客户端或用户必须以表单数据形式发送 `username` 和 `password` 字段。 +OAuth2 规范要求使用“密码流”时,客户端或用户必须以表单数据形式发送 `username` 和 `password` 字段。 -并且,这两个字段必须命名为 `username` 和 `password` ,不能使用 `user-name` 或 `email` 等其它名称。 +并且,这两个字段必须命名为 `username` 和 `password`,不能使用 `user-name` 或 `email` 等其它名称。 不过也不用担心,前端仍可以显示终端用户所需的名称。 @@ -74,7 +74,7 @@ OAuth2 中,**作用域**只是声明指定权限的字符串。 /// info | 信息 -`OAuth2PasswordRequestForm` 与 `OAuth2PasswordBearer` 一样,都不是 FastAPI 的特殊类。 +`OAuth2PasswordRequestForm` 并不像 `OAuth2PasswordBearer` 那样是 **FastAPI** 的特殊类。 **FastAPI** 把 `OAuth2PasswordBearer` 识别为安全方案。因此,可以通过这种方式把它添加至 OpenAPI。 @@ -200,7 +200,7 @@ UserInDB( 此处返回值为 `Bearer` 的响应头 `WWW-Authenticate` 也是规范的一部分。 -任何 401**UNAUTHORIZED**HTTP(错误)状态码都应返回 `WWW-Authenticate` 响应头。 +任何 401“UNAUTHORIZED”HTTP(错误)状态码都应返回 `WWW-Authenticate` 响应头。 本例中,因为使用的是 Bearer Token,该响应头的值应为 `Bearer`。 @@ -220,7 +220,7 @@ UserInDB( ### 身份验证 { #authenticate } -点击**Authorize**按钮。 +点击“Authorize”按钮。 使用以下凭证: @@ -286,4 +286,4 @@ UserInDB( 唯一欠缺的是,它仍然不是真的**安全**。 -下一章,介绍使用密码哈希支持库与 JWT 令牌实现真正的安全机制。 +下一章你将看到如何使用安全的密码哈希库和 JWT 令牌。 diff --git a/docs/zh/docs/tutorial/sql-databases.md b/docs/zh/docs/tutorial/sql-databases.md index 944e960a7..ef0b7c460 100644 --- a/docs/zh/docs/tutorial/sql-databases.md +++ b/docs/zh/docs/tutorial/sql-databases.md @@ -216,7 +216,7 @@ $ fastapi dev main.py 它包含与 `HeroBase` 相同的字段,因此不会包括 `secret_name`。 -终于,我们英雄(hero)的身份得到了保护!🥷 +终于,我们英雄的身份得到了保护!🥷 它还重新声明了 `id: int`。这样我们便与 API 客户端建立了一种**约定**,使他们始终可以期待 `id` 存在并且是一个整数 `int`(永远不会是 `None`)。 diff --git a/docs/zh/docs/tutorial/static-files.md b/docs/zh/docs/tutorial/static-files.md index 5b2f920b2..1f4ebae9a 100644 --- a/docs/zh/docs/tutorial/static-files.md +++ b/docs/zh/docs/tutorial/static-files.md @@ -7,9 +7,9 @@ * 导入 `StaticFiles`。 * 将一个 `StaticFiles()` 实例“挂载”(Mount)到指定路径。 -{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *} +{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *} -/// note | 注意 +/// note | 技术细节 你也可以用 `from starlette.staticfiles import StaticFiles`。 diff --git a/docs/zh/docs/tutorial/testing.md b/docs/zh/docs/tutorial/testing.md index 1aff9f799..7eb32f19e 100644 --- a/docs/zh/docs/tutorial/testing.md +++ b/docs/zh/docs/tutorial/testing.md @@ -30,7 +30,7 @@ $ pip install httpx 为你需要检查的地方用标准的Python表达式写个简单的 `assert` 语句(重申,标准的`pytest`)。 -{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *} +{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *} /// tip | 提示 @@ -76,7 +76,7 @@ $ pip install httpx 在 `main.py` 文件中你有一个 **FastAPI** app: -{* ../../docs_src/app_testing/app_a_py39/main.py *} +{* ../../docs_src/app_testing/app_a_py310/main.py *} ### 测试文件 { #testing-file } @@ -92,7 +92,7 @@ $ pip install httpx 因为这文件在同一个包中,所以你可以通过相对导入从 `main` 模块(`main.py`)导入`app`对象: -{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *} +{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *} ...然后测试代码和之前一样的。 diff --git a/docs/zh/docs/virtual-environments.md b/docs/zh/docs/virtual-environments.md index 29e272b59..60fb9e23f 100644 --- a/docs/zh/docs/virtual-environments.md +++ b/docs/zh/docs/virtual-environments.md @@ -30,7 +30,7 @@ 首先,为你的工程创建一个目录。 -我 (指原作者 —— 译者注) 通常会在我的主目录下创建一个名为 `code` 的目录。 +我通常会在我的主目录下创建一个名为 `code` 的目录。 在这个目录下,我再为每个工程创建一个目录。 @@ -53,7 +53,7 @@ $ cd awesome-project ## 创建一个虚拟环境 { #create-a-virtual-environment } -在开始一个 Python 工程的**第一时间**,**在你的工程内部**创建一个虚拟环境。 +在开始一个 Python 工程的**第一时间**,**在你的工程内部**创建一个虚拟环境。 /// tip | 提示 @@ -316,7 +316,7 @@ $ echo "*" > .venv/.gitignore ### 直接安装包 { #install-packages-directly } -如果你急于安装,不想使用文件来声明工程的软件包依赖,您可以直接安装它们。 +如果你急于安装,不想使用文件来声明工程的软件包依赖,你可以直接安装它们。 /// tip | 提示 @@ -412,7 +412,7 @@ Hello World ## 配置编辑器 { #configure-your-editor } -你可能会用到编辑器(即 IDE —— 译者注),请确保配置它使用与你创建的相同的虚拟环境(它可能会自动检测到),以便你可以获得自动补全和内联错误提示。 +你可能会用到编辑器,请确保配置它使用与你创建的相同的虚拟环境(它可能会自动检测到),以便你可以获得自动补全和内联错误提示。 例如: @@ -437,7 +437,7 @@ $ deactivate -这样,当你运行 `python` 时,它不会尝试从安装了软件包的虚拟环境中运行。(即,它将不再会尝试从虚拟环境中运行,也不会使用其中安装的软件包。—— 译者注) +这样,当你运行 `python` 时,它不会尝试从那个虚拟环境及其已安装的软件包中运行。 ## 开始工作 { #ready-to-work }