mirror of
https://github.com/fastapi/fastapi.git
synced 2026-09-12 21:38:39 -04:00
🌐 Update translations for zh (update-outdated) (#16204)
Co-authored-by: pr-submit[bot] <pr-submit[bot]@users.noreply.github.com> Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com> Co-authored-by: pr-push[bot] <pr-push[bot]@users.noreply.github.com>
This commit is contained in:
61 files changed
+375
-1426
No files matched your search
@@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
|
||||
|
||||
要查看响应中究竟可以包含什么,你可以查看 OpenAPI 规范中的以下部分:
|
||||
|
||||
* [OpenAPI Responses 对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object),它包含 `Response Object`。
|
||||
* [OpenAPI Response 对象](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object),你可以把这里的任何内容直接包含到 `responses` 参数中的每个响应里。包括 `description`、`headers`、`content`(在这里声明不同的媒体类型和 JSON Schemas),以及 `links`。
|
||||
* [OpenAPI Responses 对象](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object),它包含 `Response Object`。
|
||||
* [OpenAPI Response 对象](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#response-object),你可以把这里的任何内容直接包含到 `responses` 参数中的每个响应里。包括 `description`、`headers`、`content`(在这里声明不同的媒体类型和 JSON Schemas),以及 `links`。
|
||||
@@ -45,7 +45,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pytest
|
||||
$ uv run pytest
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run --forwarded-allow-ips="*"
|
||||
$ uv run fastapi run --forwarded-allow-ips="*"
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -91,9 +91,9 @@ sequenceDiagram
|
||||
|
||||
这些请求头保留了原始请求中否则会丢失的信息:
|
||||
|
||||
- X-Forwarded-For:原始客户端的 IP 地址
|
||||
- X-Forwarded-Proto:原始协议(`https`)
|
||||
- X-Forwarded-Host:原始主机(`mysuperapp.com`)
|
||||
* **X-Forwarded-For**:原始客户端的 IP 地址
|
||||
* **X-Forwarded-Proto**:原始协议(`https`)
|
||||
* **X-Forwarded-Host**:原始主机(`mysuperapp.com`)
|
||||
|
||||
当 **FastAPI CLI** 配置了 `--forwarded-allow-ips` 后,它会信任并使用这些请求头,例如用于在重定向中生成正确的 URL。
|
||||
|
||||
@@ -149,14 +149,14 @@ IP `0.0.0.0` 通常表示程序监听该机器/服务器上的所有可用 IP。
|
||||
```JSON hl_lines="4-8"
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
// More stuff here
|
||||
// 这里还有更多内容
|
||||
"servers": [
|
||||
{
|
||||
"url": "/api/v1"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
// More stuff here
|
||||
// 这里还有更多内容
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -170,7 +170,7 @@ IP `0.0.0.0` 通常表示程序监听该机器/服务器上的所有可用 IP。
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -200,7 +200,7 @@ ASGI 规范为这种用例定义了 `root_path`。
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -253,7 +253,7 @@ Uvicorn 会期望代理以 `http://127.0.0.1:8000/app` 访问 Uvicorn,而在
|
||||
|
||||
你可以很容易地使用 [Traefik](https://docs.traefik.io/) 在本地运行一个移除路径前缀的实验。
|
||||
|
||||
[下载 Traefik](https://github.com/containous/traefik/releases),它是一个单独的二进制文件,你可以解压压缩包并直接在终端中运行。
|
||||
[下载 Traefik](https://github.com/traefik/traefik/releases),它是一个单独的二进制文件,你可以解压压缩包并直接在终端中运行。
|
||||
|
||||
然后创建一个 `traefik.toml` 文件,内容如下:
|
||||
|
||||
@@ -321,7 +321,7 @@ INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -407,7 +407,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
```JSON hl_lines="5-7"
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
// More stuff here
|
||||
// 这里还有更多内容
|
||||
"servers": [
|
||||
{
|
||||
"url": "/api/v1"
|
||||
@@ -422,7 +422,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
// More stuff here
|
||||
// 这里还有更多内容
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -7,7 +7,7 @@ FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydant
|
||||
|
||||
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
|
||||
|
||||
这仍然得益于 **Pydantic**,因为它对 [`dataclasses` 的内置支持](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel)。
|
||||
这仍然得益于 **Pydantic**,因为它对 [`dataclasses` 的内置支持](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/#usage-of-stdlib-dataclasses-with-basemodel)。
|
||||
|
||||
因此,即便上面的代码没有显式使用 Pydantic,FastAPI 也会使用 Pydantic 将那些标准数据类转换为 Pydantic 风格的 dataclasses。
|
||||
|
||||
@@ -81,7 +81,7 @@ FastAPI 基于 **Pydantic** 构建,我已经向你展示过如何使用 Pydant
|
||||
|
||||
你还可以把 `dataclasses` 与其它 Pydantic 模型组合、从它们继承、把它们包含到你自己的模型中等。
|
||||
|
||||
想了解更多,请查看 [Pydantic 关于 dataclasses 的文档](https://docs.pydantic.dev/latest/concepts/dataclasses/)。
|
||||
想了解更多,请查看 [Pydantic 关于 dataclasses 的文档](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/)。
|
||||
|
||||
## 版本 { #version }
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ async with lifespan(app):
|
||||
|
||||
/// note | 注意
|
||||
|
||||
你可以在 [Starlette 的 Lifespan 文档](https://www.starlette.dev/lifespan/) 中阅读更多关于 `lifespan` 处理器的内容。
|
||||
你可以在 [Starlette 的 Lifespan 文档](https://starlette.dev/lifespan/) 中阅读更多关于 `lifespan` 处理器的内容。
|
||||
|
||||
包括如何处理生命周期状态,以便在代码的其他部分使用。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
对于 **TypeScript 客户端**,[Hey API](https://heyapi.dev/) 是为 TypeScript 生态打造的专用方案,提供优化的使用体验。
|
||||
|
||||
你还可以在 [OpenAPI.Tools](https://openapi.tools/#sdk) 上发现更多 SDK 生成器。
|
||||
你还可以在 [OpenAPI.Tools](https://openapi.tools/categories/sdk-generators) 上发现更多 SDK 生成器。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
|
||||
@@ -87,11 +87,11 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
|
||||
|
||||
## 其它中间件 { #other-middlewares }
|
||||
|
||||
除了上述中间件外,FastAPI 还支持其它 ASGI 中间件。
|
||||
还有许多其它 ASGI 中间件。
|
||||
|
||||
例如:
|
||||
|
||||
* [Uvicorn 的 `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
|
||||
* [Uvicorn 的 `ProxyHeadersMiddleware`](https://github.com/Kludex/uvicorn/blob/main/uvicorn/middleware/proxy_headers.py)
|
||||
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
|
||||
|
||||
其它可用中间件详见 [Starlette 官档 - 中间件](https://www.starlette.dev/middleware/) 及 [ASGI Awesome 列表](https://github.com/florimondmanca/awesome-asgi)。
|
||||
其它可用中间件详见 [Starlette 的中间件文档](https://starlette.dev/middleware/) 及 [ASGI Awesome 列表](https://github.com/florimondmanca/awesome-asgi)。
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
`callback_url` 查询参数使用 Pydantic 的 [Url](https://docs.pydantic.dev/latest/api/networks/) 类型。
|
||||
`callback_url` 查询参数使用 Pydantic 的 [Url](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/) 类型。
|
||||
|
||||
///
|
||||
|
||||
@@ -106,11 +106,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
|
||||
它与普通*路径操作*有 2 个主要区别:
|
||||
|
||||
* 它不需要任何实际代码,因为你的应用永远不会调用这段代码。它只用于记录*外部 API*。因此,函数可以只有 `pass`。
|
||||
* *路径*可以包含 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(见下文),其中可以使用带参数的变量,以及发送到*你的 API*的原始请求的部分内容。
|
||||
* *路径*可以包含 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression)(见下文),其中可以使用带参数的变量,以及发送到*你的 API*的原始请求的部分内容。
|
||||
|
||||
### 回调路径表达式 { #the-callback-path-expression }
|
||||
|
||||
回调*路径*可以有一个 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression),其中可以包含发送到*你的 API*的原始请求的部分内容。
|
||||
回调*路径*可以有一个 [OpenAPI 3 表达式](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression),其中可以包含发送到*你的 API*的原始请求的部分内容。
|
||||
|
||||
在这个例子中,它是这个 `str`:
|
||||
|
||||
|
||||
@@ -48,4 +48,4 @@
|
||||
|
||||
///
|
||||
|
||||
要查看所有可用参数和选项,请查看 [Starlette 文档](https://www.starlette.dev/responses/#set-cookie)。
|
||||
要查看所有可用参数和选项,请查看 [Starlette 文档](https://starlette.dev/responses/#set-cookie)。
|
||||
@@ -1,6 +1,5 @@
|
||||
# 响应头 { #response-headers }
|
||||
|
||||
|
||||
## 使用 `Response` 参数 { #use-a-response-parameter }
|
||||
|
||||
你可以在你的*路径操作函数*中声明一个 `Response` 类型的参数(就像你可以为 cookies 做的那样)。
|
||||
@@ -39,4 +38,4 @@
|
||||
|
||||
请注意,可以通过[使用 `X-` 前缀](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)添加自定义专有头部。
|
||||
|
||||
但是,如果你有自定义头部,并希望浏览器中的客户端能够看到它们,你需要将它们添加到你的 CORS 配置中(在 [CORS(跨源资源共享)](../tutorial/cors.md) 中阅读更多),使用在 [Starlette 的 CORS 文档](https://www.starlette.dev/middleware/#corsmiddleware)中记录的 `expose_headers` 参数。
|
||||
但是,如果你有自定义头部,并希望浏览器中的客户端能够看到它们,你需要将它们添加到你的 CORS 配置中(在 [CORS(跨源资源共享)](../tutorial/cors.md) 中阅读更多),使用在 [Starlette 的 CORS 文档](https://starlette.dev/middleware/#corsmiddleware)中记录的 `expose_headers` 参数。
|
||||
@@ -6,9 +6,13 @@
|
||||
|
||||
因此,通常会将它们提供为由应用程序读取的环境变量。
|
||||
|
||||
**环境变量**(也称为 **env var**)是存在于 Python 代码之外、操作系统中的值,可以由你的应用和其他程序读取。
|
||||
|
||||
你可以在运行命令时为该命令创建环境变量。你将在下面看到特定于平台的命令。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
要理解环境变量,你可以阅读[环境变量](../environment-variables.md)。
|
||||
阅读[环境变量指南](https://tiangolo.com/guides/environment-variables/)以详细了解环境变量的工作方式。
|
||||
|
||||
///
|
||||
|
||||
@@ -20,16 +24,16 @@
|
||||
|
||||
## Pydantic 的 `Settings` { #pydantic-settings }
|
||||
|
||||
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:[Pydantic:Settings 管理](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)。
|
||||
幸运的是,Pydantic 提供了一个很好的工具来处理来自环境变量的这些设置:[Pydantic:Settings 管理](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/)。
|
||||
|
||||
### 安装 `pydantic-settings` { #install-pydantic-settings }
|
||||
|
||||
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md),然后安装 `pydantic-settings` 包:
|
||||
将 `pydantic-settings` 包添加到你的项目:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pydantic-settings
|
||||
$ uv add pydantic-settings
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -40,7 +44,7 @@ $ pip install pydantic-settings
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[all]"
|
||||
$ uv add "fastapi[all]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -76,19 +80,39 @@ $ pip install "fastapi[all]"
|
||||
|
||||
接下来,运行服务器,并把配置作为环境变量传入,例如你可以设置 `ADMIN_EMAIL` 和 `APP_NAME`:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
|
||||
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uv run fastapi run main.py
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ $Env:ADMIN_EMAIL = "deadpool@example.com"
|
||||
$ $Env:APP_NAME = "ChimichangApp"
|
||||
$ uv run fastapi run main.py
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
要为单个命令设置多个环境变量,只需用空格分隔它们,并把它们都放在命令前面。
|
||||
在 Bash 中,要为单个命令设置多个环境变量,只需用空格分隔它们,并把它们都放在命令前面。
|
||||
|
||||
///
|
||||
|
||||
@@ -172,11 +196,11 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
|
||||
|
||||
///
|
||||
|
||||
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 [Pydantic Settings:Dotenv(.env)支持](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support) 中阅读更多信息。
|
||||
Pydantic 支持使用一个外部库来从这类文件中读取。你可以在 [Pydantic Settings:Dotenv(.env)支持](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/#dotenv-env-support) 中阅读更多信息。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
要使其工作,你需要执行 `pip install python-dotenv`。
|
||||
要使其工作,请使用 `uv add python-dotenv` 将 `python-dotenv` 添加到你的项目。
|
||||
|
||||
///
|
||||
|
||||
@@ -197,7 +221,7 @@ APP_NAME="ChimichangApp"
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
`model_config` 属性仅用于 Pydantic 配置。你可以在 [Pydantic:概念:配置](https://docs.pydantic.dev/latest/concepts/config/) 中阅读更多信息。
|
||||
`model_config` 属性仅用于 Pydantic 配置。你可以在 [Pydantic:概念:配置](https://pydantic.dev/docs/validation/latest/concepts/config/) 中阅读更多信息。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 子应用 - 挂载 { #sub-applications-mounts }
|
||||
|
||||
如果需要两个独立的 FastAPI 应用,拥有各自独立的 OpenAPI 与文档,则需设置一个主应用,并**挂载**一个(或多个)子应用。
|
||||
如果需要两个独立的 FastAPI 应用,拥有各自独立的 OpenAPI 与文档 UI,则需设置一个主应用,并**挂载**一个(或多个)子应用。
|
||||
|
||||
## 挂载 **FastAPI** 应用 { #mounting-a-fastapi-application }
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
# 模板 { #templates }
|
||||
|
||||
**FastAPI** 支持多种模板引擎。
|
||||
你可以在 **FastAPI** 中使用任何你想用的模板引擎。
|
||||
|
||||
Flask 等工具使用的 Jinja2 是最用的模板引擎。
|
||||
常见选择是 Jinja2,它也是 Flask 和其他工具使用的模板引擎。
|
||||
|
||||
在 Starlette 的支持下,**FastAPI** 应用可以直接使用工具轻易地配置 Jinja2。
|
||||
有一些工具可以轻松配置它,你可以直接在 **FastAPI** 应用中使用(由 Starlette 提供)。
|
||||
|
||||
## 安装依赖项 { #install-dependencies }
|
||||
|
||||
确保你创建一个[虚拟环境](../virtual-environments.md),激活它,并安装 `jinja2`:
|
||||
将 `jinja2` 添加到你的项目中:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install jinja2
|
||||
$ uv add jinja2
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -22,37 +22,38 @@ $ pip install jinja2
|
||||
|
||||
## 使用 `Jinja2Templates` { #using-jinja2templates }
|
||||
|
||||
* 导入 `Jinja2Templates`
|
||||
* 创建可复用的 `templates` 对象
|
||||
* 在返回模板的*路径操作*中声明 `Request` 参数
|
||||
* 使用 `templates` 渲染并返回 `TemplateResponse`,传递模板的名称、request 对象以及一个包含多个键值对(用于 Jinja2 模板)的 "context" 字典。
|
||||
* 导入 `Jinja2Templates`。
|
||||
* 创建可复用的 `templates` 对象。
|
||||
* 在返回模板的*路径操作*中声明 `Request` 参数。
|
||||
* 使用你创建的 `templates` 渲染并返回 `TemplateResponse`,传递模板的名称、请求对象以及一个包含多个键值对(用于 Jinja2 模板)的 "context" 字典。
|
||||
|
||||
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
|
||||
|
||||
/// note | 注意
|
||||
|
||||
在 FastAPI 0.108.0,Starlette 0.29.0 之前,`name` 是第一个参数。
|
||||
并且,在此之前,`request` 对象是作为 context 的一部分以键值对的形式传递的。
|
||||
|
||||
并且,在此之前的旧版本中,`request` 对象是作为 Jinja2 的 context 中的键值对的一部分传递的。
|
||||
|
||||
///
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
通过声明 `response_class=HTMLResponse`,API 文档就能识别响应的对象是 HTML。
|
||||
通过声明 `response_class=HTMLResponse`,文档 UI 就能知道响应会是 HTML。
|
||||
|
||||
///
|
||||
|
||||
/// note | 技术细节
|
||||
|
||||
您还可以使用 `from starlette.templating import Jinja2Templates`。
|
||||
你还可以使用 `from starlette.templating import Jinja2Templates`。
|
||||
|
||||
**FastAPI** 的 `fastapi.templating` 只是为开发者提供的快捷方式。实际上,绝大多数可用响应都直接继承自 Starlette。`Request` 与 `StaticFiles` 也一样。
|
||||
**FastAPI** 将同一个 `starlette.templating` 作为 `fastapi.templating` 提供,只是为了方便开发者使用。但绝大多数可用响应都直接来自 Starlette。`Request` 和 `StaticFiles` 也一样。
|
||||
|
||||
///
|
||||
|
||||
## 编写模板 { #writing-templates }
|
||||
|
||||
编写模板 `templates/item.html`,代码如下:
|
||||
然后你可以在 `templates/item.html` 编写一个模板,例如:
|
||||
|
||||
```jinja hl_lines="7"
|
||||
{!../../docs_src/templates/templates/item.html!}
|
||||
@@ -60,7 +61,7 @@ $ pip install jinja2
|
||||
|
||||
### 模板上下文值 { #template-context-values }
|
||||
|
||||
在包含如下语句的html中:
|
||||
在包含如下语句的 HTML 中:
|
||||
|
||||
{% raw %}
|
||||
|
||||
@@ -70,13 +71,13 @@ Item ID: {{ id }}
|
||||
|
||||
{% endraw %}
|
||||
|
||||
...这将显示你从 "context" 字典传递的 `id`:
|
||||
...它会显示你传入的 "context" `dict` 中取得的 `id`:
|
||||
|
||||
```Python
|
||||
{"id": id}
|
||||
```
|
||||
|
||||
例如。当 ID 为 `42` 时, 会渲染成:
|
||||
例如,当 ID 为 `42` 时,会渲染成:
|
||||
|
||||
```html
|
||||
Item ID: 42
|
||||
@@ -84,9 +85,9 @@ Item ID: 42
|
||||
|
||||
### 模板 `url_for` 参数 { #template-url-for-arguments }
|
||||
|
||||
你还可以在模板内使用 `url_for()`,其参数与*路径操作函数*的参数相同。
|
||||
你还可以在模板内使用 `url_for()`,其参数与*路径操作函数*使用的参数相同。
|
||||
|
||||
所以,该部分:
|
||||
所以,该部分:
|
||||
|
||||
{% raw %}
|
||||
|
||||
@@ -96,9 +97,9 @@ Item ID: 42
|
||||
|
||||
{% endraw %}
|
||||
|
||||
...将生成一个与处理*路径操作函数* `read_item(id=id)`的 URL 相同的链接
|
||||
...将生成一个链接,指向由*路径操作函数* `read_item(id=id)` 处理的同一个 URL。
|
||||
|
||||
例如。当 ID 为 `42` 时, 会渲染成:
|
||||
例如,当 ID 为 `42` 时,会渲染成:
|
||||
|
||||
```html
|
||||
<a href="/items/42">
|
||||
@@ -106,20 +107,20 @@ Item ID: 42
|
||||
|
||||
## 模板与静态文件 { #templates-and-static-files }
|
||||
|
||||
你还可以在模板内部将 `url_for()` 用于静态文件,例如你挂载的 `name="static"` 的 `StaticFiles`。
|
||||
你还可以在模板内部使用 `url_for()`,例如将它与你挂载的 `name="static"` 的 `StaticFiles` 一起使用。
|
||||
|
||||
```jinja hl_lines="4"
|
||||
{!../../docs_src/templates/templates/item.html!}
|
||||
```
|
||||
|
||||
本例中,它将链接到 `static/styles.css` 中的 CSS 文件:
|
||||
在这个示例中,它会通过以下内容链接到 `static/styles.css` 中的 CSS 文件:
|
||||
|
||||
```CSS hl_lines="4"
|
||||
{!../../docs_src/templates/static/styles.css!}
|
||||
```
|
||||
|
||||
因为使用了 `StaticFiles`,**FastAPI** 应用会自动提供位于 URL `/static/styles.css` 的 CSS 文件。
|
||||
而且因为你使用了 `StaticFiles`,该 CSS 文件会由你的 **FastAPI** 应用在 URL `/static/styles.css` 自动提供。
|
||||
|
||||
## 更多说明 { #more-details }
|
||||
|
||||
包括如何测试模板在内的更多详情,请查看 [Starlette 的模板文档](https://www.starlette.dev/templates/)。
|
||||
包括如何测试模板在内的更多详情,请查看 [Starlette 的模板文档](https://starlette.dev/templates/)。
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
{* ../../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)阅读更多细节。
|
||||
|
||||
你可以阅读更多关于[“官方 Starlette 文档站点中的在测试中运行 lifespan。”](https://starlette.dev/lifespan/#running-lifespan-in-tests)的细节。
|
||||
|
||||
对于已弃用的 `startup` 和 `shutdown` 事件,可以按如下方式使用 `TestClient`:
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
/// note | 注意
|
||||
|
||||
更多细节请查看 Starlette 的文档:[测试 WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions)。
|
||||
更多细节请查看 Starlette 的文档:[测试 WebSockets](https://starlette.dev/testclient/#testing-websocket-sessions)。
|
||||
|
||||
///
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
## `Request` 对象的细节 { #details-about-the-request-object }
|
||||
|
||||
实际上,**FastAPI** 的底层是 **Starlette**,**FastAPI** 只不过是在 **Starlette** 顶层提供了一些工具,所以能直接使用 Starlette 的 [`Request`](https://www.starlette.dev/requests/) 对象。
|
||||
实际上,**FastAPI** 的底层是 **Starlette**,**FastAPI** 只不过是在 **Starlette** 顶层提供了一些工具,所以能直接使用 Starlette 的 [`Request`](https://starlette.dev/requests/) 对象。
|
||||
|
||||
但直接从 `Request` 对象提取数据时(例如,读取请求体),这些数据不会被 **FastAPI** 验证、转换或文档化(使用 OpenAPI,为自动的 API 用户界面)。
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
## 直接使用 `Request` 对象 { #use-the-request-object-directly }
|
||||
|
||||
假设要在*路径操作函数*中获取客户端 IP 地址和主机。
|
||||
假设要在*路径操作函数*中获取客户端 IP 地址/主机。
|
||||
|
||||
此时,需要直接访问请求。
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
|
||||
因此,能够提取、验证路径参数、并转换为指定类型,还可以用 OpenAPI 注释。
|
||||
|
||||
同样,您也可以正常声明其它参数,而且还可以提取 `Request`。
|
||||
同样,你也可以正常声明其它参数,而且还可以提取 `Request`。
|
||||
|
||||
///
|
||||
|
||||
## `Request` 文档 { #request-documentation }
|
||||
|
||||
你可以在[Starlette 官方文档站点的 `Request` 对象](https://www.starlette.dev/requests/)中阅读更多细节。
|
||||
你可以在[Starlette 官方文档站点的 `Request` 对象](https://starlette.dev/requests/)中阅读更多细节。
|
||||
|
||||
/// note | 技术细节
|
||||
|
||||
您也可以使用 `from starlette.requests import Request`。
|
||||
你也可以使用 `from starlette.requests import Request`。
|
||||
|
||||
**FastAPI** 直接提供它只是为了方便开发者,但它直接来自 Starlette。
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
## 安装 `websockets` { #install-websockets }
|
||||
|
||||
请确保您创建一个[虚拟环境](../virtual-environments.md)、激活它,并安装 `websockets`(一个让使用“WebSocket”协议更容易的 Python 库):
|
||||
将 `websockets`(一个让使用“WebSocket”协议更容易的 Python 库)添加到你的项目中:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install websockets
|
||||
$ uv add websockets
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -64,12 +64,12 @@ $ pip install websockets
|
||||
|
||||
## 尝试一下 { #try-it }
|
||||
|
||||
将代码放在 `main.py`,然后运行你的应用程序:
|
||||
将代码放在文件 `main.py` 中,然后运行你的应用程序:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -126,7 +126,7 @@ $ fastapi dev
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -182,5 +182,5 @@ Client #1596980209979 left the chat
|
||||
|
||||
要了解更多选项,请查看 Starlette 的文档:
|
||||
|
||||
* [`WebSocket` 类](https://www.starlette.dev/websockets/)。
|
||||
* [基于类的 WebSocket 处理](https://www.starlette.dev/endpoints/#websocketendpoint)。
|
||||
* [`WebSocket` 类](https://starlette.dev/websockets/)。
|
||||
* [基于类的 WebSocket 处理](https://starlette.dev/endpoints/#websocketendpoint)。
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/// note | 注意
|
||||
|
||||
需要安装 `a2wsgi`,例如使用 `pip install a2wsgi`。
|
||||
这需要将 `a2wsgi` 添加到你的项目中,例如使用 `uv add a2wsgi`。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework }
|
||||
|
||||
Django REST framework 作为一个灵活工具箱而创建,用于在底层使用 Django 构建 Web API,从而增强其 API 能力。
|
||||
Django REST Framework 作为一个灵活工具箱而创建,用于在底层使用 Django 构建 Web API,从而增强其 API 能力。
|
||||
|
||||
它被包括 Mozilla、Red Hat、Eventbrite 在内的许多公司使用。
|
||||
|
||||
@@ -125,7 +125,7 @@ def read_url():
|
||||
并集成基于标准的用户界面工具:
|
||||
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui)
|
||||
* [ReDoc](https://github.com/Rebilly/ReDoc)
|
||||
* [ReDoc](https://github.com/Redocly/redoc)
|
||||
|
||||
选择这两者是因为它们相当流行且稳定;但稍作搜索,你就能找到数十种 OpenAPI 的替代用户界面(都可以与 **FastAPI** 搭配使用)。
|
||||
|
||||
@@ -237,7 +237,7 @@ Flask-apispec 由与 Marshmallow 相同的开发者创建。
|
||||
|
||||
///
|
||||
|
||||
### [NestJS](https://nestjs.com/)(以及 [Angular](https://angular.io/)) { #nestjs-and-angular }
|
||||
### [NestJS](https://nestjs.com/)(以及 [Angular](https://angular.dev/)) { #nestjs-and-angular }
|
||||
|
||||
这甚至不是 Python。NestJS 是一个 JavaScript(TypeScript)的 NodeJS 框架,受 Angular 启发。
|
||||
|
||||
@@ -335,7 +335,7 @@ Hug 是最早使用 Python 类型提示来声明 API 参数类型的框架之一
|
||||
|
||||
/// note | 注意
|
||||
|
||||
Hug 由 Timothy Crosley 创建,他也是 [`isort`](https://github.com/timothycrosley/isort) 的作者,这是一个能自动排序 Python 文件中导入的优秀工具。
|
||||
Hug 由 Timothy Crosley 创建,他也是 [`isort`](https://github.com/PyCQA/isort) 的作者,这是一个能自动排序 Python 文件中导入的优秀工具。
|
||||
|
||||
///
|
||||
|
||||
@@ -399,7 +399,7 @@ APIStar 由 Tom Christie 创建。他还创建了:
|
||||
|
||||
## **FastAPI** 所使用的组件 { #used-by-fastapi }
|
||||
|
||||
### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
|
||||
### [Pydantic](https://pydantic.dev/docs/) { #pydantic }
|
||||
|
||||
Pydantic 是一个基于 Python 类型提示来定义数据校验、序列化与文档(使用 JSON Schema)的库。
|
||||
|
||||
@@ -415,7 +415,7 @@ Pydantic 是一个基于 Python 类型提示来定义数据校验、序列化与
|
||||
|
||||
///
|
||||
|
||||
### [Starlette](https://www.starlette.dev/) { #starlette }
|
||||
### [Starlette](https://starlette.dev/) { #starlette }
|
||||
|
||||
Starlette 是一个轻量级的 <dfn title="构建异步 Python Web 应用的新标准">ASGI</dfn> 框架/工具集,非常适合构建高性能的 asyncio 服务。
|
||||
|
||||
@@ -460,7 +460,7 @@ ASGI 是由 Django 核心团队成员推动的新“标准”。它尚不是正
|
||||
|
||||
///
|
||||
|
||||
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
|
||||
### [Uvicorn](https://uvicorn.dev) { #uvicorn }
|
||||
|
||||
Uvicorn 是一个基于 uvloop 与 httptools 构建的极速 ASGI 服务器。
|
||||
|
||||
|
||||
@@ -106,36 +106,32 @@ Docker 一直是创建和管理**容器镜像**与**容器**的主要工具之
|
||||
|
||||
### 包依赖 { #package-requirements }
|
||||
|
||||
通常你会把应用的**包依赖**放在某个文件里。
|
||||
当你使用 `uv` 管理项目时,它的直接依赖会声明在 `pyproject.toml` 中,而精确解析出的版本会存储在 `uv.lock` 中。
|
||||
|
||||
这主要取决于你用来**安装**这些依赖的工具。
|
||||
|
||||
最常见的方式是使用 `requirements.txt` 文件,每行一个包名及其版本范围。
|
||||
|
||||
当然,你也可以参考你在[关于 FastAPI 版本](versions.md)中读到的思路来设置版本范围。
|
||||
|
||||
例如,你的 `requirements.txt` 可能是:
|
||||
|
||||
```
|
||||
fastapi[standard]>=0.113.0,<0.114.0
|
||||
pydantic>=2.7.0,<3.0.0
|
||||
```
|
||||
|
||||
通常你会用 `pip` 安装这些依赖,例如:
|
||||
你可以用以下命令添加应用所需的包:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
$ uv add "fastapi[standard]" pydantic
|
||||
---> 100%
|
||||
Successfully installed fastapi pydantic
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// note | 注意
|
||||
|
||||
还有其他格式和工具可以定义并安装包依赖。
|
||||
下面的 Dockerfile 在容器内使用 `pip`。你可以将 uv 项目中锁定的依赖导出为它所期望的 `requirements.txt` 格式:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv export --format requirements-txt --no-dev --no-emit-project --output-file requirements.txt
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
生成的 `requirements.txt` 是用于容器构建的导出文件。继续使用 `uv add` 管理依赖,并在 `uv.lock` 变化时重新生成它。
|
||||
|
||||
///
|
||||
|
||||
@@ -373,7 +369,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
|
||||
|
||||
你还可以访问 [http://192.168.99.100/redoc](http://192.168.99.100/redoc) 或 [http://127.0.0.1/redoc](http://127.0.0.1/redoc)(或其他等价地址,取决于你的 Docker 主机)。
|
||||
|
||||
你将看到备选的自动文档(由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
你将看到备选的自动文档(由 [ReDoc](https://github.com/Redocly/redoc) 提供):
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称
|
||||
|
||||
除此之外,还有其他一些可选的 ASGI 服务器,例如:
|
||||
|
||||
* [Uvicorn](https://www.uvicorn.dev/): 高性能 ASGI 服务器。
|
||||
* [Uvicorn](https://uvicorn.dev): 高性能 ASGI 服务器。
|
||||
* [Hypercorn](https://hypercorn.readthedocs.io/): 与 HTTP/2 和 Trio 等兼容的 ASGI 服务器。
|
||||
* [Daphne](https://github.com/django/daphne): 为 Django Channels 构建的 ASGI 服务器。
|
||||
* [Granian](https://github.com/emmett-framework/granian): 基于 Rust 的 HTTP 服务器,专为 Python 应用设计。
|
||||
@@ -73,14 +73,14 @@ FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称
|
||||
|
||||
不过,你也可以手动安装 ASGI 服务器。
|
||||
|
||||
请确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装服务器应用程序。
|
||||
将服务器应用程序添加到你的项目中。
|
||||
|
||||
例如,要安装 Uvicorn,可以运行以下命令:
|
||||
例如,要安装 Uvicorn:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
$ uv add "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -91,11 +91,11 @@ $ pip install "uvicorn[standard]"
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
通过添加 `standard` 选项,Uvicorn 将安装并使用一些推荐的额外依赖项。
|
||||
通过添加 `standard`,Uvicorn 将安装并使用一些推荐的额外依赖项。
|
||||
|
||||
其中包括 `uvloop`,这是 `asyncio` 的高性能替代方案,能够显著提升并发性能。
|
||||
|
||||
当你使用 `pip install "fastapi[standard]"` 安装 FastAPI 时,实际上也会安装 `uvicorn[standard]`。
|
||||
当你使用类似 `uv add "fastapi[standard]"` 的命令添加 FastAPI 时,也已经会同时得到 `uvicorn[standard]`。
|
||||
|
||||
///
|
||||
|
||||
@@ -106,7 +106,7 @@ $ pip install "uvicorn[standard]"
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
$ uv run uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -86,7 +86,7 @@ $ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
|
||||
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
|
||||
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>]
|
||||
|
||||
@@ -1,299 +1,11 @@
|
||||
# 环境变量 { #environment-variables }
|
||||
|
||||
**环境变量**(也称为 **env var**)是一个独立于 Python 代码之外、存在于操作系统中的值,可以被你的应用程序和其他程序读取。
|
||||
|
||||
/// tip | 提示
|
||||
FastAPI 应用程序通常使用环境变量进行配置,例如数据库 URL、电子邮件凭据和密钥。
|
||||
|
||||
如果你已经知道什么是“环境变量”并且知道如何使用它们,你可以放心跳过这一部分。
|
||||
你将在[设置和环境变量](advanced/settings.md)中了解如何将它们用于应用程序配置。
|
||||
|
||||
///
|
||||
## 了解更多 { #learn-more }
|
||||
|
||||
环境变量(也称为“**env var**”)是一个独立于 Python 代码**之外**的变量,它存在于**操作系统**中,可以被你的 Python 代码(或其他程序)读取。
|
||||
|
||||
环境变量对于处理应用程序**设置**、作为 Python **安装**的一部分等方面非常有用。
|
||||
|
||||
## 创建和使用环境变量 { #create-and-use-env-vars }
|
||||
|
||||
你在 **shell(终端)**中就可以**创建**和使用环境变量,并不需要用到 Python:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 你可以使用以下命令创建一个名为 MY_NAME 的环境变量
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// 然后,你可以在其他程序中使用它,例如
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 创建一个名为 MY_NAME 的环境变量
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// 在其他程序中使用它,例如
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
## 在 Python 中读取环境变量 { #read-env-vars-in-python }
|
||||
|
||||
你也可以在 Python **之外**的终端中创建环境变量(或使用任何其他方法),然后在 Python 中**读取**它们。
|
||||
|
||||
例如,你可以创建一个名为 `main.py` 的文件,其中包含以下内容:
|
||||
|
||||
```Python hl_lines="3"
|
||||
import os
|
||||
|
||||
name = os.getenv("MY_NAME", "World")
|
||||
print(f"Hello {name} from Python")
|
||||
```
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
第二个参数是 [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) 的默认返回值。
|
||||
|
||||
如果没有提供,默认值为 `None`,这里我们提供 `"World"` 作为默认值。
|
||||
|
||||
///
|
||||
|
||||
然后你可以调用这个 Python 程序:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 这里我们还没有设置环境变量
|
||||
$ python main.py
|
||||
|
||||
// 因为我们没有设置环境变量,所以我们得到的是默认值
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// 但是如果我们事先创建过一个环境变量
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// 然后再次调用程序
|
||||
$ python main.py
|
||||
|
||||
// 现在就可以读取到环境变量了
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 这里我们还没有设置环境变量
|
||||
$ python main.py
|
||||
|
||||
// 因为我们没有设置环境变量,所以我们得到的是默认值
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// 但是如果我们事先创建过一个环境变量
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// 然后再次调用程序
|
||||
$ python main.py
|
||||
|
||||
// 现在就可以读取到环境变量了
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
由于环境变量可以在代码之外设置、但可以被代码读取,并且不必与其他文件一起存储(提交到 `git`),因此通常用于配置或**设置**。
|
||||
|
||||
你还可以为**特定的程序调用**创建特定的环境变量,该环境变量仅对该程序可用,且仅在其运行期间有效。
|
||||
|
||||
要实现这一点,只需在同一行内、程序本身之前创建它:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 在这个程序调用的同一行中创建一个名为 MY_NAME 的环境变量
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// 现在就可以读取到环境变量了
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// 在此之后这个环境变量将不会依然存在
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
你可以在 [The Twelve-Factor App: 配置](https://12factor.net/config) 中了解更多信息。
|
||||
|
||||
///
|
||||
|
||||
## 类型和验证 { #types-and-validation }
|
||||
|
||||
这些环境变量只能处理**文本字符串**,因为它们是处于 Python 范畴之外的,必须与其他程序和操作系统的其余部分兼容(甚至与不同的操作系统兼容,如 Linux、Windows、macOS)。
|
||||
|
||||
这意味着从环境变量中读取的**任何值**在 Python 中都将是一个 `str`,任何类型转换或验证都必须在代码中完成。
|
||||
|
||||
你将在[高级用户指南 - 设置和环境变量](./advanced/settings.md)中了解更多关于使用环境变量处理**应用程序设置**的信息。
|
||||
|
||||
## `PATH` 环境变量 { #path-environment-variable }
|
||||
|
||||
有一个**特殊的**环境变量称为 **`PATH`**,操作系统(Linux、macOS、Windows)用它来查找要运行的程序。
|
||||
|
||||
`PATH` 变量的值是一个长字符串,由 Linux 和 macOS 上的冒号 `:` 分隔的目录组成,而在 Windows 上则是由分号 `;` 分隔的。
|
||||
|
||||
例如,`PATH` 环境变量可能如下所示:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
这意味着系统应该在以下目录中查找程序:
|
||||
|
||||
- `/usr/local/bin`
|
||||
- `/usr/bin`
|
||||
- `/bin`
|
||||
- `/usr/sbin`
|
||||
- `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
|
||||
```
|
||||
|
||||
这意味着系统应该在以下目录中查找程序:
|
||||
|
||||
- `C:\Program Files\Python312\Scripts`
|
||||
- `C:\Program Files\Python312`
|
||||
- `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
当你在终端中输入一个**命令**时,操作系统会在 `PATH` 环境变量中列出的**每个目录**中**查找**程序。
|
||||
|
||||
例如,当你在终端中输入 `python` 时,操作系统会在该列表中的**第一个目录**中查找名为 `python` 的程序。
|
||||
|
||||
如果找到了,那么操作系统将**使用它**;否则,操作系统会继续在**其他目录**中查找。
|
||||
|
||||
### 安装 Python 和更新 `PATH` { #installing-python-and-updating-the-path }
|
||||
|
||||
安装 Python 时,可能会询问你是否要更新 `PATH` 环境变量。
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
假设你安装 Python 并最终将其安装在了目录 `/opt/custompython/bin` 中。
|
||||
|
||||
如果你同意更新 `PATH` 环境变量,那么安装程序将会将 `/opt/custompython/bin` 添加到 `PATH` 环境变量中。
|
||||
|
||||
它看起来大概会像这样:
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
|
||||
```
|
||||
|
||||
如此一来,当你在终端中输入 `python` 时,系统会在 `/opt/custompython/bin` 中找到 Python 程序(最后一个目录)并使用它。
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
假设你安装 Python 并最终将其安装在了目录 `C:\opt\custompython\bin` 中。
|
||||
|
||||
如果你同意更新 `PATH` 环境变量,那么安装程序将会将 `C:\opt\custompython\bin` 添加到 `PATH` 环境变量中。
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
|
||||
```
|
||||
|
||||
如此一来,当你在终端中输入 `python` 时,系统会在 `C:\opt\custompython\bin` 中找到 Python 程序(最后一个目录)并使用它。
|
||||
|
||||
////
|
||||
|
||||
因此,如果你输入:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
系统会在 `/opt/custompython/bin` 中**找到** `python` 程序并运行它。
|
||||
|
||||
这和输入以下命令大致等价:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ /opt/custompython/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
系统会在 `C:\opt\custompython\bin\python` 中**找到** `python` 程序并运行它。
|
||||
|
||||
这和输入以下命令大致等价:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ C:\opt\custompython\bin\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
当学习[虚拟环境](virtual-environments.md)时,这些信息将会很有用。
|
||||
|
||||
## 结论 { #conclusion }
|
||||
|
||||
通过这个教程,你应该对**环境变量**是什么以及如何在 Python 中使用它们有了基本的了解。
|
||||
|
||||
你也可以在[环境变量 - 维基百科](https://en.wikipedia.org/wiki/Environment_variable)中了解更多关于它们的信息。
|
||||
|
||||
在许多情况下,环境变量的用途和适用性并不是很明显。但是在开发过程中,它们会在许多不同的场景中出现,因此了解它们是很有必要的。
|
||||
|
||||
例如,你将在下一节关于[虚拟环境](virtual-environments.md)中需要这些信息。
|
||||
阅读[环境变量指南](https://tiangolo.com/guides/environment-variables/),了解详细的跨平台说明,包括如何创建和读取环境变量,以及 `PATH` 环境变量的工作方式。
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**FastAPI <abbr title="command line interface - 命令行接口">CLI</abbr>** 是一个命令行程序,你可以用它来部署和运行你的 FastAPI 应用、管理 FastAPI 项目,等等。
|
||||
|
||||
当你安装 FastAPI(例如使用 `pip install "fastapi[standard]"`)时,会附带一个可以在终端中运行的命令行程序。
|
||||
当你将 FastAPI 添加到你的项目中(例如使用 `uv add "fastapi[standard]"`)时,会附带一个可以在终端中运行的命令行程序。
|
||||
|
||||
要在开发环境中运行你的 FastAPI 应用,可以使用 `fastapi dev` 命令:
|
||||
|
||||
@@ -52,7 +52,7 @@ $ <font color="#4E9A06">fastapi</font> dev
|
||||
|
||||
///
|
||||
|
||||
在内部,**FastAPI CLI** 使用 [Uvicorn](https://www.uvicorn.dev),这是一个高性能、适用于生产环境的 ASGI 服务器。😎
|
||||
在内部,**FastAPI CLI** 使用 [Uvicorn](https://uvicorn.dev),这是一个高性能、适用于生产环境的 ASGI 服务器。😎
|
||||
|
||||
`fastapi` CLI 会尝试自动检测要运行的 FastAPI 应用,默认假设它是文件 `main.py` 中名为 `app` 的对象(或少数其他变体)。
|
||||
|
||||
@@ -100,28 +100,32 @@ from backend.main import app
|
||||
你也可以把文件路径传给 `fastapi dev` 命令,它会猜测要使用的 FastAPI 应用对象:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ uv run fastapi dev main.py
|
||||
```
|
||||
|
||||
或者,你也可以给 `fastapi dev` 命令传入 `--entrypoint` 选项:
|
||||
|
||||
```console
|
||||
$ fastapi dev --entrypoint main:app
|
||||
$ uv run fastapi dev --entrypoint main:app
|
||||
```
|
||||
|
||||
但每次运行 `fastapi` 命令都需要记得传入正确的路径或 entrypoint。
|
||||
但每次运行 `fastapi` 命令都需要记得传入正确的路径\entrypoint。
|
||||
|
||||
另外,其他工具可能找不到它,例如 [VS Code 扩展](editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此推荐在 `pyproject.toml` 中使用 `entrypoint`。
|
||||
|
||||
## `fastapi dev` { #fastapi-dev }
|
||||
|
||||
当你运行 `fastapi dev` 时,它将以开发模式运行。
|
||||
运行 `fastapi dev` 会启动开发模式。
|
||||
|
||||
默认情况下,它会启用**自动重载**,因此当你更改代码时,它会自动重新加载服务器。该功能是资源密集型的,且相较不启用时更不稳定,因此你应该仅在开发环境下使用它。它还会监听 IP 地址 `127.0.0.1`,这是你的机器仅与自身通信的 IP(`localhost`)。
|
||||
|
||||
在导入你的应用之前,`fastapi dev` 会将 `FASTAPI_ENV` 环境变量设置为 `development`。如果 `FASTAPI_ENV` 已经设置,则会保留其现有值。这让应用启动代码可以选择适合开发的行为,同时允许你提供应用特定的环境,例如 `staging`。
|
||||
|
||||
约定的 `FASTAPI_ENV` 值是 `development` 和 `production`。`fastapi run` 目前会保持 `FASTAPI_ENV` 不变,因此如果你的应用需要检测生产模式,请显式设置它。
|
||||
|
||||
## `fastapi run` { #fastapi-run }
|
||||
|
||||
当你运行 `fastapi run` 时,它默认以生产环境模式运行。
|
||||
执行 `fastapi run` 会以生产模式启动 FastAPI。
|
||||
|
||||
默认情况下,**自动重载是禁用的**。它将监听 IP 地址 `0.0.0.0`,即所有可用的 IP 地址,这样任何能够与该机器通信的人都可以公开访问它。这通常是你在生产环境中运行它的方式,例如在容器中运行。
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||

|
||||
|
||||
* 另外的 API 文档:[**ReDoc**](https://github.com/Rebilly/ReDoc)。
|
||||
* 另外的 API 文档:[**ReDoc**](https://github.com/Redocly/redoc)。
|
||||
|
||||

|
||||
|
||||
@@ -160,7 +160,7 @@ FastAPI 有一个使用非常简单,但是非常强大的<dfn title='也称为
|
||||
|
||||
## Starlette 特性 { #starlette-features }
|
||||
|
||||
**FastAPI** 与 [**Starlette**](https://www.starlette.dev/) 完全兼容(并基于它构建)。所以,你有的其他的 Starlette 代码也能正常工作。
|
||||
**FastAPI** 与 [**Starlette**](https://starlette.dev/) 完全兼容(并基于它构建)。所以,你有的其他的 Starlette 代码也能正常工作。
|
||||
|
||||
`FastAPI` 实际上是 `Starlette` 的一个子类。所以,如果你已经知道或者使用 Starlette,大部分的功能会以相同的方式工作。
|
||||
|
||||
@@ -178,7 +178,7 @@ FastAPI 有一个使用非常简单,但是非常强大的<dfn title='也称为
|
||||
|
||||
## Pydantic 特性 { #pydantic-features }
|
||||
|
||||
**FastAPI** 与 [**Pydantic**](https://docs.pydantic.dev/) 完全兼容(并基于它构建)。所以,你有的其他的 Pydantic 代码也能正常工作。
|
||||
**FastAPI** 与 [**Pydantic**](https://pydantic.dev/docs/) 完全兼容(并基于它构建)。所以,你有的其他的 Pydantic 代码也能正常工作。
|
||||
|
||||
兼容包括基于 Pydantic 的外部库,例如用于数据库的 <abbr title="Object-Relational Mapper - 对象关系映射">ORM</abbr>s、<abbr title="Object-Document Mapper - 对象文档映射">ODM</abbr>s。
|
||||
|
||||
|
||||
@@ -45,20 +45,6 @@
|
||||
* [@tiangolo.com 在 **Bluesky** 上](https://bsky.app/profile/tiangolo.com)
|
||||
* [@tiangolo 在 **LinkedIn** 上](https://www.linkedin.com/in/tiangolo/)。
|
||||
|
||||
## 在 GitHub 上帮别人解答问题 { #help-others-with-questions-in-github }
|
||||
|
||||
你可以尝试在 [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered) 中帮助他人解答问题。
|
||||
|
||||
很多情况下,你也许已经知道这些问题的答案了。🤓
|
||||
|
||||
如果你帮助了很多人解答问题,你会成为官方的 [FastAPI 专家](fastapi-people.md#fastapi-experts)。🎉
|
||||
|
||||
只要记住,最重要的是:尽量友善。🤗
|
||||
|
||||
### 如何提供帮助 { #how-to-help }
|
||||
|
||||
请参照这里的[帮助指南](https://tiangolo.com/open-source/help/#help-others-with-questions-in-github)。
|
||||
|
||||
## 提问 { #ask-questions }
|
||||
|
||||
你可以在 GitHub 资源库中[创建一个新问题(Question)](https://github.com/fastapi/fastapi/discussions/new?category=questions),例如:
|
||||
@@ -68,7 +54,7 @@
|
||||
|
||||
## 加入聊天 { #join-the-chat }
|
||||
|
||||
加入 👥 [Discord 聊天服务器](https://discord.gg/VQjSZaeJmf) 👥,和 FastAPI 社区的小伙伴们一起交流。
|
||||
加入 👥 [Discord 聊天服务器](https://discord.com/invite/VQjSZaeJmf) 👥,和 FastAPI 社区的小伙伴们一起交流。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
@@ -85,3 +71,9 @@
|
||||
在 GitHub 中,模板会引导你写出恰当的问题,从而更容易获得好的回答,甚至在提问之前就能自己解决。
|
||||
|
||||
聊天系统中的对话也不像 GitHub 那样容易搜索,它们会淹没消失。
|
||||
|
||||
## 试用 FastAPI Cloud { #try-fastapi-cloud }
|
||||
|
||||
FastAPI 及其小伙伴的主要资金来源是 [**FastAPI Cloud**](https://fastapicloud.com),这是一个用简单快速的方式部署 FastAPI 应用的平台,只需一个命令:`fastapi deploy`。
|
||||
|
||||
FastAPI Cloud 由 FastAPI 背后的同一团队构建。你可以试用它,并考虑在你的项目中使用。
|
||||
@@ -17,6 +17,7 @@
|
||||
正如[备选方案](alternatives.md)一章所述:
|
||||
|
||||
<blockquote markdown="1">
|
||||
|
||||
没有大家之前所做的工作,**FastAPI** 就不会存在。
|
||||
|
||||
以前创建的这些工具为它的出现提供了灵感。
|
||||
@@ -24,6 +25,7 @@
|
||||
在那几年中,我一直回避创建新的框架。首先,我尝试使用各种框架、插件、工具解决 **FastAPI** 现在的功能。
|
||||
|
||||
但到了一定程度之后,我别无选择,只能从之前的工具中汲取最优思路,并以尽量好的方式把这些思路整合在一起,使用之前甚至是不支持的语言特性(Python 3.6+ 的类型提示),从而创建一个能满足我所有需求的框架。
|
||||
|
||||
</blockquote>
|
||||
|
||||
## 调研 { #investigation }
|
||||
@@ -52,11 +54,11 @@
|
||||
|
||||
## 需求项 { #requirements }
|
||||
|
||||
经过测试多种备选方案,我最终决定使用 [**Pydantic**](https://docs.pydantic.dev/),并充分利用它的优势。
|
||||
经过测试多种备选方案,我最终决定使用 [**Pydantic**](https://pydantic.dev/docs/),并充分利用它的优势。
|
||||
|
||||
我甚至为它做了不少贡献,让它完美兼容了 JSON Schema,支持多种方式定义约束声明,并基于多个编辑器,改进了它对编辑器支持(类型检查、自动补全)。
|
||||
|
||||
在开发期间,我还为 [**Starlette**](https://www.starlette.dev/) 做了不少贡献,这是另一个关键需求项。
|
||||
在开发期间,我还为 [**Starlette**](https://starlette.dev/) 做了不少贡献,这是另一个关键需求项。
|
||||
|
||||
## 开发 { #development }
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
创建一个新的 `Request` 实例需要这两样:`scope` 和 `receive`。
|
||||
|
||||
想了解更多关于 `Request` 的信息,请查看 [Starlette 的 Request 文档](https://www.starlette.dev/requests/)。
|
||||
想了解更多关于 `Request` 的信息,请查看 [Starlette 的 Request 文档](https://starlette.dev/requests/)。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
基于以上信息,你可以用同一个工具函数生成 OpenAPI 架构,并按需覆盖其中的各个部分。
|
||||
|
||||
例如,让我们添加 [ReDoc 的 OpenAPI 扩展以包含自定义 Logo](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo)。
|
||||
例如,让我们添加 [ReDoc 的 OpenAPI 扩展以包含自定义 Logo](https://github.com/Redocly/redoc/blob/main/docs/redoc-vendor-extensions.md#x-logo)。
|
||||
|
||||
### 常规 **FastAPI** { #normal-fastapi }
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* [Strawberry](https://strawberry.rocks/) 🍓
|
||||
* 提供 [面向 FastAPI 的文档](https://strawberry.rocks/docs/integrations/fastapi)
|
||||
* [Ariadne](https://ariadnegraphql.org/)
|
||||
* 提供 [面向 FastAPI 的文档](https://ariadnegraphql.org/docs/fastapi-integration)
|
||||
* 提供 [面向 FastAPI 的文档](https://ariadnegraphql.org/server/Integrations/fastapi-integration)
|
||||
* [Tartiflette](https://tartiflette.io/)
|
||||
* 提供用于 ASGI 集成的 [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/)
|
||||
* [Graphene](https://graphene-python.org/)
|
||||
|
||||
@@ -24,7 +24,7 @@ FastAPI 0.128.0 也移除了对 `pydantic.v1` 的支持,因此最新版本的
|
||||
|
||||
## 官方指南 { #official-guide }
|
||||
|
||||
Pydantic 有一份从 v1 迁移到 v2 的官方[迁移指南](https://docs.pydantic.dev/latest/migration/)。
|
||||
Pydantic 有一份从 v1 迁移到 v2 的官方[迁移指南](https://pydantic.dev/docs/validation/latest/get-started/migration/)。
|
||||
|
||||
其中包含变更内容、校验如何更准确更严格、可能的注意事项等。
|
||||
|
||||
@@ -80,7 +80,7 @@ Pydantic v2 以子模块 `pydantic.v1` 的形式包含了 Pydantic v1 的全部
|
||||
|
||||
### 同一应用中同时使用 Pydantic v1 与 v2 { #pydantic-v1-and-v2-on-the-same-app }
|
||||
|
||||
Pydantic 不支持在一个 Pydantic v2 模型的字段中定义 Pydantic v1 模型,反之亦然。
|
||||
Pydantic **不支持**在一个 Pydantic v2 模型的字段中定义 Pydantic v1 模型,反之亦然。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
@@ -120,7 +120,7 @@ graph TB
|
||||
style V2Field fill:#f9fff3
|
||||
```
|
||||
|
||||
在某些情况下,甚至可以在 FastAPI 应用的同一个路径操作中同时使用 Pydantic v1 和 v2 模型:
|
||||
在某些情况下,甚至可以在 FastAPI 应用的同一个 **路径操作** 中同时使用 Pydantic v1 和 v2 模型:
|
||||
|
||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
||||
|
||||
|
||||
+20
-24
@@ -110,7 +110,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框
|
||||
</div>
|
||||
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
|
||||
<blockquote class="fastapi-opinions__quote">“我们采用了 <strong>FastAPI</strong> 库来启动一个可查询获取<strong>预测结果</strong>的 <strong>REST</strong> 服务器。” <em>[用于 Ludwig]</em></blockquote>
|
||||
<div class="fastapi-opinions__attr">— Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala,<strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(参考)</a></div>
|
||||
<div class="fastapi-opinions__attr">— Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala,<strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/">(参考)</a></div>
|
||||
</div>
|
||||
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
|
||||
<blockquote class="fastapi-opinions__quote">“<strong>Netflix</strong> 很高兴宣布开源我们的<strong>危机管理</strong>编排框架:<strong>Dispatch</strong>!” <em>[使用 FastAPI 构建]</em></blockquote>
|
||||
@@ -133,7 +133,7 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框
|
||||
|
||||
「_我们采用 **FastAPI** 库来启动一个可查询以获取**预测结果**的 **REST** 服务器。[用于 Ludwig]_」
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(参考)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino,Yaroslav Dudin,Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(参考)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -151,12 +151,6 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框
|
||||
|
||||
</div>
|
||||
|
||||
## FastAPI 大会 { #fastapi-conf }
|
||||
|
||||
[**FastAPI Conf '26**](https://fastapiconf.com) 将于 **2026 年 10 月 28 日** 在 **荷兰阿姆斯特丹** 举行。来自源头的 FastAPI 干货。🎤
|
||||
|
||||
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf '26 - 2026 年 10 月 28 日 - 荷兰阿姆斯特丹"></a>
|
||||
|
||||
## FastAPI 迷你纪录片 { #fastapi-mini-documentary }
|
||||
|
||||
在 2025 年末发布了一部 [FastAPI 迷你纪录片](https://www.youtube.com/watch?v=mpR8ngthqiE),你可以在线观看:
|
||||
@@ -175,17 +169,17 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框
|
||||
|
||||
FastAPI 站在巨人的肩膀之上:
|
||||
|
||||
* [Starlette](https://www.starlette.dev/) 负责 Web 部分。
|
||||
* [Pydantic](https://docs.pydantic.dev/) 负责数据部分。
|
||||
* [Starlette](https://starlette.dev/) 负责 Web 部分。
|
||||
* [Pydantic](https://pydantic.dev/docs/) 负责数据部分。
|
||||
|
||||
## 安装 { #installation }
|
||||
|
||||
创建并激活一个 [虚拟环境](https://fastapi.tiangolo.com/zh/virtual-environments/),然后安装 FastAPI:
|
||||
首先,[安装 `uv`](https://docs.astral.sh/uv/getting-started/installation/),然后将 FastAPI 添加到你的项目中:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
$ uv add "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -194,6 +188,8 @@ $ pip install "fastapi[standard]"
|
||||
|
||||
**注意**: 请确保把 `"fastapi[standard]"` 用引号包起来,以保证在所有终端中都能正常工作。
|
||||
|
||||
如果你更喜欢使用 `pip`,请在虚拟环境中安装 `fastapi[standard]`。请参阅[安装指南](tutorial/#install-fastapi)了解替代步骤。
|
||||
|
||||
## 示例 { #example }
|
||||
|
||||
### 创建 { #create-it }
|
||||
@@ -250,7 +246,7 @@ async def read_item(item_id: int, q: str | None = None):
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
╭────────── FastAPI CLI - Development mode ───────────╮
|
||||
│ │
|
||||
@@ -277,7 +273,7 @@ INFO: Application startup complete.
|
||||
<details markdown="1">
|
||||
<summary>关于命令 <code>fastapi dev</code>...</summary>
|
||||
|
||||
`fastapi dev` 命令会读取你的 `main.py` 文件,检测其中的 **FastAPI** 应用,并使用 [Uvicorn](https://www.uvicorn.dev) 启动服务器。
|
||||
`fastapi dev` 命令会自动读取你的 `main.py` 文件,检测其中的 **FastAPI** 应用,并使用 [Uvicorn](https://uvicorn.dev) 启动服务器。
|
||||
|
||||
默认情况下,`fastapi dev` 会在本地开发时启用自动重载。
|
||||
|
||||
@@ -314,7 +310,7 @@ INFO: Application startup complete.
|
||||
|
||||
然后访问 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)。
|
||||
|
||||
你会看到另一个自动生成的文档(由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
你会看到另一个自动生成的文档(由 [ReDoc](https://github.com/Redocly/redoc) 提供):
|
||||
|
||||

|
||||
|
||||
@@ -497,7 +493,7 @@ item: Item
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
@@ -520,7 +516,7 @@ CLI 会自动检测你的 FastAPI 应用并将其部署到云端。如果你尚
|
||||
|
||||
它把用 FastAPI 构建应用时的**开发者体验**带到了部署到云上的过程。🎉
|
||||
|
||||
FastAPI Cloud 是「FastAPI and friends」开源项目的主要赞助方和资金提供者。✨
|
||||
FastAPI Cloud 是 *FastAPI and friends* 开源项目的主要赞助方和资金提供者。✨
|
||||
|
||||
#### 部署到其他云厂商 { #deploy-to-other-cloud-providers }
|
||||
|
||||
@@ -540,7 +536,7 @@ FastAPI 依赖 Pydantic 和 Starlette。
|
||||
|
||||
### `standard` 依赖 { #standard-dependencies }
|
||||
|
||||
当你通过 `pip install "fastapi[standard]"` 安装 FastAPI 时,会包含 `standard` 组的一些可选依赖:
|
||||
当你通过 `uv add "fastapi[standard]"` 安装 FastAPI 时,会包含 `standard` 组的一些可选依赖:
|
||||
|
||||
Pydantic 使用:
|
||||
|
||||
@@ -554,17 +550,17 @@ Starlette 使用:
|
||||
|
||||
FastAPI 使用:
|
||||
|
||||
* [`uvicorn`](https://www.uvicorn.dev) - 加载并提供你的应用的服务器。包含 `uvicorn[standard]`,其中包含高性能服务所需的一些依赖(例如 `uvloop`)。
|
||||
* [`uvicorn`](https://uvicorn.dev) - 加载并提供你的应用的服务器。包含 `uvicorn[standard]`,其中包含高性能服务所需的一些依赖(例如 `uvloop`)。
|
||||
* `fastapi-cli[standard]` - 提供 `fastapi` 命令。
|
||||
* 其中包含 `fastapi-cloud-cli`,它允许你将 FastAPI 应用部署到 [FastAPI Cloud](https://fastapicloud.com)。
|
||||
|
||||
### 不包含 `standard` 依赖 { #without-standard-dependencies }
|
||||
|
||||
如果你不想包含这些 `standard` 可选依赖,可以使用 `pip install fastapi`,而不是 `pip install "fastapi[standard]"`。
|
||||
如果你不想包含这些 `standard` 可选依赖,可以使用 `uv add fastapi`,而不是 `uv add "fastapi[standard]"`。
|
||||
|
||||
### 不包含 `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
|
||||
|
||||
如果你想安装带有 standard 依赖但不包含 `fastapi-cloud-cli` 的 FastAPI,可以使用 `pip install "fastapi[standard-no-fastapi-cloud-cli]"`。
|
||||
如果你想安装带有 standard 依赖但不包含 `fastapi-cloud-cli` 的 FastAPI,可以使用 `uv add "fastapi[standard-no-fastapi-cloud-cli]"`。
|
||||
|
||||
### 其他可选依赖 { #additional-optional-dependencies }
|
||||
|
||||
@@ -572,13 +568,13 @@ FastAPI 使用:
|
||||
|
||||
额外的 Pydantic 可选依赖:
|
||||
|
||||
* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - 用于配置管理。
|
||||
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - 用于在 Pydantic 中使用的额外类型。
|
||||
* [`pydantic-settings`](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/) - 用于配置管理。
|
||||
* [`pydantic-extra-types`](https://github.com/pydantic/pydantic-extra-types) - 用于在 Pydantic 中使用的额外类型。
|
||||
|
||||
额外的 FastAPI 可选依赖:
|
||||
|
||||
* [`orjson`](https://github.com/ijl/orjson) - 使用 `ORJSONResponse` 时需要。
|
||||
* [`ujson`](https://github.com/esnme/ultrajson) - 使用 `UJSONResponse` 时需要。
|
||||
* [`ujson`](https://github.com/ultrajson/ultrajson) - 使用 `UJSONResponse` 时需要。
|
||||
|
||||
## 许可协议 { #license }
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
你可以使用此模板开始,它已经为你完成了大量的初始设置、安全性、数据库以及一些 API 端点。
|
||||
|
||||
GitHub 仓库:[Full Stack FastAPI Template](https://github.com/tiangolo/full-stack-fastapi-template)
|
||||
GitHub 仓库:[Full Stack FastAPI Template](https://github.com/fastapi/full-stack-fastapi-template)
|
||||
|
||||
## FastAPI全栈模板 - 技术栈和特性 { #full-stack-fastapi-template-technology-stack-and-features }
|
||||
|
||||
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/zh) 用于 Python 后端 API。
|
||||
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) 用于 Python 与 SQL 数据库的交互(ORM)。
|
||||
- 🔍 [Pydantic](https://docs.pydantic.dev),FastAPI 使用,用于数据验证与配置管理。
|
||||
- 🔍 [Pydantic](https://pydantic.dev/docs/),FastAPI 使用,用于数据验证与配置管理。
|
||||
- 💾 [PostgreSQL](https://www.postgresql.org) 作为 SQL 数据库。
|
||||
- 🚀 [React](https://react.dev) 用于前端。
|
||||
- 💃 使用 TypeScript、hooks、Vite 以及现代前端技术栈的其他部分。
|
||||
|
||||
@@ -269,7 +269,7 @@ def some_function(data: Any):
|
||||
|
||||
## Pydantic 模型 { #pydantic-models }
|
||||
|
||||
[Pydantic](https://docs.pydantic.dev/) 是一个用于执行数据校验的 Python 库。
|
||||
[Pydantic](https://pydantic.dev/docs/) 是一个用于执行数据校验的 Python 库。
|
||||
|
||||
你将数据的“结构”声明为带有属性的类。
|
||||
|
||||
@@ -285,7 +285,7 @@ def some_function(data: Any):
|
||||
|
||||
/// note | 注意
|
||||
|
||||
要了解更多关于 [Pydantic 的信息,请查看其文档](https://docs.pydantic.dev/)。
|
||||
要了解更多关于 [Pydantic 的信息,请查看其文档](https://pydantic.dev/docs/)。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
包括这些例子:
|
||||
|
||||
* 执行操作后发送的电子邮件通知:
|
||||
* 由于连接到电子邮件服务器并发送电子邮件往往很“慢”(几秒钟),您可以立即返回响应并在后台发送电子邮件通知。
|
||||
* 由于连接到电子邮件服务器并发送电子邮件往往很“慢”(几秒钟),你可以立即返回响应并在后台发送电子邮件通知。
|
||||
* 处理数据:
|
||||
* 例如,假设您收到的文件必须经过一个缓慢的过程,您可以返回一个"Accepted"(HTTP 202)响应并在后台处理它。
|
||||
* 例如,假设你收到的文件必须经过一个缓慢的过程,你可以返回一个"Accepted"(HTTP 202)响应并在后台处理它。
|
||||
|
||||
## 使用 `BackgroundTasks` { #using-backgroundtasks }
|
||||
|
||||
@@ -61,23 +61,23 @@
|
||||
|
||||
## 技术细节 { #technical-details }
|
||||
|
||||
`BackgroundTasks` 类直接来自 [`starlette.background`](https://www.starlette.dev/background/)。
|
||||
`BackgroundTasks` 类直接来自 [`starlette.background`](https://starlette.dev/background/)。
|
||||
|
||||
它被直接导入/包含到FastAPI以便你可以从 `fastapi` 导入,并避免意外从 `starlette.background` 导入备用的 `BackgroundTask` (后面没有 `s`)。
|
||||
|
||||
通过仅使用 `BackgroundTasks` (而不是 `BackgroundTask`),使得能将它作为 *路径操作函数* 的参数 ,并让**FastAPI**为您处理其余部分, 就像直接使用 `Request` 对象。
|
||||
通过仅使用 `BackgroundTasks` (而不是 `BackgroundTask`),使得能将它作为 *路径操作函数* 的参数 ,并让**FastAPI**为你处理其余部分, 就像直接使用 `Request` 对象。
|
||||
|
||||
在FastAPI中仍然可以单独使用 `BackgroundTask`,但您必须在代码中创建对象,并返回包含它的Starlette `Response`。
|
||||
在FastAPI中仍然可以单独使用 `BackgroundTask`,但你必须在代码中创建对象,并返回包含它的Starlette `Response`。
|
||||
|
||||
更多细节查看 [Starlette 后台任务的官方文档](https://www.starlette.dev/background/)。
|
||||
更多细节查看 [Starlette 后台任务的官方文档](https://starlette.dev/background/)。
|
||||
|
||||
## 告诫 { #caveat }
|
||||
|
||||
如果您需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,您不需要共享内存、变量等),那么使用其他更大的工具(如 [Celery](https://docs.celeryq.dev))可能更好。
|
||||
如果你需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,你不需要共享内存、变量等),那么使用其他更大的工具(如 [Celery](https://docs.celeryq.dev))可能更好。
|
||||
|
||||
它们往往需要更复杂的配置,即消息/作业队列管理器,如RabbitMQ或Redis,但它们允许您在多个进程中运行后台任务,甚至是在多个服务器中。
|
||||
它们往往需要更复杂的配置,即消息/作业队列管理器,如RabbitMQ或Redis,但它们允许你在多个进程中运行后台任务,甚至是在多个服务器中。
|
||||
|
||||
但是,如果您需要从同一个**FastAPI**应用程序访问变量和对象,或者您需要执行小型后台任务(如发送电子邮件通知),您只需使用 `BackgroundTasks` 即可。
|
||||
但是,如果你需要从同一个**FastAPI**应用程序访问变量和对象,或者你需要执行小型后台任务(如发送电子邮件通知),你只需使用 `BackgroundTasks` 即可。
|
||||
|
||||
## 回顾 { #recap }
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ from app.main import app
|
||||
你也可以把路径传给命令,比如:
|
||||
|
||||
```console
|
||||
$ fastapi dev app/main.py
|
||||
$ uv run fastapi dev app/main.py
|
||||
```
|
||||
|
||||
但是每次调用 `fastapi` 命令时,你都需要记得传入正确的路径。
|
||||
@@ -503,7 +503,7 @@ $ fastapi dev app/main.py
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -95,7 +95,7 @@ Pydantic 模型的每个属性都具有类型。
|
||||
|
||||
除了普通的单一值类型(如 `str`、`int`、`float` 等)外,你还可以使用从 `str` 继承的更复杂的单一值类型。
|
||||
|
||||
要了解所有的可用选项,请查看 [Pydantic 的类型概览](https://docs.pydantic.dev/latest/concepts/types/)。你将在下一章节中看到一些示例。
|
||||
要了解所有的可用选项,请查看 [Pydantic 的类型概览](https://pydantic.dev/docs/validation/latest/concepts/types/)。你将在下一章节中看到一些示例。
|
||||
|
||||
例如,在 `Image` 模型中我们有一个 `url` 字段,我们可以把它声明为 Pydantic 的 `HttpUrl`,而不是 `str`:
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
你的 API 几乎总是需要发送**响应体**。但客户端不一定总是要发送**请求体**,有时它们只请求某个路径,可能带一些查询参数,但不会发送请求体。
|
||||
|
||||
使用 [Pydantic](https://docs.pydantic.dev/) 模型来声明**请求体**,能充分利用它的功能和优点。
|
||||
使用 [Pydantic](https://pydantic.dev/docs/) 模型来声明**请求体**,能充分利用它的功能和优点。
|
||||
|
||||
/// note | 注意
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
$ uv run python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -35,7 +35,7 @@ from myapp import app
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
$ uv run python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
* `datetime.timedelta`:
|
||||
* 一个 Python `datetime.timedelta`.
|
||||
* 在请求和响应中将表示为 `float` 代表总秒数。
|
||||
* Pydantic 也允许将其表示为 "ISO 8601 时间差异编码", [查看文档了解更多信息](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers)。
|
||||
* Pydantic 也允许将其表示为 "ISO 8601 时间差异编码", [查看文档了解更多信息](https://pydantic.dev/docs/validation/latest/concepts/serialization/#custom-serializers)。
|
||||
* `frozenset`:
|
||||
* 在请求和响应中,作为 `set` 对待:
|
||||
* 在请求中,列表将被读取,消除重复,并将其转换为一个 `set`。
|
||||
@@ -49,7 +49,7 @@
|
||||
* `Decimal`:
|
||||
* 标准的 Python `Decimal`。
|
||||
* 在请求和响应中被当做 `float` 一样处理。
|
||||
* 你可以在这里检查所有有效的 Pydantic 数据类型: [Pydantic data types](https://docs.pydantic.dev/latest/usage/types/types/)。
|
||||
* 你可以在这里检查所有有效的 Pydantic 数据类型: [Pydantic 数据类型](https://pydantic.dev/docs/validation/latest/concepts/types/)。
|
||||
|
||||
## 例子 { #example }
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ UserInDB(
|
||||
|
||||
/// note | 注意
|
||||
|
||||
定义 [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions) 类型时,要把更具体的类型写在前面,然后是不太具体的类型。下例中,更具体的 `PlaneItem` 位于 `Union[PlaneItem, CarItem]` 中的 `CarItem` 之前。
|
||||
定义 [`Union`](https://pydantic.dev/docs/validation/latest/concepts/unions/) 类型时,要把更具体的类型写在前面,然后是不太具体的类型。下例中,更具体的 `PlaneItem` 位于 `Union[PlaneItem, CarItem]` 中的 `CarItem` 之前。
|
||||
|
||||
///
|
||||
|
||||
@@ -209,4 +209,4 @@ some_variable: PlaneItem | CarItem
|
||||
|
||||
针对不同场景,可以随意使用不同的 Pydantic 模型并通过继承复用。
|
||||
|
||||
当一个实体需要具备不同的“状态”时,无需只为该实体定义一个数据模型。例如,用户“实体”就可能有包含 `password`、包含 `password_hash` 以及不含密码等多种状态。
|
||||
当一个实体需要具备不同的“状态”时,无需只为该实体定义一个数据模型。例如,**用户**“实体”就可能有包含 `password`、包含 `password_hash` 以及不含密码等多种状态。
|
||||
@@ -7,12 +7,18 @@
|
||||
|
||||
将其复制到 `main.py` 文件中。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
FastAPI 有一个[官方 VS Code 扩展](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode)(以及 Cursor),它提供了很多功能,包括路径操作浏览器、路径操作搜索、测试中的 CodeLens 导航(从测试跳转到定义),以及 FastAPI Cloud 部署和日志,全部都可以在你的编辑器中完成。
|
||||
|
||||
///
|
||||
|
||||
运行实时服务器:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
$ <font color="#4E9A06">uv run fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
@@ -79,7 +85,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
|
||||
前往 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)。
|
||||
|
||||
你将会看到可选的自动生成文档 (由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
你将会看到可选的自动生成文档 (由 [ReDoc](https://github.com/Redocly/redoc) 提供):
|
||||
|
||||

|
||||
|
||||
@@ -186,16 +192,16 @@ from backend.main import app
|
||||
你也可以把文件路径传给 `fastapi dev` 命令,它会尝试推断要使用的 FastAPI 应用对象:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ uv run fastapi dev main.py
|
||||
```
|
||||
|
||||
或者,你也可以给 `fastapi dev` 命令传入 `--entrypoint` 选项:
|
||||
|
||||
```console
|
||||
$ fastapi dev --entrypoint main:app
|
||||
$ uv run fastapi dev --entrypoint main:app
|
||||
```
|
||||
|
||||
但这样每次调用 `fastapi` 命令时都需要记得传入正确的路径/entrypoint。
|
||||
但这样每次调用 `fastapi` 命令时都需要记得传入正确的路径\entrypoint。
|
||||
|
||||
另外,其他工具可能无法找到它,例如 [VS Code 扩展](../editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此推荐在 `pyproject.toml` 中使用 `entrypoint`。
|
||||
|
||||
@@ -206,7 +212,7 @@ $ fastapi dev --entrypoint main:app
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
@@ -233,7 +239,7 @@ CLI 会自动检测你的 FastAPI 应用并将其部署到云端。如果你尚
|
||||
|
||||
`FastAPI` 是直接从 `Starlette` 继承的类。
|
||||
|
||||
你可以通过 `FastAPI` 使用所有的 [Starlette](https://www.starlette.dev/) 的功能。
|
||||
你也可以通过 `FastAPI` 使用所有的 [Starlette](https://starlette.dev/) 的功能。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ npm run build
|
||||
|
||||
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
|
||||
|
||||
**FastAPI** 只会对看起来像浏览器导航的 `GET` 和 `HEAD` 请求使用此 fallback。缺失的 JavaScript、CSS 和图片等文件仍会返回 `404`。
|
||||
**FastAPI** 只会对明确使用 `Accept: text/html` 或 `Accept: application/xhtml+xml` 接受 HTML 的 `GET` 和 `HEAD` 请求使用此 fallback,就像浏览器导航请求通常会做的那样。缺失的 JavaScript、CSS 和图片等文件仍会返回 `404`。
|
||||
|
||||
对于其他方法的请求,例如 `POST` 或 `PUT`,如果路径只匹配前端 fallback,也会返回 `404`。常规 **FastAPI** *路径操作*仍然比前端路由具有更高优先级。
|
||||
|
||||
@@ -106,9 +106,13 @@ npm run build
|
||||
|
||||
## 检查目录 { #check-directory }
|
||||
|
||||
默认情况下,`app.frontend()` 会在应用创建时检查目录是否存在。
|
||||
默认情况下,`app.frontend()` 使用 `check_dir="auto"`。
|
||||
|
||||
这有助于尽早发现配置错误。例如,如果前端构建输出目录缺失,**FastAPI** 会在启动时抛出错误。
|
||||
当 `FASTAPI_ENV` 环境变量设置为 `development` 时,如果前端构建输出目录缺失,**FastAPI** 只会显示警告。如果尚未设置,[`fastapi dev` 命令](https://github.com/fastapi/fastapi-cli#fastapi-dev)会为你设置这个环境变量。这样你就可以在开发期间,在构建或启动前端之前先启动后端。
|
||||
|
||||
在其他任何环境中,**FastAPI** 会在创建应用时抛出错误。这有助于在部署缺少前端文件的应用之前,尽早发现配置错误。
|
||||
|
||||
你也可以设置 `check_dir=True`,以便始终在创建应用时检查目录。
|
||||
|
||||
如果你的前端文件会稍后创建,例如在应用对象创建之后由单独的构建步骤创建,请设置 `check_dir=False`:
|
||||
|
||||
@@ -132,6 +136,8 @@ npm run build
|
||||
|
||||
来自 app、`APIRouter` 和 `include_router()` 的依赖项也会应用于前端响应。这可用于通过 cookie 身份验证或类似方式保护前端。
|
||||
|
||||
依赖项也可以像普通*路径操作*一样修改响应标头并添加后台任务。
|
||||
|
||||
## 仅限静态构建输出 { #static-build-output-only }
|
||||
|
||||
`app.frontend()` 提供的是你的前端构建已经生成的文件。
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
## 安装自定义异常处理器 { #install-custom-exception-handlers }
|
||||
|
||||
可以使用[与 Starlette 相同的异常处理工具](https://www.starlette.dev/exceptions/)添加自定义异常处理器。
|
||||
可以使用[与 Starlette 相同的异常处理工具](https://starlette.dev/exceptions/)添加自定义异常处理器。
|
||||
|
||||
假设有一个自定义异常 `UnicornException`(你自己或你使用的库可能会 `raise` 它)。
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
|
||||
所有代码片段都可以复制后直接使用(它们实际上是经过测试的 Python 文件)。
|
||||
|
||||
要运行任何示例,请将代码复制到 `main.py` 文件中,然后启动 `fastapi dev`:
|
||||
要运行任何示例,请将代码复制到 `main.py` 文件中,然后使用 `uv run` 启动 `fastapi dev`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
$ <font color="#4E9A06">uv run fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
@@ -60,35 +60,75 @@ $ <font color="#4E9A06">fastapi</font> dev
|
||||
|
||||
## 安装 FastAPI { #install-fastapi }
|
||||
|
||||
第一个步骤是安装 FastAPI。
|
||||
第一步是设置你的项目并添加 FastAPI。
|
||||
|
||||
请确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后**安装 FastAPI**:
|
||||
安装 [`uv`](https://docs.astral.sh/uv/getting-started/installation/),然后创建一个项目并添加 FastAPI:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
$ uv init awesome-project --bare
|
||||
$ cd awesome-project
|
||||
$ uv add "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
`uv add` 会在 `.venv` 中创建项目的虚拟环境,将 FastAPI 添加到 `pyproject.toml`,并创建 `uv.lock`,以便稍后可以安装相同的包版本。
|
||||
|
||||
/// details | 这些命令的作用
|
||||
|
||||
* `uv init`:创建一个新的 Python 项目。
|
||||
* `awesome-project`:在一个使用此名称的新目录中创建项目。
|
||||
* `--bare`:只创建最小的 `pyproject.toml` 文件,不生成示例 `main.py`、`README.md` 或其他文件。你将在本教程的后续步骤中自己创建应用程序文件。
|
||||
|
||||
然后,`cd awesome-project` 会在添加 FastAPI 之前进入新的项目目录。
|
||||
|
||||
`uv` 会使用系统中已安装的兼容 Python 版本,或者在需要时下载一个。
|
||||
|
||||
当你运行 `uv add` 时,它会选择 FastAPI 以及 FastAPI 依赖的所有包的兼容版本。它会把确切版本记录到 `uv.lock` 中,从而可以稍后在另一台计算机上或部署应用程序时安装相同的包版本。
|
||||
|
||||
创建或更新此文件称为[**锁定**项目依赖项](https://docs.astral.sh/uv/concepts/projects/sync/)。当你添加包时,`uv` 会自动执行此操作。
|
||||
|
||||
///
|
||||
|
||||
/// details | FastAPI 安装选项
|
||||
|
||||
当你使用 `uv add "fastapi[standard]"` 安装时,它会附带一些默认的可选标准依赖项,其中包括 `fastapi-cloud-cli`,它可以让你部署到 [FastAPI Cloud](https://fastapicloud.com)。
|
||||
|
||||
如果你不想安装这些可选依赖,可以选择安装 `uv add fastapi`。
|
||||
|
||||
如果你想安装标准依赖但不包含 `fastapi-cloud-cli`,可以使用 `uv add "fastapi[standard-no-fastapi-cloud-cli]"` 安装。
|
||||
|
||||
///
|
||||
|
||||
/// details | 改用 `pip`
|
||||
|
||||
如果你更喜欢手动管理虚拟环境和包,请创建并激活一个虚拟环境,然后使用 `pip install "fastapi[standard]"` 安装 FastAPI。
|
||||
|
||||
阅读[虚拟环境指南](https://tiangolo.com/guides/virtual-environments/)了解详细步骤。
|
||||
|
||||
///
|
||||
|
||||
## AI Agent 技能 { #ai-agent-skills }
|
||||
|
||||
FastAPI 为 AI coding agent 提供了一个官方 skill。它随包一起提供,因此它的指导会与你项目中安装的 FastAPI 版本保持一致,并在你更新 FastAPI 时随之更新。
|
||||
|
||||
在你的项目中安装 FastAPI 后,你可以使用 <a href="https://library-skills.io">Library Skills</a> 安装该 skill:
|
||||
|
||||
```bash
|
||||
uvx library-skills
|
||||
```
|
||||
|
||||
/// note | 注意
|
||||
|
||||
当你使用 `pip install "fastapi[standard]"` 安装时,它会附带一些默认的可选标准依赖项,其中包括 `fastapi-cloud-cli`,它可以让你部署到 [FastAPI Cloud](https://fastapicloud.com)。
|
||||
|
||||
如果你不想安装这些可选依赖,可以选择安装 `pip install fastapi`。
|
||||
|
||||
如果你想安装标准依赖但不包含 `fastapi-cloud-cli`,可以使用 `pip install "fastapi[standard-no-fastapi-cloud-cli]"` 安装。
|
||||
`uvx` 是 `uv tool run` 的别名。它会在一个临时、隔离的环境中运行 Library Skills,同时 Library Skills 会扫描你项目中安装的包。
|
||||
|
||||
///
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
FastAPI 提供了一个[VS Code 官方扩展](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode)(也支持 Cursor),包含众多功能,例如路径操作浏览器、路径操作搜索、测试中的 CodeLens 导航(从测试跳转到定义),以及从编辑器内进行 FastAPI Cloud 部署和查看日志。
|
||||
|
||||
///
|
||||
该 skill 与 Codex、Claude Code、Cursor、GitHub Copilot、Gemini CLI、Pi、OpenCode 以及大多数其他 coding agent 兼容。对于 Claude Code,当被询问要将该 skill 安装到哪里时,选择 `.claude/skills`。
|
||||
|
||||
## 进阶用户指南 { #advanced-user-guide }
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
|
||||
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
|
||||
|
||||
/// tip
|
||||
/// tip | 提示
|
||||
|
||||
请记住可以[使用 `X-` 前缀](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)添加专有自定义请求头。
|
||||
|
||||
但是如果你有希望让浏览器中的客户端可见的自定义请求头,你需要把它们加到你的 CORS 配置([CORS(跨域资源共享)](cors.md))的 `expose_headers` 参数中,参见 [Starlette 的 CORS 文档](https://www.starlette.dev/middleware/#corsmiddleware)。
|
||||
但是如果你有希望让浏览器中的客户端可见的自定义请求头,你需要把它们加到你的 CORS 配置([CORS(跨域资源共享)](cors.md))的 `expose_headers` 参数中,参见 [Starlette 的 CORS 文档](https://starlette.dev/middleware/#corsmiddleware)。
|
||||
|
||||
///
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
|
||||
|
||||
/// tip
|
||||
/// tip | 提示
|
||||
|
||||
这里我们使用 [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) 而不是 `time.time()`,因为在这类场景中它可能更精确。🤓
|
||||
|
||||
@@ -82,9 +82,9 @@ app.add_middleware(MiddlewareB)
|
||||
|
||||
这会产生如下执行顺序:
|
||||
|
||||
* 请求:MiddlewareB → MiddlewareA → 路由
|
||||
* **请求**:MiddlewareB → MiddlewareA → 路由
|
||||
|
||||
* 响应:路由 → MiddlewareA → MiddlewareB
|
||||
* **响应**:路由 → MiddlewareA → MiddlewareB
|
||||
|
||||
这种栈式行为确保中间件按可预测且可控的顺序执行。
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
注意,函数接收并返回的值是 `3`( `int`),不是 `"3"`(`str`)。
|
||||
|
||||
**FastAPI** 通过类型声明自动进行请求的<dfn title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</dfn>。
|
||||
**FastAPI** 通过类型声明自动进行请求的<dfn title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">“解析”</dfn>。
|
||||
|
||||
///
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
## 基于标准的好处,备选文档 { #standards-based-benefits-alternative-documentation }
|
||||
|
||||
**FastAPI** 使用 [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md) 生成概图,所以能兼容很多工具。
|
||||
**FastAPI** 使用 [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md) 生成概图,所以能兼容很多工具。
|
||||
|
||||
因此,**FastAPI** 还内置了 ReDoc 生成的备选 API 文档,可在此查看 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc):
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
## Pydantic { #pydantic }
|
||||
|
||||
所有数据校验都由 [Pydantic](https://docs.pydantic.dev/) 在幕后完成,因此你能从中获得所有好处。而且你可以放心。
|
||||
所有数据校验都由 [Pydantic](https://pydantic.dev/docs/) 在幕后完成,因此你能从中获得所有好处。而且你可以放心。
|
||||
|
||||
同样,`str`、`float`、`bool` 以及很多复合数据类型都可以使用类型声明。
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
|
||||
## 预设值 { #predefined-values }
|
||||
|
||||
路径操作使用 Python 的 <abbr title="Enumeration - 枚举">`Enum`</abbr> 类型接收预设的路径参数。
|
||||
如果你的*路径操作*接收一个*路径参数*,但你希望可能有效的*路径参数*值是预设的,可以使用标准 Python <abbr title="Enumeration - 枚举">`Enum`</abbr>。
|
||||
|
||||
### 创建 `Enum` 类 { #create-an-enum-class }
|
||||
|
||||
@@ -144,33 +144,33 @@
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
**AlexNet**、**ResNet**、**LeNet** 是机器学习<dfn title="技术上来说是深度学习模型架构">模型</dfn>的名字。
|
||||
如果你好奇,"AlexNet"、"ResNet" 和 "LeNet" 只是机器学习<dfn title="技术上来说是深度学习模型架构">模型</dfn>的名字。
|
||||
|
||||
///
|
||||
|
||||
### 声明路径参数 { #declare-a-path-parameter }
|
||||
### 声明*路径参数* { #declare-a-path-parameter }
|
||||
|
||||
使用 Enum 类(`ModelName`)创建使用类型注解的路径参数:
|
||||
使用你创建的枚举类(`ModelName`)创建带有类型注解的*路径参数*:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
|
||||
|
||||
### 查看文档 { #check-the-docs }
|
||||
|
||||
API 文档会显示预定义路径参数的可用值:
|
||||
由于*路径参数*的可用值是预定义的,交互式文档可以很好地显示它们:
|
||||
|
||||
<img src="/img/tutorial/path-params/image03.png">
|
||||
|
||||
### 使用 Python 枚举 { #working-with-python-enumerations }
|
||||
### 使用 Python *枚举* { #working-with-python-enumerations }
|
||||
|
||||
路径参数的值是一个枚举成员。
|
||||
*路径参数*的值是一个*枚举成员*。
|
||||
|
||||
#### 比较枚举成员 { #compare-enumeration-members }
|
||||
#### 比较*枚举成员* { #compare-enumeration-members }
|
||||
|
||||
可以将其与枚举类 `ModelName` 中的枚举成员进行比较:
|
||||
可以将其与你创建的枚举 `ModelName` 中的*枚举成员*进行比较:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
|
||||
|
||||
#### 获取枚举值 { #get-the-enumeration-value }
|
||||
#### 获取*枚举值* { #get-the-enumeration-value }
|
||||
|
||||
使用 `model_name.value` 或通用的 `your_enum_member.value` 获取实际的值(本例中为 `str`):
|
||||
|
||||
@@ -182,11 +182,11 @@ API 文档会显示预定义路径参数的可用值:
|
||||
|
||||
///
|
||||
|
||||
#### 返回枚举成员 { #return-enumeration-members }
|
||||
#### 返回*枚举成员* { #return-enumeration-members }
|
||||
|
||||
即使嵌套在 JSON 请求体里(例如,`dict`),也可以从路径操作返回枚举成员。
|
||||
即使嵌套在 JSON 请求体里(例如,`dict`),也可以从你的*路径操作*返回*枚举成员*。
|
||||
|
||||
返回给客户端之前,会把枚举成员转换为对应的值(本例中为字符串):
|
||||
返回给客户端之前,会把它们转换为对应的值(本例中为字符串):
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
|
||||
|
||||
@@ -201,29 +201,29 @@ API 文档会显示预定义路径参数的可用值:
|
||||
|
||||
## 包含路径的路径参数 { #path-parameters-containing-paths }
|
||||
|
||||
假设路径操作的路径为 `/files/{file_path}`。
|
||||
假设你有一个路径为 `/files/{file_path}` 的*路径操作*。
|
||||
|
||||
但需要 `file_path` 中也包含路径,比如,`home/johndoe/myfile.txt`。
|
||||
但需要 `file_path` 本身也包含*路径*,比如,`home/johndoe/myfile.txt`。
|
||||
|
||||
此时,该文件的 URL 是这样的:`/files/home/johndoe/myfile.txt`。
|
||||
因此,该文件的 URL 可能是这样的:`/files/home/johndoe/myfile.txt`。
|
||||
|
||||
### OpenAPI 支持 { #openapi-support }
|
||||
|
||||
OpenAPI 不支持声明包含路径的路径参数,因为这会导致测试和定义更加困难。
|
||||
OpenAPI 不支持声明内部包含*路径*的*路径参数*,因为这会导致测试和定义更加困难。
|
||||
|
||||
不过,仍可使用 Starlette 内置工具在 **FastAPI** 中实现这一功能。
|
||||
不过,仍可使用 Starlette 内部工具之一在 **FastAPI** 中实现这一功能。
|
||||
|
||||
而且不影响文档正常运行,但是不会添加该参数包含路径的说明。
|
||||
而且不影响文档正常运行,但是不会添加该参数应包含路径的说明。
|
||||
|
||||
### 路径转换器 { #path-convertor }
|
||||
|
||||
直接使用 Starlette 的选项声明包含路径的路径参数:
|
||||
直接使用 Starlette 的选项,就可以用如下 URL 声明包含*路径*的*路径参数*:
|
||||
|
||||
```
|
||||
/files/{file_path:path}
|
||||
```
|
||||
|
||||
本例中,参数名为 `file_path`,结尾部分的 `:path` 说明该参数应匹配路径。
|
||||
本例中,参数名为 `file_path`,结尾部分的 `:path` 说明该参数应匹配任意*路径*。
|
||||
|
||||
用法如下:
|
||||
|
||||
@@ -241,10 +241,10 @@ OpenAPI 不支持声明包含路径的路径参数,因为这会导致测试和
|
||||
|
||||
通过简短、直观的 Python 标准类型声明,**FastAPI** 可以获得:
|
||||
|
||||
- 编辑器支持:错误检查,代码自动补全等
|
||||
- 数据 "<dfn title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</dfn>"
|
||||
- 数据校验
|
||||
- API 注解和自动文档
|
||||
* 编辑器支持:错误检查,代码自动补全等
|
||||
* 数据 "<dfn title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</dfn>"
|
||||
* 数据校验
|
||||
* API 注解和自动文档
|
||||
|
||||
只需要声明一次即可。
|
||||
|
||||
|
||||
@@ -370,11 +370,11 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
||||
|
||||
在这些情况下,你可以使用**自定义校验函数**,该函数会在正常校验之后应用(例如,在先校验值是 `str` 之后)。
|
||||
|
||||
你可以在 `Annotated` 中使用 [Pydantic 的 `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) 来实现。
|
||||
你可以在 `Annotated` 中使用 [Pydantic 的 `AfterValidator`](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-after-validator) 来实现。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
Pydantic 还有 [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) 等。🤓
|
||||
Pydantic 还有 [`BeforeValidator`](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-before-validator) 等。🤓
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
要接收上传的文件,请先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
请确保你创建一个[虚拟环境](../virtual-environments.md)、激活它,然后安装,例如:
|
||||
将它添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
这是因为上传文件是以「表单数据」发送的。
|
||||
@@ -151,7 +151,7 @@ HTML 表单(`<form></form>`)向服务器发送数据的方式通常会对数
|
||||
|
||||
它们会被关联到同一个通过「表单数据」发送的「表单字段」。
|
||||
|
||||
要实现这一点,声明一个由 `bytes` 或 `UploadFile` 组成的列表(`List`):
|
||||
要实现这一点,声明一个由 `bytes` 或 `UploadFile` 组成的列表:
|
||||
|
||||
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
确保你创建一个[虚拟环境](../virtual-environments.md),激活它,然后再安装,例如:
|
||||
将它添加到你的项目:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -6,10 +6,10 @@ FastAPI 支持同时使用 `File` 和 `Form` 定义文件和表单字段。
|
||||
|
||||
接收上传的文件和/或表单数据,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
请先创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
|
||||
将它添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
要使用表单,首先安装 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
请先创建并激活一个[虚拟环境](../virtual-environments.md),然后再进行安装,例如:
|
||||
将其添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -76,16 +76,16 @@ FastAPI 会使用这个 `response_model` 来完成数据文档、校验等,并
|
||||
|
||||
要使用 `EmailStr`,首先安装 [`email-validator`](https://github.com/JoshData/python-email-validator)。
|
||||
|
||||
请先创建并激活一个[虚拟环境](../virtual-environments.md),然后安装,例如:
|
||||
将它添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install email-validator
|
||||
$ uv add email-validator
|
||||
```
|
||||
|
||||
或者:
|
||||
或者使用:
|
||||
|
||||
```console
|
||||
$ pip install "pydantic[email]"
|
||||
$ uv add "pydantic[email]"
|
||||
```
|
||||
|
||||
///
|
||||
@@ -258,7 +258,7 @@ FastAPI 在内部配合 Pydantic 做了多项处理,确保不会把类继承
|
||||
* `response_model_exclude_defaults=True`
|
||||
* `response_model_exclude_none=True`
|
||||
|
||||
详见 [Pydantic 文档](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict)中对 `exclude_defaults` 和 `exclude_none` 的说明。
|
||||
详见 [Pydantic 文档](https://pydantic.dev/docs/validation/latest/concepts/serialization/#excluding-and-including-fields-based-on-their-value)中对 `exclude_defaults` 和 `exclude_none` 的说明。
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
这些额外信息会原样添加到该模型输出的 **JSON Schema** 中,并会在 API 文档中使用。
|
||||
|
||||
你可以使用属性 `model_config`,它接收一个 `dict`,详见 [Pydantic 文档:配置](https://docs.pydantic.dev/latest/api/config/)。
|
||||
你可以使用属性 `model_config`,它接收一个 `dict`,详见 [Pydantic 文档:配置](https://pydantic.dev/docs/validation/latest/api/pydantic/config/)。
|
||||
|
||||
你可以设置 `"json_schema_extra"`,其值为一个 `dict`,包含你希望出现在生成 JSON Schema 中的任意附加数据,包括 `examples`。
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# 安全 - 第一步 { #security-first-steps }
|
||||
|
||||
|
||||
假设你的**后端** API 位于某个域名下。
|
||||
|
||||
而**前端**在另一个域名,或同一域名的不同路径(或在移动应用中)。
|
||||
@@ -27,14 +26,14 @@
|
||||
|
||||
/// note | 注意
|
||||
|
||||
当你使用命令 `pip install "fastapi[standard]"` 安装 **FastAPI** 时,[`python-multipart`](https://github.com/Kludex/python-multipart) 包会自动安装。
|
||||
当你运行 `uv add "fastapi[standard]"` 命令时,[`python-multipart`](https://github.com/Kludex/python-multipart) 包会随 **FastAPI** 自动安装。
|
||||
|
||||
但是,如果你使用 `pip install fastapi`,默认不会包含 `python-multipart` 包。
|
||||
但是,如果你使用 `uv add fastapi` 命令,默认不会包含 `python-multipart` 包。
|
||||
|
||||
如需手动安装,请先创建[虚拟环境](../../virtual-environments.md)、激活它,然后执行:
|
||||
如需手动安装,请把它添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
这是因为 **OAuth2** 使用“表单数据”来发送 `username` 和 `password`。
|
||||
@@ -46,7 +45,7 @@ $ pip install python-multipart
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -145,7 +144,7 @@ OAuth2 的设计目标是让后端或 API 与负责用户认证的服务器解
|
||||
|
||||
///
|
||||
|
||||
这个参数不会创建该端点/*路径操作*,而是声明客户端应使用 `/token` 这个 URL 来获取令牌。这些信息会用于 OpenAPI,进而用于交互式 API 文档系统。
|
||||
这个参数不会创建该端点 / *路径操作*,而是声明客户端应使用 `/token` 这个 URL 来获取令牌。这些信息会用于 OpenAPI,进而用于交互式 API 文档系统。
|
||||
|
||||
我们很快也会创建对应的实际路径操作。
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
|
||||
|
||||
我们需要安装 `PyJWT`,以便在 Python 中生成和校验 JWT 令牌。
|
||||
|
||||
请确保创建并激活一个[虚拟环境](../../virtual-environments.md),然后安装 `pyjwt`:
|
||||
将 `pyjwt` 添加到你的项目:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pyjwt
|
||||
$ uv add pyjwt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -72,12 +72,12 @@ pwdlib 是一个用于处理密码哈希的优秀 Python 包。
|
||||
|
||||
推荐的算法是 “Argon2”。
|
||||
|
||||
请确保创建并激活一个[虚拟环境](../../virtual-environments.md),然后安装带 Argon2 的 pwdlib:
|
||||
将带 Argon2 的 `pwdlib` 添加到你的项目:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "pwdlib[argon2]"
|
||||
$ uv add "pwdlib[argon2]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
|
||||
## 安装 `SQLModel` { #install-sqlmodel }
|
||||
|
||||
首先,确保你创建并激活了[虚拟环境](../virtual-environments.md),然后安装 `sqlmodel`:
|
||||
将 `sqlmodel` 添加到你的项目中:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install sqlmodel
|
||||
$ uv add sqlmodel
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ SQLModel 将会拥有封装 Alembic 的迁移工具,但目前你可以直接
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -337,7 +337,7 @@ $ fastapi dev
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -45,4 +45,4 @@
|
||||
|
||||
## 更多信息 { #more-info }
|
||||
|
||||
更多细节和选项请查阅 [Starlette 的静态文件文档](https://www.starlette.dev/staticfiles/)。
|
||||
更多细节和选项请查阅 [Starlette 的静态文件文档](https://starlette.dev/staticfiles/)。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 测试 { #testing }
|
||||
|
||||
感谢 [Starlette](https://www.starlette.dev/testclient/),测试**FastAPI** 应用轻松又愉快。
|
||||
感谢 [Starlette](https://starlette.dev/testclient/),测试**FastAPI** 应用轻松又愉快。
|
||||
|
||||
它基于 [HTTPX](https://www.python-httpx.org),而HTTPX又是基于Requests设计的,所以很相似且易懂。
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
要使用 `TestClient`,先要安装 [`httpx`](https://www.python-httpx.org)。
|
||||
|
||||
确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
|
||||
将它添加到你的项目中:
|
||||
|
||||
```console
|
||||
$ pip install httpx
|
||||
$ uv add httpx
|
||||
```
|
||||
|
||||
///
|
||||
@@ -156,12 +156,12 @@ $ pip install httpx
|
||||
|
||||
之后,你只需要安装 `pytest`。
|
||||
|
||||
确保你创建并激活一个[虚拟环境](../virtual-environments.md),然后再安装,例如:
|
||||
将它添加到你的项目中:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pytest
|
||||
$ uv add pytest
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -175,7 +175,7 @@ $ pip install pytest
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pytest
|
||||
$ uv run pytest
|
||||
|
||||
================ test session starts ================
|
||||
platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
|
||||
|
||||
@@ -1,864 +1,35 @@
|
||||
# 虚拟环境 { #virtual-environments }
|
||||
|
||||
当你在 Python 工程中工作时,你可能会有必要用到一个**虚拟环境**(或类似的机制)来隔离你为每个工程安装的包。
|
||||
当你在 Python 工程中工作时,你应该使用**虚拟环境**来隔离为每个工程安装的包。
|
||||
|
||||
/// note | 注意
|
||||
对于 FastAPI 工程,我推荐使用 [uv](https://docs.astral.sh/uv/) 来管理工程、依赖项和虚拟环境。
|
||||
|
||||
如果你已经了解虚拟环境,知道如何创建和使用它们,你可以考虑跳过这一部分。🤓
|
||||
## 创建工程 { #create-a-project }
|
||||
|
||||
///
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
**虚拟环境**和**环境变量**是不同的。
|
||||
|
||||
**环境变量**是系统中的一个变量,可以被程序使用。
|
||||
|
||||
**虚拟环境**是一个包含一些文件的目录。
|
||||
|
||||
///
|
||||
|
||||
/// note | 注意
|
||||
|
||||
这个页面将教你如何使用**虚拟环境**以及了解它们的工作原理。
|
||||
|
||||
如果你计划使用一个**可以为你管理一切的工具**(包括安装 Python),试试 [uv](https://github.com/astral-sh/uv)。
|
||||
|
||||
///
|
||||
|
||||
## 创建一个工程 { #create-a-project }
|
||||
|
||||
首先,为你的工程创建一个目录。
|
||||
|
||||
我通常会在我的主目录下创建一个名为 `code` 的目录。
|
||||
|
||||
在这个目录下,我再为每个工程创建一个目录。
|
||||
使用[官方安装指南](https://docs.astral.sh/uv/getting-started/installation/)安装 `uv`,然后创建一个工程:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 进入主目录
|
||||
$ cd
|
||||
// 创建一个用于存放所有代码工程的目录
|
||||
$ mkdir code
|
||||
// 进入 code 目录
|
||||
$ cd code
|
||||
// 创建一个用于存放这个工程的目录
|
||||
$ mkdir awesome-project
|
||||
// 进入这个工程的目录
|
||||
$ uv init awesome-project --bare
|
||||
$ cd awesome-project
|
||||
$ uv add "fastapi[standard]"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 创建一个虚拟环境 { #create-a-virtual-environment }
|
||||
`uv` 会自动为工程创建虚拟环境。你不需要自己创建或激活虚拟环境。
|
||||
|
||||
在开始一个 Python 工程的**第一时间**,**<dfn title="还有其他做法,此处仅作一个简单的指南">在你的工程内部</dfn>**创建一个虚拟环境。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
你只需要 **在每个工程中操作一次**,而不是每次工作时都操作。
|
||||
|
||||
///
|
||||
|
||||
//// tab | `venv`
|
||||
|
||||
你可以使用 Python 自带的 `venv` 模块来创建一个虚拟环境。
|
||||
使用 `uv run` 在工程环境中运行命令,例如:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m venv .venv
|
||||
$ uv run fastapi dev
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | 上述命令的含义
|
||||
## 了解更多 { #learn-more }
|
||||
|
||||
* `python`: 使用名为 `python` 的程序
|
||||
* `-m`: 以脚本的方式调用一个模块,我们将告诉它接下来使用哪个模块
|
||||
* `venv`: 使用名为 `venv` 的模块,这个模块通常随 Python 一起安装
|
||||
* `.venv`: 在新目录 `.venv` 中创建虚拟环境
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你安装了 [`uv`](https://github.com/astral-sh/uv),你也可以使用它来创建一个虚拟环境。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv venv
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
默认情况下,`uv` 会在一个名为 `.venv` 的目录中创建一个虚拟环境。
|
||||
|
||||
但你可以通过传递一个额外的参数来自定义它,指定目录的名称。
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
这个命令会在一个名为 `.venv` 的目录中创建一个新的虚拟环境。
|
||||
|
||||
/// details | `.venv`,或是其他名称
|
||||
|
||||
你可以在不同的目录下创建虚拟环境,但通常我们会把它命名为 `.venv`。
|
||||
|
||||
///
|
||||
|
||||
## 激活虚拟环境 { #activate-the-virtual-environment }
|
||||
|
||||
激活新的虚拟环境来确保你运行的任何 Python 命令或安装的包都能使用到它。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
**每次**开始一个 **新的终端会话** 来工作在这个工程时,你都需要执行这个操作。
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
或者,如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
每次你在这个环境中安装一个 **新的包** 时,都需要 **重新激活** 这个环境。
|
||||
|
||||
这么做确保了当你使用一个由这个包安装的 **终端(<abbr title="command line interface - 命令行界面">CLI</abbr>)程序** 时,你使用的是你的虚拟环境中的程序,而不是全局安装、可能版本不同的程序。
|
||||
|
||||
///
|
||||
|
||||
## 检查虚拟环境是否激活 { #check-the-virtual-environment-is-active }
|
||||
|
||||
检查虚拟环境是否激活 (前面的命令是否生效)。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
这是 **可选的**,但这是一个很好的方法,可以 **检查** 一切是否按预期工作,以及你是否使用了你打算使用的虚拟环境。
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv/bin/python` 中的 `python` 二进制文件,那么它就生效了。🎉
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
如果它显示了在你工程 (在这个例子中是 `awesome-project`) 的 `.venv\Scripts\python` 中的 `python` 二进制文件,那么它就生效了。🎉
|
||||
|
||||
////
|
||||
|
||||
## 升级 `pip` { #upgrade-pip }
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 来安装内容,而不是 `pip`,那么你就不需要升级 `pip`。😎
|
||||
|
||||
///
|
||||
|
||||
如果你使用 `pip` 来安装包(它是 Python 的默认组件),你应该将它 **升级** 到最新版本。
|
||||
|
||||
在安装包时出现的许多奇怪的错误都可以通过先升级 `pip` 来解决。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
通常你只需要在创建虚拟环境后 **执行一次** 这个操作。
|
||||
|
||||
///
|
||||
|
||||
确保虚拟环境是激活的 (使用上面的命令),然后运行:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m pip install --upgrade pip
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
有时在尝试升级 pip 时,你可能会遇到 **`No module named pip`** 错误。
|
||||
|
||||
如果发生这种情况,使用下面的命令来安装并升级 pip:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m ensurepip --upgrade
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
该命令会在尚未安装 pip 时进行安装,并确保安装的 pip 版本不早于 `ensurepip` 提供的版本。
|
||||
|
||||
///
|
||||
|
||||
## 添加 `.gitignore` { #add-gitignore }
|
||||
|
||||
如果你使用 **Git** (这是你应该使用的),添加一个 `.gitignore` 文件来排除你的 `.venv` 中的所有内容。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 来创建虚拟环境,它会自动为你完成这个操作,你可以跳过这一步。😎
|
||||
|
||||
///
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
通常你只需要在创建虚拟环境后 **执行一次** 这个操作。
|
||||
|
||||
///
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ echo "*" > .venv/.gitignore
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | 上述命令的含义
|
||||
|
||||
* `echo "*"`: 将在终端中 "打印" 文本 `*`(接下来的部分会对这个操作进行一些修改)
|
||||
* `>`: 使左边的命令打印到终端的任何内容实际上都不会被打印,而是会被写入到右边的文件中
|
||||
* `.gitignore`: 被写入文本的文件的名称
|
||||
|
||||
而 `*` 对于 Git 来说意味着 "所有内容"。所以,它会忽略 `.venv` 目录中的所有内容。
|
||||
|
||||
该命令会创建一个名为 `.gitignore` 的文件,内容如下:
|
||||
|
||||
```gitignore
|
||||
*
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## 安装软件包 { #install-packages }
|
||||
|
||||
在激活虚拟环境后,你可以在其中安装软件包。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
当你需要安装或升级软件包时,执行本操作**一次**;
|
||||
|
||||
如果你需要再升级版本或添加新软件包,你可以**再次执行此操作**。
|
||||
|
||||
///
|
||||
|
||||
### 直接安装包 { #install-packages-directly }
|
||||
|
||||
如果你急于安装,不想使用文件来声明工程的软件包依赖,你可以直接安装它们。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
将程序所需的软件包及其版本放在文件中(例如 `requirements.txt` 或 `pyproject.toml`)是个好(并且非常好)的主意。
|
||||
|
||||
///
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
### 从 `requirements.txt` 安装 { #install-from-requirements-txt }
|
||||
|
||||
如果你有一个 `requirements.txt` 文件,你可以使用它来安装其中的软件包。
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// details | 关于 `requirements.txt`
|
||||
|
||||
一个包含一些软件包的 `requirements.txt` 文件看起来应该是这样的:
|
||||
|
||||
```requirements.txt
|
||||
fastapi[standard]==0.113.0
|
||||
pydantic==2.8.0
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## 运行程序 { #run-your-program }
|
||||
|
||||
在你激活虚拟环境后,你可以运行你的程序,它将使用虚拟环境中的 Python 和你在其中安装的软件包。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py
|
||||
|
||||
Hello World
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 配置编辑器 { #configure-your-editor }
|
||||
|
||||
你可能会用到编辑器,请确保配置它使用与你创建的相同的虚拟环境(它可能会自动检测到),以便你可以获得自动补全和内联错误提示。
|
||||
|
||||
例如:
|
||||
|
||||
* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
|
||||
* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
通常你只需要在创建虚拟环境时执行此操作**一次**。
|
||||
|
||||
///
|
||||
|
||||
## 退出虚拟环境 { #deactivate-the-virtual-environment }
|
||||
|
||||
当你完成工作后,你可以**退出**虚拟环境。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deactivate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
这样,当你运行 `python` 时,它不会尝试从那个虚拟环境及其已安装的软件包中运行。
|
||||
|
||||
## 开始工作 { #ready-to-work }
|
||||
|
||||
现在你已经准备好开始你的工作了。
|
||||
|
||||
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
你想要理解上面的所有内容吗?
|
||||
|
||||
继续阅读。👇🤓
|
||||
|
||||
///
|
||||
|
||||
## 为什么要使用虚拟环境 { #why-virtual-environments }
|
||||
|
||||
你需要安装 [Python](https://www.python.org/) 才能使用 FastAPI。
|
||||
|
||||
之后,你需要**安装** FastAPI 和你想要使用的任何其他**软件包**。
|
||||
|
||||
要安装软件包,你通常会使用随 Python 一起提供的 `pip` 命令(或类似的替代方案)。
|
||||
|
||||
然而,如果你直接使用 `pip`,软件包将被安装在你的**全局 Python 环境**中(即 Python 的全局安装)。
|
||||
|
||||
### 存在的问题 { #the-problem }
|
||||
|
||||
那么,在全局 Python 环境中安装软件包有什么问题呢?
|
||||
|
||||
有些时候,你可能会编写许多不同的程序,这些程序依赖于**不同的软件包**;你所做的一些工程也会依赖于**同一软件包的不同版本**。😱
|
||||
|
||||
例如,你可能会创建一个名为 `philosophers-stone` 的工程,这个程序依赖于另一个名为 **`harry` 的软件包,使用版本 `1`**。因此,你需要安装 `harry`。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
stone(philosophers-stone) -->|需要| harry-1[harry v1]
|
||||
```
|
||||
|
||||
然而在此之后,你又创建了另一个名为 `prisoner-of-azkaban` 的工程,这个工程也依赖于 `harry`,但是这个工程需要 **`harry` 版本 `3`**。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
azkaban(prisoner-of-azkaban) --> |需要| harry-3[harry v3]
|
||||
```
|
||||
|
||||
那么现在的问题是,如果你将软件包安装在全局环境中而不是在本地**虚拟环境**中,你将不得不面临选择安装哪个版本的 `harry` 的问题。
|
||||
|
||||
如果你想运行 `philosophers-stone`,你需要首先安装 `harry` 版本 `1`,例如:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==1"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
然后你将在全局 Python 环境中安装 `harry` 版本 `1`。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[全局环境]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
subgraph stone-project[工程 philosophers-stone]
|
||||
stone(philosophers-stone) -->|需要| harry-1
|
||||
end
|
||||
```
|
||||
|
||||
但是如果你想运行 `prisoner-of-azkaban`,你需要卸载 `harry` 版本 `1` 并安装 `harry` 版本 `3`(或者说,只要你安装版本 `3` ,版本 `1` 就会自动卸载)。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==3"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
于是,你在你的全局 Python 环境中安装了 `harry` 版本 `3`。
|
||||
|
||||
如果你再次尝试运行 `philosophers-stone`,有可能它**无法正常工作**,因为它需要 `harry` 版本 `1`。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[全局环境]
|
||||
harry-1[<strike>harry v1</strike>]
|
||||
style harry-1 fill:#ccc,stroke-dasharray: 5 5
|
||||
harry-3[harry v3]
|
||||
end
|
||||
subgraph stone-project[工程 philosophers-stone]
|
||||
stone(philosophers-stone) -.-x|⛔️| harry-1
|
||||
end
|
||||
subgraph azkaban-project[工程 prisoner-of-azkaban]
|
||||
azkaban(prisoner-of-azkaban) --> |需要| harry-3
|
||||
end
|
||||
```
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
Python 包在推出**新版本**时通常会尽量**避免破坏性更改**,但最好还是要小心,要想清楚再安装新版本,而且在运行测试以确保一切能正常工作时再安装。
|
||||
|
||||
///
|
||||
|
||||
现在,想象一下,如果有**许多**其他**软件包**,它们都是你的**工程所依赖的**。这是非常难以管理的。你可能会发现,有些工程使用了一些**不兼容的软件包版本**,而不知道为什么某些东西无法正常工作。
|
||||
|
||||
此外,取决于你的操作系统(例如 Linux、Windows、macOS),它可能已经预先安装了 Python。在这种情况下,它可能已经预先安装了一些软件包,这些软件包的特定版本是**系统所需的**。如果你在全局 Python 环境中安装软件包,你可能会**破坏**一些随操作系统一起安装的程序。
|
||||
|
||||
## 软件包安装在哪里 { #where-are-packages-installed }
|
||||
|
||||
当你安装 Python 时,它会在你的计算机上创建一些目录,并在这些目录中放一些文件。
|
||||
|
||||
其中一些目录负责存放你安装的所有软件包。
|
||||
|
||||
当你运行:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// 先别去运行这个命令,这只是一个示例 🤓
|
||||
$ pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
这将会从 [PyPI](https://pypi.org/project/fastapi/) 下载一个压缩文件,其中包含 FastAPI 代码。
|
||||
|
||||
它还会**下载** FastAPI 依赖的其他软件包的文件。
|
||||
|
||||
然后它会**解压**所有这些文件,并将它们放在你的计算机上的一个目录中。
|
||||
|
||||
默认情况下,它会将下载并解压的这些文件放在随 Python 安装的目录中,这就是**全局环境**。
|
||||
|
||||
## 什么是虚拟环境 { #what-are-virtual-environments }
|
||||
|
||||
解决软件包都安装在全局环境中的问题的方法是为你所做的每个工程使用一个**虚拟环境**。
|
||||
|
||||
虚拟环境是一个**目录**,与全局环境非常相似,你可以在其中专为某个工程安装软件包。
|
||||
|
||||
这样,每个工程都会有自己的虚拟环境(`.venv` 目录),其中包含自己的软件包。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph stone-project[工程 philosophers-stone]
|
||||
stone(philosophers-stone) --->|需要| harry-1
|
||||
subgraph venv1[.venv]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
end
|
||||
subgraph azkaban-project[工程 prisoner-of-azkaban]
|
||||
azkaban(prisoner-of-azkaban) --->|需要| harry-3
|
||||
subgraph venv2[.venv]
|
||||
harry-3[harry v3]
|
||||
end
|
||||
end
|
||||
stone-project ~~~ azkaban-project
|
||||
```
|
||||
|
||||
## 激活虚拟环境意味着什么 { #what-does-activating-a-virtual-environment-mean }
|
||||
|
||||
当你激活了一个虚拟环境,例如:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
或者如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
这个命令会创建或修改一些[环境变量](environment-variables.md),这些环境变量将在接下来的命令中可用。
|
||||
|
||||
其中之一是 `PATH` 变量。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
你可以在 [环境变量](environment-variables.md#path-environment-variable) 部分了解更多关于 `PATH` 环境变量的内容。
|
||||
|
||||
///
|
||||
|
||||
激活虚拟环境会将其路径 `.venv/bin`(在 Linux 和 macOS 上)或 `.venv\Scripts`(在 Windows 上)添加到 `PATH` 环境变量中。
|
||||
|
||||
假设在激活环境之前,`PATH` 变量看起来像这样:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
这意味着系统会在以下目录中查找程序:
|
||||
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Windows\System32
|
||||
```
|
||||
|
||||
这意味着系统会在以下目录中查找程序:
|
||||
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
激活虚拟环境后,`PATH` 变量会变成这样:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
这意味着系统现在会首先在以下目录中查找程序:
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin
|
||||
```
|
||||
|
||||
然后再在其他目录中查找。
|
||||
|
||||
因此,当你在终端中输入 `python` 时,系统会在以下目录中找到 Python 程序:
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
并使用这个。
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
|
||||
```
|
||||
|
||||
这意味着系统现在会首先在以下目录中查找程序:
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts
|
||||
```
|
||||
|
||||
然后再在其他目录中查找。
|
||||
|
||||
因此,当你在终端中输入 `python` 时,系统会在以下目录中找到 Python 程序:
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
并使用这个。
|
||||
|
||||
////
|
||||
|
||||
一个重要的细节是,虚拟环境路径会被放在 `PATH` 变量的**开头**。系统会在找到任何其他可用的 Python **之前**找到它。这样,当你运行 `python` 时,它会使用**虚拟环境中**的 Python,而不是任何其他 `python`(例如,全局环境中的 `python`)。
|
||||
|
||||
激活虚拟环境还会改变其他一些东西,但这是它所做的最重要的事情之一。
|
||||
|
||||
## 检查虚拟环境 { #checking-a-virtual-environment }
|
||||
|
||||
当你检查虚拟环境是否激活时,例如:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
这意味着将使用的 `python` 程序是**在虚拟环境中**的那个。
|
||||
|
||||
在 Linux 和 macOS 中使用 `which`,在 Windows PowerShell 中使用 `Get-Command`。
|
||||
|
||||
这个命令的工作方式是,它会在 `PATH` 环境变量中查找,按顺序**逐个路径**查找名为 `python` 的程序。一旦找到,它会**显示该程序的路径**。
|
||||
|
||||
最重要的部分是,当你调用 `python` 时,将执行的就是这个确切的 "`python`"。
|
||||
|
||||
因此,你可以确认你是否在正确的虚拟环境中。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
激活一个虚拟环境,获取一个 Python,然后**转到另一个工程**是一件很容易的事情;
|
||||
|
||||
但如果第二个工程**无法工作**,那是因为你使用了来自另一个工程的虚拟环境的、**不正确的 Python**。
|
||||
|
||||
因此,会检查正在使用的 `python` 是很有用的。🤓
|
||||
|
||||
///
|
||||
|
||||
## 为什么要停用虚拟环境 { #why-deactivate-a-virtual-environment }
|
||||
|
||||
例如,你可能正在一个工程 `philosophers-stone` 上工作,**激活了该虚拟环境**,安装了包并使用了该环境,
|
||||
|
||||
然后你想要在**另一个工程** `prisoner-of-azkaban` 上工作,
|
||||
|
||||
你进入那个工程:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
如果你不去停用 `philosophers-stone` 的虚拟环境,当你在终端中运行 `python` 时,它会尝试使用 `philosophers-stone` 中的 Python。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
$ python main.py
|
||||
|
||||
// 导入 sirius 报错,它没有安装 😱
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1, in <module>
|
||||
import sirius
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
但是如果你停用虚拟环境并激活 `prisoner-of-azkaban` 的新虚拟环境,那么当你运行 `python` 时,它会使用 `prisoner-of-azkaban` 中的虚拟环境中的 Python。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
// 你不需要在旧目录中操作停用,你可以在任何地方操作停用,甚至在转到另一个工程之后 😎
|
||||
$ deactivate
|
||||
|
||||
// 激活 prisoner-of-azkaban/.venv 中的虚拟环境 🚀
|
||||
$ source .venv/bin/activate
|
||||
|
||||
// 现在当你运行 python 时,它会在这个虚拟环境中找到安装的 sirius 包 ✨
|
||||
$ python main.py
|
||||
|
||||
I solemnly swear 🐺
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 替代方案 { #alternatives }
|
||||
|
||||
这是一个简单的指南,可以帮助你入门并教会你如何理解一切**底层**的东西。
|
||||
|
||||
有许多**替代方案**来管理虚拟环境、包依赖(requirements)、工程。
|
||||
|
||||
一旦你准备好并想要使用一个工具来**管理整个工程**、包依赖、虚拟环境等,建议你尝试 [uv](https://github.com/astral-sh/uv)。
|
||||
|
||||
`uv` 可以做很多事情,它可以:
|
||||
|
||||
* 为你**安装 Python**,包括不同的版本
|
||||
* 为你的工程管理**虚拟环境**
|
||||
* 安装**软件包**
|
||||
* 为你的工程管理软件包的**依赖和版本**
|
||||
* 确保你有一个**确切**的软件包和版本集合来安装,包括它们的依赖项,这样你就可以确保在生产中运行你的工程与在开发时在你的计算机上运行的工程完全相同,这被称为**锁定**
|
||||
* 还有很多其他功能
|
||||
|
||||
## 结论 { #conclusion }
|
||||
|
||||
如果你读过并理解了所有这些,现在**你对虚拟环境的了解比很多开发者都要多**。🤓
|
||||
|
||||
在未来当你调试看起来复杂的东西时,了解这些细节很可能会有用,你会知道**它是如何在底层工作的**。😎
|
||||
阅读[虚拟环境指南](https://tiangolo.com/guides/virtual-environments/)以了解虚拟环境在底层是如何工作的,包括激活以及替代的 `python -m venv` 和 `pip` 工作流。
|
||||
Reference in new issue
Block a user