diff --git a/docs/zh/docs/_llm-test.md b/docs/zh/docs/_llm-test.md index 0da76d43c2..5748c09008 100644 --- a/docs/zh/docs/_llm-test.md +++ b/docs/zh/docs/_llm-test.md @@ -37,7 +37,7 @@ 昨天,我的朋友写道:"如果你把 incorrectly 拼对了,你就把它拼错了"。我回答:"没错,但 'incorrectly' 错的不是 '"incorrectly"'"。 -/// note +/// note | 注意 LLM 很可能会把这段翻错。我们只关心在重新翻译时它是否能保持修正后的译文。 @@ -124,24 +124,24 @@ works(foo="bar") # 这可行 🎉 //// tab | 测试 -/// note -Some text +/// note | 注意 +一些文本 /// /// note | 技术细节 -Some text +一些文本 /// -/// tip -Some text +/// tip | 提示 +一些文本 /// -/// warning -Some text +/// warning | 警告 +一些文本 /// -/// danger -Some text +/// danger | 危险 +一些文本 /// //// @@ -213,7 +213,7 @@ Some text ## HTML "dfn" 元素 { #html-dfn-elements } -* 集群 +* 集群 * 深度学习 ## 标题 { #headings } @@ -222,15 +222,15 @@ Some text ### 开发 Web 应用——教程 { #develop-a-webapp-a-tutorial } -Hello. +你好。 ### 类型提示与注解 { #type-hints-and-annotations } -Hello again. +再次你好。 ### 超类与子类 { #super-and-subclasses } -Hello again. +再次你好。 //// @@ -248,241 +248,241 @@ Hello again. //// tab | 测试 -* you -* your +* 你 +* 你的 -* e.g. -* etc. +* 例如 +* 等 -* `foo` as an `int` -* `bar` as a `str` -* `baz` as a `list` +* 作为 `int` 的 `foo` +* 作为 `str` 的 `bar` +* 作为 `list` 的 `baz` -* the Tutorial - User guide -* the Advanced User Guide -* the SQLModel docs -* the API docs -* the automatic docs +* 教程 - 用户指南 +* 高级用户指南 +* SQLModel 文档 +* API 文档 +* 自动文档 -* Data Science -* Deep Learning -* Machine Learning -* Dependency Injection -* HTTP Basic authentication +* 数据科学 +* 深度学习 +* 机器学习 +* 依赖注入 +* HTTP Basic 认证 * HTTP Digest -* ISO format -* the JSON Schema standard -* the JSON schema -* the schema definition -* Password Flow -* Mobile - -* deprecated -* designed -* invalid -* on the fly -* standard -* default -* case-sensitive -* case-insensitive - -* to serve the application -* to serve the page - -* the app -* the application - -* the request -* the response -* the error response - -* the path operation -* the path operation decorator -* the path operation function - -* the body -* the request body -* the response body -* the JSON body -* the form body -* the file body -* the function body - -* the parameter -* the body parameter -* the path parameter -* the query parameter -* the cookie parameter -* the header parameter -* the form parameter -* the function parameter - -* the event -* the startup event -* the startup of the server -* the shutdown event -* the lifespan event - -* the handler -* the event handler -* the exception handler -* to handle - -* the model -* the Pydantic model -* the data model -* the database model -* the form model -* the model object - -* the class -* the base class -* the parent class -* the subclass -* the child class -* the sibling class -* the class method - -* the header -* the headers -* the authorization header -* the `Authorization` header -* the forwarded header - -* the dependency injection system -* the dependency -* the dependable -* the dependant - -* I/O bound -* CPU bound -* concurrency -* parallelism -* multiprocessing - -* the env var -* the environment variable -* the `PATH` -* the `PATH` variable - -* the authentication -* the authentication provider -* the authorization -* the authorization form -* the authorization provider -* the user authenticates -* the system authenticates the user - -* the CLI -* the command line interface - -* the server -* the client - -* the cloud provider -* the cloud service - -* the development -* the development stages - -* the dict -* the dictionary -* the enumeration -* the enum -* the enum member - -* the encoder -* the decoder -* to encode -* to decode - -* the exception -* to raise - -* the expression -* the statement - -* the frontend -* the backend - -* the GitHub discussion -* the GitHub issue - -* the performance -* the performance optimization - -* the return type -* the return value - -* the security -* the security scheme - -* the task -* the background task -* the task function - -* the template -* the template engine - -* the type annotation -* the type hint - -* the server worker -* the Uvicorn worker -* the Gunicorn Worker -* the worker process -* the worker class -* the workload - -* the deployment -* to deploy - -* the SDK -* the software development kit - -* the `APIRouter` -* the `requirements.txt` -* the Bearer Token -* the breaking change -* the bug -* the button -* the callable -* the code -* the commit -* the context manager -* the coroutine -* the database session -* the disk -* the domain -* the engine -* the fake X -* the HTTP GET method -* the item -* the library -* the lifespan -* the lock -* the middleware -* the mobile application -* the module -* the mounting -* the network -* the origin -* the override -* the payload -* the processor -* the property -* the proxy -* the pull request -* the query -* the RAM -* the remote machine -* the status code -* the string -* the tag -* the web framework -* the wildcard -* to return -* to validate +* ISO 格式 +* JSON Schema 标准 +* JSON schema +* schema 定义 +* 密码流 +* 移动端 + +* 已弃用 +* 设计的 +* 无效 +* 动态地 +* 标准 +* 默认 +* 区分大小写 +* 不区分大小写 + +* 为应用提供服务 +* 为页面提供服务 + +* 应用 +* 应用程序 + +* 请求 +* 响应 +* 错误响应 + +* 路径操作 +* 路径操作装饰器 +* 路径操作函数 + +* 请求体 +* 请求体 +* 响应体 +* JSON 请求体 +* 表单体 +* 文件体 +* 函数体 + +* 参数 +* 请求体参数 +* 路径参数 +* 查询参数 +* Cookie 参数 +* Header 参数 +* 表单参数 +* 函数参数 + +* 事件 +* 启动事件 +* 服务器启动 +* 关闭事件 +* lifespan 事件 + +* 处理器 +* 事件处理器 +* 异常处理器 +* 处理 + +* 模型 +* Pydantic 模型 +* 数据模型 +* 数据库模型 +* 表单模型 +* 模型对象 + +* 类 +* 基类 +* 父类 +* 子类 +* 子类 +* 兄弟类 +* 类方法 + +* Header +* Headers +* 授权 Header +* `Authorization` header +* 转发 Header + +* 依赖注入系统 +* 依赖项 +* 可依赖项 +* 依赖方 + +* I/O 密集型 +* CPU 密集型 +* 并发 +* 并行 +* 多进程 + +* 环境变量 +* 环境变量 +* `PATH` +* `PATH` 变量 + +* 认证 +* 认证提供方 +* 授权 +* 授权表单 +* 授权提供方 +* 用户进行认证 +* 系统对用户进行认证 + +* CLI +* 命令行界面 + +* 服务器 +* 客户端 + +* 云服务提供商 +* 云服务 + +* 开发 +* 开发阶段 + +* dict +* 字典 +* 枚举 +* 枚举 +* 枚举成员 + +* 编码器 +* 解码器 +* 编码 +* 解码 + +* 异常 +* 抛出 + +* 表达式 +* 语句 + +* 前端 +* 后端 + +* GitHub 讨论 +* GitHub issue + +* 性能 +* 性能优化 + +* 返回类型 +* 返回值 + +* 安全 +* 安全方案 + +* 任务 +* 后台任务 +* 任务函数 + +* 模板 +* 模板引擎 + +* 类型注解 +* 类型提示 + +* 服务器 worker +* Uvicorn worker +* Gunicorn Worker +* worker 进程 +* worker 类 +* 工作负载 + +* 部署 +* 部署 + +* SDK +* 软件开发工具包 + +* `APIRouter` +* `requirements.txt` +* Bearer Token +* 破坏性变更 +* bug +* 按钮 +* 可调用对象 +* 代码 +* 提交 +* 上下文管理器 +* 协程 +* 数据库会话 +* 磁盘 +* 域名 +* 引擎 +* 虚假 X +* HTTP GET 方法 +* 项 +* 库 +* 生命周期 +* 锁 +* 中间件 +* 移动应用 +* 模块 +* 挂载 +* 网络 +* 源 +* 覆盖 +* 载荷 +* 处理器 +* 属性 +* 代理 +* Pull Request +* 查询 +* RAM +* 远程机器 +* 状态码 +* 字符串 +* 标签 +* Web 框架 +* 通配符 +* 返回 +* 校验 //// diff --git a/docs/zh/docs/advanced/additional-status-codes.md b/docs/zh/docs/advanced/additional-status-codes.md index af212ad8b1..0f2e3d2eef 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` 对象时,它会直接返回。 @@ -38,4 +38,4 @@ 如果你直接返回额外的状态码和响应,它们不会包含在 OpenAPI 方案(API 文档)中,因为 FastAPI 没办法预先知道你要返回什么。 -但是你可以使用 [额外的响应](additional-responses.md) 在代码中记录这些内容。 +但是你可以使用:[额外的响应](additional-responses.md),在代码中记录这些内容。 diff --git a/docs/zh/docs/advanced/advanced-dependencies.md b/docs/zh/docs/advanced/advanced-dependencies.md index da299a6bfc..12f2616c09 100644 --- a/docs/zh/docs/advanced/advanced-dependencies.md +++ b/docs/zh/docs/advanced/advanced-dependencies.md @@ -1,5 +1,6 @@ # 高级依赖项 { #advanced-dependencies } + ## 参数化的依赖项 { #parameterized-dependencies } 目前我们看到的依赖项都是固定的函数或类。 diff --git a/docs/zh/docs/advanced/dataclasses.md b/docs/zh/docs/advanced/dataclasses.md index a46615286c..df94a7de70 100644 --- a/docs/zh/docs/advanced/dataclasses.md +++ b/docs/zh/docs/advanced/dataclasses.md @@ -1,5 +1,6 @@ # 使用数据类 { #using-dataclasses } + FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydantic 模型声明请求与响应。 但 FastAPI 也支持以相同方式使用 [`dataclasses`](https://docs.python.org/3/library/dataclasses.html): diff --git a/docs/zh/docs/advanced/events.md b/docs/zh/docs/advanced/events.md index e1bb2ed60b..49d497d3d0 100644 --- a/docs/zh/docs/advanced/events.md +++ b/docs/zh/docs/advanced/events.md @@ -1,5 +1,6 @@ # 生命周期事件 { #lifespan-events } + 你可以定义在应用**启动**前执行的逻辑(代码)。这意味着在应用**开始接收请求**之前,这些代码只会被执行**一次**。 同样地,你可以定义在应用**关闭**时应执行的逻辑。在这种情况下,这段代码将在**处理可能的多次请求后**执行**一次**。 diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md index 9feaf6cf56..dd15f0e9c4 100644 --- a/docs/zh/docs/advanced/generate-clients.md +++ b/docs/zh/docs/advanced/generate-clients.md @@ -20,20 +20,6 @@ FastAPI 会自动生成 **OpenAPI 3.1** 规范,因此你使用的任何工具 /// -## 来自 FastAPI 赞助商的 SDK 生成器 { #sdk-generators-from-fastapi-sponsors } - -本节介绍的是由赞助 FastAPI 的公司提供的、具备**风险投资背景**或**公司支持**的方案。这些产品在高质量生成的 SDK 之上,提供了**更多特性**和**集成**。 - -通过 ✨ [**赞助 FastAPI**](../help-fastapi.md#sponsor-the-author) ✨,这些公司帮助确保框架及其**生态**保持健康并且**可持续**。 - -他们的赞助也体现了对 FastAPI **社区**(也就是你)的高度承诺,不仅关注提供**优秀的服务**,也支持一个**健壮且繁荣的框架**——FastAPI。🙇 - -例如,你可以尝试: - -* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral) - -其中一些方案也可能是开源的或提供免费层级,你可以不花钱就先试用。其他商业 SDK 生成器也可在网上找到。🤓 - ## 创建一个 TypeScript SDK { #create-a-typescript-sdk } 先从一个简单的 FastAPI 应用开始: @@ -56,7 +42,7 @@ OpenAPI 中包含的这些模型信息就是用于**生成客户端代码**的 ### Hey API { #hey-api } -当我们有了带模型的 FastAPI 应用后,可以使用 Hey API 来生成 TypeScript 客户端。最快的方式是通过 npx: +当我们有了带模型的 FastAPI 应用后,可以使用 Hey API 来生成 TypeScript 客户端。最快的方式是通过 npx。 ```sh npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client @@ -119,9 +105,9 @@ 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,以确保其唯一性。 +OpenAPI 要求每个操作 ID 在所有*路径操作*中都是唯一的,因此 FastAPI 会使用**函数名**、**路径**和**HTTP 方法/操作**来生成操作 ID,因为这样可以确保操作 ID 是唯一的。 接下来我会告诉你如何改进。🤓 @@ -193,9 +179,9 @@ npx @hey-api/openapi-ts -i ./openapi.json -o src/client 使用自动生成的客户端时,你会获得以下内容的**自动补全**: -* 方法 -* 请求体中的数据、查询参数等 -* 响应数据 +* 方法。 +* 请求体中的数据、查询参数等。 +* 响应数据。 你还会为所有内容获得**内联错误**。 diff --git a/docs/zh/docs/advanced/json-base64-bytes.md b/docs/zh/docs/advanced/json-base64-bytes.md index 7792282c72..040957c69c 100644 --- a/docs/zh/docs/advanced/json-base64-bytes.md +++ b/docs/zh/docs/advanced/json-base64-bytes.md @@ -4,7 +4,7 @@ ## Base64 与文件 { #base64-vs-files } -请先考虑是否可以使用 [请求文件](../tutorial/request-files.md) 来上传二进制数据,并使用 [自定义响应 - FileResponse](./custom-response.md#fileresponse--fileresponse-) 来发送二进制数据,而不是把它编码进 JSON。 +请先考虑是否可以使用 [请求文件](../tutorial/request-files.md) 来上传二进制数据,并使用 [自定义响应 - FileResponse](./custom-response.md#fileresponse) 来发送二进制数据,而不是把它编码进 JSON。 JSON 只能包含 UTF-8 编码的字符串,因此无法直接包含原始字节。 @@ -14,7 +14,7 @@ Base64 可以把二进制数据编码为字符串,但为此会使用比原始 ## Pydantic `bytes` { #pydantic-bytes } -你可以声明带有 `bytes` 字段的 Pydantic 模型,然后在模型配置中使用 `val_json_bytes` 指定用 base64 来验证输入的 JSON 数据;作为验证的一部分,它会将该 base64 字符串解码为字节。 +你可以声明带有 `bytes` 字段的 Pydantic 模型,然后在模型配置中使用 `val_json_bytes` 指定用 base64 来*验证*输入的 JSON 数据;作为验证的一部分,它会将该 base64 字符串解码为字节。 {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *} @@ -52,12 +52,12 @@ Base64 可以把二进制数据编码为字符串,但为此会使用比原始 ## 用于输出数据的 Pydantic `bytes` { #pydantic-bytes-for-output-data } -对于输出数据,你也可以在模型配置中为 `bytes` 字段使用 `ser_json_bytes`,Pydantic 会在生成 JSON 响应时将字节以 base64 进行序列化。 +对于输出数据,你也可以在模型配置中为 `bytes` 字段使用 `ser_json_bytes`,Pydantic 会在生成 JSON 响应时将字节以 base64 进行*序列化*。 {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *} ## 用于输入和输出数据的 Pydantic `bytes` { #pydantic-bytes-for-input-and-output-data } -当然,你也可以使用同一个配置了 base64 的模型,在接收和发送 JSON 数据时,同时处理输入(使用 `val_json_bytes` 进行验证)和输出(使用 `ser_json_bytes` 进行序列化)。 +当然,你也可以使用同一个配置了 base64 的模型,在接收和发送 JSON 数据时,同时处理输入(使用 `val_json_bytes` 进行*验证*)和输出(使用 `ser_json_bytes` 进行*序列化*)。 {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *} diff --git a/docs/zh/docs/advanced/openapi-callbacks.md b/docs/zh/docs/advanced/openapi-callbacks.md index f4f2e7b81d..3ca99b9808 100644 --- a/docs/zh/docs/advanced/openapi-callbacks.md +++ b/docs/zh/docs/advanced/openapi-callbacks.md @@ -1,35 +1,35 @@ # OpenAPI 回调 { #openapi-callbacks } -您可以创建一个包含*路径操作*的 API,它会触发对别人创建的*外部 API*的请求(很可能就是那个会“使用”您 API 的同一个开发者)。 +你可以创建一个包含*路径操作*的 API,该*路径操作*可以触发对其他人创建的*外部 API*的请求(很可能就是那个会*使用*你的 API 的同一个开发者)。 -当您的 API 应用调用*外部 API*时,这个过程被称为“回调”。因为外部开发者编写的软件会先向您的 API 发送请求,然后您的 API 再进行*回调*,向*外部 API*发送请求(很可能也是该开发者创建的)。 +当你的 API 应用调用*外部 API*时,这个过程被称为“回调”。因为外部开发者编写的软件会先向你的 API 发送请求,然后你的 API 再*回调*,向*外部 API*发送请求(很可能也是该开发者创建的)。 -此时,我们需要存档外部 API 的*信息*,比如应该有哪些*路径操作*,请求体应该是什么,应该返回什么响应等。 +在这种情况下,你可能希望记录该外部 API *应该*是什么样子。它应该有哪些*路径操作*,应该接收什么请求体,应该返回什么响应等。 ## 使用回调的应用 { #an-app-with-callbacks } -示例如下。 +让我们通过一个例子来看这一切。 -假设要开发一个创建发票的应用。 +假设你开发一个可以创建发票的应用。 -发票包括 `id`、`title`(可选)、`customer`、`total` 等属性。 +这些发票会有 `id`、`title`(可选)、`customer` 和 `total`。 -API 的用户(外部开发者)要在您的 API 内使用 POST 请求创建一条发票记录。 +你的 API 用户(外部开发者)会通过 POST 请求在你的 API 中创建一张发票。 -(假设)您的 API 将: +然后你的 API 会(假设): -* 把发票发送至外部开发者的消费者 -* 归集现金 -* 把通知发送至 API 的用户(外部开发者) - * 通过(从您的 API)发送 POST 请求至外部 API(即**回调**)来完成 +* 将发票发送给外部开发者的某个客户。 +* 收款。 +* 向 API 用户(外部开发者)发回通知。 + * 这会通过(从*你的 API*)向该外部开发者提供的某个*外部 API*发送 POST 请求来完成(这就是“回调”)。 ## 常规 **FastAPI** 应用 { #the-normal-fastapi-app } -添加回调前,首先看下常规 API 应用是什么样子。 +我们先看看在添加回调之前,常规 API 应用会是什么样子。 -常规 API 应用包含接收 `Invoice` 请求体的*路径操作*,还有包含回调 URL 的查询参数 `callback_url`。 +它会有一个接收 `Invoice` 请求体的*路径操作*,以及一个包含回调 URL 的查询参数 `callback_url`。 -这部分代码很常规,您对绝大多数代码应该都比较熟悉了: +这部分很常规,大部分代码你应该已经很熟悉了: {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *} @@ -39,92 +39,92 @@ API 的用户(外部开发者)要在您的 API 内使用 POST 请求创建 /// -此处唯一比较新的内容是*路径操作装饰器*中的 `callbacks=invoices_callback_router.routes` 参数,下文介绍。 +唯一的新内容是*路径操作装饰器*中的参数 `callbacks=invoices_callback_router.routes`。接下来我们会看看它是什么。 -## 存档回调 { #documenting-the-callback } +## 为回调编写文档 { #documenting-the-callback } -实际的回调代码高度依赖于您自己的 API 应用。 +实际的回调代码会高度依赖你自己的 API 应用。 -并且可能每个应用都各不相同。 +而且很可能在不同应用之间差异很大。 -回调代码可能只有一两行,比如: +它可能只有一两行代码,例如: ```Python callback_url = "https://example.com/api/v1/invoices/events/" httpx.post(callback_url, json={"description": "Invoice paid", "paid": True}) ``` -但回调最重要的部分可能是,根据 API 要发送给回调请求体的数据等内容,确保您的 API 用户(外部开发者)正确地实现*外部 API*。 +但回调最重要的部分可能是确保你的 API 用户(外部开发者)正确实现*外部 API*,与*你的 API*将在回调请求体中发送的数据等相匹配。 -因此,我们下一步要做的就是添加代码,为从 API 接收回调的*外部 API*存档。 +因此,接下来我们要做的是添加代码,用来记录该*外部 API*应该是什么样子,才能接收来自*你的 API*的回调。 -这部分文档在 `/docs` 下的 Swagger UI 中显示,并且会告诉外部开发者如何构建*外部 API*。 +这份文档会显示在你的 API 的 `/docs` 下的 Swagger UI 中,并且会让外部开发者知道如何构建*外部 API*。 -本例没有实现回调本身(只是一行代码),只有文档部分。 +本例不实现回调本身(那可能只是一行代码),只实现文档部分。 /// tip | 提示 -实际的回调只是 HTTP 请求。 +实际的回调只是一个 HTTP 请求。 -实现回调时,要使用 [HTTPX](https://www.python-httpx.org) 或 [Requests](https://requests.readthedocs.io/)。 +自己实现回调时,你可以使用类似 [HTTPX](https://www.python-httpx.org) 或 [Requests](https://requests.readthedocs.io/) 的工具。 /// ## 编写回调文档代码 { #write-the-callback-documentation-code } -应用不执行这部分代码,只是用它来*记录 外部 API* 。 +这段代码不会在你的应用中执行,我们只需要用它来*记录*该*外部 API*应该是什么样子。 -但,您已经知道用 **FastAPI** 创建自动 API 文档有多简单了。 +不过,你已经知道如何使用 **FastAPI** 轻松为 API 创建自动文档了。 -我们要使用与存档*外部 API* 相同的知识...通过创建外部 API 要实现的*路径操作*(您的 API 要调用的)。 +因此,我们会使用相同的知识来记录该*外部 API*应该是什么样子...通过创建外部 API 应该实现的*路径操作*(也就是你的 API 将调用的那些)。 /// tip | 提示 -编写存档回调的代码时,假设您是*外部开发者*可能会用的上。并且您当前正在实现的是*外部 API*,不是*您自己的 API*。 +在编写用于记录回调的代码时,可以想象你就是那个*外部开发者*。而且你现在正在实现的是*外部 API*,不是*你的 API*。 -临时改变(为外部开发者的)视角能让您更清楚该如何放置*外部 API* 响应和请求体的参数与 Pydantic 模型等。 +临时采用这个(*外部开发者*的)视角,可以帮助你更清楚地判断该把参数、请求体的 Pydantic 模型、响应等放在该*外部 API*的什么位置。 /// -### 创建回调的 `APIRouter` { #create-a-callback-apirouter } +### 创建回调 `APIRouter` { #create-a-callback-apirouter } -首先,新建包含一些用于回调的 `APIRouter`。 +首先创建一个新的 `APIRouter`,它将包含一个或多个回调。 {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *} ### 创建回调*路径操作* { #create-the-callback-path-operation } -创建回调*路径操作*也使用之前创建的 `APIRouter`。 +要创建回调*路径操作*,请使用你在上面创建的同一个 `APIRouter`。 -它看起来和常规 FastAPI *路径操作*差不多: +它看起来应该就像普通的 FastAPI *路径操作*: -* 声明要接收的请求体,例如,`body: InvoiceEvent` -* 还要声明要返回的响应,例如,`response_model=InvoiceEventReceived` +* 它可能应该声明要接收的请求体,例如 `body: InvoiceEvent`。 +* 它也可以声明要返回的响应,例如 `response_model=InvoiceEventReceived`。 {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *} -回调*路径操作*与常规*路径操作*有两点主要区别: +它与普通*路径操作*有 2 个主要区别: -* 它不需要任何实际的代码,因为应用不会调用这段代码。它只是用于存档*外部 API*。因此,函数的内容只需要 `pass` 就可以了 -* *路径*可以包含 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(详见下文),可以使用带参数的变量,以及发送至您的 API 的原始请求的部分 +* 它不需要任何实际代码,因为你的应用永远不会调用这段代码。它只用于记录*外部 API*。因此,函数可以只有 `pass`。 +* *路径*可以包含 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(见下文),其中可以使用带参数的变量,以及发送到*你的 API*的原始请求的部分内容。 ### 回调路径表达式 { #the-callback-path-expression } -回调*路径*支持包含发送给您的 API 的原始请求的部分的 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)。 +回调*路径*可以有一个 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression),其中可以包含发送到*你的 API*的原始请求的部分内容。 -本例中是 `str`: +在这个例子中,它是这个 `str`: ```Python "{$callback_url}/invoices/{$request.body.id}" ``` -因此,如果您的 API 用户(外部开发者)发送请求到您的 API: +所以,如果你的 API 用户(外部开发者)向*你的 API*发送请求到: ``` https://yourapi.com/invoices/?callback_url=https://www.external.org/events ``` -使用如下 JSON 请求体: +并带有如下 JSON 请求体: ```JSON { @@ -134,13 +134,13 @@ https://yourapi.com/invoices/?callback_url=https://www.external.org/events } ``` -然后,您的 API 就会处理发票,并在某个点之后,发送回调请求至 `callback_url`(外部 API): +那么*你的 API*会处理该发票,并在稍后的某个时间点,向 `callback_url`(*外部 API*)发送回调请求: ``` https://www.external.org/events/invoices/2expen51ve ``` -JSON 请求体包含如下内容: +并带有类似如下内容的 JSON 请求体: ```JSON { @@ -149,7 +149,7 @@ JSON 请求体包含如下内容: } ``` -它会预期*外部 API* 的响应包含如下 JSON 请求体: +它会预期该*外部 API*返回类似如下 JSON 请求体的响应: ```JSON { @@ -159,28 +159,28 @@ JSON 请求体包含如下内容: /// tip | 提示 -注意,回调 URL 包含 `callback_url`(`https://www.external.org/events`)中的查询参数,还有 JSON 请求体内部的发票 ID(`2expen51ve`)。 +请注意,使用的回调 URL 包含在 `callback_url` 中作为查询参数接收到的 URL(`https://www.external.org/events`),也包含 JSON 请求体内部的发票 `id`(`2expen51ve`)。 /// ### 添加回调路由 { #add-the-callback-router } -至此,在上文创建的回调路由里就包含了*回调路径操作*(外部开发者要在外部 API 中实现)。 +此时,你已经在上面创建的回调路由中拥有了所需的*回调路径操作*(即*外部开发者*应该在*外部 API*中实现的那些)。 -现在使用 API *路径操作装饰器*的参数 `callbacks`,从回调路由传递属性 `.routes`(实际上只是路由/路径操作的**列表**): +现在,在*你的 API 的路径操作装饰器*中使用参数 `callbacks`,传入该回调路由的 `.routes` 属性: {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *} /// tip | 提示 -注意,不能把路由本身(`invoices_callback_router`)传递给 `callbacks=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。FastAPI 会使用这些路由来生成回调的 OpenAPI 文档。 +请注意,你不是把路由本身(`invoices_callback_router`)传给 `callbacks=`,而是传它的 `.routes`,也就是 `invoices_callback_router.routes`。FastAPI 会使用这些路由来生成回调的 OpenAPI 文档。 /// ### 查看文档 { #check-the-docs } -现在,启动应用并打开 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。 +现在你可以启动应用并访问 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。 -就能看到文档的*路径操作*已经包含了**回调**的内容以及*外部 API*: +你会看到文档中为你的*路径操作*包含了一个 "Callbacks" 部分,展示了*外部 API*应该是什么样子: diff --git a/docs/zh/docs/advanced/response-change-status-code.md b/docs/zh/docs/advanced/response-change-status-code.md index 379afd4eb9..4339875e45 100644 --- a/docs/zh/docs/advanced/response-change-status-code.md +++ b/docs/zh/docs/advanced/response-change-status-code.md @@ -22,7 +22,7 @@ {* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *} -然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。 +然后你可以像平常一样返回任何你需要的对象(一个`dict`、一个数据库模型等)。 如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。 diff --git a/docs/zh/docs/advanced/response-cookies.md b/docs/zh/docs/advanced/response-cookies.md index 7fad89e5c6..9a41b95e4e 100644 --- a/docs/zh/docs/advanced/response-cookies.md +++ b/docs/zh/docs/advanced/response-cookies.md @@ -1,36 +1,38 @@ -# 响应Cookies { #response-cookies } +# 响应 Cookies { #response-cookies } ## 使用 `Response` 参数 { #use-a-response-parameter } -你可以在 *路径操作函数* 中定义一个类型为 `Response` 的参数,这样你就可以在这个临时响应对象中设置cookie了。 +你可以在*路径操作函数*中声明一个类型为 `Response` 的参数。 + +然后你可以在这个*临时*响应对象中设置 Cookie。 {* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *} -而且你还可以根据你的需要响应不同的对象,比如常用的 `dict`,数据库model等。 +然后你可以像平常一样返回所需的任何对象(`dict`、数据库模型等)。 -如果你定义了 `response_model`,程序会自动根据`response_model`来过滤和转换你响应的对象。 +如果你声明了 `response_model`,它仍会用于过滤和转换你返回的对象。 -**FastAPI** 会使用这个 *临时* 响应对象去装在这些cookies信息 (同样还有headers和状态码等信息), 最终会将这些信息和通过`response_model`转化过的数据合并到最终的响应里。 +**FastAPI** 会使用这个*临时*响应来提取 Cookie(还有 header 和状态码),并将它们放入最终响应中;最终响应包含你返回的值,并经过任何 `response_model` 过滤。 -你也可以在依赖中定义`Response`参数,并设置cookie和header。 +你也可以在依赖项中声明 `Response` 参数,并在其中设置 Cookie(和 header)。 -## 直接响应 `Response` { #return-a-response-directly } +## 直接返回 `Response` { #return-a-response-directly } -你还可以在直接响应`Response`时直接创建cookies。 +在代码中直接返回 `Response` 时,你也可以创建 Cookie。 为此,你可以按照[直接返回 Response](response-directly.md)中的说明创建一个响应。 -然后设置Cookies,并返回: +然后在其中设置 Cookie,并返回它: {* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *} /// tip | 提示 -需要注意,如果你直接反馈一个response对象,而不是使用`Response`入参,FastAPI则会直接反馈你封装的response对象。 +请记住,如果你直接返回响应,而不是使用 `Response` 参数,FastAPI 会直接返回它。 -所以你需要确保你响应数据类型的正确性,如:你可以使用`JSONResponse`来兼容JSON的场景。 +因此,你必须确保你的数据类型正确。例如,如果你返回的是 `JSONResponse`,数据就需要兼容 JSON。 -同时,你也应当仅反馈通过`response_model`过滤过的数据。 +并且还要确保你没有发送本应由 `response_model` 过滤的数据。 /// @@ -38,12 +40,12 @@ /// note | 技术细节 -你也可以使用`from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。 +你也可以使用 `from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。 -为了方便开发者,**FastAPI** 封装了相同数据类型,如`starlette.responses` 和 `fastapi.responses`。不过大部分response对象都是直接引用自Starlette。 +**FastAPI** 为了方便开发者,提供了与 `starlette.responses` 相同的 `fastapi.responses`。但大多数可用的响应都直接来自 Starlette。 -因为`Response`对象可以非常便捷的设置headers和cookies,所以 **FastAPI** 同时也封装了`fastapi.Response`。 +由于 `Response` 经常用于设置 header 和 Cookie,**FastAPI** 也在 `fastapi.Response` 中提供了它。 /// -如果你想查看所有可用的参数和选项,可以参考 [Starlette 文档](https://www.starlette.dev/responses/#set-cookie)。 +要查看所有可用参数和选项,请查看 [Starlette 文档](https://www.starlette.dev/responses/#set-cookie)。 diff --git a/docs/zh/docs/advanced/response-headers.md b/docs/zh/docs/advanced/response-headers.md index ab99a4ece1..89357058db 100644 --- a/docs/zh/docs/advanced/response-headers.md +++ b/docs/zh/docs/advanced/response-headers.md @@ -1,5 +1,6 @@ # 响应头 { #response-headers } + ## 使用 `Response` 参数 { #use-a-response-parameter } 你可以在你的*路径操作函数*中声明一个 `Response` 类型的参数(就像你可以为 cookies 做的那样)。 diff --git a/docs/zh/docs/advanced/security/oauth2-scopes.md b/docs/zh/docs/advanced/security/oauth2-scopes.md index db29e49163..fa0dd8eff0 100644 --- a/docs/zh/docs/advanced/security/oauth2-scopes.md +++ b/docs/zh/docs/advanced/security/oauth2-scopes.md @@ -86,7 +86,7 @@ OAuth2 规范将“作用域”定义为由空格分隔的字符串列表。 现在,修改令牌的*路径操作*以返回请求的作用域。 -我们仍然使用 `OAuth2PasswordRequestForm`。它包含 `scopes` 属性,其值是 `list[str]`,包含请求中接收到的每个作用域。 +我们仍然使用 `OAuth2PasswordRequestForm`。它包含 `scopes` 属性,其值是 `list` of `str`,包含请求中接收到的每个作用域。 我们把这些作用域作为 JWT 令牌的一部分返回。 @@ -174,7 +174,7 @@ OAuth2 规范将“作用域”定义为由空格分隔的字符串列表。 为此,我们给 Pydantic 模型 `TokenData` 添加了一个新属性 `scopes`。 -通过用 Pydantic 验证数据,我们可以确保确实得到了例如一个由作用域组成的 `list[str]`,以及一个 `str` 类型的 `username`。 +通过用 Pydantic 验证数据,我们可以确保确实得到了例如一个由作用域组成的 `list` of `str`,以及一个 `str` 类型的 `username`。 而不是,例如得到一个 `dict` 或其它什么,这可能会在后续某个时刻破坏应用,形成安全风险。 diff --git a/docs/zh/docs/advanced/settings.md b/docs/zh/docs/advanced/settings.md index 31a7cc82de..2159ccb259 100644 --- a/docs/zh/docs/advanced/settings.md +++ b/docs/zh/docs/advanced/settings.md @@ -297,6 +297,6 @@ participant execute as Execute function 你可以使用 Pydantic Settings 来处理应用的设置或配置,享受 Pydantic 模型的全部能力。 -- 通过使用依赖项,你可以简化测试。 -- 你可以与它一起使用 `.env` 文件。 -- 使用 `@lru_cache` 可以避免为每个请求反复读取 dotenv 文件,同时允许你在测试时进行覆盖。 +* 通过使用依赖项,你可以简化测试。 +* 你可以与它一起使用 `.env` 文件。 +* 使用 `@lru_cache` 可以避免为每个请求反复读取 dotenv 文件,同时允许你在测试时进行覆盖。 diff --git a/docs/zh/docs/advanced/stream-data.md b/docs/zh/docs/advanced/stream-data.md index 366ab203be..44e005ace9 100644 --- a/docs/zh/docs/advanced/stream-data.md +++ b/docs/zh/docs/advanced/stream-data.md @@ -2,7 +2,7 @@ 如果你要流式传输可以结构化为 JSON 的数据,你应该[流式传输 JSON Lines](../tutorial/stream-json-lines.md)。 -但如果你想流式传输纯二进制数据或字符串,可以按下面的方法操作。 +但如果你想**流式传输纯二进制数据**或字符串,可以按下面的方法操作。 /// note | 注意 @@ -12,11 +12,11 @@ ## 使用场景 { #use-cases } -如果你想流式传输纯字符串,例如直接来自某个 AI LLM 服务的输出,可以使用它。 +如果你想流式传输纯字符串,例如直接来自某个 **AI LLM** 服务的输出,可以使用它。 -你也可以用它来流式传输大型二进制文件,在读取的同时按块发送,无需一次性把所有内容读入内存。 +你也可以用它来流式传输**大型二进制文件**,在读取的同时按块发送,无需一次性把所有内容读入内存。 -你还可以用这种方式流式传输视频或音频,甚至可以在处理的同时生成并发送。 +你还可以用这种方式流式传输**视频**或**音频**,甚至可以在处理的同时生成并发送。 ## 使用 `yield` 的 `StreamingResponse` { #a-streamingresponse-with-yield } @@ -40,7 +40,7 @@ FastAPI 会将每个数据块原样交给 `StreamingResponse`,不会尝试将 {* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *} -这也意味着,使用 `StreamingResponse` 时,你拥有按需精确生成与编码字节数据的自由,同时也承担相应的责任,它与类型注解无关。🤓 +这也意味着,使用 `StreamingResponse` 时,你拥有按需精确生成与编码字节数据的**自由**,同时也承担相应的**责任**,它与类型注解无关。🤓 ### 流式传输字节 { #stream-bytes } diff --git a/docs/zh/docs/advanced/wsgi.md b/docs/zh/docs/advanced/wsgi.md index f665c371f4..eb83a09b2c 100644 --- a/docs/zh/docs/advanced/wsgi.md +++ b/docs/zh/docs/advanced/wsgi.md @@ -1,5 +1,6 @@ # 包含 WSGI - Flask,Django,其它 { #including-wsgi-flask-django-others } + 您可以挂载 WSGI 应用,正如您在 [子应用 - 挂载](sub-applications.md)、[在代理之后](behind-a-proxy.md) 中所看到的那样。 为此, 您可以使用 `WSGIMiddleware` 来包装你的 WSGI 应用,如:Flask,Django,等等。 diff --git a/docs/zh/docs/alternatives.md b/docs/zh/docs/alternatives.md index 08893fca71..20de25cbdc 100644 --- a/docs/zh/docs/alternatives.md +++ b/docs/zh/docs/alternatives.md @@ -28,7 +28,7 @@ Django REST framework 作为一个灵活工具箱而创建,用于在底层使 它被包括 Mozilla、Red Hat、Eventbrite 在内的许多公司使用。 -它是最早的“自动 API 文档”的范例之一,这正是启发“寻找” **FastAPI** 的最初想法之一。 +它是最早的**自动 API 文档**的范例之一,这正是启发“寻找” **FastAPI** 的最初想法之一。 /// note | 注意 @@ -58,8 +58,9 @@ Flask 是一个“微框架”,它不包含数据库集成,也没有像 Djan /// tip | 启发 **FastAPI**: -- 成为微框架,便于按需组合所需的工具与组件。 -- 提供简单易用的路由系统。 +成为微框架。让按需组合所需的工具与组件变得容易。 + +提供简单易用的路由系统。 /// @@ -87,7 +88,7 @@ Requests 设计非常简单直观,易于使用,且有合理的默认值。 response = requests.get("http://example.com/some/url") ``` -对应地,FastAPI 的 API 路径操作可能看起来是这样的: +对应地,FastAPI 的 API *路径操作*可能看起来是这样的: ```Python hl_lines="1" @app.get("/some/url") @@ -282,7 +283,7 @@ Flask-apispec 由与 Marshmallow 相同的开发者创建。 Falcon 是另一个高性能 Python 框架,它被设计为精简且可作为 Hug 等其他框架的基础。 -它设计为接收两个参数的函数:一个“request”和一个“response”。然后从 request 中“读取”,向 response 中“写入”。由于这种设计,无法用标准的 Python 类型提示将请求参数和请求体声明为函数形参。 +它设计为接收两个参数的函数:一个“请求”和一个“响应”。然后从请求中“读取”,向响应中“写入”。由于这种设计,无法用标准的 Python 类型提示将请求参数和请求体声明为函数形参。 因此,数据校验、序列化与文档要么需要手写完成,无法自动化;要么需要在 Falcon 之上实现一个框架,例如 Hug。其他受 Falcon 设计启发、采用“一个 request 对象 + 一个 response 对象作为参数”的框架也有同样的区别。 diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md index bee98fc8b9..8645fd6349 100644 --- a/docs/zh/docs/async.md +++ b/docs/zh/docs/async.md @@ -95,11 +95,11 @@ Python 的现代版本支持通过一种叫**“协程”**——使用 `async` ### 并发与汉堡 { #concurrency-and-burgers } -上述异步代码的思想有时也被称为“并发”,它不同于“并行”。 +上述**异步**代码的思想有时也被称为**“并发”**,它不同于**“并行”**。 -并发和并行都与“不同的事情或多或少同时发生”有关。 +**并发**和**并行**都与“不同的事情或多或少同时发生”有关。 -但是并发和并行之间的细节是完全不同的。 +但是*并发*和*并行*之间的细节是完全不同的。 要了解差异,请想象以下关于汉堡的故事: @@ -367,7 +367,7 @@ Starlette(和 **FastAPI**)是基于 [AnyIO](https://anyio.readthedocs.io/en/ 特别是,你可以直接使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 来处理高级的并发用例,这些用例需要在自己的代码中使用更高级的模式。 -即使你没有使用 **FastAPI**,你也可以使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如,结构化并发)。 +即使你没有使用 FastAPI,你也可以使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如,结构化并发)。 我基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的**自动补全**、**内联错误提示**等功能。这个库还附带了一个友好的入门指南和教程,能帮助你**理解**并编写**自己的异步代码**:[Asyncer](https://asyncer.tiangolo.com/)。如果你有**结合使用异步代码和常规**(阻塞/同步)代码的需求,这个库会特别有用。 @@ -429,13 +429,13 @@ Starlette(和 **FastAPI**)是基于 [AnyIO](https://anyio.readthedocs.io/en/ 你可以拥有多个相互依赖的依赖以及[子依赖](tutorial/dependencies/sub-dependencies.md)(作为函数的参数),它们中的一些可能是通过 `async def` 声明,也可能是通过 `def` 声明。它们仍然可以正常工作,这些通过 `def` 声明的函数将会在外部线程中调用(来自线程池),而不是“被等待”。 -### 其他函数 { #other-utility-functions } +### 其他工具函数 { #other-utility-functions } -你可直接调用通过 `def` 或 `async def` 创建的任何其他函数,FastAPI 不会影响你调用它们的方式。 +你可直接调用通过 `def` 或 `async def` 创建的任何其他工具函数,FastAPI 不会影响你调用它们的方式。 这与 FastAPI 为你调用*路径操作函数*和依赖项的逻辑相反。 -如果你的函数是通过 `def` 声明的,它将被直接调用(在代码中编写的地方),而不会在线程池中;如果这个函数通过 `async def` 声明,当在代码中调用时,你就应该使用 `await` 等待函数的结果。 +如果你的工具函数是通过 `def` 声明的,它将被直接调用(在代码中编写的地方),而不会在线程池中;如果这个函数通过 `async def` 声明,当在代码中调用时,你就应该使用 `await` 等待函数的结果。 --- diff --git a/docs/zh/docs/deployment/cloud.md b/docs/zh/docs/deployment/cloud.md index 025715f523..d20cc3ce11 100644 --- a/docs/zh/docs/deployment/cloud.md +++ b/docs/zh/docs/deployment/cloud.md @@ -16,7 +16,7 @@ FastAPI Cloud 是 *FastAPI and friends* 开源项目的主要赞助方和资金 ## 云服务商 - 赞助商 { #cloud-providers-sponsors } -还有一些云服务商也会 ✨ [**赞助 FastAPI**](../help-fastapi.md#sponsor-the-author) ✨。🙇 +还有一些云服务商也会 ✨ [**赞助 FastAPI**](https://github.com/sponsors/tiangolo) ✨。🙇 你也可以考虑按照他们的指南尝试他们的服务: diff --git a/docs/zh/docs/deployment/concepts.md b/docs/zh/docs/deployment/concepts.md index dd5ba2ba80..4e7d69b415 100644 --- a/docs/zh/docs/deployment/concepts.md +++ b/docs/zh/docs/deployment/concepts.md @@ -1,6 +1,6 @@ # 部署概念 { #deployments-concepts } -在部署 **FastAPI** 应用程序或任何类型的 Web API 时,有几个概念值得了解,通过掌握这些概念您可以找到**最合适的**方法来**部署您的应用程序**。 +在部署 **FastAPI** 应用程序,或者实际上,任何类型的 Web API 时,有几个你可能会关心的概念,通过掌握这些概念你可以找到**最合适的**方法来**部署你的应用程序**。 一些重要的概念是: @@ -9,23 +9,23 @@ * 重新启动 * 复制(运行的进程数) * 内存 -* 开始前的先前步骤 +* 启动前的先前步骤 我们接下来了解它们将如何影响**部署**。 -我们的最终目标是能够以**安全**的方式**为您的 API 客户端**提供服务,同时要**避免中断**,并且尽可能高效地利用**计算资源**(例如远程服务器/虚拟机)。 🚀 +最终目标是能够以**安全**的方式**为你的 API 客户端**提供服务,同时**避免中断**,并且尽可能高效地利用**计算资源**(例如远程服务器/虚拟机)。 🚀 -我将在这里告诉您更多关于这些**概念**的信息,希望能给您提供**直觉**来决定如何在非常不同的环境中部署 API,甚至在是尚不存在的**未来**的环境里。 +我将在这里告诉你更多关于这些**概念**的信息,希望能给你提供**直觉**来决定如何在非常不同的环境中部署你的 API,甚至是在尚不存在的**未来**环境里。 -通过考虑这些概念,您将能够**评估和设计**部署**您自己的 API**的最佳方式。 +通过考虑这些概念,你将能够**评估和设计**部署**你自己的 API** 的最佳方式。 -在接下来的章节中,我将为您提供更多部署 FastAPI 应用程序的**具体方法**。 +在接下来的章节中,我将为你提供更多部署 FastAPI 应用程序的**具体方案**。 -但现在,让我们仔细看一下这些重要的**概念**。 这些概念也适用于任何其他类型的 Web API。 💡 +但现在,让我们仔细看一下这些重要的**概念性想法**。这些概念也适用于任何其他类型的 Web API。 💡 ## 安全性 - HTTPS { #security-https } -在[上一章有关 HTTPS](https.md) 中,我们了解了 HTTPS 如何为您的 API 提供加密。 +在[上一章有关 HTTPS](https.md) 中,我们了解了 HTTPS 如何为你的 API 提供加密。 我们还看到,HTTPS 通常由应用程序服务器的**外部**组件(**TLS 终止代理**)提供。 @@ -33,7 +33,7 @@ ### HTTPS 示例工具 { #example-tools-for-https } -您可以用作 TLS 终止代理的一些工具包括: +你可以用作 TLS 终止代理的一些工具包括: * Traefik * 自动处理证书更新 ✨ @@ -43,13 +43,13 @@ * 使用 Certbot 等外部组件进行证书更新 * HAProxy * 使用 Certbot 等外部组件进行证书更新 -* 带有 Ingress Controller(如 Nginx) 的 Kubernetes +* 带有 Ingress Controller(如 Nginx)的 Kubernetes * 使用诸如 cert-manager 之类的外部组件来进行证书更新 * 由云服务商内部处理,作为其服务的一部分(请阅读下文👇) -另一种选择是您可以使用**云服务**来完成更多工作,包括设置 HTTPS。 它可能有一些限制或向您收取更多费用等。但在这种情况下,您不必自己设置 TLS 终止代理。 +另一种选择是你可以使用**云服务**来完成更多工作,包括设置 HTTPS。它可能有一些限制或向你收取更多费用等。但在这种情况下,你不必自己设置 TLS 终止代理。 -我将在接下来的章节中向您展示一些具体示例。 +我将在接下来的章节中向你展示一些具体示例。 --- @@ -63,52 +63,52 @@ **程序**这个词通常用来描述很多东西: -* 您编写的 **代码**,**Python 文件**。 -* 操作系统可以**执行**的**文件**,例如:`python`、`python.exe`或`uvicorn`。 -* 在操作系统上**运行**、使用CPU 并将内容存储在内存上的特定程序。 这也被称为**进程**。 +* 你编写的 **代码**,**Python 文件**。 +* 操作系统可以**执行**的**文件**,例如:`python`、`python.exe` 或 `uvicorn`。 +* 在操作系统上**运行**、使用 CPU 并将内容存储在内存上的特定程序。这也被称为**进程**。 ### 什么是进程 { #what-is-a-process } -**进程** 这个词通常以更具体的方式使用,仅指在操作系统中运行的东西(如上面的最后一点): +**进程**这个词通常以更具体的方式使用,仅指在操作系统中运行的东西(如上面的最后一点): * 在操作系统上**运行**的特定程序。 * 这不是指文件,也不是指代码,它**具体**指的是操作系统正在**执行**和管理的东西。 -* 任何程序,任何代码,**只有在执行时才能做事**。 因此,是当有**进程正在运行**时。 -* 该进程可以由您或操作系统**终止**(或“杀死”)。 那时,它停止运行/被执行,并且它可以**不再做事情**。 -* 您计算机上运行的每个应用程序背后都有一些进程,每个正在运行的程序,每个窗口等。并且通常在计算机打开时**同时**运行许多进程。 +* 任何程序,任何代码,**只有在执行时才能做事**。因此,是当有**进程正在运行**时。 +* 该进程可以由你或操作系统**终止**(或“杀死”)。那时,它停止运行/被执行,并且它**不再能做事情**。 +* 你计算机上运行的每个应用程序背后都有一些进程,每个正在运行的程序,每个窗口等。并且通常在计算机打开时**同时**运行许多进程。 * **同一程序**可以有**多个进程**同时运行。 -如果您检查操作系统中的“任务管理器”或“系统监视器”(或类似工具),您将能够看到许多正在运行的进程。 +如果你检查操作系统中的“任务管理器”或“系统监视器”(或类似工具),你将能够看到许多正在运行的进程。 -例如,您可能会看到有多个进程运行同一个浏览器程序(Firefox、Chrome、Edge 等)。 他们通常每个tab运行一个进程,再加上一些其他额外的进程。 +例如,你可能会看到有多个进程运行同一个浏览器程序(Firefox、Chrome、Edge 等)。它们通常每个 tab 运行一个进程,再加上一些其他额外的进程。 --- -现在我们知道了术语“进程”和“程序”之间的区别,让我们继续讨论部署。 +现在我们知道了术语 **进程** 和 **程序** 之间的区别,让我们继续讨论部署。 ## 启动时运行 { #running-on-startup } -在大多数情况下,当您创建 Web API 时,您希望它**始终运行**、不间断,以便您的客户端始终可以访问它。 这是当然的,除非您有特定原因希望它仅在某些情况下运行,但大多数时候您希望它不断运行并且**可用**。 +在大多数情况下,当你创建 Web API 时,你希望它**始终运行**、不间断,以便你的客户端始终可以访问它。当然,除非你有特定原因希望它仅在某些情况下运行,但大多数时候你希望它不断运行并且**可用**。 ### 在远程服务器中 { #in-a-remote-server } -当您设置远程服务器(云服务器、虚拟机等)时,您可以做的最简单的事情就是使用 `fastapi run`(它使用 Uvicorn)或类似方式,手动运行,就像本地开发时一样。 +当你设置远程服务器(云服务器、虚拟机等)时,你可以做的最简单的事情就是使用 `fastapi run`(它使用 Uvicorn)或类似方式,手动运行,就像本地开发时一样。 -它将会在**开发过程中**发挥作用并发挥作用。 +它将会**在开发过程中**发挥作用并且很有用。 -但是,如果您与服务器的连接丢失,**正在运行的进程**可能会终止。 +但是,如果你与服务器的连接丢失,**正在运行的进程**可能会终止。 -如果服务器重新启动(例如更新后或从云提供商迁移后),您可能**不会注意到它**。 因此,您甚至不知道必须手动重新启动该进程。 所以,你的 API 将一直处于挂掉的状态。 😱 +如果服务器重新启动(例如更新后或从云提供商迁移后),你可能**不会注意到它**。因此,你甚至不知道必须手动重新启动该进程。所以,你的 API 将一直处于挂掉的状态。 😱 ### 启动时自动运行 { #run-automatically-on-startup } -一般来说,您可能希望服务器程序(例如 Uvicorn)在服务器启动时自动启动,并且不需要任何**人为干预**,让进程始终与您的 API 一起运行(例如 Uvicorn 运行您的 FastAPI 应用程序) 。 +一般来说,你可能希望服务器程序(例如 Uvicorn)在服务器启动时自动启动,并且不需要任何**人为干预**,让进程始终与你的 API 一起运行(例如 Uvicorn 运行你的 FastAPI 应用程序)。 ### 单独的程序 { #separate-program } -为了实现这一点,您通常会有一个**单独的程序**来确保您的应用程序在启动时运行。 在许多情况下,它还可以确保其他组件或应用程序也运行,例如数据库。 +为了实现这一点,你通常会有一个**单独的程序**来确保你的应用程序在启动时运行。在许多情况下,它还可以确保其他组件或应用程序也运行,例如数据库。 ### 启动时运行的示例工具 { #example-tools-to-run-at-startup } @@ -123,43 +123,43 @@ * 作为其服务的一部分由云提供商内部处理 * 其他的... -我将在接下来的章节中为您提供更具体的示例。 +我将在接下来的章节中为你提供更具体的示例。 ## 重新启动 { #restarts } -与确保应用程序在启动时运行类似,您可能还想确保它在挂掉后**重新启动**。 +与确保应用程序在启动时运行类似,你可能还想确保它在失败后**重新启动**。 ### 我们会犯错误 { #we-make-mistakes } -作为人类,我们总是会犯**错误**。 软件几乎*总是*在不同的地方隐藏着**bug**。 🐛 +作为人类,我们总是会犯**错误**。软件几乎*总是*在不同的地方隐藏着 **bug**。 🐛 -作为开发人员,当我们发现这些bug并实现新功能(也可能添加新bug😅)时,我们会不断改进代码。 +作为开发人员,当我们发现这些 bug 并实现新功能(也可能添加新 bug 😅)时,我们会不断改进代码。 ### 自动处理小错误 { #small-errors-automatically-handled } -使用 FastAPI 构建 Web API 时,如果我们的代码中存在错误,FastAPI 通常会将其包含到触发错误的单个请求中。 🛡 +使用 FastAPI 构建 Web API 时,如果我们的代码中存在错误,FastAPI 通常会将其限制在触发错误的单个请求中。 🛡 对于该请求,客户端将收到 **500 内部服务器错误**,但应用程序将继续处理下一个请求,而不是完全崩溃。 ### 更大的错误 - 崩溃 { #bigger-errors-crashes } -尽管如此,在某些情况下,我们编写的一些代码可能会导致整个应用程序崩溃,从而导致 Uvicorn 和 Python 崩溃。 💥 +尽管如此,在某些情况下,我们编写的一些代码可能会**导致整个应用程序崩溃**,从而导致 Uvicorn 和 Python 崩溃。 💥 -尽管如此,您可能不希望应用程序因为某个地方出现错误而保持死机状态,您可能希望它**继续运行**,至少对于未破坏的*路径操作*。 +尽管如此,你可能不希望应用程序因为某个地方出现错误而保持死机状态,你可能希望它**继续运行**,至少对于未损坏的*路径操作*。 ### 崩溃后重新启动 { #restart-after-crash } -但在那些严重错误导致正在运行的**进程**崩溃的情况下,您需要一个外部组件来负责**重新启动**进程,至少尝试几次... +但在那些严重错误导致正在运行的**进程**崩溃的情况下,你需要一个外部组件来负责**重新启动**进程,至少尝试几次... /// tip | 提示 -...尽管如果整个应用程序只是**立即崩溃**,那么永远重新启动它可能没有意义。 但在这些情况下,您可能会在开发过程中注意到它,或者至少在部署后立即注意到它。 +...尽管如果整个应用程序只是**立即崩溃**,那么永远重新启动它可能没有意义。但在这些情况下,你可能会在开发过程中注意到它,或者至少在部署后立即注意到它。 因此,让我们关注主要情况,在**未来**的某些特定情况下,它可能会完全崩溃,但重新启动它仍然有意义。 /// -您可能希望让这个东西作为 **外部组件** 负责重新启动您的应用程序,因为到那时,使用 Uvicorn 和 Python 的同一应用程序已经崩溃了,因此同一应用程序的相同代码中没有东西可以对此做出什么。 +你可能希望让这个负责重新启动你的应用程序的东西作为一个**外部组件**,因为到那时,使用 Uvicorn 和 Python 的同一应用程序已经崩溃了,因此同一应用程序的相同代码中没有任何东西可以对此做什么。 ### 自动重新启动的示例工具 { #example-tools-to-restart-automatically } @@ -178,19 +178,19 @@ ## 复制 - 进程和内存 { #replication-processes-and-memory } -对于 FastAPI 应用程序,使用像 `fastapi` 命令(运行 Uvicorn)这样的服务器程序,在**一个进程**中运行一次就可以同时为多个客户端提供服务。 +对于 FastAPI 应用程序,使用像运行 Uvicorn 的 `fastapi` 命令这样的服务器程序,在**一个进程**中运行一次就可以同时为多个客户端提供服务。 -但在许多情况下,您会希望同时运行多个工作进程。 +但在许多情况下,你会希望同时运行多个工作进程。 ### 多进程 - Workers { #multiple-processes-workers } -如果您的客户端数量多于单个进程可以处理的数量(例如,如果虚拟机不是太大),并且服务器的 CPU 中有 **多个核心**,那么您可以让 **多个进程** 同时运行同一个应用程序,并在它们之间分发所有请求。 +如果你的客户端数量多于单个进程可以处理的数量(例如,如果虚拟机不是太大),并且服务器的 CPU 中有**多个核心**,那么你可以让**多个进程**同时运行同一个应用程序,并在它们之间分发所有请求。 -当您运行同一 API 程序的**多个进程**时,它们通常称为 **workers**。 +当你运行同一 API 程序的**多个进程**时,它们通常称为 **workers**。 ### 工作进程和端口 { #worker-processes-and-ports } -还记得文档 [关于 HTTPS](https.md) 中只有一个进程可以侦听服务器中的端口和 IP 地址的一种组合吗? +还记得文档[关于 HTTPS](https.md) 中说的,在服务器中只有一个进程可以侦听端口和 IP 地址的一种组合吗? 现在仍然是对的。 @@ -198,124 +198,124 @@ ### 每个进程的内存 { #memory-per-process } -现在,当程序将内容加载到内存中时,例如,将机器学习模型加载到变量中,或者将大文件的内容加载到变量中,所有这些都会消耗服务器的一点内存 (RAM) 。 +现在,当程序将内容加载到内存中时,例如,将机器学习模型加载到变量中,或者将大文件的内容加载到变量中,所有这些都会**消耗服务器的一些内存 (RAM)**。 -多个进程通常**不共享任何内存**。 这意味着每个正在运行的进程都有自己的东西、变量和内存。 如果您的代码消耗了大量内存,**每个进程**将消耗等量的内存。 +多个进程通常**不共享任何内存**。这意味着每个正在运行的进程都有自己的东西、变量和内存。如果你的代码消耗了大量内存,**每个进程**将消耗等量的内存。 ### 服务器内存 { #server-memory } -例如,如果您的代码加载 **1 GB 大小**的机器学习模型,则当您使用 API 运行一个进程时,它将至少消耗 1 GB RAM。 如果您启动 **4 个进程**(4 个工作进程),每个进程将消耗 1 GB RAM。 因此,您的 API 总共将消耗 **4 GB RAM**。 +例如,如果你的代码加载**大小为 1 GB** 的机器学习模型,则当你使用 API 运行一个进程时,它将至少消耗 1 GB RAM。如果你启动 **4 个进程**(4 个工作进程),每个进程将消耗 1 GB RAM。因此,你的 API 总共将消耗 **4 GB RAM**。 -如果您的远程服务器或虚拟机只有 3 GB RAM,尝试加载超过 4 GB RAM 将导致问题。 🚨 +如果你的远程服务器或虚拟机只有 3 GB RAM,尝试加载超过 4 GB RAM 将导致问题。 🚨 ### 多进程 - 一个例子 { #multiple-processes-an-example } 在此示例中,有一个 **Manager Process** 启动并控制两个 **Worker Processes**。 -该管理器进程可能是监听 IP 中的 **端口** 的进程。 它将所有通信传输到工作进程。 +该管理器进程可能是监听 IP 中的**端口**的进程。它将所有通信传输到工作进程。 -这些工作进程将是运行您的应用程序的进程,它们将执行主要计算以接收 **请求** 并返回 **响应**,并且它们将加载您放入 RAM 中的变量中的任何内容。 +这些工作进程将是运行你的应用程序的进程,它们将执行主要计算以接收**请求**并返回**响应**,并且它们将加载你放入 RAM 中的变量中的任何内容。 -当然,除了您的应用程序之外,同一台机器可能还运行**其他进程**。 +当然,除了你的应用程序之外,同一台机器可能还运行**其他进程**。 一个有趣的细节是,随着时间的推移,每个进程使用的 **CPU 百分比**可能会发生很大变化,但**内存 (RAM)** 通常会或多或少保持**稳定**。 -如果您有一个每次执行相当数量的计算的 API,并且您有很多客户端,那么 **CPU 利用率** 可能也会保持稳定(而不是不断快速上升和下降)。 +如果你有一个每次执行相当数量的计算的 API,并且你有很多客户端,那么 **CPU 利用率** 可能*也会保持稳定*(而不是不断快速上升和下降)。 ### 复制工具和策略示例 { #examples-of-replication-tools-and-strategies } -可以通过多种方法来实现这一目标,我将在接下来的章节中向您详细介绍具体策略,例如在谈论 Docker 和容器时。 +可以通过多种方法来实现这一目标,我将在接下来的章节中向你详细介绍具体策略,例如在谈论 Docker 和容器时。 -要考虑的主要限制是必须有一个**单个**组件来处理**公共IP**中的**端口**。 然后它必须有一种方法将通信**传输**到复制的**进程/worker**。 +要考虑的主要限制是必须有一个**单个**组件来处理**公共 IP** 中的**端口**。然后它必须有一种方法将通信**传输**到复制的**进程/worker**。 以下是一些可能的组合和策略: * 带有 `--workers` 的 **Uvicorn** - * 一个 Uvicorn **进程管理器** 将监听 **IP** 和 **端口**,并且它将启动 **多个 Uvicorn 工作进程**。 -* **Kubernetes** 和其他分布式 **容器系统** - * **Kubernetes** 层中的某些东西将侦听 **IP** 和 **端口**。 复制将通过拥有**多个容器**,每个容器运行**一个 Uvicorn 进程**。 -* **云服务** 为您处理此问题 - * 云服务可能**为您处理复制**。 它可能会让您定义 **要运行的进程**,或要使用的 **容器映像**,在任何情况下,它很可能是 **单个 Uvicorn 进程**,并且云服务将负责复制它。 + * 一个 Uvicorn **进程管理器**将监听 **IP** 和**端口**,并且它将启动**多个 Uvicorn 工作进程**。 +* **Kubernetes** 和其他分布式**容器系统** + * **Kubernetes** 层中的某些东西将侦听 **IP** 和**端口**。复制将通过拥有**多个容器**来完成,每个容器运行**一个 Uvicorn 进程**。 +* **云服务** 为你处理此问题 + * 云服务可能**为你处理复制**。它可能会让你定义**要运行的进程**,或要使用的**容器镜像**,在任何情况下,它很可能是**单个 Uvicorn 进程**,并且云服务将负责复制它。 /// tip | 提示 -如果这些关于 **容器**、Docker 或 Kubernetes 的内容还没有多大意义,请不要担心。 +如果这些关于**容器**、Docker 或 Kubernetes 的内容还没有多大意义,请不要担心。 -我将在以后的章节中向您详细介绍容器镜像、Docker、Kubernetes 等:[容器中的 FastAPI - Docker](docker.md)。 +我将在以后的章节中向你详细介绍容器镜像、Docker、Kubernetes 等:[容器中的 FastAPI - Docker](docker.md)。 /// ## 启动之前的步骤 { #previous-steps-before-starting } -在很多情况下,您希望在**启动**应用程序之前执行一些步骤。 +在很多情况下,你希望在**启动**应用程序之前执行一些步骤。 -例如,您可能想要运行**数据库迁移**。 +例如,你可能想要运行**数据库迁移**。 -但在大多数情况下,您只想执行这些步骤**一次**。 +但在大多数情况下,你只想执行这些步骤**一次**。 -因此,在启动应用程序之前,您将需要一个**单个进程**来执行这些**前面的步骤**。 +因此,在启动应用程序之前,你将需要一个**单个进程**来执行这些**前面的步骤**。 -而且您必须确保它是运行前面步骤的单个进程, *即使*之后您为应用程序本身启动**多个进程**(多个worker)。 如果这些步骤由**多个进程**运行,它们会通过在**并行**运行来**重复**工作,并且如果这些步骤像数据库迁移一样需要小心处理,它们可能会导致每个进程和其他进程发生冲突。 +而且你必须确保它是运行前面步骤的单个进程,*即使*之后你为应用程序本身启动**多个进程**(多个 worker)。如果这些步骤由**多个进程**运行,它们会通过**并行**运行来**重复**工作,并且如果这些步骤像数据库迁移一样需要小心处理,它们可能会导致彼此之间发生冲突。 当然,也有一些情况,多次运行前面的步骤也没有问题,这样的话就好办多了。 /// tip | 提示 -另外,请记住,根据您的设置,在某些情况下,您在开始应用程序之前**可能甚至不需要任何先前的步骤**。 +另外,请记住,根据你的设置,在某些情况下,你在启动应用程序之前**可能甚至不需要任何先前的步骤**。 -在这种情况下,您就不必担心这些。 🤷 +在这种情况下,你就不必担心这些。 🤷 /// ### 前面步骤策略的示例 { #examples-of-previous-steps-strategies } -这将在**很大程度上取决于您部署系统的方式**,并且可能与您启动程序、处理重启等的方式有关。 +这将在**很大程度上取决于你部署系统的方式**,并且可能与你启动程序、处理重启等的方式有关。 以下是一些可能的想法: * Kubernetes 中的“Init Container”在应用程序容器之前运行 -* 一个 bash 脚本,运行前面的步骤,然后启动您的应用程序 - * 您仍然需要一种方法来启动/重新启动 bash 脚本、检测错误等。 +* 一个 bash 脚本,运行前面的步骤,然后启动你的应用程序 + * 你仍然需要一种方法来启动/重新启动*那个* bash 脚本、检测错误等。 /// tip | 提示 -我将在以后的章节中为您提供使用容器执行此操作的更具体示例:[容器中的 FastAPI - Docker](docker.md)。 +我将在以后的章节中为你提供使用容器执行此操作的更具体示例:[容器中的 FastAPI - Docker](docker.md)。 /// ## 资源利用率 { #resource-utilization } -您的服务器是一个**资源**,您可以通过您的程序消耗或**利用**CPU 上的计算时间以及可用的 RAM 内存。 +你的服务器是一个**资源**,你可以通过你的程序消耗或**利用** CPU 上的计算时间以及可用的 RAM 内存。 -您想要消耗/利用多少系统资源? 您可能很容易认为“不多”,但实际上,您可能希望在不崩溃的情况下**尽可能多地消耗**。 +你想要消耗/利用多少系统资源?你可能很容易认为“不多”,但实际上,你可能希望在不崩溃的情况下**尽可能多地消耗**。 -如果您支付了 3 台服务器的费用,但只使用了它们的一点点 RAM 和 CPU,那么您可能**浪费金钱** 💸,并且可能 **浪费服务器电力** 🌎,等等。 +如果你支付了 3 台服务器的费用,但只使用了它们的一点点 RAM 和 CPU,那么你可能**浪费金钱** 💸,并且可能**浪费服务器电力** 🌎,等等。 在这种情况下,最好只拥有 2 台服务器并使用更高比例的资源(CPU、内存、磁盘、网络带宽等)。 -另一方面,如果您有 2 台服务器,并且正在使用 **100% 的 CPU 和 RAM**,则在某些时候,一个进程会要求更多内存,并且服务器将不得不使用磁盘作为“内存” (这可能会慢数千倍),甚至**崩溃**。 或者一个进程可能需要执行一些计算,并且必须等到 CPU 再次空闲。 +另一方面,如果你有 2 台服务器,并且正在使用**它们 100% 的 CPU 和 RAM**,则在某些时候,一个进程会要求更多内存,并且服务器将不得不使用磁盘作为“内存”(这可能会慢数千倍),甚至**崩溃**。或者一个进程可能需要执行一些计算,并且必须等到 CPU 再次空闲。 在这种情况下,最好购买**一台额外的服务器**并在其上运行一些进程,以便它们都有**足够的 RAM 和 CPU 时间**。 -由于某种原因,您的 API 的使用量也有可能出现**激增**。 也许它像病毒一样传播开来,或者也许其他一些服务或机器人开始使用它。 在这些情况下,您可能需要额外的资源来保证安全。 +由于某种原因,你的 API 的使用量也有可能出现**激增**。也许它像病毒一样传播开来,或者也许其他一些服务或机器人开始使用它。在这些情况下,你可能需要额外的资源来保证安全。 -您可以将一个**任意数字**设置为目标,例如,资源利用率**在 50% 到 90%** 之间。 重点是,这些可能是您想要衡量和用来调整部署的主要内容。 +你可以将一个**任意数字**设置为目标,例如,资源利用率**在 50% 到 90%** 之间。重点是,这些可能是你想要衡量和用来调整部署的主要内容。 -您可以使用“htop”等简单工具来查看服务器中使用的 CPU 和 RAM 或每个进程使用的数量。 或者您可以使用更复杂的监控工具,这些工具可能分布在服务器等上。 +你可以使用 `htop` 等简单工具来查看服务器中使用的 CPU 和 RAM 或每个进程使用的数量。或者你可以使用更复杂的监控工具,这些工具可能分布在服务器等上。 ## 回顾 { #recap } -您在这里阅读了一些在决定如何部署应用程序时可能需要牢记的主要概念: +你在这里阅读了一些在决定如何部署应用程序时可能需要牢记的主要概念: * 安全性 - HTTPS * 启动时运行 * 重新启动 * 复制(运行的进程数) * 内存 -* 开始前的先前步骤 +* 启动前的先前步骤 -了解这些想法以及如何应用它们应该会给您足够的直觉在配置和调整部署时做出任何决定。 🤓 +了解这些想法以及如何应用它们应该会给你足够的直觉,以便在配置和调整部署时做出任何决定。 🤓 -在接下来的部分中,我将为您提供更具体的示例,说明您可以遵循的可能策略。 🚀 +在接下来的部分中,我将为你提供更具体的示例,说明你可以遵循的可能策略。 🚀 diff --git a/docs/zh/docs/deployment/docker.md b/docs/zh/docs/deployment/docker.md index c1b216953e..5e3919bd2e 100644 --- a/docs/zh/docs/deployment/docker.md +++ b/docs/zh/docs/deployment/docker.md @@ -1,5 +1,6 @@ # 容器中的 FastAPI - Docker { #fastapi-in-containers-docker } + 部署 FastAPI 应用时,常见做法是构建一个**Linux 容器镜像**。通常使用 [**Docker**](https://www.docker.com/) 实现。然后你可以用几种方式之一部署该镜像。 使用 Linux 容器有多种优势,包括**安全性**、**可复制性**、**简单性**等。 diff --git a/docs/zh/docs/deployment/https.md b/docs/zh/docs/deployment/https.md index 916fb46da2..090c4ba593 100644 --- a/docs/zh/docs/deployment/https.md +++ b/docs/zh/docs/deployment/https.md @@ -67,7 +67,7 @@ 你可能拥有一个云服务器(虚拟机)或类似的东西,并且它会有一个固定 **公共IP地址**。 -在 DNS 服务器中,你可以配置一条记录(“A 记录”)以将 **你的域名** 指向你服务器的公共 **IP 地址**。 +在 DNS 服务器中,你可以配置一条记录(一个 `A record`)以将 **你的域名** 指向你服务器的公共 **IP 地址**。 这个操作一般只需要在最开始执行一次。 @@ -179,7 +179,7 @@ TLS 终止代理将使用协商好的加密算法**解密请求**,并将**( 因此,要更新证书,更新程序需要向权威机构(Let's Encrypt)**证明**它确实**“拥有”并控制该域名**。 -有多种方法可以做到这一点。 一些流行的方式是: +有多种方法可以做到这一点,并适应不同的应用需求。 一些流行的方式是: * **修改一些DNS记录**。 * 为此,续订程序需要支持 DNS 提供商的 API,因此,要看你使用的 DNS 提供商是否提供这一功能。 @@ -188,8 +188,7 @@ TLS 终止代理将使用协商好的加密算法**解密请求**,并将**( * 这就是当同一个 TLS 终止代理还负责证书续订过程时它非常有用的原因之一。 * 否则,你可能需要暂时停止 TLS 终止代理,启动续订程序以获取证书,然后使用 TLS 终止代理配置它们,然后重新启动 TLS 终止代理。 这并不理想,因为你的应用程序在 TLS 终止代理关闭期间将不可用。 -通过拥有一个**单独的系统来使用 TLS 终止代理来处理 HTTPS**, 而不是直接将 TLS 证书与应用程序服务器一起使用 (例如 Uvicorn),你可以在 -更新证书的过程中同时保持提供服务。 +在仍然为应用提供服务的同时完成整个更新流程,是你想要用 TLS 终止代理拥有一个**单独系统来处理 HTTPS**,而不是直接在应用服务器(例如 Uvicorn)上使用 TLS 证书的主要原因之一。 ## 代理转发请求头 { #proxy-forwarded-headers } @@ -209,7 +208,7 @@ TLS 终止代理将使用协商好的加密算法**解密请求**,并将**( 不过,由于**应用服务器**并不知道自己位于受信任的**代理**之后,默认情况下,它不会信任这些请求头。 -但你可以配置**应用服务器**去信任由**代理**发送的这些“转发”请求头。如果你在使用 FastAPI CLI,可以使用命令行选项 `--forwarded-allow-ips` 指定它应该信任哪些 IP 发来的这些“转发”请求头。 +但你可以配置**应用服务器**去信任由**代理**发送的这些*转发*请求头。如果你在使用 FastAPI CLI,可以使用 *CLI 选项* `--forwarded-allow-ips` 指定它应该信任哪些 IP 发来的这些*转发*请求头。 例如,如果**应用服务器**只接收来自受信任**代理**的通信,你可以设置 `--forwarded-allow-ips="*"`,让它信任所有传入的 IP,因为它只会接收来自**代理**所使用 IP 的请求。 diff --git a/docs/zh/docs/deployment/manually.md b/docs/zh/docs/deployment/manually.md index a395f96da5..ee468f4e4d 100644 --- a/docs/zh/docs/deployment/manually.md +++ b/docs/zh/docs/deployment/manually.md @@ -2,7 +2,7 @@ ## 使用 `fastapi run` 命令 { #use-the-fastapi-run-command } -简而言之,使用 `fastapi run` 来运行您的 FastAPI 应用程序: +简而言之,使用 `fastapi run` 来运行你的 FastAPI 应用程序:
@@ -40,7 +40,7 @@ $ fastapi run fastapi run ASGI。FastAPI 本质上是一个 ASGI Web 框架。 -要在远程服务器上运行 **FastAPI** 应用(或任何其他 ASGI 应用),您需要一个 ASGI 服务器程序,例如 **Uvicorn**。它是 `fastapi` 命令默认使用的 ASGI 服务器。 +要在远程服务器上运行 **FastAPI** 应用(或任何其他 ASGI 应用),你需要一个 ASGI 服务器程序,例如 **Uvicorn**。它是 `fastapi` 命令默认使用的 ASGI 服务器。 除此之外,还有其他一些可选的 ASGI 服务器,例如: @@ -63,17 +63,17 @@ FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称 “**服务器**”一词通常用于指远程/云计算机(物理机或虚拟机)以及在该计算机上运行的程序(例如 Uvicorn)。 -请记住,当您一般读到“服务器”这个名词时,它可能指的是这两者之一。 +请记住,当你一般读到“服务器”这个名词时,它可能指的是这两者之一。 -当提到远程主机时,通常将其称为**服务器**,但也称为**机器**(machine)、**VM**(虚拟机)、**节点**。 这些都是指某种类型的远程计算机,通常运行 Linux,您可以在其中运行程序。 +当提到远程主机时,通常将其称为**服务器**,但也称为**机器**(machine)、**VM**(虚拟机)、**节点**。 这些都是指某种类型的远程计算机,通常运行 Linux,你可以在其中运行程序。 ## 安装服务器程序 { #install-the-server-program } -当您安装 FastAPI 时,它自带一个生产环境服务器——Uvicorn,并且您可以使用 `fastapi run` 命令来启动它。 +当你安装 FastAPI 时,它自带一个生产环境服务器——Uvicorn,并且你可以使用 `fastapi run` 命令来启动它。 -不过,您也可以手动安装 ASGI 服务器。 +不过,你也可以手动安装 ASGI 服务器。 -请确保您创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装服务器应用程序。 +请确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装服务器应用程序。 例如,要安装 Uvicorn,可以运行以下命令: @@ -95,13 +95,13 @@ $ pip install "uvicorn[standard]" 其中包括 `uvloop`,这是 `asyncio` 的高性能替代方案,能够显著提升并发性能。 -当您使用 `pip install "fastapi[standard]"` 安装 FastAPI 时,实际上也会安装 `uvicorn[standard]`。 +当你使用 `pip install "fastapi[standard]"` 安装 FastAPI 时,实际上也会安装 `uvicorn[standard]`。 /// ## 运行服务器程序 { #run-the-server-program } -如果您手动安装了 ASGI 服务器,通常需要以特定格式传递一个导入字符串,以便服务器能够正确导入您的 FastAPI 应用: +如果你手动安装了 ASGI 服务器,通常需要以特定格式传递一个导入字符串,以便服务器能够正确导入你的 FastAPI 应用:
@@ -128,7 +128,7 @@ from main import app /// -每种 ASGI 服务器程序通常都会有类似的命令,您可以在它们的官方文档中找到更多信息。 +每种 ASGI 服务器程序通常都会有类似的命令,你可以在它们的官方文档中找到更多信息。 /// warning | 警告 @@ -144,7 +144,7 @@ Uvicorn 和其他服务器支持 `--reload` 选项,该选项在开发过程中 这些示例运行服务器程序(例如 Uvicorn),启动**单个进程**,在所有 IP(`0.0.0.0`)上监听预定义端口(例如`80`)。 -这是基本思路。 但您可能需要处理一些其他事情,例如: +这是基本思路。 但你可能需要处理一些其他事情,例如: * 安全性 - HTTPS * 启动时运行 @@ -153,4 +153,4 @@ Uvicorn 和其他服务器支持 `--reload` 选项,该选项在开发过程中 * 内存 * 开始前的步骤 -在接下来的章节中,我将向您详细介绍每个概念、如何思考它们,以及一些具体示例以及处理它们的策略。 🚀 +在接下来的章节中,我将向你详细介绍每个概念、如何思考它们,以及一些具体示例以及处理它们的策略。 🚀 diff --git a/docs/zh/docs/editor-support.md b/docs/zh/docs/editor-support.md index 5028c6c957..7caff801e3 100644 --- a/docs/zh/docs/editor-support.md +++ b/docs/zh/docs/editor-support.md @@ -14,7 +14,7 @@ ## 功能 { #features } -- **Path Operation 资源管理器** - 侧边栏树状视图展示应用中的所有 *路径操作*。点击可跳转至任一路由或 APIRouter 的定义。 +- **Path Operation 资源管理器** - 侧边栏树状视图展示应用中的所有 *路径操作*。点击可跳转至任一路由或 router 的定义。 - **路由搜索** - 使用 Ctrl + Shift + E(macOS 上为 Cmd + Shift + E)按路径、方法或名称进行搜索。 - **CodeLens 导航** - 测试客户端调用(例如 `client.get('/items')`)上方的可点击链接,可跳转到匹配的*路径操作*,在测试与实现之间快速往返。 - **部署到 FastAPI Cloud** - 一键将你的应用部署到 [FastAPI Cloud](https://fastapicloud.com/)。 diff --git a/docs/zh/docs/environment-variables.md b/docs/zh/docs/environment-variables.md index 3a90ecde62..be6869e44d 100644 --- a/docs/zh/docs/environment-variables.md +++ b/docs/zh/docs/environment-variables.md @@ -1,5 +1,6 @@ # 环境变量 { #environment-variables } + /// tip | 提示 如果你已经知道什么是“环境变量”并且知道如何使用它们,你可以放心跳过这一部分。 diff --git a/docs/zh/docs/features.md b/docs/zh/docs/features.md index 5fd9d48c43..1405bee469 100644 --- a/docs/zh/docs/features.md +++ b/docs/zh/docs/features.md @@ -19,11 +19,11 @@ ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) -* 另外的 API 文档:[**ReDoc**](https://github.com/Rebilly/ReDoc) +* 另外的 API 文档:[**ReDoc**](https://github.com/Rebilly/ReDoc)。 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### 更主流的 Python { #just-modern-python } +### 就是现代 Python { #just-modern-python } 全部都基于标准的 **Python 类型** 声明(感谢 Pydantic)。没有新的语法需要学习。只需要标准的现代 Python。 @@ -98,7 +98,7 @@ my_second_user: User = User(**second_user_data) ### 简洁 { #short } -任何类型都有合理的**默认值**,任何和地方都有可选配置。所有的参数被微调,来满足你的需求,定义成你需要的 API。 +任何类型都有合理的**默认值**,任何地方都有可选配置。所有的参数被微调,来满足你的需求,定义成你需要的 API。 但是默认情况下,一切都能**“顺利工作”**。 @@ -110,7 +110,7 @@ my_second_user: User = User(**second_user_data) * 字符串 (`str`) 字段,定义最小或最大长度。 * 数字 (`int`, `float`) 有最大值和最小值,等等。 -* 校验外来类型,比如: +* 校验更特殊的类型,比如: * URL。 * Email。 * UUID。 @@ -120,9 +120,9 @@ my_second_user: User = User(**second_user_data) ### 安全性及身份验证 { #security-and-authentication } -集成了安全性和身份认证。杜绝数据库或者数据模型的渗透风险。 +集成了安全性和身份验证。不需要在数据库或数据模型上作出任何妥协。 -OpenAPI 中定义的安全模式,包括: +OpenAPI 中定义的所有安全模式,包括: * HTTP 基本认证。 * **OAuth2**(也使用 **JWT tokens**)。在 [使用 JWT 的 OAuth2](tutorial/security/oauth2-jwt.md) 查看教程。 @@ -131,7 +131,7 @@ OpenAPI 中定义的安全模式,包括: * 查询参数。 * Cookies,等等。 -加上来自 Starlette(包括 **session cookie**)的所有安全特性。 +加上来自 Starlette(包括 **session cookies**)的所有安全特性。 所有的这些都是可复用的工具和组件,可以轻松与你的系统,数据仓库,关系型以及 NoSQL 数据库等等集成。 @@ -142,7 +142,7 @@ FastAPI 有一个使用非常简单,但是非常强大的测试覆盖。 -* 代码库100% 类型注释。 +* 代码库100% 类型标注。 * 用于生产应用。 ## Starlette 特性 { #starlette-features } -**FastAPI** 和 [**Starlette**](https://www.starlette.dev/) 完全兼容(并基于)。所以,你有的其他的 Starlette 代码也能正常工作。`FastAPI` 实际上是 `Starlette` 的一个子类。所以,如果你已经知道或者使用 Starlette,大部分的功能会以相同的方式工作。 +**FastAPI** 与 [**Starlette**](https://www.starlette.dev/) 完全兼容(并基于它构建)。所以,你有的其他的 Starlette 代码也能正常工作。 + +`FastAPI` 实际上是 `Starlette` 的一个子类。所以,如果你已经知道或者使用 Starlette,大部分的功能会以相同的方式工作。 通过 **FastAPI** 你可以获得所有 **Starlette** 的特性(FastAPI 就像加强版的 Starlette): @@ -172,11 +174,11 @@ FastAPI 有一个使用非常简单,但是非常强大的IDE/linter/brain** 适配: * 因为 pydantic 数据结构仅仅是你定义的类的实例;自动补全,linting,mypy 以及你的直觉应该可以和你验证的数据一起正常工作。 * 验证**复杂结构**: diff --git a/docs/zh/docs/help-fastapi.md b/docs/zh/docs/help-fastapi.md index 2ff9752eb6..1692d07ecb 100644 --- a/docs/zh/docs/help-fastapi.md +++ b/docs/zh/docs/help-fastapi.md @@ -26,7 +26,7 @@ 你可以在 GitHub 上为 FastAPI 点亮「星标」(点击右上角的星形按钮):[https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)。⭐️ -加星后,其他用户更容易发现它,并看到它已经对许多人有帮助。 +加星后,其他用户更容易发现它,并看到它已经对其他人有帮助。 ## 关注 GitHub 资源库的版本发布 { #watch-the-github-repository-for-releases } @@ -34,7 +34,7 @@ 在那里你可以选择「Releases only」。 -这样做之后,每当 **FastAPI** 发布新版本(包含修复和新功能),你都会收到通知(邮件)。 +这样做之后,每当 **FastAPI** 发布包含 Bug 修复和新功能的新版本时,你都会收到通知(邮件)。 ## 关注作者 { #follow-the-author } diff --git a/docs/zh/docs/how-to/configure-swagger-ui.md b/docs/zh/docs/how-to/configure-swagger-ui.md index 3dbc54911b..d1909488a8 100644 --- a/docs/zh/docs/how-to/configure-swagger-ui.md +++ b/docs/zh/docs/how-to/configure-swagger-ui.md @@ -16,11 +16,11 @@ FastAPI会将这些配置转换为 **JSON**,使其与 JavaScript 兼容,因 -但是你可以通过设置 `syntaxHighlight` 为 `False` 来禁用 Swagger UI 中的语法高亮: +但是你可以通过设置 `syntaxHighlight` 为 `False` 来禁用它: {* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *} -...在此之后,Swagger UI 将不会高亮代码: +...在此之后,Swagger UI 将不再显示语法高亮: @@ -30,7 +30,7 @@ FastAPI会将这些配置转换为 **JSON**,使其与 JavaScript 兼容,因 {* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *} -这个配置会改变语法高亮主题: +这个配置会改变语法高亮颜色主题: diff --git a/docs/zh/docs/how-to/custom-request-and-route.md b/docs/zh/docs/how-to/custom-request-and-route.md index 79860a5623..4065818eaa 100644 --- a/docs/zh/docs/how-to/custom-request-and-route.md +++ b/docs/zh/docs/how-to/custom-request-and-route.md @@ -72,7 +72,7 @@ 由 `GzipRequest.get_route_handler` 返回的函数唯一不同之处是把 `Request` 转换为 `GzipRequest`。 -这样,在传给我们的路径操作之前,`GzipRequest` 会(在需要时)负责解压数据。 +这样,在传给我们的*路径操作*之前,`GzipRequest` 会(在需要时)负责解压数据。 之后,其余处理逻辑完全相同。 @@ -104,6 +104,6 @@ {* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *} -在此示例中,`router` 下的路径操作将使用自定义的 `TimedRoute` 类,响应中会多一个 `X-Response-Time` 头,包含生成响应所用的时间: +在此示例中,`router` 下的*路径操作*将使用自定义的 `TimedRoute` 类,响应中会多一个 `X-Response-Time` 头,包含生成响应所用的时间: {* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *} diff --git a/docs/zh/docs/how-to/graphql.md b/docs/zh/docs/how-to/graphql.md index b33d6759fa..31d15d3b41 100644 --- a/docs/zh/docs/how-to/graphql.md +++ b/docs/zh/docs/how-to/graphql.md @@ -2,7 +2,7 @@ 由于 **FastAPI** 基于 **ASGI** 标准,因此很容易集成任何也兼容 ASGI 的 **GraphQL** 库。 -你可以在同一个应用中将常规的 FastAPI 路径操作与 GraphQL 结合使用。 +你可以在同一个应用中将常规的 FastAPI *路径操作* 与 GraphQL 结合使用。 /// tip | 提示 diff --git a/docs/zh/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md b/docs/zh/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md index 3723eb0327..ecfdd0278b 100644 --- a/docs/zh/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md +++ b/docs/zh/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md @@ -8,9 +8,11 @@ FastAPI 0.119.0 引入了在 Pydantic v2 内部以 `pydantic.v1` 形式对 Pydan FastAPI 0.126.0 移除了对 Pydantic v1 的支持,但在一段时间内仍支持 `pydantic.v1`。 +FastAPI 0.128.0 也移除了对 `pydantic.v1` 的支持,因此最新版本的 FastAPI 需要 Pydantic v2。 + /// warning | 警告 -从 Python 3.14 开始,Pydantic 团队不再为最新的 Python 版本提供 Pydantic v1 的支持。 +从 **Python 3.14** 开始,Pydantic 团队不再为最新的 Python 版本提供 Pydantic v1 的支持。 这也包括 `pydantic.v1`,在 Python 3.14 及更高版本中不再受支持。 @@ -18,7 +20,7 @@ FastAPI 0.126.0 移除了对 Pydantic v1 的支持,但在一段时间内仍支 /// -如果你的旧 FastAPI 应用在用 Pydantic v1,这里将向你展示如何迁移到 Pydantic v2,以及 FastAPI 0.119.0 中可帮助你渐进式迁移的功能。 +如果你的旧 FastAPI 应用在用 Pydantic v1,这里将向你展示如何迁移到 Pydantic v2,以及 **FastAPI 0.119.0 中的功能** 可帮助你渐进式迁移。 ## 官方指南 { #official-guide } @@ -54,6 +56,16 @@ Pydantic v2 以子模块 `pydantic.v1` 的形式包含了 Pydantic v1 的全部 ### FastAPI 对 v2 中 Pydantic v1 的支持 { #fastapi-support-for-pydantic-v1-in-v2 } +/// warning | 警告 + +此 FastAPI 对 `pydantic.v1` 模型的支持是在 **FastAPI 0.119.0** 中添加的,并在 **FastAPI 0.128.0** 中移除。它原本是为了迁移到 Pydantic v2 而提供的临时辅助。 + +在当前版本的 FastAPI 中,在你的应用里使用 `pydantic.v1` 模型会引发错误。 + +本节其余部分描述的临时支持仅在那些较旧版本中可用。 + +/// + 自 FastAPI 0.119.0 起,FastAPI 也对 Pydantic v2 内的 Pydantic v1 提供了部分支持,以便迁移到 v2。 因此,你可以将 Pydantic 升级到最新的 v2,并将导入改为使用 `pydantic.v1` 子模块,在很多情况下就能直接工作。 @@ -122,6 +134,12 @@ graph TB ### 分步迁移 { #migrate-in-steps } +/// warning | 警告 + +下面描述的在同一应用中同时使用 Pydantic v1 和 v2 模型进行渐进式迁移,只适用于 **FastAPI 0.119.0 到 0.127.x**。它已在 **FastAPI 0.128.0** 中移除,最新版本需要 **Pydantic v2** 模型。 + +/// + /// tip | 提示 优先尝试 `bump-pydantic`,如果测试通过且可行,那么你就用一个命令完成了。✨ diff --git a/docs/zh/docs/how-to/separate-openapi-schemas.md b/docs/zh/docs/how-to/separate-openapi-schemas.md index 19d372b461..a7335143a9 100644 --- a/docs/zh/docs/how-to/separate-openapi-schemas.md +++ b/docs/zh/docs/how-to/separate-openapi-schemas.md @@ -1,5 +1,6 @@ # 是否为输入和输出分别生成 OpenAPI JSON Schema { #separate-openapi-schemas-for-input-and-output-or-not } + 自从发布了 **Pydantic v2**,生成的 OpenAPI 比之前更精确、更**正确**了。😎 事实上,在某些情况下,对于同一个 Pydantic 模型,OpenAPI 中会根据是否带有**默认值**,为输入和输出分别生成**两个 JSON Schema**。 diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md index 74b799e5c1..6b75291fe1 100644 --- a/docs/zh/docs/index.md +++ b/docs/zh/docs/index.md @@ -106,19 +106,19 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框
“我最近大量使用 FastAPI。我实际上计划把它用于我团队在 微软的机器学习(ML)服务。其中一些正在集成进核心 Windows 产品以及一些 Office 产品。”
-
— Kabir Khan,Microsoft (ref)
+
— Kabir Khan,Microsoft (参考)
@@ -127,25 +127,25 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框 「_[...] 我最近大量使用 **FastAPI**。[...] 我实际上计划把它用于我团队在 **微软的机器学习(ML)服务**。其中一些正在集成进核心 **Windows** 产品以及一些 **Office** 产品。_」 -
Kabir Khan - Microsoft (ref)
+
Kabir Khan - Microsoft (参考)
--- 「_我们采用 **FastAPI** 库来启动一个可查询以获取**预测结果**的 **REST** 服务器。[用于 Ludwig]_」 -
Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala - Uber (ref)
+
Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala - Uber (参考)
--- 「_**Netflix** 很高兴宣布开源我们的**危机管理**编排框架:**Dispatch**![使用 **FastAPI** 构建]_」 -
Kevin Glisson,Marc Vilanova,Forest Monsen - Netflix (ref)
+
Kevin Glisson,Marc Vilanova,Forest Monsen - Netflix (参考)
--- 「_如果有人正在构建生产级的 Python API,我强烈推荐 **FastAPI**。它**设计优雅**、**使用简单**且**高度可扩展**,它已经成为我们 API 优先开发战略中的**关键组件**,并驱动了许多自动化和服务,比如我们的 Virtual TAC Engineer。_」 -
Deon Pillsbury - Cisco (ref)
+
Deon Pillsbury - Cisco (参考)
--- @@ -192,7 +192,7 @@ $ pip install "fastapi[standard]"
-**Note**: 请确保把 `"fastapi[standard]"` 用引号包起来,以保证在所有终端中都能正常工作。 +**注意**: 请确保把 `"fastapi[standard]"` 用引号包起来,以保证在所有终端中都能正常工作。 ## 示例 { #example } @@ -237,7 +237,7 @@ async def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` -**Note**: +**注意**: 如果你不确定,请查看文档中 _"In a hurry?"_ 章节的 [`async` 和 `await`](https://fastapi.tiangolo.com/zh/async/#in-a-hurry) 部分。 @@ -400,7 +400,7 @@ item_id: int item: Item ``` -……通过一次声明,你将获得: +...通过一次声明,你将获得: * 编辑器支持,包括: * 自动补全。 @@ -421,7 +421,7 @@ item: Item * `datetime` 对象。 * `UUID` 对象。 * 数据库模型。 - * ……以及更多。 + * ...以及更多。 * 自动生成的交互式 API 文档,包括两种可选的用户界面: * Swagger UI。 * ReDoc。 @@ -457,19 +457,19 @@ item: Item return {"item_name": item.name, "item_id": item_id} ``` -……从: +...从: ```Python ... "item_name": item.name ... ``` -……改为: +...改为: ```Python ... "item_price": item.price ... ``` -……看看你的编辑器如何自动补全属性并知道它们的类型: +...看看你的编辑器如何自动补全属性并知道它们的类型: ![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) @@ -488,7 +488,7 @@ item: Item * 基于 HTTPX 和 `pytest` 的极其简单的测试 * **CORS** * **Cookie Sessions** - * ……以及更多。 + * ...以及更多。 ### 部署你的应用(可选) { #deploy-your-app-optional } diff --git a/docs/zh/docs/project-generation.md b/docs/zh/docs/project-generation.md index 8cc50c0963..371eb73199 100644 --- a/docs/zh/docs/project-generation.md +++ b/docs/zh/docs/project-generation.md @@ -1,5 +1,6 @@ # FastAPI全栈模板 { #full-stack-fastapi-template } + 模板通常带有特定的设置,但它们被设计为灵活且可定制。这样你可以根据项目需求进行修改和调整,使其成为很好的起点。🏁 你可以使用此模板开始,它已经为你完成了大量的初始设置、安全性、数据库以及一些 API 端点。 diff --git a/docs/zh/docs/python-types.md b/docs/zh/docs/python-types.md index 7901f9702e..4d2c2749a0 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** 完全基于这些类型提示构建,它们带来了许多优势和好处。 @@ -44,7 +44,7 @@ John Doe 但现在想象你要从零开始写它。 -在某个时刻你开始定义函数,并且准备好了参数…… +在某个时刻你开始定义函数,并且准备好了参数... 接下来你需要调用“那个把首字母变大写的方法”。 @@ -62,7 +62,7 @@ John Doe 我们来改前一个版本的一行代码。 -把函数参数从: +我们会把这个片段,也就是函数参数,从: ```Python first_name, last_name @@ -151,7 +151,7 @@ def some_function(data: Any): 有些类型可以在方括号中接收“类型参数”(type parameters),用于声明其内部值的类型。比如“字符串列表”可以写为 `list[str]`。 -这些能接收类型参数的类型称为“泛型类型”(Generic types)或“泛型”(Generics)。 +这些能接收类型参数的类型称为**泛型类型**(Generic types)或**泛型**(Generics)。 你可以把相同的内建类型作为泛型使用(带方括号和内部类型): @@ -221,7 +221,7 @@ def some_function(data: Any): #### Union { #union } -你可以声明一个变量可以是若干种类型中的任意一种,比如既可以是 `int` 也可以是 `str`。 +你可以声明一个变量可以是**若干种类型**中的任意一种,比如既可以是 `int` 也可以是 `str`。 定义时使用竖线(`|`)把两种类型分开。 @@ -263,9 +263,9 @@ def some_function(data: Any): -注意,这表示“`one_person` 是类 `Person` 的一个实例(instance)”。 +注意,这表示“`one_person` 是类 `Person` 的一个**实例**(instance)”。 -它并不表示“`one_person` 是名为 `Person` 的类本身(class)”。 +它并不表示“`one_person` 是名为 `Person` 的**类**(class)”。 ## Pydantic 模型 { #pydantic-models } @@ -285,7 +285,7 @@ def some_function(data: Any): /// note | 注意 -想了解更多关于 [Pydantic](https://docs.pydantic.dev/) 的信息,请查看其文档。 +要了解更多关于 [Pydantic 的信息,请查看其文档](https://docs.pydantic.dev/)。 /// @@ -295,7 +295,7 @@ def some_function(data: Any): ## 带元数据注解的类型提示 { #type-hints-with-metadata-annotations } -Python 还提供了一个特性,可以使用 `Annotated` 在这些类型提示中放入额外的元数据。 +Python 还提供了一个特性,可以使用 `Annotated` 在这些类型提示中放入**额外的元数据**。 你可以从 `typing` 导入 `Annotated`。 @@ -305,15 +305,15 @@ Python 本身不会对这个 `Annotated` 做任何处理。对于编辑器和其 但你可以在 `Annotated` 中为 **FastAPI** 提供额外的元数据,来描述你希望应用如何行为。 -重要的是要记住:传给 `Annotated` 的第一个类型参数才是实际类型。其余的只是给其他工具用的元数据。 +重要的是要记住:传给 `Annotated` 的**第一个*类型参数***才是**实际类型**。其余的只是给其他工具用的元数据。 现在你只需要知道 `Annotated` 的存在,并且它是标准 Python。😎 -稍后你会看到它有多么强大。 +稍后你会看到它有多么**强大**。 /// tip | 提示 -这是标准 Python,这意味着你仍然可以在编辑器里获得尽可能好的开发体验,并能和你用来分析、重构代码的工具良好协作等。✨ +这是**标准 Python**,这意味着你仍然可以在编辑器里获得**尽可能好的开发体验**,并能和你用来分析、重构代码的工具良好协作等。✨ 同时你的代码也能与许多其他 Python 工具和库高度兼容。🚀 @@ -325,16 +325,16 @@ Python 本身不会对这个 `Annotated` 做任何处理。对于编辑器和其 在 **FastAPI** 中,用类型提示来声明参数,你将获得: -* 编辑器支持。 -* 类型检查。 +* **编辑器支持**。 +* **类型检查**。 -……并且 **FastAPI** 会使用相同的声明来: +...并且 **FastAPI** 会使用相同的声明来: -* 定义要求:从请求路径参数、查询参数、请求头、请求体、依赖等。 -* 转换数据:把请求中的数据转换为所需类型。 -* 校验数据:对于每个请求: - * 当数据无效时,自动生成错误信息返回给客户端。 -* 使用 OpenAPI 记录 API: +* **定义要求**:从请求路径参数、查询参数、请求头、请求体、依赖等。 +* **转换数据**:把请求中的数据转换为所需类型。 +* **校验数据**:对于每个请求: + * 当数据无效时,自动生成返回给客户端的**错误**。 +* 使用 OpenAPI **记录** API: * 然后用于自动生成交互式文档界面。 这些听起来可能有点抽象。别担心。你会在[教程 - 用户指南](tutorial/index.md)中看到所有这些的实际效果。 @@ -343,6 +343,6 @@ Python 本身不会对这个 `Annotated` 做任何处理。对于编辑器和其 /// note | 注意 -如果你已经读完所有教程,又回来想进一步了解类型,一个不错的资源是 [`mypy` 的“速查表”](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)。 +如果你已经读完整个教程,又回来想进一步了解类型,一个不错的资源是 [`mypy` 的“速查表”](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)。 /// diff --git a/docs/zh/docs/tutorial/bigger-applications.md b/docs/zh/docs/tutorial/bigger-applications.md index 1be1be6284..9bb4bea999 100644 --- a/docs/zh/docs/tutorial/bigger-applications.md +++ b/docs/zh/docs/tutorial/bigger-applications.md @@ -17,16 +17,16 @@ ``` . ├── app -│   ├── __init__.py -│   ├── main.py -│   ├── dependencies.py -│   └── routers -│   │ ├── __init__.py -│   │ ├── items.py -│   │ └── users.py -│   └── internal -│   ├── __init__.py -│   └── admin.py +│ ├── __init__.py +│ ├── main.py +│ ├── dependencies.py +│ └── routers +│ │ ├── __init__.py +│ │ ├── items.py +│ │ └── users.py +│ └── internal +│ ├── __init__.py +│ └── admin.py ``` /// tip | 提示 diff --git a/docs/zh/docs/tutorial/body-nested-models.md b/docs/zh/docs/tutorial/body-nested-models.md index 98e5168aa5..ce10b74a98 100644 --- a/docs/zh/docs/tutorial/body-nested-models.md +++ b/docs/zh/docs/tutorial/body-nested-models.md @@ -137,7 +137,7 @@ Pydantic 模型的每个属性都具有类型。 /// note | 注意 -请注意 `images` 键现在具有一组 image 对象是如何发生的。 +请注意 `images` 键现在具有一个 image 对象列表是如何发生的。 /// @@ -149,7 +149,7 @@ Pydantic 模型的每个属性都具有类型。 /// note | 注意 -请注意 `Offer` 拥有一组 `Item` 而反过来 `Item` 又有一个可选的 `Image` 列表是如何发生的。 +请注意 `Offer` 拥有一个 `Item` 列表,而反过来 `Item` 又有一个可选的 `Image` 列表是如何发生的。 /// diff --git a/docs/zh/docs/tutorial/body.md b/docs/zh/docs/tutorial/body.md index ee4124e945..b32a5ac60d 100644 --- a/docs/zh/docs/tutorial/body.md +++ b/docs/zh/docs/tutorial/body.md @@ -20,21 +20,22 @@ ## 导入 Pydantic 的 `BaseModel` { #import-pydantics-basemodel } -从 `pydantic` 中导入 `BaseModel`: +首先,你需要从 `pydantic` 中导入 `BaseModel`: {* ../../docs_src/body/tutorial001_py310.py hl[2] *} ## 创建数据模型 { #create-your-data-model } -把数据模型声明为继承 `BaseModel` 的类。 +然后,把数据模型声明为继承 `BaseModel` 的类。 使用 Python 标准类型声明所有属性: {* ../../docs_src/body/tutorial001_py310.py hl[5:9] *} + 与声明查询参数一样,包含默认值的模型属性是可选的,否则就是必选的。把默认值设为 `None` 可使其变为可选。 -例如,上述模型声明如下 JSON "object"(即 Python `dict`): +例如,上述模型声明如下 JSON "`object`"(即 Python `dict`): ```JSON { @@ -45,7 +46,7 @@ } ``` -...由于 `description` 和 `tax` 是可选的(默认值为 `None`),下面的 JSON "object" 也有效: +...由于 `description` 和 `tax` 是可选的(默认值为 `None`),下面的 JSON "`object`" 也有效: ```JSON { @@ -123,7 +124,7 @@ ## 使用模型 { #use-the-model } -在*路径操作*函数内部直接访问模型对象的所有属性: +在函数内部直接访问模型对象的所有属性: {* ../../docs_src/body/tutorial002_py310.py *} @@ -135,6 +136,7 @@ {* ../../docs_src/body/tutorial003_py310.py hl[15:16] *} + ## 请求体 + 路径 + 查询参数 { #request-body-path-query-parameters } 也可以同时声明**请求体**、**路径**和**查询**参数。 diff --git a/docs/zh/docs/tutorial/debugging.md b/docs/zh/docs/tutorial/debugging.md index 4f4503eef3..0b1ada2de0 100644 --- a/docs/zh/docs/tutorial/debugging.md +++ b/docs/zh/docs/tutorial/debugging.md @@ -62,7 +62,7 @@ from myapp import app # 其他一些代码 ``` -在这种情况下,`myapp.py` 内部的自动变量不会有值为 `"__main__"` 的变量 `__name__`。 +在这种情况下,`myapp.py` 内部自动创建的变量 `__name__` 不会有值 `"__main__"`。 所以,这一行: @@ -89,7 +89,7 @@ from myapp import app * 进入到「调试」面板。 * 「添加配置...」。 * 选中「Python」 -* 运行「Python:当前文件(集成终端)」选项的调试器。 +* 使用选项 "`Python: Current File (Integrated Terminal)`" 运行调试器。 然后它会使用你的 **FastAPI** 代码开启服务器,停在断点处,等等。 @@ -99,7 +99,7 @@ from myapp import app --- -如果使用 Pycharm,你可以: +如果使用 PyCharm,你可以: * 打开「运行」菜单。 * 选中「调试...」。 diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md index 5beda57099..85510bbf40 100644 --- a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md @@ -267,7 +267,8 @@ with open("./somefile.txt") as f: 在 Python 中,你可以通过[创建一个带有 `__enter__()` 和 `__exit__()` 方法的类](https://docs.python.org/3/reference/datamodel.html#context-managers)来创建上下文管理器。 -你也可以在 **FastAPI** 的带有 `yield` 的依赖中,使用依赖函数内部的 `with` 或 `async with` 语句来使用它们: +你也可以在 **FastAPI** 的带有 `yield` 的依赖中通过在依赖函数内部使用 +`with` 或 `async with` 语句来使用它们: {* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *} diff --git a/docs/zh/docs/tutorial/extra-data-types.md b/docs/zh/docs/tutorial/extra-data-types.md index 76748a7a38..4415582859 100644 --- a/docs/zh/docs/tutorial/extra-data-types.md +++ b/docs/zh/docs/tutorial/extra-data-types.md @@ -1,15 +1,15 @@ # 额外数据类型 { #extra-data-types } -到目前为止,您一直在使用常见的数据类型,如: +到目前为止,你一直在使用常见的数据类型,如: * `int` * `float` * `str` * `bool` -但是您也可以使用更复杂的数据类型。 +但是你也可以使用更复杂的数据类型。 -您仍然会拥有现在已经看到的相同的特性: +你仍然会拥有现在已经看到的相同的特性: * 很棒的编辑器支持。 * 传入请求的数据转换。 @@ -49,7 +49,7 @@ * `Decimal`: * 标准的 Python `Decimal`。 * 在请求和响应中被当做 `float` 一样处理。 -* 您可以在这里检查所有有效的 Pydantic 数据类型: [Pydantic data types](https://docs.pydantic.dev/latest/usage/types/types/)。 +* 你可以在这里检查所有有效的 Pydantic 数据类型: [Pydantic data types](https://docs.pydantic.dev/latest/usage/types/types/)。 ## 例子 { #example } diff --git a/docs/zh/docs/tutorial/extra-models.md b/docs/zh/docs/tutorial/extra-models.md index 0ad35cc4fc..60f66c5f19 100644 --- a/docs/zh/docs/tutorial/extra-models.md +++ b/docs/zh/docs/tutorial/extra-models.md @@ -1,5 +1,6 @@ # 更多模型 { #extra-models } + 书接上文,多个关联模型这种情况很常见。 特别是用户模型,因为: diff --git a/docs/zh/docs/tutorial/first-steps.md b/docs/zh/docs/tutorial/first-steps.md index 3eee0d44fd..cadcac3e26 100644 --- a/docs/zh/docs/tutorial/first-steps.md +++ b/docs/zh/docs/tutorial/first-steps.md @@ -1,5 +1,6 @@ # 第一步 { #first-steps } + 最简单的 FastAPI 文件可能像下面这样: {* ../../docs_src/first_steps/tutorial001_py310.py *} diff --git a/docs/zh/docs/tutorial/handling-errors.md b/docs/zh/docs/tutorial/handling-errors.md index f3a23fab0a..b77ca7a6c1 100644 --- a/docs/zh/docs/tutorial/handling-errors.md +++ b/docs/zh/docs/tutorial/handling-errors.md @@ -6,16 +6,16 @@ 你可能需要告诉客户端: -- 客户端没有执行该操作的权限 -- 客户端没有访问该资源的权限 -- 客户端要访问的项目不存在 -- 等等 +* 客户端没有执行该操作的权限 +* 客户端没有访问该资源的权限 +* 客户端要访问的项目不存在 +* 等等 -遇到这些情况时,通常要返回 **4XX**(400 至 499)**HTTP 状态码**。 +遇到这些情况时,通常要返回 **400** 范围内(400 至 499)的 **HTTP 状态码**。 -这与表示请求成功的 **2XX**(200 至 299)HTTP 状态码类似。那些“200”状态码表示某种程度上的“成功”。 +这与 200 HTTP 状态码(200 至 299)类似。那些“200”状态码表示请求在某种程度上“成功”。 -而 **4XX** 状态码表示客户端发生了错误。 +而 400 范围内的状态码表示客户端发生了错误。 大家都知道**「404 Not Found」**错误,还有调侃这个错误的笑话吧? @@ -237,8 +237,8 @@ from starlette.exceptions import HTTPException as StarletteHTTPException ### 复用 **FastAPI** 的异常处理器 { #reuse-fastapis-exception-handlers } -如果你想在自定义处理后仍复用 **FastAPI** 的默认异常处理器,可以从 `fastapi.exception_handlers` 导入并复用这些默认处理器: +如果你想在使用该异常的同时使用 **FastAPI** 的相同默认异常处理器,可以从 `fastapi.exception_handlers` 导入并复用这些默认处理器: {* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *} -虽然本例只是用非常夸张的信息打印了错误,但足以说明:你可以先处理异常,然后再复用默认的异常处理器。 +虽然本例只是用非常夸张的信息打印了错误,但足以说明:你可以使用该异常,然后直接复用默认的异常处理器。 diff --git a/docs/zh/docs/tutorial/index.md b/docs/zh/docs/tutorial/index.md index 8d6cbc7a6d..fde264d2cf 100644 --- a/docs/zh/docs/tutorial/index.md +++ b/docs/zh/docs/tutorial/index.md @@ -1,10 +1,10 @@ # 教程 - 用户指南 { #tutorial-user-guide } -本教程将一步步向您展示如何使用 **FastAPI** 的绝大部分特性。 +本教程将一步步向你展示如何使用 **FastAPI** 的绝大部分特性。 -各个章节的内容循序渐进,但是又围绕着单独的主题,所以您可以直接跳转到某个章节以解决您的特定 API 需求。 +各个章节的内容循序渐进,但是又围绕着单独的主题,所以你可以直接跳转到某个章节以解决你的特定 API 需求。 -本教程同样可以作为将来的参考手册,所以您可以随时回到本教程并查阅您需要的内容。 +本教程同样可以作为将来的参考手册,所以你可以随时回到本教程并查阅你需要的内容。 ## 运行代码 { #run-the-code } @@ -52,7 +52,7 @@ $ fastapi dev -**强烈建议**您在本地编写或复制代码,对其进行编辑并运行。 +**强烈建议**你在本地编写或复制代码,对其进行编辑并运行。 在编辑器中使用 FastAPI 会真正地展现出它的优势:只需要编写很少的代码,所有的类型检查,代码补全等等。 @@ -60,9 +60,9 @@ $ fastapi dev ## 安装 FastAPI { #install-fastapi } -第一个步骤是安装 FastAPI. +第一个步骤是安装 FastAPI。 -请确保您创建并激活一个[虚拟环境](../virtual-environments.md),然后**安装 FastAPI**: +请确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后**安装 FastAPI**:
@@ -76,11 +76,11 @@ $ pip install "fastapi[standard]" /// note | 注意 -当您使用 `pip install "fastapi[standard]"` 安装时,它会附带一些默认的可选标准依赖项,其中包括 `fastapi-cloud-cli`,它可以让您部署到 [FastAPI Cloud](https://fastapicloud.com)。 +当你使用 `pip install "fastapi[standard]"` 安装时,它会附带一些默认的可选标准依赖项,其中包括 `fastapi-cloud-cli`,它可以让你部署到 [FastAPI Cloud](https://fastapicloud.com)。 -如果您不想安装这些可选依赖,可以选择安装 `pip install fastapi`。 +如果你不想安装这些可选依赖,可以选择安装 `pip install fastapi`。 -如果您想安装标准依赖但不包含 `fastapi-cloud-cli`,可以使用 `pip install "fastapi[standard-no-fastapi-cloud-cli]"` 安装。 +如果你想安装标准依赖但不包含 `fastapi-cloud-cli`,可以使用 `pip install "fastapi[standard-no-fastapi-cloud-cli]"` 安装。 /// @@ -92,10 +92,10 @@ FastAPI 提供了一个[VS Code 官方扩展](https://marketplace.visualstudio.c ## 进阶用户指南 { #advanced-user-guide } -在本**教程-用户指南**之后,您可以阅读**进阶用户指南**。 +在本**教程-用户指南**之后,你可以阅读**进阶用户指南**。 **进阶用户指南**以本教程为基础,使用相同的概念,并教授一些额外的特性。 -但是您应该先阅读**教程-用户指南**(即您现在正在阅读的内容)。 +但是你应该先阅读**教程-用户指南**(即你现在正在阅读的内容)。 -教程经过精心设计,使您可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据您的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。 +教程经过精心设计,使你可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据你的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。 diff --git a/docs/zh/docs/tutorial/metadata.md b/docs/zh/docs/tutorial/metadata.md index ba480637b3..6518d096ca 100644 --- a/docs/zh/docs/tutorial/metadata.md +++ b/docs/zh/docs/tutorial/metadata.md @@ -1,6 +1,6 @@ # 元数据和文档 URL { #metadata-and-docs-urls } -你可以在 FastAPI 应用程序中自定义多个元数据配置。 +你可以在 **FastAPI** 应用程序中自定义多个元数据配置。 ## API 元数据 { #metadata-for-api } @@ -11,7 +11,7 @@ | `title` | `str` | API 的标题。 | | `summary` | `str` | API 的简短摘要。 自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。 | | `description` | `str` | API 的简短描述。可以使用 Markdown。 | -| `version` | `string` | API 的版本。这是您自己的应用程序的版本,而不是 OpenAPI 的版本。例如 `2.5.0`。 | +| `version` | `str` | API 的版本。这是你自己的应用程序的版本,而不是 OpenAPI 的版本。例如 `2.5.0`。 | | `terms_of_service` | `str` | API 服务条款的 URL。如果提供,则必须是 URL。 | | `contact` | `dict` | 公开的 API 的联系信息。它可以包含多个字段。
contact 字段
参数类型描述
namestr联系人/组织的识别名称。
urlstr指向联系信息的 URL。必须采用 URL 格式。
emailstr联系人/组织的电子邮件地址。必须采用电子邮件地址的格式。
| | `license_info` | `dict` | 公开的 API 的许可证信息。它可以包含多个字段。
license_info 字段
参数类型描述
namestr必须(如果设置了 license_info)。用于 API 的许可证名称。
identifierstrAPI 的 [SPDX](https://spdx.org/licenses/) 许可证表达式。字段 identifier 与字段 url 互斥。自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。
urlstr用于 API 的许可证的 URL。必须采用 URL 格式。
| @@ -46,11 +46,11 @@ 每个字典可以包含: -- `name`(必填):一个 `str`,与在你的*路径操作*和 `APIRouter` 的 `tags` 参数中使用的标签名相同。 -- `description`:一个 `str`,该标签的简短描述。可以使用 Markdown,并会显示在文档 UI 中。 -- `externalDocs`:一个 `dict`,描述外部文档,包含: - - `description`:一个 `str`,该外部文档的简短描述。 - - `url`(必填):一个 `str`,该外部文档的 URL。 +* `name`(**必填**):一个 `str`,与在你的*路径操作*和 `APIRouter` 的 `tags` 参数中使用的标签名相同。 +* `description`:一个 `str`,该标签的简短描述。可以使用 Markdown,并会显示在文档 UI 中。 +* `externalDocs`:一个 `dict`,描述外部文档,包含: + * `description`:一个 `str`,该外部文档的简短描述。 + * `url`(**必填**):一个 `str`,该外部文档的 URL。 ### 创建标签元数据 { #create-metadata-for-tags } @@ -108,12 +108,12 @@ 你可以配置两个文档用户界面,包括: -- **Swagger UI**:服务于 `/docs`。 - - 可以使用参数 `docs_url` 设置它的 URL。 - - 可以通过设置 `docs_url=None` 禁用它。 -- **ReDoc**:服务于 `/redoc`。 - - 可以使用参数 `redoc_url` 设置它的 URL。 - - 可以通过设置 `redoc_url=None` 禁用它。 +* **Swagger UI**:服务于 `/docs`。 + * 可以使用参数 `docs_url` 设置它的 URL。 + * 可以通过设置 `docs_url=None` 禁用它。 +* **ReDoc**:服务于 `/redoc`。 + * 可以使用参数 `redoc_url` 设置它的 URL。 + * 可以通过设置 `redoc_url=None` 禁用它。 例如,设置 Swagger UI 服务于 `/documentation` 并禁用 ReDoc: diff --git a/docs/zh/docs/tutorial/path-operation-configuration.md b/docs/zh/docs/tutorial/path-operation-configuration.md index b813e38f80..f1aae0bc27 100644 --- a/docs/zh/docs/tutorial/path-operation-configuration.md +++ b/docs/zh/docs/tutorial/path-operation-configuration.md @@ -1,5 +1,6 @@ # 路径操作配置 { #path-operation-configuration } + *路径操作装饰器*支持多种配置参数。 /// warning | 警告 diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md index 05cefc6e25..0164c27e62 100644 --- a/docs/zh/docs/tutorial/query-params-str-validations.md +++ b/docs/zh/docs/tutorial/query-params-str-validations.md @@ -1,5 +1,6 @@ # 查询参数和字符串校验 { #query-parameters-and-string-validations } + **FastAPI** 允许你为参数声明额外的信息和校验。 让我们以下面的应用为例: diff --git a/docs/zh/docs/tutorial/query-params.md b/docs/zh/docs/tutorial/query-params.md index c9cb2d26e1..971dbb0ede 100644 --- a/docs/zh/docs/tutorial/query-params.md +++ b/docs/zh/docs/tutorial/query-params.md @@ -1,5 +1,6 @@ # 查询参数 { #query-parameters } + 声明的参数不是路径参数时,路径操作函数会把该参数自动解释为“查询”参数。 {* ../../docs_src/query_params/tutorial001_py310.py hl[9] *} diff --git a/docs/zh/docs/tutorial/request-files.md b/docs/zh/docs/tutorial/request-files.md index 102d422155..38c089ff3f 100644 --- a/docs/zh/docs/tutorial/request-files.md +++ b/docs/zh/docs/tutorial/request-files.md @@ -147,7 +147,7 @@ HTML 表单(`
`)向服务器发送数据的方式通常会对数 ## 多文件上传 { #multiple-file-uploads } -FastAPI 支持同时上传多个文件。 +可以同时上传多个文件。 它们会被关联到同一个通过「表单数据」发送的「表单字段」。 diff --git a/docs/zh/docs/tutorial/request-forms.md b/docs/zh/docs/tutorial/request-forms.md index 3d305779f8..0e7f19c70d 100644 --- a/docs/zh/docs/tutorial/request-forms.md +++ b/docs/zh/docs/tutorial/request-forms.md @@ -2,7 +2,7 @@ 当你需要接收表单字段而不是 JSON 时,可以使用 `Form`。 -/// note +/// note | 注意 要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。 @@ -32,13 +32,13 @@ $ pip install python-multipart 使用 `Form` 可以像使用 `Body`(以及 `Query`、`Path`、`Cookie`)一样声明相同的配置,包括校验、示例、别名(例如将 `username` 写成 `user-name`)等。 -/// note +/// note | 注意 `Form` 是直接继承自 `Body` 的类。 /// -/// tip +/// tip | 提示 要声明表单请求体,必须显式使用 `Form`,否则这些参数会被当作查询参数或请求体(JSON)参数。 @@ -60,9 +60,9 @@ HTML 表单(`
`)向服务器发送数据时通常会对数据使 /// -/// warning +/// warning | 警告 -你可以在一个路径操作中声明多个 `Form` 参数,但不能同时再声明要接收为 JSON 的 `Body` 字段,因为此时请求体会使用 `application/x-www-form-urlencoded` 而不是 `application/json` 进行编码。 +你可以在一个*路径操作*中声明多个 `Form` 参数,但不能同时再声明要接收为 JSON 的 `Body` 字段,因为此时请求体会使用 `application/x-www-form-urlencoded` 而不是 `application/json` 进行编码。 这不是 **FastAPI** 的限制,而是 HTTP 协议的一部分。 diff --git a/docs/zh/docs/tutorial/response-status-code.md b/docs/zh/docs/tutorial/response-status-code.md index 411ece71c1..c06e67e6f2 100644 --- a/docs/zh/docs/tutorial/response-status-code.md +++ b/docs/zh/docs/tutorial/response-status-code.md @@ -6,7 +6,7 @@ * `@app.post()` * `@app.put()` * `@app.delete()` -* 等... +* 等。 {* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *} @@ -27,13 +27,13 @@ 它可以: * 在响应中返回状态码 -* 在 OpenAPI 概图(及用户界面)中存档: +* 在 OpenAPI schema(以及用户界面)中将其记录为该状态码: /// note | 注意 -某些响应状态码表示响应没有响应体(参阅下一章)。 +某些响应状态码表示响应没有响应体(参阅下一节)。 FastAPI 可以进行识别,并生成表明无响应体的 OpenAPI 文档。 @@ -43,7 +43,7 @@ FastAPI 可以进行识别,并生成表明无响应体的 OpenAPI 文档。 /// note | 注意 -如果已经了解 HTTP 状态码,请跳到下一章。 +如果已经了解 HTTP 状态码,请跳到下一节。 /// diff --git a/docs/zh/docs/tutorial/schema-extra-example.md b/docs/zh/docs/tutorial/schema-extra-example.md index 2ea590c868..b18e696410 100644 --- a/docs/zh/docs/tutorial/schema-extra-example.md +++ b/docs/zh/docs/tutorial/schema-extra-example.md @@ -10,7 +10,7 @@ {* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *} -这些额外信息会原样添加到该模型输出的 JSON Schema 中,并会在 API 文档中使用。 +这些额外信息会原样添加到该模型输出的 **JSON Schema** 中,并会在 API 文档中使用。 你可以使用属性 `model_config`,它接收一个 `dict`,详见 [Pydantic 文档:配置](https://docs.pydantic.dev/latest/api/config/)。 @@ -26,7 +26,7 @@ /// note | 注意 -OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持,它是 JSON Schema 标准的一部分。 +OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持,它是 **JSON Schema** 标准的一部分。 在此之前,只支持使用单个示例的关键字 `example`。OpenAPI 3.1.0 仍然支持它,但它已被弃用,并不属于 JSON Schema 标准。因此,建议你把 `example` 迁移到 `examples`。🤓 @@ -52,7 +52,7 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持 - `Form()` - `File()` -你也可以声明一组 `examples`,这些带有附加信息的示例将被添加到它们在 OpenAPI 中的 JSON Schema 里。 +你也可以声明一组 `examples`,这些带有附加信息的示例将被添加到它们在 **OpenAPI** 中的 **JSON Schema** 里。 ### 带有 `examples` 的 `Body` { #body-with-examples } @@ -72,21 +72,21 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持 {* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *} -这样做时,这些示例会成为该请求体数据内部 JSON Schema 的一部分。 +这样做时,这些示例会成为该请求体数据内部 **JSON Schema** 的一部分。 -不过,在撰写本文时,用于展示文档 UI 的 Swagger UI 并不支持显示 JSON Schema 中数据的多个示例。但请继续阅读,下面有一种变通方法。 +不过,在撰写本文时,用于展示文档 UI 的 Swagger UI 并不支持显示 **JSON Schema** 中数据的多个示例。但请继续阅读,下面有一种变通方法。 ### OpenAPI 特定的 `examples` { #openapi-specific-examples } -在 JSON Schema 支持 `examples` 之前,OpenAPI 就已支持一个同名但不同的字段 `examples`。 +在 **JSON Schema** 支持 `examples` 之前,OpenAPI 就已支持一个同名但不同的字段 `examples`。 -这个面向 OpenAPI 的 `examples` 位于 OpenAPI 规范的另一处。它放在每个路径操作的详细信息中,而不是每个 JSON Schema 里。 +这个 **OpenAPI 特定的** `examples` 位于 OpenAPI 规范的另一处。它放在**每个*路径操作*的详细信息**中,而不是每个 JSON Schema 里。 -而 Swagger UI 早就支持这个特定的 `examples` 字段。因此,你可以用它在文档 UI 中展示不同的示例。 +而 Swagger UI 早就支持这个特定的 `examples` 字段。因此,你可以用它在文档 UI 中**展示**不同的**示例**。 -这个 OpenAPI 特定字段 `examples` 的结构是一个包含多个示例的 `dict`(而不是一个 `list`),每个示例都包含会被添加到 OpenAPI 的额外信息。 +这个 OpenAPI 特定字段 `examples` 的结构是一个包含**多个示例**的 `dict`(而不是一个 `list`),每个示例都包含会被添加到 **OpenAPI** 的额外信息。 -这不放在 OpenAPI 内部包含的各个 JSON Schema 里,而是直接放在路径操作上。 +这不放在 OpenAPI 内部包含的各个 JSON Schema 里,而是直接放在*路径操作*上。 ### 使用 `openapi_examples` 参数 { #using-the-openapi-examples-parameter } @@ -123,23 +123,23 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持 /// tip | 提示 -如果你已经在使用 FastAPI 版本 0.99.0 或更高版本,你大概率可以跳过这些细节。 +如果你已经在使用 **FastAPI** 版本 **0.99.0 或更高版本**,你大概率可以**跳过**这些细节。 它们对更早版本(OpenAPI 3.1.0 尚不可用之前)更相关。 -你可以把这当作一堂简短的 OpenAPI 和 JSON Schema 历史课。🤓 +你可以把这当作一堂简短的 OpenAPI 和 JSON Schema **历史课**。🤓 /// /// warning | 警告 -以下是关于 JSON Schema 和 OpenAPI 标准的非常技术性的细节。 +以下是关于 **JSON Schema** 和 **OpenAPI** 标准的非常技术性的细节。 如果上面的思路对你已经足够可用,你可能不需要这些细节,可以直接跳过。 /// -在 OpenAPI 3.1.0 之前,OpenAPI 使用的是一个更旧且经过修改的 JSON Schema 版本。 +在 OpenAPI 3.1.0 之前,OpenAPI 使用的是一个更旧且经过修改的 **JSON Schema** 版本。 当时 JSON Schema 没有 `examples`,所以 OpenAPI 在它修改过的版本中添加了自己的 `example` 字段。 @@ -169,7 +169,7 @@ OpenAPI 还在规范的其他部分添加了 `example` 和 `examples` 字段: 现在,这个新的 `examples` 字段优先于旧的单个(且自定义的)`example` 字段,后者已被弃用。 -JSON Schema 中这个新的 `examples` 字段只是一个由示例组成的 `list`,而不是像上面提到的 OpenAPI 其他位置那样带有额外元数据的 `dict`。 +在 JSON Schema 中,这个新的 `examples` 字段**只是一个由示例组成的 `list`**,而不是像上面提到的 OpenAPI 其他位置那样带有额外元数据的 `dict`。 /// note | 注意 @@ -181,22 +181,22 @@ JSON Schema 中这个新的 `examples` 字段只是一个由示例组成的 `lis ### Pydantic 与 FastAPI 的 `examples` { #pydantic-and-fastapi-examples } -当你在 Pydantic 模型中添加 `examples`,通过 `schema_extra` 或 `Field(examples=["something"])`,这些示例会被添加到该 Pydantic 模型的 JSON Schema 中。 +当你在 Pydantic 模型中添加 `examples`,通过 `schema_extra` 或 `Field(examples=["something"])`,这些示例会被添加到该 Pydantic 模型的 **JSON Schema** 中。 -这个 Pydantic 模型的 JSON Schema 会被包含到你的 API 的 OpenAPI 中,然后在文档 UI 中使用。 +这个 Pydantic 模型的 **JSON Schema** 会被包含到你的 API 的 **OpenAPI** 中,然后在文档 UI 中使用。 -在 FastAPI 0.99.0 之前的版本(0.99.0 及以上使用更新的 OpenAPI 3.1.0),当你在其他工具(`Query()`、`Body()` 等)中使用 `example` 或 `examples` 时,这些示例不会被添加到描述该数据的 JSON Schema 中(甚至不会添加到 OpenAPI 自己的 JSON Schema 版本中),而是会直接添加到 OpenAPI 的路径操作声明中(在 OpenAPI 使用 JSON Schema 的部分之外)。 +在 FastAPI 0.99.0 之前的版本(0.99.0 及以上使用更新的 OpenAPI 3.1.0),当你在其他工具(`Query()`、`Body()` 等)中使用 `example` 或 `examples` 时,这些示例不会被添加到描述该数据的 JSON Schema 中(甚至不会添加到 OpenAPI 自己的 JSON Schema 版本中),而是会直接添加到 OpenAPI 的*路径操作*声明中(在 OpenAPI 使用 JSON Schema 的部分之外)。 但现在 FastAPI 0.99.0 及以上使用 OpenAPI 3.1.0(其使用 JSON Schema 2020-12)以及 Swagger UI 5.0.0 及以上后,一切更加一致,示例会包含在 JSON Schema 中。 ### Swagger UI 与 OpenAPI 特定的 `examples` { #swagger-ui-and-openapi-specific-examples } -此前,由于 Swagger UI 不支持多个 JSON Schema 示例(截至 2023-08-26),用户无法在文档中展示多个示例。 +由于截至 2023-08-26,Swagger UI 不支持多个 JSON Schema 示例,用户无法在文档中展示多个示例。 -为了解决这个问题,FastAPI `0.103.0` 通过新增参数 `openapi_examples`,为声明同样的旧式 OpenAPI 特定 `examples` 字段提供了支持。🤓 +为了解决这个问题,FastAPI `0.103.0` **增加了支持**,可以通过新参数 `openapi_examples` 声明同样的旧式 **OpenAPI 特定的** `examples` 字段。🤓 ### 总结 { #summary } -我曾经说我不太喜欢历史……结果现在在这儿上“技术史”课。😅 +我曾经说我不太喜欢历史... 结果现在在这儿上“技术史”课。😅 -简而言之,升级到 FastAPI 0.99.0 或更高版本,一切会更简单、一致、直观,你也不必了解这些历史细节。😎 +简而言之,**升级到 FastAPI 0.99.0 或更高版本**,一切会更**简单、一致、直观**,你也不必了解这些历史细节。😎 diff --git a/docs/zh/docs/tutorial/security/first-steps.md b/docs/zh/docs/tutorial/security/first-steps.md index e274d513a4..ca3ef83527 100644 --- a/docs/zh/docs/tutorial/security/first-steps.md +++ b/docs/zh/docs/tutorial/security/first-steps.md @@ -1,5 +1,6 @@ # 安全 - 第一步 { #security-first-steps } + 假设你的**后端** API 位于某个域名下。 而**前端**在另一个域名,或同一域名的不同路径(或在移动应用中)。 diff --git a/docs/zh/docs/tutorial/security/get-current-user.md b/docs/zh/docs/tutorial/security/get-current-user.md index e8a1de9d5a..dc8c70014f 100644 --- a/docs/zh/docs/tutorial/security/get-current-user.md +++ b/docs/zh/docs/tutorial/security/get-current-user.md @@ -8,14 +8,13 @@ 接下来,我们学习如何返回当前用户。 - ## 创建用户模型 { #create-a-user-model } 首先,创建 Pydantic 用户模型。 与使用 Pydantic 声明请求体相同,并且可在任何位置使用: -{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *} +{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *} ## 创建 `get_current_user` 依赖项 { #create-a-get-current-user-dependency } @@ -55,7 +54,7 @@ /// tip | 提示 -依赖系统的这种设计方式可以支持不同的依赖项返回同一个 `User` 模型。 +依赖系统的这种设计方式可以支持不同的依赖项(不同的“可依赖项”)返回同一个 `User` 模型。 而不是局限于只能有一个返回该类型数据的依赖项。 @@ -77,7 +76,6 @@ 尽管使用应用所需的任何模型、类、数据库。**FastAPI** 通过依赖注入系统都能帮您搞定。 - ## 代码大小 { #code-size } 这个示例看起来有些冗长。毕竟这个文件同时包含了安全、数据模型的工具函数,以及路径操作等代码。 diff --git a/docs/zh/docs/tutorial/security/oauth2-jwt.md b/docs/zh/docs/tutorial/security/oauth2-jwt.md index e0cbdf685e..418b3b97d5 100644 --- a/docs/zh/docs/tutorial/security/oauth2-jwt.md +++ b/docs/zh/docs/tutorial/security/oauth2-jwt.md @@ -120,7 +120,7 @@ pwdlib 也支持 bcrypt 哈希算法,但不包含遗留算法——如果需 当使用一个在数据库中不存在的用户名调用 `authenticate_user` 时,我们仍然会针对一个虚拟哈希运行 `verify_password`。 -这可以确保无论用户名是否有效,端点的响应时间大致相同,从而防止可用于枚举已存在用户名的“时间攻击”(timing attacks)。 +这可以确保无论用户名是否有效,端点的响应时间大致相同,从而防止可用于枚举已存在用户名的**时序攻击**。 /// note | 注意 @@ -168,7 +168,7 @@ $ openssl rand -hex 32 {* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *} -## 更新 `/token` 路径操作 { #update-the-token-path-operation } +## 更新 `/token` *路径操作* { #update-the-token-path-operation } 用令牌的过期时间创建一个 `timedelta`。 diff --git a/docs/zh/docs/tutorial/security/simple-oauth2.md b/docs/zh/docs/tutorial/security/simple-oauth2.md index 6ebf77e36f..92cf02dd25 100644 --- a/docs/zh/docs/tutorial/security/simple-oauth2.md +++ b/docs/zh/docs/tutorial/security/simple-oauth2.md @@ -6,7 +6,7 @@ 首先,使用 **FastAPI** 安全工具获取 `username` 和 `password`。 -OAuth2 规范要求使用“密码流”时,客户端或用户必须以表单数据形式发送 `username` 和 `password` 字段。 +OAuth2 规范要求使用“密码流”(也就是我们正在使用的流程)时,客户端或用户必须以表单数据形式发送 `username` 和 `password` 字段。 并且,这两个字段必须命名为 `username` 和 `password`,不能使用 `user-name` 或 `email` 等其它名称。 @@ -80,7 +80,7 @@ OAuth2 中,**作用域**只是声明指定权限的字符串。 但 `OAuth2PasswordRequestForm` 只是可以自行编写的类依赖项,也可以直接声明 `Form` 参数。 -但由于这种用例很常见,FastAPI 为了简便,就直接提供了对它的支持。 +但由于这种用例很常见,**FastAPI** 为了简便,就直接提供了对它的支持。 /// @@ -146,7 +146,7 @@ UserInDB( /// note | 注意 -`user_dict` 的说明,详见[**更多模型**一章](../extra-models.md#about-user-in-dict)。 +关于 `**user_dict` 的更完整说明,详见[**更多模型**文档](../extra-models.md#about-user-in-model-dump)。 /// @@ -208,7 +208,7 @@ UserInDB( 之所以在此提供这个附加响应头,是为了符合规范的要求。 -说不定什么时候,就有工具用得上它,而且,开发者或用户也可能用得上。 +此外,现在或将来,可能会有工具期望并使用它,而且现在或将来这也可能对你或你的用户有用。 这就是遵循标准的好处... diff --git a/docs/zh/docs/tutorial/sql-databases.md b/docs/zh/docs/tutorial/sql-databases.md index 9004983b10..1d6a3cd34a 100644 --- a/docs/zh/docs/tutorial/sql-databases.md +++ b/docs/zh/docs/tutorial/sql-databases.md @@ -8,7 +8,7 @@ /// tip | 提示 -你可以使用任意其他你想要的 SQL 或 NoSQL 数据库库(在某些情况下称为 "ORMs"),FastAPI 不会强迫你使用任何东西。😎 +你可以使用任意其他你想要的 SQL 或 NoSQL 数据库类库(在某些情况下称为 "ORMs"),FastAPI 不会强迫你使用任何东西。😎 /// @@ -57,7 +57,7 @@ $ pip install sqlmodel {* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} -`Hero` 类与 Pydantic 模型非常相似(实际上,从底层来看,它确实就是一个 Pydantic 模型)。 +`Hero` 类与 Pydantic 模型非常相似(实际上,从底层来看,它*确实就是一个 Pydantic 模型*)。 有一些区别: @@ -65,7 +65,7 @@ $ pip install sqlmodel * `Field(primary_key=True)` 会告诉 SQLModel `id` 是 SQL 数据库中的**主键**(你可以在 SQLModel 文档中了解更多关于 SQL 主键的信息)。 - **注意:** 我们为主键字段使用 `int | None`,这样在 Python 代码中我们可以在没有 `id`(`id=None`)的情况下创建对象,并假定数据库在保存时会生成它。SQLModel 会理解数据库会提供 `id`,并在数据库模式中将该列定义为非空的 `INTEGER`。详见 [SQLModel 关于主键的文档](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id)。 + **注意:** 我们为主键字段使用 `int | None`,这样在 Python 代码中我们可以*在没有 `id` 的情况下创建对象*(`id=None`),并假定数据库会*在保存时生成它*。SQLModel 会理解数据库会提供 `id`,并在数据库模式中*将该列定义为非空的 `INTEGER`*。详见 [SQLModel 关于主键的文档](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id)。 * `Field(index=True)` 会告诉 SQLModel 应该为此列创建一个 **SQL 索引**,这样在读取按此列过滤的数据时,程序能在数据库中进行更快的查找。 @@ -292,7 +292,7 @@ $ fastapi dev /// tip | 提示 -现在我们使用 `response_model=HeroPublic` 来代替**返回类型注解** `-> HeroPublic`,因为我们返回的值实际上并不是 `HeroPublic`。 +现在我们使用 `response_model=HeroPublic` 来代替**返回类型注解** `-> HeroPublic`,因为我们返回的值实际上*并不是* `HeroPublic`。 如果我们声明了 `-> HeroPublic`,你的编辑器和代码检查工具会(理所应当地)抱怨你返回了一个 `Hero` 而不是一个 `HeroPublic`。 diff --git a/docs/zh/docs/tutorial/static-files.md b/docs/zh/docs/tutorial/static-files.md index 65262bdb40..b700f46d65 100644 --- a/docs/zh/docs/tutorial/static-files.md +++ b/docs/zh/docs/tutorial/static-files.md @@ -2,6 +2,14 @@ 你可以使用 `StaticFiles` 从目录中自动提供静态文件。 +/// tip | 提示 + +如果你需要托管前端,请改用 `app.frontend()`,可在[前端](frontend.md)中阅读相关内容。 + +`app.frontend()` 底层使用 `StaticFiles`,并为前端提供了几个额外优势,例如处理客户端路由。 + +/// + ## 使用 `StaticFiles` { #use-staticfiles } * 导入 `StaticFiles`。 diff --git a/docs/zh/docs/tutorial/testing.md b/docs/zh/docs/tutorial/testing.md index 50e1d8f2de..79e5044c99 100644 --- a/docs/zh/docs/tutorial/testing.md +++ b/docs/zh/docs/tutorial/testing.md @@ -52,7 +52,7 @@ $ pip install httpx /// tip | 提示 -除了发送请求之外,如果你还想测试时在FastAPI应用中调用 `async` 函数(例如异步数据库函数), 可以在高级教程中看下 [Async Tests](../advanced/async-tests.md) 。 +除了发送请求之外,如果你还想测试时在FastAPI应用中调用 `async` 函数(例如异步数据库函数), 可以在高级教程中看下[异步测试](../advanced/async-tests.md)。 /// @@ -60,7 +60,7 @@ $ pip install httpx 在实际应用中,你可能会把你的测试放在另一个文件里。 -您的**FastAPI**应用程序也可能由一些文件/模块组成等等。 +你的**FastAPI**应用程序也可能由一些文件/模块组成等等。 ### **FastAPI** app 文件 { #fastapi-app-file } @@ -80,7 +80,7 @@ $ pip install httpx ### 测试文件 { #testing-file } -然后你会有一个包含测试的文件 `test_main.py` 。app可以像Python包那样存在(一样是目录,但有个 `__init__.py` 文件): +然后你会有一个包含测试的文件 `test_main.py` 。它可以位于同一个 Python 包中(一样是目录,但有个 `__init__.py` 文件): ``` hl_lines="5" . @@ -94,6 +94,7 @@ $ pip install httpx {* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *} + ...然后测试代码和之前一样的。 ## 测试:扩展示例 { #testing-extended-example } @@ -114,20 +115,21 @@ $ pip install httpx 假设现在包含**FastAPI** app的文件 `main.py` 有些其他**路径操作**。 -有个 `GET` 操作会返回错误。 +有个 `GET` 操作可能返回一个错误。 -有个 `POST` 操作会返回一些错误。 +有个 `POST` 操作可能返回多个错误。 -所有*路径操作* 都需要一个`X-Token` 头。 +两个*路径操作* 都需要一个`X-Token` 头。 {* ../../docs_src/app_testing/app_b_an_py310/main.py *} ### 扩展后的测试文件 { #extended-testing-file } -然后您可以使用扩展后的测试更新`test_main.py`: +然后你可以使用扩展后的测试更新`test_main.py`: {* ../../docs_src/app_testing/app_b_an_py310/test_main.py *} + 每当你需要客户端在请求中传递信息,但你不知道如何传递时,你可以通过搜索(谷歌)如何用 `httpx` 做,或者是用 `requests` 做,毕竟HTTPX的设计是基于Requests的设计的。 接着只需在测试中同样操作。 @@ -146,7 +148,7 @@ $ pip install httpx 注意 `TestClient` 接收可以被转化为JSON的数据,而不是Pydantic模型。 -如果你在测试中有一个Pydantic模型,并且你想在测试时发送它的数据给应用,你可以使用在[JSON Compatible Encoder](encoder.md)介绍的`jsonable_encoder` 。 +如果你在测试中有一个Pydantic模型,并且你想在测试时发送它的数据给应用,你可以使用在[JSON 兼容编码器](encoder.md)介绍的`jsonable_encoder` 。 /// @@ -166,7 +168,7 @@ $ pip install pytest
-他会自动检测文件和测试,执行测试,然后向你报告结果。 +它会自动检测文件和测试,执行测试,然后向你报告结果。 执行测试: diff --git a/docs/zh/docs/virtual-environments.md b/docs/zh/docs/virtual-environments.md index d10251dbeb..a31240d9fd 100644 --- a/docs/zh/docs/virtual-environments.md +++ b/docs/zh/docs/virtual-environments.md @@ -861,4 +861,4 @@ I solemnly swear 🐺 如果你读过并理解了所有这些,现在**你对虚拟环境的了解比很多开发者都要多**。🤓 -在未来当你调看看起来复杂的东西时,了解这些细节很可能会有用,你会知道**它是如何在底层工作的**。😎 +在未来当你调试看起来复杂的东西时,了解这些细节很可能会有用,你会知道**它是如何在底层工作的**。😎