Sync fastapi docs from 50113da1 on 2026-09-11

This commit is contained in:
The Librarian
2026-09-11 04:00:08 +00:00
parent 632909b5f6
commit 818066b271
739 changed files with 4974 additions and 17395 deletions
@@ -16,7 +16,7 @@
## Дополнительный ответ с `model` { #additional-response-with-model }
Вы можете передать вашим декораторам операции пути параметр `responses`.
Вы можете передать вашим *декораторам операций пути* параметр `responses`.
Он принимает `dict`: ключи — это статус-коды для каждого ответа (например, `200`), а значения — другие `dict` с информацией для каждого из них.
@@ -49,7 +49,7 @@
///
Сгенерированные в OpenAPI ответы для этой операции пути будут такими:
Сгенерированные в OpenAPI ответы для этой *операции пути* будут такими:
```JSON hl_lines="3-12"
{
@@ -173,7 +173,7 @@
Вы можете использовать этот же параметр `responses`, чтобы добавить разные типы содержимого для того же основного ответа.
Например, вы можете добавить дополнительный тип содержимого `image/png`, объявив, что ваша операция пути может возвращать JSON‑объект (с типом содержимого `application/json`) или PNG‑изображение:
Например, вы можете добавить дополнительный тип содержимого `image/png`, объявив, что ваша *операция пути* может возвращать JSON‑объект (с типом содержимого `application/json`) или PNG‑изображение:
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
@@ -211,7 +211,7 @@
## Комбинирование предопределённых и пользовательских ответов { #combine-predefined-responses-and-custom-ones }
Возможно, вы хотите иметь некоторые предопределённые ответы, применимые ко многим операциям пути, но при этом комбинировать их с пользовательскими ответами, необходимыми для каждой конкретной операции пути.
Возможно, вы хотите иметь некоторые предопределённые ответы, применимые ко многим *операциям пути*, но при этом комбинировать их с пользовательскими ответами, необходимыми для каждой конкретной *операции пути*.
В таких случаях вы можете использовать приём Python «распаковки» `dict` с помощью `**dict_to_unpack`:
@@ -233,7 +233,7 @@ new_dict = {**old_dict, "new key": "new value"}
}
```
Вы можете использовать этот приём, чтобы переиспользовать некоторые предопределённые ответы в ваших операциях пути и комбинировать их с дополнительными пользовательскими.
Вы можете использовать этот приём, чтобы переиспользовать некоторые предопределённые ответы в ваших *операциях пути* и комбинировать их с дополнительными пользовательскими.
Например:
@@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
Чтобы увидеть, что именно можно включать в ответы, посмотрите эти разделы спецификации OpenAPI:
* [Объект Responses OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), он включает `Response Object`.
* [Объект Response OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), вы можете включить всё из этого объекта напрямую в каждый ответ внутри вашего параметра `responses`. Включая `description`, `headers`, `content` (внутри него вы объявляете разные типы содержимого и JSON‑схемы) и `links`.
* [Объект Responses OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object), он включает `Response Object`.
* [Объект Response OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#response-object), вы можете включить всё из этого объекта напрямую в каждый ответ внутри вашего параметра `responses`. Включая `description`, `headers`, `content` (внутри него вы объявляете разные типы содержимого и JSON‑схемы) и `links`.
+6 -6
View File
@@ -1,8 +1,8 @@
# Асинхронное тестирование { #async-tests }
Вы уже видели как тестировать **FastAPI** приложение, используя имеющийся класс `TestClient`. К этому моменту вы видели только как писать тесты в синхронном стиле без использования `async` функций.
Вы уже видели, как тестировать **FastAPI** приложение, используя имеющийся класс `TestClient`. К этому моменту вы видели только, как писать тесты в синхронном стиле без использования `async` функций.
Возможность использования асинхронных функций в ваших тестах может быть полезнa, когда, например, вы асинхронно обращаетесь к вашей базе данных. Представьте, что вы хотите отправить запросы в ваше FastAPI приложение, а затем при помощи асинхронной библиотеки для работы с базой данных удостовериться, что ваш бекэнд корректно записал данные в базу данных.
Возможность использования асинхронных функций в ваших тестах может быть полезна, когда, например, вы асинхронно обращаетесь к вашей базе данных. Представьте, что вы хотите отправить запросы в ваше FastAPI приложение, а затем при помощи асинхронной библиотеки для работы с базой данных удостовериться, что ваш бекэнд корректно записал данные в базу данных.
Давайте рассмотрим, как мы можем это реализовать.
@@ -45,7 +45,7 @@
<div class="termy">
```console
$ pytest
$ uv run pytest
---> 100%
```
@@ -78,7 +78,7 @@ response = client.get('/')
/// tip | Подсказка
Обратите внимание, что мы используем async/await с `AsyncClient` - запрос асинхронный.
Обратите внимание, что мы используем async/await с новым `AsyncClient` - запрос асинхронный.
///
@@ -90,10 +90,10 @@ response = client.get('/')
## Вызов других асинхронных функций { #other-asynchronous-function-calls }
Теперь тестовая функция стала асинхронной, поэтому внутри нее вы можете вызывать также и другие `async` функции, не связанные с отправлением запросов в ваше FastAPI приложение. Как если бы вы вызывали их в любом другом месте вашего кода.
Теперь тестовая функция стала асинхронной, поэтому внутри нее вы можете вызывать (и использовать `await` для) другие `async` функции, помимо отправки запросов в ваше FastAPI приложение в ваших тестах. Как если бы вы вызывали их в любом другом месте вашего кода.
/// tip | Подсказка
Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании [MongoDB's MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), то не забывайте создавать экземпляры объектов, которым нужен цикл событий (event loop), только внутри асинхронных функций, например, в `@app.on_event("startup")` callback.
Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании [MongoDB's MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), то не забывайте создавать экземпляры объектов, которым нужен цикл событий, только внутри асинхронных функций, например, в `@app.on_event("startup")` callback.
///
+7 -7
View File
@@ -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)
```
@@ -80,7 +80,7 @@ sequenceDiagram
Proxy->>Server: HTTP-запрос<br/>X-Forwarded-For: [client IP]<br/>X-Forwarded-Proto: https<br/>X-Forwarded-Host: mysuperapp.com<br/>Path: /items
Note over Server: Server интерпретирует HTTP-заголовки<br/>(если --forwarded-allow-ips установлен)
Note over Server: Сервер интерпретирует HTTP-заголовки<br/>(если --forwarded-allow-ips установлен)
Server->>Proxy: HTTP-ответ<br/>с верными HTTPS URLs
@@ -170,7 +170,7 @@ IP `0.0.0.0` обычно означает, что программа слуша
<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 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<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 ожидает, что прокси обратится к нему по
Вы можете легко поэкспериментировать локально с функцией удаления префикса пути, используя [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)
```
@@ -358,7 +358,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
но уже по URL с префиксом, который добавляет прокси: `/api/v1`.
Разумеется, задумывается, что все будут обращаться к приложению через прокси, поэтому вариант с префиксом пути `/api/v1` является «правильным».
Разумеется, идея здесь в том, что все будут обращаться к приложению через прокси, поэтому вариант с префиксом пути `/api/v1` является «правильным».
А вариант без префикса (`http://127.0.0.1:8000/app`), выдаваемый напрямую Uvicorn, предназначен исключительно для того, чтобы прокси (Traefik) мог к нему обращаться.
+2 -2
View File
@@ -6,7 +6,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
{* ../../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, чтобы конвертировать стандартные dataclasses в собственный вариант dataclasses от Pydantic.
@@ -88,7 +88,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
Вы также можете комбинировать `dataclasses` с другими Pydantic-моделями, наследоваться от них, включать их в свои модели и т.д.
Чтобы узнать больше, посмотрите [документацию Pydantic о dataclasses](https://docs.pydantic.dev/latest/concepts/dataclasses/).
Чтобы узнать больше, посмотрите [документацию Pydantic о dataclasses](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/).
## Версия { #version }
+1 -1
View File
@@ -154,7 +154,7 @@ async with lifespan(app):
/// note | Примечание
Вы можете прочитать больше про обработчики `lifespan` в Starlette в [документации Starlette по Lifespan](https://www.starlette.dev/lifespan/).
Вы можете прочитать больше про обработчики `lifespan` в Starlette в [документации Starlette по Lifespan](https://starlette.dev/lifespan/).
Включая то, как работать с состоянием lifespan, которое можно использовать в других частях вашего кода.
+1 -1
View File
@@ -12,7 +12,7 @@
Для **TypeScript‑клиентов** [Hey API](https://heyapi.dev/) — специализированное решение, обеспечивающее оптимальный опыт для экосистемы TypeScript.
Больше генераторов SDK можно найти на [OpenAPI.Tools](https://openapi.tools/#sdk).
Больше генераторов SDK можно найти на [OpenAPI.Tools](https://openapi.tools/categories/sdk-generators).
/// tip | Совет
+15 -15
View File
@@ -8,7 +8,7 @@
## Добавление ASGI middleware { #adding-asgi-middlewares }
Так как **FastAPI** основан на Starlette и реализует спецификацию <abbr title="Asynchronous Server Gateway Interface Асинхронный шлюзовой интерфейс сервера">ASGI</abbr>, вы можете использовать любое ASGI middleware.
Так как **FastAPI** основан на Starlette и реализует спецификацию <abbr title="Asynchronous Server Gateway Interface - Асинхронный шлюзовой интерфейс сервера">ASGI</abbr>, вы можете использовать любое ASGI middleware.
Middleware не обязательно должно быть сделано специально для FastAPI или Starlette — достаточно, чтобы оно соответствовало спецификации ASGI.
@@ -24,7 +24,7 @@ app = SomeASGIApp()
new_app = UnicornMiddleware(app, some_config="rainbow")
```
Но FastAPI (точнее, Starlette) предоставляет более простой способ, который гарантирует корректную обработку внутренних ошибок сервера и корректную работу пользовательских обработчиков исключений.
Но FastAPI (точнее, Starlette) предоставляет более простой способ, который гарантирует, что внутренние middleware обрабатывают ошибки сервера, а пользовательские обработчики исключений работают корректно.
Для этого используйте `app.add_middleware()` (как в примере с CORS).
@@ -53,37 +53,37 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
Гарантирует, что все входящие запросы должны использовать либо `https`, либо `wss`.
Гарантирует, что все входящие HTTP-запросы должны использовать либо `https`, либо `wss`.
Любой входящий запрос по `http` или `ws` будет перенаправлен на безопасную схему.
Любой входящий HTTP-запрос по `http` или `ws` будет перенаправлен на безопасную схему.
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
Гарантирует, что во всех входящих запросах корректно установлен `Host`заголовок, чтобы защититься от атак на HTTPзаголовок Host.
Гарантирует, что во всех входящих HTTP-запросах корректно установлен `Host` HTTP-заголовок, чтобы защититься от атак на HTTP-заголовок Host.
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
Поддерживаются следующие аргументы:
- `allowed_hosts` список доменных имён, которые следует разрешить как имена хостов. Подстановки вида `*.example.com` поддерживаются для сопоставления поддоменов. Чтобы разрешить любой хост, используйте либо `allowed_hosts=["*"]`, либо не добавляйте это middleware.
- `www_redirect` если установлено в True, запросы к не‑www версиям разрешённых хостов будут перенаправляться на их www‑аналоги. По умолчанию — `True`.
* `allowed_hosts` - список доменных имён, которые следует разрешить как имена хостов. Подстановки вида `*.example.com` поддерживаются для сопоставления поддоменов. Чтобы разрешить любой хост, используйте либо `allowed_hosts=["*"]`, либо не добавляйте это middleware.
* `www_redirect` - если установлено в True, запросы к не‑www версиям разрешённых хостов будут перенаправляться на их www‑аналоги. По умолчанию — `True`.
Если входящий запрос не проходит валидацию, будет отправлен ответ `400`.
Если входящий HTTP-запрос не проходит валидацию, будет отправлен HTTP-ответ `400`.
## `GZipMiddleware` { #gzipmiddleware }
Обрабатывает GZip‑ответы для любых запросов, которые включают `"gzip"` в заголовке `Accept-Encoding`.
Обрабатывает GZip‑ответы для любого HTTP-запроса, который включает `"gzip"` в HTTP-заголовке `Accept-Encoding`.
Это middleware обрабатывает как обычные, так и потоковые ответы.
Это middleware обрабатывает как обычные, так и потоковые HTTP-ответы.
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
Поддерживаются следующие аргументы:
- `minimum_size` не сжимать GZip‑ом ответы, размер которых меньше этого минимального значения в байтах. По умолчанию — `500`.
- `compresslevel` уровень GZip‑сжатия. Целое число от 1 до 9. По умолчанию — `9`. Более низкое значение — быстрее сжатие, но больший размер файла; более высокое значение — более медленное сжатие, но меньший размер файла.
* `minimum_size` - не сжимать GZip‑ом HTTP-ответы, размер которых меньше этого минимального значения в байтах. По умолчанию — `500`.
* `compresslevel` - уровень GZip‑сжатия. Целое число от 1 до 9. По умолчанию — `9`. Более низкое значение — быстрее сжатие, но больший размер файла; более высокое значение — более медленное сжатие, но меньший размер файла.
## Другие middleware { #other-middlewares }
@@ -91,7 +91,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
Например:
- [`ProxyHeadersMiddleware` от Uvicorn](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
- [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
* [`ProxyHeadersMiddleware` от Uvicorn](https://github.com/Kludex/uvicorn/blob/main/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
Чтобы увидеть другие доступные middleware, посмотрите [документацию по middleware в Starlette](https://www.starlette.dev/middleware/) и [список ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
Чтобы увидеть другие доступные middleware, посмотрите [документацию по middleware в Starlette](https://starlette.dev/middleware/) и [список ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
+3 -3
View File
@@ -35,7 +35,7 @@
/// tip | Совет
Query-параметр `callback_url` использует тип Pydantic [Url](https://docs.pydantic.dev/latest/api/networks/).
Query-параметр `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) (подробнее ниже), где можно использовать переменные с параметрами и части исходного HTTP-запроса, отправленного *вашему API*.
* *Путь* может содержать [выражение OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression) (подробнее ниже), где можно использовать переменные с параметрами и части исходного HTTP-запроса, отправленного *вашему 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`:
+2 -3
View File
@@ -1,6 +1,5 @@
# Cookies в ответе { #response-cookies }
## Использование параметра `Response` { #use-a-response-parameter }
Вы можете объявить параметр типа `Response` в вашей функции-обработчике пути.
@@ -19,7 +18,7 @@
## Возвращение `Response` напрямую { #return-a-response-directly }
Вы также можете установить Cookies, если возвращаете `Response` напрямую в вашем коде.
Вы также можете создать cookies, если возвращаете `Response` напрямую в вашем коде.
Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md).
@@ -49,4 +48,4 @@
///
Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с [документацией Starlette](https://www.starlette.dev/responses/#set-cookie).
Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с [документацией Starlette](https://starlette.dev/responses/#set-cookie).
+1 -1
View File
@@ -38,4 +38,4 @@
Помните, что собственные проприетарные HTTP-заголовки можно добавлять, [используя префикс `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
Но если у вас есть пользовательские HTTP-заголовки, которые вы хотите показывать клиенту в браузере, вам нужно добавить их в настройки CORS (подробнее см. в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), используя параметр `expose_headers`, описанный в [документации Starlette по CORS](https://www.starlette.dev/middleware/#corsmiddleware).
Но если у вас есть пользовательские HTTP-заголовки, которые вы хотите показывать клиенту в браузере, вам нужно добавить их в настройки CORS (подробнее см. в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), используя параметр `expose_headers`, описанный в [документации Starlette по CORS](https://starlette.dev/middleware/#corsmiddleware).
+36 -12
View File
@@ -6,41 +6,45 @@
По этой причине обычно их передают через переменные окружения, которые считываются приложением.
**Переменная окружения** (также известная как **env var**) — это значение, которое существует вне Python-кода, в операционной системе, и может быть прочитано вашим приложением и другими программами.
Вы можете создать переменную окружения для команды при её запуске. Ниже вы увидите команды, специфичные для разных платформ.
/// tip | Совет
Чтобы понять, что такое переменные окружения, вы можете прочитать [Переменные окружения](../environment-variables.md).
Прочитайте [руководство по переменным окружения](https://tiangolo.com/guides/environment-variables/) для подробного объяснения того, как работают переменные окружения.
///
## Типы и валидация { #types-and-validation }
Переменные окружения могут содержать только текстовые строки, так как они внешние по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с разными операционными системами, такими как Linux, Windows, macOS).
Эти переменные окружения могут содержать только текстовые строки, так как они внешние по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с разными операционными системами, такими как Linux, Windows и macOS).
Это означает, что любое значение, прочитанное в Python из переменной окружения, будет `str`, а любые преобразования к другим типам или любая валидация должны выполняться в коде.
## Pydantic `Settings` { #pydantic-settings }
К счастью, Pydantic предоставляет отличную утилиту для работы с этими настройками, поступающими из переменных окружения, — [Pydantic: управление настройками](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
К счастью, Pydantic предоставляет отличную утилиту для работы с этими настройками, поступающими из переменных окружения, — [Pydantic: управление настройками](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%
```
</div>
Он также включен при установке набора `all` с:
Он также включен при установке дополнительных зависимостей `all` с:
<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`.
Чтобы это работало, добавьте `python-dotenv` в ваш проект с помощью `uv add python-dotenv`.
///
@@ -197,7 +221,7 @@ APP_NAME="ChimichangApp"
/// tip | Совет
Атрибут `model_config` используется только для конфигурации Pydantic. Подробнее см. [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
Атрибут `model_config` используется только для конфигурации Pydantic. Подробнее см. [Pydantic: Concepts: Configuration](https://pydantic.dev/docs/validation/latest/concepts/config/).
///
+1 -1
View File
@@ -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)
```
+7 -7
View File
@@ -8,12 +8,12 @@
## Установка зависимостей { #install-dependencies }
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и установили `jinja2`:
Добавьте `jinja2` в ваш проект:
<div class="termy">
```console
$ pip install jinja2
$ uv add jinja2
---> 100%
```
@@ -22,10 +22,10 @@ $ pip install jinja2
## Использование `Jinja2Templates` { #using-jinja2templates }
- Импортируйте `Jinja2Templates`.
- Создайте объект `templates`, который сможете переиспользовать позже.
- Объявите параметр `Request` в *операции пути*, которая будет возвращать шаблон.
- Используйте созданный `templates`, чтобы отрендерить и вернуть `TemplateResponse`; передайте имя шаблона, объект `request` и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2.
* Импортируйте `Jinja2Templates`.
* Создайте объект `templates`, который сможете переиспользовать позже.
* Объявите параметр `Request` в *операции пути*, которая будет возвращать шаблон.
* Используйте созданный `templates`, чтобы отрендерить и вернуть `TemplateResponse`; передайте имя шаблона, объект request и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2.
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
@@ -123,4 +123,4 @@ Item ID: 42
## Подробнее { #more-details }
Больше подробностей, включая то, как тестировать шаблоны, смотрите в [документации Starlette по шаблонам](https://www.starlette.dev/templates/).
Больше подробностей, включая то, как тестировать шаблоны, смотрите в [документации Starlette по шаблонам](https://starlette.dev/templates/).
+1 -1
View File
@@ -5,7 +5,7 @@
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
Вы можете узнать больше подробностей в статье [Запуск lifespan в тестах на официальном сайте документации Starlette.](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
Вы можете узнать больше подробностей в статье [Запуск lifespan в тестах на официальном сайте документации Starlette.](https://starlette.dev/lifespan/#running-lifespan-in-tests)
Для устаревших событий `startup` и `shutdown` вы можете использовать `TestClient` следующим образом:
+1 -1
View File
@@ -8,6 +8,6 @@
/// note | Примечание
Подробности смотрите в документации Starlette по [тестированию WebSocket](https://www.starlette.dev/testclient/#testing-websocket-sessions).
Подробности смотрите в документации Starlette по [тестированию WebSocket](https://starlette.dev/testclient/#testing-websocket-sessions).
///
@@ -4,9 +4,9 @@
Извлекая данные из:
* пути (как параметров),
* HTTP-заголовков,
* Cookie,
* пути как параметров.
* HTTP-заголовков.
* Cookie.
* и т.д.
Тем самым **FastAPI** валидирует эти данные, преобразует их и автоматически генерирует документацию для вашего API.
@@ -15,7 +15,7 @@
## Подробности об объекте `Request` { #details-about-the-request-object }
Так как под капотом **FastAPI** — это **Starlette** с дополнительным слоем инструментов, вы можете при необходимости напрямую использовать объект [`Request`](https://www.starlette.dev/requests/) из Starlette.
Так как под капотом **FastAPI** — это **Starlette** с дополнительным слоем инструментов, вы можете при необходимости напрямую использовать объект [`Request`](https://starlette.dev/requests/) из Starlette.
Это также означает, что если вы получаете данные напрямую из объекта `Request` (например, читаете тело запроса), то они не будут валидироваться, конвертироваться или документироваться (с OpenAPI, для автоматического пользовательского интерфейса API) средствами FastAPI.
@@ -45,7 +45,7 @@
## Документация по `Request` { #request-documentation }
Подробнее об [объекте `Request` на официальном сайте документации Starlette](https://www.starlette.dev/requests/).
Подробнее об [объекте `Request` на официальном сайте документации Starlette](https://starlette.dev/requests/).
/// note | Технические детали
+20 -20
View File
@@ -4,12 +4,12 @@
## Установка `websockets` { #install-websockets }
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и установили `websockets` (библиотека Python, упрощающая работу с протоколом "WebSocket"):
Добавьте `websockets` (библиотека Python, упрощающая работу с протоколом "WebSocket") в ваш проект:
<div class="termy">
```console
$ pip install websockets
$ uv add websockets
---> 100%
```
@@ -36,13 +36,13 @@ $ pip install websockets
В продакшн у вас был бы один из вариантов выше.
Для примера нам нужен наиболее простой способ, который позволит сосредоточиться на серверной части веб‑сокетов и получить рабочий код:
Но это самый простой способ сосредоточиться на серверной части веб‑сокетов и получить рабочий пример:
{* ../../docs_src/websockets_/tutorial001_py310.py hl[2,6:38,41:43] *}
## Создание `websocket` { #create-a-websocket }
Создайте `websocket` в своем **FastAPI** приложении:
В вашем **FastAPI** приложении создайте `websocket`:
{* ../../docs_src/websockets_/tutorial001_py310.py hl[1,46:47] *}
@@ -50,13 +50,13 @@ $ pip install websockets
Вы также можете использовать `from starlette.websockets import WebSocket`.
**FastAPI** напрямую предоставляет тот же самый `WebSocket` просто для удобства. На самом деле это `WebSocket` из Starlette.
**FastAPI** напрямую предоставляет тот же самый `WebSocket` просто для удобства вас, разработчика. Но на самом деле это `WebSocket` из Starlette.
///
## Ожидание и отправка сообщений { #await-for-messages-and-send-messages }
Через эндпоинт веб-сокета вы можете получать и отправлять сообщения.
В вашем WebSocket-маршруте вы можете `await` сообщения и отправлять сообщения.
{* ../../docs_src/websockets_/tutorial001_py310.py hl[48:52] *}
@@ -69,7 +69,7 @@ $ pip install websockets
<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)
```
@@ -90,15 +90,15 @@ $ fastapi dev
<img src="/img/tutorial/websockets/image03.png">
Вы можете отправлять и получать множество сообщений:
Вы можете отправлять (и получать) множество сообщений:
<img src="/img/tutorial/websockets/image04.png">
И все они будут использовать одно и то же веб-сокет соединение.
И все они будут использовать одно и то же WebSocket-соединение.
## Использование `Depends` и не только { #using-depends-and-others }
Вы можете импортировать из `fastapi` и использовать в эндпоинте вебсокета:
В WebSocket-эндпоинтах вы можете импортировать из `fastapi` и использовать:
* `Depends`
* `Security`
@@ -113,7 +113,7 @@ $ fastapi dev
/// note | Примечание
В веб-сокете вызывать `HTTPException` не имеет смысла. Вместо этого нужно использовать `WebSocketException`.
Поскольку это WebSocket, вызывать `HTTPException` на самом деле не имеет смысла, вместо этого мы вызываем `WebSocketException`.
Вы можете использовать код закрытия из [допустимых кодов, определённых в спецификации](https://tools.ietf.org/html/rfc6455#section-7.4.1).
@@ -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)
```
@@ -142,17 +142,17 @@ $ fastapi dev
/// tip | Подсказка
Обратите внимание, что query-параметр `token` будет обработан в зависимости.
Обратите внимание, что query `token` будет обработан в зависимости.
///
Теперь вы можете подключиться к веб-сокету и начинать отправку и получение сообщений:
После этого вы можете подключиться к веб-сокету, а затем отправлять и получать сообщения:
<img src="/img/tutorial/websockets/image05.png">
## Обработка отключений и работа с несколькими клиентами { #handling-disconnections-and-multiple-clients }
Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере.
Когда WebSocket-соединение закрыто, `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере.
{* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *}
@@ -170,9 +170,9 @@ Client #1596980209979 left the chat
/// tip | Подсказка
Приложение выше - это всего лишь простой минимальный пример, демонстрирующий обработку и передачу сообщений нескольким веб-сокет соединениям.
Приложение выше - это минимальный и простой пример, демонстрирующий обработку и рассылку сообщений нескольким WebSocket-соединениям.
Но имейте в виду, что это будет работать только в одном процессе и только пока он активен, так как всё обрабатывается в простом списке в оперативной памяти.
Но имейте в виду, что, так как всё обрабатывается в памяти, в простом списке, это будет работать только пока процесс запущен и только с одним процессом.
Если нужно что-то легко интегрируемое с FastAPI, но более надежное и с поддержкой Redis, PostgreSQL или другого, то можно воспользоваться [encode/broadcaster](https://github.com/encode/broadcaster).
@@ -180,7 +180,7 @@ Client #1596980209979 left the chat
## Дополнительная информация { #more-info }
Для более глубокого изучения темы воспользуйтесь документацией Starlette:
Для более глубокого изучения возможностей воспользуйтесь документацией 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).
+1 -1
View File
@@ -8,7 +8,7 @@
/// note | Примечание
Для этого требуется установить `a2wsgi`, например с помощью `pip install a2wsgi`.
Для этого требуется добавить `a2wsgi` в ваш проект, например с помощью `uv add a2wsgi`.
///
+8 -8
View File
@@ -70,7 +70,7 @@ Flask — это «микрофреймворк», он не включает и
Обычно Requests используют даже внутри приложения FastAPI.
И всё же **FastAPI** во многом вдохновлялся Requests.
И всё же FastAPI во многом вдохновлялся Requests.
**Requests** — это библиотека для взаимодействия с API (как клиент), а **FastAPI** — библиотека для создания API (как сервер).
@@ -120,12 +120,12 @@ def read_url():
/// tip | Вдохновило **FastAPI** на
Использовать открытый стандарт для спецификаций API вместо самодельной схемы.
Начать использовать открытый стандарт для спецификаций API вместо самодельной схемы.
И интегрировать основанные на стандартах инструменты пользовательского интерфейса:
* [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 был создан теми же разработчиками, ч
///
### [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.
@@ -337,7 +337,7 @@ Hug был одним из первых фреймворков, реализов
/// note | Заметка
Hug был создан Тимоти Кросли, тем же автором [`isort`](https://github.com/timothycrosley/isort), отличного инструмента для автоматической сортировки импортов в файлах Python.
Hug был создан Тимоти Кросли, тем же автором [`isort`](https://github.com/PyCQA/isort), отличного инструмента для автоматической сортировки импортов в файлах Python.
///
@@ -401,7 +401,7 @@ APIStar был создан Томом Кристи. Тем самым чело
## Что используется в **FastAPI** { #used-by-fastapi }
### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
### [Pydantic](https://pydantic.dev/docs/) { #pydantic }
Pydantic — это библиотека для определения валидации данных, сериализации и документации (с использованием JSON Schema) на основе аннотаций типов Python.
@@ -417,7 +417,7 @@ Pydantic — это библиотека для определения вали
///
### [Starlette](https://www.starlette.dev/) { #starlette }
### [Starlette](https://starlette.dev/) { #starlette }
Starlette — это лёгкий <dfn title="Новый стандарт построения асинхронных веб-приложений на Python">ASGI</dfn> фреймворк/набор инструментов, идеально подходящий для создания высокопроизводительных asyncio‑сервисов.
@@ -462,7 +462,7 @@ ASGI — это новый «стандарт», разрабатываемый
///
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
### [Uvicorn](https://uvicorn.dev) { #uvicorn }
Uvicorn — молниеносный ASGI-сервер, построенный на uvloop и httptools.
+15 -19
View File
@@ -105,36 +105,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`.
///
@@ -372,7 +368,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) (или аналогичный URL вашего Docker-хоста).
Вы увидите альтернативную автоматическую документацию (на базе [ReDoc](https://github.com/Rebilly/ReDoc)):
Вы увидите альтернативную автоматическую документацию (на базе [ReDoc](https://github.com/Redocly/redoc)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
+1 -1
View File
@@ -5,7 +5,7 @@
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
+6 -6
View File
@@ -52,7 +52,7 @@ FastAPI использует стандарт для построения Python
Есть несколько альтернатив, например:
* [Uvicorn](https://www.uvicorn.dev/): высокопроизводительный ASGI‑сервер.
* [Uvicorn](https://uvicorn.dev): высокопроизводительный ASGI‑сервер.
* [Hypercorn](https://hypercorn.readthedocs.io/): ASGI‑сервер, среди прочего совместимый с HTTP/2 и Trio.
* [Daphne](https://github.com/django/daphne): ASGI‑сервер, созданный для Django Channels.
* [Granian](https://github.com/emmett-framework/granian): HTTP‑сервер на Rust для Python‑приложений.
@@ -73,21 +73,21 @@ FastAPI использует стандарт для построения Python
Но вы также можете установить ASGI‑сервер вручную.
Создайте [виртуальное окружение](../virtual-environments.md), активируйте его и затем установите серверное приложение.
Добавьте серверное приложение в ваш проект.
Например, чтобы установить Uvicorn:
<div class="termy">
```console
$ pip install "uvicorn[standard]"
$ uv add "uvicorn[standard]"
---> 100%
```
</div>
Аналогично устанавливаются и другие ASGI‑серверы.
Похожий процесс применим к любой другой программе ASGI‑сервера.
/// tip | Совет
@@ -95,7 +95,7 @@ $ pip install "uvicorn[standard]"
В их числе `uvloop` — высокопроизводительная замена `asyncio`, дающая серьёзный прирост производительности при параллельной работе.
Если вы устанавливаете FastAPI, например так: `pip install "fastapi[standard]"`, вы уже получаете и `uvicorn[standard]`.
Когда вы добавляете FastAPI примерно так: `uv add "fastapi[standard]"`, вы уже получаете и `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)
```
+1 -1
View File
@@ -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>]
+5 -292
View File
@@ -1,298 +1,11 @@
# Переменные окружения { #environment-variables }
/// tip | Совет
**Переменная окружения** (также известная как **env var**) — это значение, которое живет вне вашего кода Python, в операционной системе, и может быть прочитано вашим приложением и другими программами.
Если вы уже знаете, что такое «переменные окружения» и как их использовать, можете пропустить это.
Приложения FastAPI часто используют переменные окружения для конфигурации, например URL-адресов баз данных, учетных данных электронной почты и секретных ключей.
///
Вы узнаете, как использовать их для конфигурации приложения, в разделе [Настройки и переменные окружения](advanced/settings.md).
Переменная окружения (также известная как «**env var**») - это переменная, которая живет **вне** кода Python, в **операционной системе**, и может быть прочитана вашим кодом Python (или другими программами).
## Подробнее { #learn-more }
Переменные окружения могут быть полезны для работы с **настройками** приложений, как часть **установки** Python и т.д.
## Создание и использование переменных окружения { #create-and-use-env-vars }
Можно **создавать** и использовать переменные окружения в **оболочке (терминале)**, не прибегая к помощи 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: Config](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` в терминале, система найдет программу Python в `/opt/custompython/bin` (последний каталог) и использует ее.
////
//// 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` в терминале, система найдет программу Python в `C:\opt\custompython\bin` (последний каталог) и использует ее.
////
Итак, если вы напечатаете:
<div class="termy">
```console
$ python
```
</div>
//// tab | Linux, macOS
Система **найдет** программу `python` в `/opt/custompython/bin` и запустит ее.
Это примерно эквивалентно набору текста:
<div class="termy">
```console
$ /opt/custompython/bin/python
```
</div>
////
//// tab | Windows
Система **найдет** программу `python` в каталоге `C:\opt\custompython\bin\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`.
+9 -5
View File
@@ -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` попытается автоматически обнаружить приложение FastAPI для запуска, предполагая, что это объект с именем `app` в файле `main.py` (или в некоторых других вариантах).
@@ -100,13 +100,13 @@ from backend.main import app
Вы также можете передать путь к файлу команде `fastapi dev`, и она постарается определить объект приложения FastAPI:
```console
$ fastapi dev main.py
$ uv run fastapi dev main.py
```
Или вы можете передать опцию `--entrypoint` команде `fastapi dev`:
```console
$ fastapi dev --entrypoint main:app
$ uv run fastapi dev --entrypoint main:app
```
Но тогда вам придется каждый раз не забывать передавать правильный путь\entrypoint при вызове команды `fastapi`.
@@ -119,11 +119,15 @@ $ fastapi dev --entrypoint main:app
По умолчанию включена авто-перезагрузка (**auto-reload**), благодаря этому при изменении кода происходит перезагрузка сервера приложения. Эта установка требует значительных ресурсов и делает систему менее стабильной. Используйте её только при разработке. Приложение слушает входящие подключения на 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 в режиме продакшн.
По умолчанию авто-перезагрузка (**auto-reload**) отключена. Приложение слушает входящие подключения на IP `0.0.0.0`, т.е. на всех доступных адресах компьютера. Таким образом, приложение будет находиться в публичном доступе для любого, кто может подсоединиться к вашей машине. Продуктовые приложения запускаются именно так, например, с помощью контейнеров.
По умолчанию авто-перезагрузка (**auto-reload**) отключена. Приложение слушает входящие подключения на IP `0.0.0.0`, т.е. на всех доступных адресах компьютера. Таким образом, приложение будет находиться в публичном доступе для любого, кто может подсоединиться к вашей машине. Именно так обычно запускают приложение в продакшн, например, в контейнере.
В большинстве случаев вы будете (и должны) использовать прокси-сервер ("termination proxy"), который будет поддерживать HTTPS поверх вашего приложения. Всё будет зависеть от того, как вы развертываете приложение: за вас это либо сделает ваш провайдер, либо вам придется сделать настройки самостоятельно.
+3 -3
View File
@@ -19,7 +19,7 @@
![Взаимодействие со Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Альтернативная документация API в [**ReDoc**](https://github.com/Rebilly/ReDoc).
* Альтернативная документация API в [**ReDoc**](https://github.com/Redocly/redoc).
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
@@ -159,7 +159,7 @@ FastAPI включает в себя чрезвычайно простую в и
## Возможности Starlette { #starlette-features }
**FastAPI** основан на [**Starlette**](https://www.starlette.dev/) и полностью совместим с ним. Так что любой дополнительный код Starlette, который у вас есть, также будет работать.
**FastAPI** основан на [**Starlette**](https://starlette.dev/) и полностью совместим с ним. Так что любой дополнительный код Starlette, который у вас есть, также будет работать.
На самом деле, `FastAPI` — это подкласс `Starlette`. Таким образом, если вы уже знаете или используете Starlette, большая часть функционала будет работать так же.
@@ -177,7 +177,7 @@ FastAPI включает в себя чрезвычайно простую в и
## Возможности 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>’ы, <abbr title="Object-Document Mapper - объектно-документный маппер">ODM</abbr>’ы для баз данных.
+7 -15
View File
@@ -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 }
Вы можете [создать новый вопрос](https://github.com/fastapi/fastapi/discussions/new?category=questions) в репозитории GitHub, например, чтобы:
@@ -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. Вы можете попробовать его и рассмотреть для своих проектов.
+28 -28
View File
@@ -1,79 +1,79 @@
# История, проектирование и будущее { #history-design-and-future }
Однажды, [один из пользователей **FastAPI** задал вопрос](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920):
Некоторое время назад [один пользователь **FastAPI** спросил](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920):
> Какова история этого проекта? Создаётся впечатление, что он явился из ниоткуда и завоевал мир за несколько недель [...]
> Какова история этого проекта? Кажется, что он из ниоткуда стал потрясающим за несколько недель [...]
Что ж, вот небольшая часть истории проекта.
Вот небольшая часть этой истории.
## Альтернативы { #alternatives }
В течение нескольких лет я, возглавляя различные команды разработчиков, создавал довольно сложные API для машинного обучения, распределённых систем, асинхронных задач, баз данных NoSQL и т.д.
Я несколько лет создавал API со сложными требованиями (Машинное обучение, распределённые системы, асинхронные задачи, базы данных NoSQL и т.д.), возглавляя несколько команд разработчиков.
В рамках работы над этими проектами я исследовал, проверял и использовал многие фреймворки.
В рамках этой работы мне нужно было исследовать, тестировать и использовать многие альтернативы.
Во многом история **FastAPI** - история его предшественников.
Во многом история **FastAPI** — это история его предшественников.
Как написано в разделе [Альтернативы](alternatives.md):
<blockquote markdown="1">
**FastAPI** не существовал бы, если б не было более ранних работ других людей.
**FastAPI** не существовал бы, если бы не предыдущая работа других людей.
Они создали большое количество инструментов, которые и вдохновили меня на создание **FastAPI**.
Ещё до него было создано много инструментов, которые помогли вдохновить его создание.
Я всячески избегал создания нового фреймворка в течение нескольких лет. Сначала я пытался собрать все нужные возможности, которые ныне есть в **FastAPI**, используя множество различных фреймворков, плагинов и инструментов.
Я всячески избегал создания нового фреймворка в течение нескольких лет. Сначала я пытался реализовать все возможности, покрываемые **FastAPI**, используя множество различных фреймворков, плагинов и инструментов.
Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти возможности сразу. Взять самые лучшие идеи из предыдущих инструментов и, используя введённые в Python аннотации типов (которых не было до версии 3.6), объединить их.
Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти возможности сразу, взяв лучшие идеи из предыдущих инструментов и объединив их наилучшим возможным образом, используя возможности языка, которые раньше были недоступны (аннотации типов Python 3.6+).
</blockquote>
## Исследования { #investigation }
Используя все существовавшие ранее альтернативы, я получил возможность у каждой из них чему-то научиться, позаимствовать идеи и объединить их наилучшим образом для себя и для команд разработчиков, с которыми я работал.
Используя все предыдущие альтернативы, я получил возможность учиться у каждой из них, брать идеи и объединять их наилучшим образом, который смог найти для себя и команд разработчиков, с которыми я работал.
Например, стало ясно, что необходимо брать за основу стандартные аннотации типов Python.
Например, было ясно, что в идеале всё должно основываться на стандартных аннотациях типов Python.
Также наилучшим подходом является использование уже существующих стандартов.
Также наилучшим подходом было использовать уже существующие стандарты.
Итак, прежде чем приступить к написанию **FastAPI**, я потратил несколько месяцев на изучение OpenAPI, JSON Schema, OAuth2, и т.п. для понимания их взаимосвязей, совпадений и различий.
Итак, ещё до того как начать писать код **FastAPI**, я потратил несколько месяцев на изучение спецификаций OpenAPI, JSON Schema, OAuth2 и т.п., чтобы понять их взаимосвязи, пересечения и различия.
## Проектирование { #design }
Затем я потратил некоторое время на придумывание "API" разработчика, который я хотел иметь как пользователь (как разработчик, использующий FastAPI).
Затем я потратил некоторое время на проектирование "API" разработчика, который я хотел иметь как пользователь (как разработчик, использующий FastAPI).
Я проверил несколько идей на самых популярных редакторах кода: PyCharm, VS Code, редакторы на базе Jedi.
Я проверил несколько идей в самых популярных редакторах кода Python: PyCharm, VS Code, редакторах на базе Jedi.
Согласно последнему [опросу Python-разработчиков](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools), который охватывает около 80% пользователей.
Это означает, что **FastAPI** был специально проверен на редакторах, используемых 80% Python-разработчиками. И поскольку большинство других редакторов, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов.
Это означает, что **FastAPI** был специально протестирован с редакторами кода, которыми пользуются 80% Python-разработчиков. И поскольку большинство других редакторов кода, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов кода.
Таким образом, я смог найти наилучшие способы сократить дублирование кода, обеспечить повсеместное автозавершение, проверку типов и ошибок и т.д.
Таким образом, я смог найти наилучшие способы максимально сократить дублирование кода, обеспечить автозавершение везде, проверки типов и ошибок и т.д.
И все это, чтобы все разработчики могли получать наилучший опыт разработки.
И всё это таким образом, чтобы предоставить всем разработчикам наилучший опыт разработки.
## Зависимости { #requirements }
Протестировав несколько вариантов, я решил, что в качестве основы буду использовать [**Pydantic**](https://docs.pydantic.dev/) и его преимущества.
Протестировав несколько альтернатив, я решил, что буду использовать [**Pydantic**](https://pydantic.dev/docs/) из-за его преимуществ.
По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить поддержку в редакторах кода (проверки типов, автозавершение) на основе тестов в нескольких редакторах.
Затем я внес в него вклад, чтобы сделать его полностью совместимым с JSON Schema, поддержать разные способы определения объявлений ограничений и улучшить поддержку редакторов кода (проверки типов, автозавершение) на основе тестов в нескольких редакторах кода.
Во время разработки я также внес вклад в [**Starlette**](https://www.starlette.dev/), другую ключевую зависимость.
Во время разработки я также внес вклад в [**Starlette**](https://starlette.dev/), другую ключевую зависимость.
## Разработка { #development }
К тому времени, когда я начал создавать **FastAPI**, большинство необходимых деталей уже существовало, дизайн был определён, зависимости и прочие инструменты были готовы, а знания о стандартах и спецификациях были четкими и свежими.
К тому времени, когда я начал создавать сам **FastAPI**, большинство деталей уже было на своих местах, дизайн был определён, зависимости и инструменты были готовы, а знания о стандартах и спецификациях были чёткими и свежими.
## Будущее { #future }
Сейчас уже ясно, что **FastAPI** со своими идеями стал полезен многим людям.
На этом этапе уже ясно, что **FastAPI** со своими идеями полезен многим людям.
При сравнении с альтернативами, выбор падает на него, поскольку он лучше подходит для множества вариантов использования.
Его выбирают вместо предыдущих альтернатив, потому что он лучше подходит для многих вариантов использования.
Многие разработчики и команды уже используют **FastAPI** в своих проектах (включая меня и мою команду).
Многие разработчики и команды уже полагаются на **FastAPI** в своих проектах (включая меня и мою команду).
Но, тем не менее, грядёт добавление ещё многих улучшений и возможностей.
Но всё ещё впереди много улучшений и возможностей.
У **FastAPI** великое будущее.
У **FastAPI** отличное будущее.
И [ваша помощь](help-fastapi.md) очень ценится.
@@ -66,7 +66,7 @@
Именно этих двух компонентов — `scope` и `receive` — достаточно, чтобы создать новый экземпляр `Request`.
Чтобы узнать больше о `Request`, см. [документацию Starlette о запросах](https://www.starlette.dev/requests/).
Чтобы узнать больше о `Request`, см. [документацию Starlette о запросах](https://starlette.dev/requests/).
///
+1 -1
View File
@@ -45,7 +45,7 @@
Используя информацию выше, вы можете той же вспомогательной функцией сгенерировать схему OpenAPI и переопределить любые нужные части.
Например, добавим [расширение OpenAPI ReDoc для включения собственного логотипа](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo).
Например, добавим [расширение OpenAPI ReDoc для включения собственного логотипа](https://github.com/Redocly/redoc/blob/main/docs/redoc-vendor-extensions.md#x-logo).
### Обычный **FastAPI** { #normal-fastapi }
+1 -1
View File
@@ -22,7 +22,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/)
* С [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) для интеграции с ASGI
* [Graphene](https://graphene-python.org/)
@@ -24,7 +24,7 @@ FastAPI 0.128.0 также убрал поддержку `pydantic.v1`, так
## Официальное руководство { #official-guide }
У Pydantic есть официальное [руководство по миграции](https://docs.pydantic.dev/latest/migration/) с v1 на v2.
У Pydantic есть официальное [руководство по миграции](https://pydantic.dev/docs/validation/latest/get-started/migration/) с v1 на v2.
Там также описано, что изменилось, как валидации стали более корректными и строгими, возможные нюансы и т.д.
+19 -23
View File
@@ -110,7 +110,7 @@ FastAPI — это современный, быстрый (высокопрои
</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>REST</strong>-сервер, к которому можно обращаться за <strong>предсказаниями</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/">(ref)</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/">(ref)</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 — это современный, быстрый (высокопрои
"_Мы начали использовать библиотеку **FastAPI**, чтобы поднять **REST**-сервер, к которому можно обращаться за **предсказаниями**. [для Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(ref)</small></a></div>
---
@@ -151,12 +151,6 @@ FastAPI — это современный, быстрый (высокопрои
</div>
## FastAPI Conf { #fastapi-conf }
[**FastAPI Conf '26**](https://fastapiconf.com) пройдёт **28 октября 2026** в **Амстердаме, Нидерланды**. Всё о FastAPI — из первых рук. 🎤
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf '26 — 28 октября 2026 — Амстердам, Нидерланды"></a>
## Мини-документальный фильм о FastAPI { #fastapi-mini-documentary }
В конце 2025 года вышел [мини-документальный фильм о FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE), вы можете посмотреть его онлайн:
@@ -175,17 +169,17 @@ FastAPI — это современный, быстрый (высокопрои
FastAPI стоит на плечах гигантов:
* [Starlette](https://www.starlette.dev/) для части, связанной с вебом.
* [Pydantic](https://docs.pydantic.dev/) для части, связанной с данными.
* [Starlette](https://starlette.dev/) для части, связанной с вебом.
* [Pydantic](https://pydantic.dev/docs/) для части, связанной с данными.
## Установка { #installation }
Создайте и активируйте [виртуальное окружение](https://fastapi.tiangolo.com/ru/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)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
@@ -497,7 +493,7 @@ item: Item
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
@@ -540,7 +536,7 @@ FastAPI зависит от Pydantic и Starlette.
### Зависимости `standard` { #standard-dependencies }
Когда вы устанавливаете FastAPI с помощью `pip install "fastapi[standard]"`, он идёт с группой опциональных зависимостей `standard`:
Когда вы устанавливаете FastAPI с помощью `uv add "fastapi[standard]"`, он идёт с группой опциональных зависимостей `standard`:
Используется Pydantic:
@@ -554,17 +550,17 @@ FastAPI зависит от Pydantic и 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 }
Если вы хотите установить FastAPI со стандартными зависимостями, но без `fastapi-cloud-cli`, установите `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
Если вы хотите установить FastAPI со стандартными зависимостями, но без `fastapi-cloud-cli`, установите `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
### Дополнительные опциональные зависимости { #additional-optional-dependencies }
@@ -572,13 +568,13 @@ FastAPI зависит от Pydantic и Starlette.
Дополнительные опциональные зависимости 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 }
+2 -2
View File
@@ -4,13 +4,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)
## Шаблон Full Stack FastAPI — Технологический стек и возможности { #full-stack-fastapi-template-technology-stack-and-features }
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/ru) для бэкенд‑API на Python.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) для взаимодействия с SQL‑базой данных на Python (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), используется FastAPI, для валидации данных и управления настройками.
- 🔍 [Pydantic](https://pydantic.dev/docs/), используется FastAPI, для валидации данных и управления настройками.
- 💾 [PostgreSQL](https://www.postgresql.org) в качестве SQL‑базы данных.
- 🚀 [React](https://react.dev) для фронтенда.
- 💃 Используются TypeScript, хуки, Vite и другие части современного фронтенд‑стека.
+2 -2
View File
@@ -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/).
///
+17 -15
View File
@@ -1,19 +1,19 @@
# Фоновые задачи { #background-tasks }
Вы можете создавать фоновые задачи, которые будут выполняться после возврата ответа.
Вы можете создавать фоновые задачи, которые будут выполняться *после* возврата HTTP-ответа.
Это полезно для операций, которые должны произойти после HTTP-запроса, но клиенту не обязательно ждать их завершения, чтобы получить ответ.
Это полезно для операций, которые должны произойти после HTTP-запроса, но клиенту не обязательно ждать их завершения, прежде чем получить HTTP-ответ.
Например:
Сюда входят, например:
* Уведомления по электронной почте, отправляемые после выполнения действия:
* Так как подключение к почтовому серверу и отправка письма обычно «медленные» (несколько секунд), вы можете сразу вернуть ответ, а отправку уведомления выполнить в фоне.
* Так как подключение к почтовому серверу и отправка письма обычно «медленные» (несколько секунд), вы можете сразу вернуть HTTP-ответ, а отправку уведомления выполнить в фоне.
* Обработка данных:
* Например, если вы получаете файл, который должен пройти через медленный процесс, вы можете вернуть ответ «Accepted» (HTTP 202) и обработать файл в фоне.
* Например, если вы получаете файл, который должен пройти через медленный процесс, вы можете вернуть HTTP-ответ «Accepted» (HTTP 202) и обработать файл в фоне.
## Использование `BackgroundTasks` { #using-backgroundtasks }
Сначала импортируйте `BackgroundTasks` и объявите параметр в вашей функции‑обработчике пути с типом `BackgroundTasks`:
Сначала импортируйте `BackgroundTasks` и объявите параметр в вашей *функции‑обработчике пути* с типом `BackgroundTasks`:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
@@ -35,7 +35,7 @@
## Добавление фоновой задачи { #add-the-background-task }
Внутри вашей функции‑обработчика пути передайте функцию задачи объекту фоновых задач методом `.add_task()`:
Внутри вашей *функции‑обработчика пути* передайте функцию задачи объекту *фоновых задач* методом `.add_task()`:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
@@ -47,29 +47,31 @@
## Встраивание зависимостей { #dependency-injection }
Использование `BackgroundTasks` также работает с системой встраивания зависимостей, вы можете объявить параметр типа `BackgroundTasks` на нескольких уровнях: в функции‑обработчике пути, в зависимости (dependable), в подзависимости и т.д.
Использование `BackgroundTasks` также работает с системой встраивания зависимостей, вы можете объявить параметр типа `BackgroundTasks` на нескольких уровнях: в *функции‑обработчике пути*, в зависимости (dependable), в подзависимости и т.д.
**FastAPI** знает, что делать в каждом случае и как переиспользовать один и тот же объект, так чтобы все фоновые задачи были объединены и затем выполнены в фоне:
{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
В этом примере сообщения будут записаны в файл `log.txt` после отправки ответа.
Если в запросе была строка запроса (query), она будет записана в лог фоновой задачей.
В этом примере сообщения будут записаны в файл `log.txt` *после* отправки HTTP-ответа.
Затем другая фоновая задача, созданная в функции‑обработчике пути, запишет сообщение, используя path‑параметр `email`.
Если в HTTP-запросе была строка запроса (query), она будет записана в лог фоновой задачей.
Затем другая фоновая задача, созданная в *функции‑обработчике пути*, запишет сообщение, используя path‑параметр `email`.
## Технические детали { #technical-details }
Класс `BackgroundTasks` приходит напрямую из [`starlette.background`](https://www.starlette.dev/background/).
Класс `BackgroundTasks` приходит напрямую из [`starlette.background`](https://starlette.dev/background/).
Он импортируется/включается прямо в FastAPI, чтобы вы могли импортировать его из `fastapi` и избежать случайного импорта альтернативного `BackgroundTask` (без `s` на конце) из `starlette.background`.
Используя только `BackgroundTasks` (а не `BackgroundTask`), его можно применять как параметр функции‑обработчика пути, и **FastAPI** сделает остальное за вас, как при использовании объекта `Request` напрямую.
Используя только `BackgroundTasks` (а не `BackgroundTask`), его можно применять как параметр *функции‑обработчика пути*, и **FastAPI** сделает остальное за вас, как при использовании объекта `Request` напрямую.
По‑прежнему можно использовать один `BackgroundTask` в FastAPI, но тогда вам нужно создать объект в своём коде и вернуть Starlette `Response`, включающий его.
Подробнее см. в [официальной документации Starlette по фоновым задачам](https://www.starlette.dev/background/).
Подробнее см. в [официальной документации Starlette по фоновым задачам](https://starlette.dev/background/).
## Предостережение { #caveat }
@@ -81,4 +83,4 @@
## Резюме { #recap }
Импортируйте и используйте `BackgroundTasks` с параметрами в функциях‑обработчиках пути и зависимостях, чтобы добавлять фоновые задачи.
Импортируйте и используйте `BackgroundTasks` с параметрами в *функциях‑обработчиках пути* и зависимостях, чтобы добавлять фоновые задачи.
+2 -2
View File
@@ -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)
```
+2 -2
View File
@@ -1,4 +1,4 @@
# Body - Вложенные модели { #body-nested-models }
# Тело запроса - Вложенные модели { #body-nested-models }
С помощью **FastAPI** вы можете определять, валидировать, документировать и использовать модели произвольной глубины вложенности (благодаря Pydantic).
@@ -96,7 +96,7 @@ my_list: list[str]
Помимо обычных простых типов, таких как `str`, `int`, `float` и т.д., вы можете использовать более сложные простые типы, которые наследуются от `str`.
Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с [обзором типов Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Вы увидите некоторые примеры в следующей главе.
Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с [обзором типов Pydantic](https://pydantic.dev/docs/validation/latest/concepts/types/). Вы увидите некоторые примеры в следующей главе.
Например, так как в модели `Image` у нас есть поле `url`, то мы можем объявить его как тип `HttpUrl` из Pydantic вместо типа `str`:
+2 -2
View File
@@ -6,7 +6,7 @@
Ваш API почти всегда должен отправлять тело **ответа**. Но клиентам не обязательно всегда отправлять **тело запроса**: иногда они запрашивают только путь, возможно с некоторыми параметрами запроса, но без тела.
Чтобы объявить тело **запроса**, используйте модели [Pydantic](https://docs.pydantic.dev/), со всей их мощью и преимуществами.
Чтобы объявить тело **запроса**, используйте модели [Pydantic](https://pydantic.dev/docs/), со всей их мощью и преимуществами.
/// note | Заметка
@@ -70,7 +70,7 @@
* Считает тело запроса как JSON.
* Приведёт данные к соответствующим типам (если потребуется).
* Проведёт валидацию данных.
* Если данные некорректны, вернёт понятную и наглядную ошибку, указывающую, где именно and что было некорректно.
* Если данные некорректны, вернёт понятную и наглядную ошибку, указывающую, где именно и что было некорректно.
* Передаст полученные данные в параметр `item`.
* Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т.п.) для всех атрибутов и их типов.
* Сгенерирует определения [JSON Schema](https://json-schema.org) для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
+2 -2
View File
@@ -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>
+8 -8
View File
@@ -25,31 +25,31 @@
* Стандартный "Универсальный уникальный идентификатор", используемый в качестве идентификатора во многих базах данных и системах.
* В HTTP-запросах и HTTP-ответах будет представлен как `str`.
* `datetime.datetime`:
* Встроенный в Python `datetime.datetime`.
* Python `datetime.datetime`.
* В HTTP-запросах и HTTP-ответах будет представлен как `str` в формате ISO 8601, например: `2008-09-15T15:53:00+05:00`.
* `datetime.date`:
* Встроенный в Python `datetime.date`.
* Python `datetime.date`.
* В HTTP-запросах и HTTP-ответах будет представлен как `str` в формате ISO 8601, например: `2008-09-15`.
* `datetime.time`:
* Встроенный в Python `datetime.time`.
* Python `datetime.time`.
* В HTTP-запросах и HTTP-ответах будет представлен как `str` в формате ISO 8601, например: `14:23:55.003`.
* `datetime.timedelta`:
* Встроенный в Python `datetime.timedelta`.
* Python `datetime.timedelta`.
* В HTTP-запросах и HTTP-ответах будет представлен в виде общего количества секунд типа `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`:
* В HTTP-запросах и HTTP-ответах обрабатывается так же, как и `set`:
* В HTTP-запросах будет прочитан список, исключены дубликаты и преобразован в `set`.
* В HTTP-ответах `set` будет преобразован в `list`.
* В сгенерированной схеме будет указано, что значения `set` уникальны (с помощью JSON-схемы `uniqueItems`).
* `bytes`:
* Встроенный в Python `bytes`.
* Стандартный Python `bytes`.
* В HTTP-запросах и HTTP-ответах будет рассматриваться как `str`.
* В сгенерированной схеме будет указано, что это `str` в "формате" `binary`.
* `Decimal`:
* Встроенный в Python `Decimal`.
* Стандартный Python `Decimal`.
* В HTTP-запросах и HTTP-ответах обрабатывается так же, как и `float`.
* Вы можете проверить все допустимые типы данных Pydantic здесь: [Типы данных Pydantic](https://docs.pydantic.dev/latest/usage/types/types/).
* Вы можете проверить все допустимые типы данных Pydantic здесь: [Типы данных Pydantic](https://pydantic.dev/docs/validation/latest/concepts/types/).
## Пример { #example }
+1 -1
View File
@@ -166,7 +166,7 @@ UserInDB(
/// note | Примечание
При объявлении [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions) сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
При объявлении [`Union`](https://pydantic.dev/docs/validation/latest/concepts/unions/) сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
///
+12 -6
View File
@@ -6,12 +6,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 🚀
@@ -78,7 +84,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)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
@@ -185,13 +191,13 @@ from backend.main import app
Вы также можете передать путь к файлу в команду `fastapi dev`, и она попытается определить объект приложения FastAPI для использования:
```console
$ fastapi dev main.py
$ uv run fastapi dev main.py
```
Или вы можете передать опцию `--entrypoint` команде `fastapi dev`:
```console
$ fastapi dev --entrypoint main:app
$ uv run fastapi dev --entrypoint main:app
```
Но в этом случае вам придётся каждый раз помнить о передаче корректного пути/entrypoint при вызове команды `fastapi`.
@@ -205,7 +211,7 @@ $ fastapi dev --entrypoint main:app
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
@@ -232,7 +238,7 @@ CLI автоматически определит ваше приложение
`FastAPI` — это класс, который напрямую наследуется от `Starlette`.
Вы можете использовать весь функционал [Starlette](https://www.starlette.dev/) и в `FastAPI`.
Вы можете использовать весь функционал [Starlette](https://starlette.dev/) и в `FastAPI`.
///
+9 -3
View File
@@ -52,7 +52,7 @@ npm run build
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
**FastAPI** использует этот fallback только для запросов `GET` и `HEAD`, которые похожи на навигацию в браузере. Отсутствующие файлы, такие как JavaScript, CSS и изображения, по-прежнему возвращают `404`.
**FastAPI** использует этот fallback только для HTTP-запросов `GET` и `HEAD`, которые явно принимают HTML с `Accept: text/html` или `Accept: application/xhtml+xml`, как обычно делают запросы навигации в браузере. Отсутствующие файлы, такие как 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) устанавливает эту переменную окружения за вас, если она ещё не установлена. Это позволяет запускать backend до сборки или запуска frontend во время разработки.
В любом другом окружении **FastAPI** вызывает ошибку при создании приложения. Это помогает рано обнаруживать ошибки конфигурации до развертывания приложения без его фронтенд-файлов.
Вы также можете установить `check_dir=True`, чтобы всегда проверять директорию при создании приложения.
Если ваши фронтенд-файлы создаются позже, например отдельным этапом сборки после создания объекта приложения, установите `check_dir=False`:
@@ -132,6 +136,8 @@ HTTP-ответы фронтенда выполняются внутри обы
Зависимости из приложения, из `APIRouter` и из `include_router()` также применяются к HTTP-ответам фронтенда. Это может быть полезно для защиты фронтенда с помощью аутентификации на основе cookie или похожего механизма.
Зависимости также могут изменять HTTP-заголовки ответа и добавлять фоновые задачи, как и в обычных *операциях пути*.
## Только статический результат сборки { #static-build-output-only }
`app.frontend()` отдаёт файлы, уже сгенерированные сборкой вашего фронтенда.
+1 -1
View File
@@ -81,7 +81,7 @@ HTTP статус-коды в диапазоне 400 означают, что п
## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
Вы можете добавить пользовательские обработчики исключений с помощью [тех же утилит обработки исключений из Starlette](https://www.starlette.dev/exceptions/).
Вы можете добавить пользовательские обработчики исключений с помощью [тех же утилит обработки исключений из Starlette](https://starlette.dev/exceptions/).
Допустим, у вас есть пользовательское исключение `UnicornException`, которое вы (или используемая вами библиотека) можете вызвать с помощью `raise`.
+56 -17
View File
@@ -1,7 +1,6 @@
# Учебник - Руководство пользователя { #tutorial-user-guide }
В этом руководстве шаг за шагом показано, как использовать **FastAPI** с большинством его функций.
This tutorial shows you how to use **FastAPI** with most of its features, step by step.
Каждый раздел постепенно основывается на предыдущих, но структура разделяет темы, так что вы можете сразу перейти к нужной теме для решения ваших конкретных задач по API.
@@ -11,12 +10,12 @@
Все блоки кода можно копировать и использовать напрямую (это действительно протестированные файлы Python).
Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `fastapi dev`:
Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `fastapi dev` с помощью `uv run`:
<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 🚀
@@ -61,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` как альтернативы
Если вы предпочитаете управлять виртуальным окружением и пакетами вручную, создайте и активируйте виртуальное окружение, а затем установите FastAPI с помощью `pip install "fastapi[standard]"`.
Подробные шаги читайте в [руководстве по виртуальным окружениям](https://tiangolo.com/guides/virtual-environments/).
///
## Навыки AI-агента { #ai-agent-skills }
FastAPI включает официальный навык для AI-агентов для написания кода. Он поставляется вместе с пакетом, поэтому его рекомендации остаются согласованными с версией FastAPI, установленной в вашем проекте, и обновляются при обновлении FastAPI.
После установки FastAPI в вашем проекте вы можете установить навык с помощью <a href="https://library-skills.io">Library Skills</a>:
```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 и просмотр логов - всё прямо из вашего редактора кода.
///
Навык совместим с Codex, Claude Code, Cursor, GitHub Copilot, Gemini CLI, Pi, OpenCode и большинством других агентов для написания кода. Для Claude Code выберите `.claude/skills`, когда вас спросят, куда установить навык.
## Продвинутое руководство пользователя { #advanced-user-guide }
+24 -24
View File
@@ -1,15 +1,15 @@
# Middleware (Промежуточный слой) { #middleware }
# Middleware { #middleware }
Вы можете добавить middleware (промежуточный слой) в **FastAPI** приложение.
Вы можете добавить middleware в приложения **FastAPI**.
"Middleware" - это функция, которая выполняется с каждым **запросом** до его обработки какой-либо конкретной *операцией пути*. А также с каждым **ответом** перед его возвращением.
"Middleware" - это функция, которая работает с каждым **HTTP-запросом** до его обработки какой-либо конкретной *операцией пути*. А также с каждым **HTTP-ответом** перед его возвращением.
* Она принимает каждый поступающий **запрос**.
* Может что-то сделать с этим **запросом** или выполнить любой нужный код.
* Затем передает **запрос** для последующей обработки (какой-либо *операцией пути*).
* Получает **ответ** (от *операции пути*).
* Может что-то сделать с этим **ответом** или выполнить любой нужный код.
* И возвращает **ответ**.
* Она принимает каждый **HTTP-запрос**, который поступает в ваше приложение.
* Затем может что-то сделать с этим **HTTP-запросом** или выполнить любой нужный код.
* Затем передаёт **HTTP-запрос** на обработку остальной части приложения (какой-либо *операцией пути*).
* Затем принимает **HTTP-ответ**, сгенерированный приложением (какой-либо *операцией пути*).
* Может что-то сделать с этим **HTTP-ответом** или выполнить любой нужный код.
* Затем возвращает **HTTP-ответ**.
/// note | Технические детали
@@ -25,19 +25,19 @@
Функция middleware получает:
* `request`.
* Функцию `call_next`, которая получает `request` в качестве параметра.
* Эта функция передаёт `request` соответствующей *операции пути*.
* Объект `request`.
* Функцию `call_next`, которая получит `request` в качестве параметра.
* Эта функция передаст `request` соответствующей *операции пути*.
* Затем она возвращает `response`, сгенерированный соответствующей *операцией пути*.
* Также имеется возможность видоизменить `response` перед тем как его вернуть.
* Затем вы можете дополнительно изменить `response` перед тем как его вернуть.
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip | Совет
Имейте в виду, что можно добавлять проприетарные HTTP-заголовки [с префиксом `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
Имейте в виду, что пользовательские проприетарные HTTP-заголовки можно добавлять [с префиксом `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
Но если вы хотите, чтобы клиент в браузере мог видеть ваши пользовательские заголовки, необходимо добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md)), используя параметр `expose_headers`, описанный в [документации по CORS Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
Но если у вас есть пользовательские HTTP-заголовки, которые клиент в браузере должен иметь возможность видеть, необходимо добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md)), используя параметр `expose_headers`, описанный в [документации по CORS Starlette](https://starlette.dev/middleware/#corsmiddleware).
///
@@ -51,17 +51,17 @@
### До и после `response` { #before-and-after-the-response }
Вы можете добавить код, использующий `request`, до передачи его какой-либо *операции пути*.
Вы можете добавить код, который будет выполняться с `request`, до того как его получит какая-либо *операция пути*.
А также после формирования `response`, до того, как вы его вернёте.
Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки HTTP-запроса и генерации HTTP-ответа:
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip | Совет
Мы используем [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) вместо `time.time()` для обеспечения большей точности в таких случаях. 🤓
Здесь мы используем [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) вместо `time.time()` потому, что он может быть более точным для таких случаев. 🤓
///
@@ -69,9 +69,9 @@
Когда вы добавляете несколько middleware с помощью декоратора `@app.middleware()` или метода `app.add_middleware()`, каждое новое middleware оборачивает приложение, формируя стек. Последнее добавленное middleware — самое внешнее (*outermost*), а первое — самое внутреннее (*innermost*).
На пути обработки запроса сначала выполняется самое внешнее middleware.
На пути обработки HTTP-запроса сначала выполняется самое внешнее middleware.
На пути формирования ответа оно выполняется последним.
На пути формирования HTTP-ответа оно выполняется последним.
Например:
@@ -82,14 +82,14 @@ app.add_middleware(MiddlewareB)
Это приводит к следующему порядку выполнения:
* **Запрос**: MiddlewareB → MiddlewareA → маршрут
* **HTTP-запрос**: MiddlewareB → MiddlewareA → маршрут
* **Ответ**: маршрут → MiddlewareA → MiddlewareB
* **HTTP-ответ**: маршрут → MiddlewareA → MiddlewareB
Такое стековое поведение обеспечивает предсказуемый и управляемый порядок выполнения middleware.
## Другие middleware { #other-middlewares }
О других middleware вы можете узнать больше в разделе [Расширенное руководство пользователя: Продвинутое middleware](../advanced/middleware.md).
О других middleware вы можете узнать больше позже в разделе [Расширенное руководство пользователя: Продвинутое middleware](../advanced/middleware.md).
В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
В следующем разделе вы прочитаете, как обрабатывать <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
+18 -17
View File
@@ -4,7 +4,7 @@
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
Значение path-параметра `item_id` будет передано в функцию в качестве аргумента `item_id`.
Если запустите этот пример и перейдёте по адресу: [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo), то увидите ответ:
@@ -12,9 +12,9 @@
{"item_id":"foo"}
```
## Параметры пути с типами { #path-parameters-with-types }
## Path-параметры с типами { #path-parameters-with-types }
Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python:
Вы можете объявить тип path-параметра в функции, используя стандартные аннотации типов Python:
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
@@ -38,7 +38,7 @@
Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
Используя такое объявление типов, **FastAPI** выполняет автоматический HTTP-запрос <dfn title="преобразование строки, которая приходит из HTTP-запроса, в данные Python">"парсинг"</dfn>.
Используя такое объявление типов, **FastAPI** выполняет автоматический парсинг HTTP-запроса <dfn title="преобразование строки, которая приходит из HTTP-запроса, в данные Python">"парсинг"</dfn>.
///
@@ -62,7 +62,7 @@
}
```
из-за того, что параметр пути `item_id` имеет значение `"foo"`, которое не является типом `int`.
из-за того, что path-параметр `item_id` имеет значение `"foo"`, которое не является типом `int`.
Та же ошибка возникнет, если вместо `int` передать `float`, например: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
@@ -86,13 +86,13 @@
Ещё раз, просто используя определения типов, **FastAPI** обеспечивает автоматическую интерактивную документацию (с интеграцией Swagger UI).
Обратите внимание, что параметр пути объявлен целочисленным.
Обратите внимание, что path-параметр объявлен целочисленным.
///
## Преимущества стандартизации, альтернативная документация { #standards-based-benefits-alternative-documentation }
Поскольку сгенерированная схема соответствует стандарту [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md), её можно использовать со множеством совместимых инструментов.
Поскольку сгенерированная схема соответствует стандарту [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md), её можно использовать со множеством совместимых инструментов.
Именно поэтому, **FastAPI** сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу: [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`, так и более сложные типы.
@@ -122,7 +122,7 @@
Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
Аналогично, вы не можете переопределить операцию с путем:
Аналогично, вы не можете переопределить операцию пути:
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
@@ -130,7 +130,7 @@
## Предопределенные значения { #predefined-values }
Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление <abbr title="Enumeration - Перечисление">`Enum`</abbr> Python.
Что если нам нужно заранее определить допустимые *path-параметры*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление <abbr title="Enumeration - Перечисление">`Enum`</abbr> Python.
### Создание класса `Enum` { #create-an-enum-class }
@@ -144,25 +144,25 @@
/// tip | Подсказка
Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия <dfn title="Технически, архитектуры моделей глубокого обучения">моделей</dfn> Машинного обучения.
Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия <dfn title="Технически, архитектуры моделей Глубокого обучения">моделей</dfn> Машинного обучения.
///
### Определение *параметра пути* { #declare-a-path-parameter }
### Объявление *path-параметра* { #declare-a-path-parameter }
Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
Определите *path-параметр*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### Проверьте документацию { #check-the-docs }
Поскольку доступные значения *параметра пути* определены заранее, интерактивная документация может наглядно их отображать:
Поскольку доступные значения *path-параметра* определены заранее, интерактивная документация может наглядно их отображать:
<img src="/img/tutorial/path-params/image03.png">
### Работа с *перечислениями* в Python { #working-with-python-enumerations }
Значение *параметра пути* будет *элементом перечисления*.
Значение *path-параметра* будет *элементом перечисления*.
#### Сравнение *элементов перечисления* { #compare-enumeration-members }
@@ -189,6 +189,7 @@
Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
На стороне клиента вы получите такой JSON-ответ:
```JSON
@@ -208,7 +209,7 @@
### Поддержка OpenAPI { #openapi-support }
OpenAPI не поддерживает способов объявления *параметра пути*, содержащего внутри *путь*, так как это может привести к сценариям, которые сложно определять и тестировать.
OpenAPI не поддерживает способа объявления *path-параметра*, содержащего внутри *путь*, так как это может привести к сценариям, которые сложно определять и тестировать.
Тем не менее это можно сделать в **FastAPI**, используя один из внутренних инструментов Starlette.
@@ -216,7 +217,7 @@ OpenAPI не поддерживает способов объявления *п
### Конвертер пути { #path-convertor }
Благодаря одной из опций Starlette, можете объявить *параметр пути*, содержащий *путь*, используя URL вроде:
Благодаря одной из опций Starlette, можете объявить *path-параметр*, содержащий *путь*, используя URL вроде:
```
/files/{file_path:path}
@@ -369,11 +369,11 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
В таких случаях можно использовать **кастомную функцию-валидатор**, которая применяется после обычной валидации (например, после проверки, что значение — это `str`).
Этого можно добиться, используя [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) внутри `Annotated`.
/// 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) и другие. 🤓
///
+5 -5
View File
@@ -6,10 +6,10 @@
Чтобы получать загруженные файлы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
Добавьте его в свой проект:
```console
$ pip install python-multipart
$ uv add python-multipart
```
Это связано с тем, что загружаемые файлы передаются как "данные формы".
@@ -42,7 +42,7 @@ $ pip install python-multipart
///
Файлы будут загружены как данные формы.
Файлы будут загружены как "данные формы".
Если вы объявите тип параметра у *функции-обработчика пути* как `bytes`, то **FastAPI** прочитает файл за вас, и вы получите его содержимое в виде `bytes`.
@@ -149,13 +149,13 @@ contents = myfile.file.read()
Можно одновременно загружать несколько файлов.
Они будут связаны с одним и тем же "полем формы", отправляемым с помощью данных формы.
Они будут связаны с одним и тем же "полем формы", отправляемым с помощью "данных формы".
Для этого необходимо объявить список `bytes` или `UploadFile`:
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
Вы получите, как и было объявлено, список `list` из `bytes` или `UploadFile`.
Вы получите, как и было объявлено, список `list` из `bytes` или объектов `UploadFile`.
/// note | Технические детали
+4 -4
View File
@@ -6,10 +6,10 @@
Чтобы использовать формы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
Убедитесь, что вы создали и активировали [виртуальное окружение](../virtual-environments.md), а затем установите пакет, например:
Добавьте его в ваш проект:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
@@ -50,7 +50,7 @@ $ pip install python-multipart
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
Если клиент попробует отправить дополнительные данные, то в ответ он получит **ошибку**.
Если клиент попробует отправить дополнительные данные, то в ответ он получит ответ с **ошибкой**.
Например, если клиент попытается отправить поля формы:
@@ -58,7 +58,7 @@ $ pip install python-multipart
* `password`: `Portal Gun`
* `extra`: `Mr. Poopybutthole`
То в ответ он получит **ошибку**, сообщающую ему, что поле `extra` не разрешено:
Он получит ответ с ошибкой, сообщающий ему, что поле `extra` не разрешено:
```json
{
@@ -6,10 +6,10 @@
Чтобы получать загруженные файлы и/или данные форм, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
Добавьте его в ваш проект:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
@@ -30,7 +30,7 @@ $ pip install python-multipart
/// warning | Внимание
Вы можете объявить несколько параметров `File` и `Form` в операции пути, но вы не можете также объявить поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с помощью `multipart/form-data` вместо `application/json`.
Вы можете объявить несколько параметров `File` и `Form` в *операции пути*, но вы не можете также объявить поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с помощью `multipart/form-data` вместо `application/json`.
Это не ограничение **FastAPI**, это часть протокола HTTP.
+3 -4
View File
@@ -1,16 +1,15 @@
# Данные формы { #form-data }
Когда вам нужно получить поля формы вместо JSON, вы можете использовать `Form`.
/// note | Примечание
Чтобы использовать формы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
Добавьте его в свой проект:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
@@ -41,7 +40,7 @@ $ pip install python-multipart
/// tip | Подсказка
Чтобы объявлять данные формы, вам нужно явно использовать `Form`, иначе параметры будут интерпретированы как параметры запроса или параметры тела (JSON).
Чтобы объявлять тела формы, вам нужно явно использовать `Form`, иначе параметры будут интерпретированы как параметры запроса или параметры тела (JSON).
///
+6 -6
View File
@@ -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]"
```
///
@@ -178,7 +178,7 @@ FastAPI делает несколько вещей внутри вместе с
## Другие аннотации возвращаемых типов { #other-return-type-annotations }
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор коды, mypy и т.д.).
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор кода, mypy и т.д.).
### Возврат Response напрямую { #return-a-response-directly }
@@ -202,7 +202,7 @@ FastAPI делает несколько вещей внутри вместе с
Но когда вы возвращаете произвольный объект, не являющийся валидным типом Pydantic (например, объект базы данных), и аннотируете его таким образом в функции, FastAPI попытается создать модель ответа Pydantic из этой аннотации типа и потерпит неудачу.
То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">объединение</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">объединения</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
@@ -258,7 +258,7 @@ FastAPI делает несколько вещей внутри вместе с
* `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`.
@@ -26,14 +26,14 @@
/// note | Примечание
Пакет [`python-multipart`](https://github.com/Kludex/python-multipart) автоматически устанавливается вместе с **FastAPI**, если вы запускаете команду `pip install "fastapi[standard]"`.
Пакет [`python-multipart`](https://github.com/Kludex/python-multipart) автоматически устанавливается вместе с **FastAPI**, когда вы запускаете команду `uv add "fastapi[standard]"`.
Однако, если вы используете команду `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`.
@@ -45,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)
```
+7 -7
View File
@@ -18,7 +18,7 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
Он не зашифрован, поэтому любой человек может восстановить информацию из его содержимого.
Но он подписан. Следовательно, когда вы получаете токен, который вы эмитировали (выдавали), вы можете убедиться, что это именно вы его эмитировали.
Но он подписан. Следовательно, когда вы получете токен, который вы эмитировали (выдавали), вы можете убедиться, что это именно вы его эмитировали.
Таким образом, можно создать токен со сроком действия, скажем, 1 неделя. А когда пользователь вернется на следующий день с тем же токеном, вы будете знать, что он все еще авторизован в вашей системе.
@@ -30,12 +30,12 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
Нам необходимо установить `PyJWT` для генерации и проверки JWT-токенов на языке Python.
Убедитесь, что вы создали [виртуальное окружение](../../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), активируйте его, и затем установите pwdlib вместе с Argon2:
Добавьте `pwdlib` с Argon2 в свой проект:
<div class="termy">
```console
$ pip install "pwdlib[argon2]"
$ uv add "pwdlib[argon2]"
---> 100%
```
@@ -246,7 +246,7 @@ Password: `secret`
## Продвинутое использование `scopes` { #advanced-usage-with-scopes }
В OAuth2 существует понятие "диапазоны" ("`scopes`").
В OAuth2 существует понятие "`scopes`" (области).
С их помощью можно добавить определенный набор разрешений к JWT-токену.
@@ -274,4 +274,4 @@ Password: `secret`
При этом вы можете использовать и реализовывать безопасные стандартные протоколы, такие как OAuth2, относительно простым способом.
В **Расширенном руководстве пользователя** вы можете узнать больше о том, как использовать "диапазоны" ("`scopes`") OAuth2 для создания более точно настроенной системы разрешений в соответствии с теми же стандартами. OAuth2 с диапазонами — это механизм, используемый многими крупными провайдерами сервиса аутентификации, такими как Facebook, Google, GitHub, Microsoft, X (Twitter) и др., для авторизации сторонних приложений на взаимодействие с их API от имени их пользователей.
В **Расширенном руководстве пользователя** вы можете узнать больше о том, как использовать OAuth2 "`scopes`" (области) для создания более точно настроенной системы разрешений в соответствии с теми же стандартами. OAuth2 со scopes — это механизм, используемый многими крупными провайдерами сервиса аутентификации, такими как Facebook, Google, GitHub, Microsoft, X (Twitter) и др., для авторизации сторонних приложений на взаимодействие с их API от имени их пользователей.
+4 -4
View File
@@ -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 @@ $ pip install sqlmodel
<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)
```
+5 -5
View File
@@ -1,4 +1,4 @@
# Статические Файлы { #static-files }
# Статические файлы { #static-files }
Вы можете предоставлять статические файлы автоматически из директории, используя `StaticFiles`.
@@ -21,11 +21,11 @@
Вы также можете использовать `from starlette.staticfiles import StaticFiles`.
**FastAPI** предоставляет `starlette.staticfiles` под псевдонимом `fastapi.staticfiles`, просто для вашего удобства, как разработчика. Но на самом деле это берётся напрямую из библиотеки Starlette.
**FastAPI** предоставляет `starlette.staticfiles` как `fastapi.staticfiles`, просто для вашего удобства, как разработчика. Но на самом деле это берётся напрямую из библиотеки Starlette.
///
### Что такое "Монтирование" { #what-is-mounting }
### Что такое "монтирование" { #what-is-mounting }
"Монтирование" означает добавление полноценного "независимого" приложения на определённый путь, которое затем обрабатывает все подпути.
@@ -35,7 +35,7 @@
## Детали { #details }
Первый параметр `"/static"` относится к подпути, по которому это "подприложение" будет "примонтировано". Таким образом, любой путь начинающийся со `"/static"` будет обработан этим приложением.
Первый параметр `"/static"` относится к подпути, по которому это "подприложение" будет "примонтировано". Таким образом, любой путь, начинающийся со `"/static"`, будет обработан этим приложением.
Параметр `directory="static"` относится к имени директории, которая содержит ваши статические файлы.
@@ -45,4 +45,4 @@
## Больше информации { #more-info }
Для получения дополнительной информации о деталях и настройках ознакомьтесь с [документацией Starlette о статических файлах](https://www.starlette.dev/staticfiles/).
Для получения дополнительной информации о деталях и настройках ознакомьтесь с [документацией Starlette о статических файлах](https://starlette.dev/staticfiles/).
+12 -12
View File
@@ -1,21 +1,21 @@
# Тестирование { #testing }
Благодаря [Starlette](https://www.starlette.dev/testclient/), тестировать приложения **FastAPI** легко и приятно.
Благодаря [Starlette](https://starlette.dev/testclient/), тестировать приложения **FastAPI** легко и приятно.
Тестирование основано на библиотеке [HTTPX](https://www.python-httpx.org), которая в свою очередь основана на библиотеке Requests, так что все действия знакомы и интуитивно понятны.
Используя эти инструменты, Вы можете напрямую задействовать [pytest](https://docs.pytest.org/) с **FastAPI**.
## Использование класса `TestClient` { #using-testclient }
## Использование `TestClient` { #using-testclient }
/// note | Примечание
Для использования класса `TestClient` сначала установите [`httpx`](https://www.python-httpx.org).
Для использования `TestClient` сначала установите [`httpx`](https://www.python-httpx.org).
Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
Добавьте его в Ваш проект:
```console
$ pip install httpx
$ uv add httpx
```
///
@@ -52,7 +52,7 @@ $ pip install httpx
/// tip | Подсказка
Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md) в расширенном руководстве.
Если для тестирования Вам, помимо отправки запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, асинхронные функции базы данных), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md) в расширенном руководстве.
///
@@ -137,7 +137,7 @@ $ pip install httpx
Например:
* Чтобы передать *path*-параметр или *query*-параметр, добавьте его непосредственно в URL.
* Передаёте JSON в теле запроса, передав Python-объект (например: `dict`) через именованный параметр `json`.
* Чтобы передать тело запроса JSON, передайте Python-объект (например: `dict`) через именованный параметр `json`.
* Если же Вам необходимо отправить *данные формы* вместо JSON, то используйте параметр `data` вместо `json`.
* Для передачи *HTTP-заголовков*, передайте объект `dict` через параметр `headers`.
* Для передачи *cookies* также передайте `dict`, но через параметр `cookies`.
@@ -148,7 +148,7 @@ $ pip install httpx
Обратите внимание, что `TestClient` принимает данные, которые можно конвертировать в JSON, но не модели Pydantic.
Если в Ваших тестах есть модели Pydantic и Вы хотите отправить их в тестируемое приложение, то можете использовать функцию `jsonable_encoder`, описанную на странице [Кодировщик совместимый с JSON](encoder.md).
Если в Ваших тестах есть модель Pydantic и Вы хотите отправить её данные в приложение во время тестирования, то можете использовать функцию `jsonable_encoder`, описанную на странице [Кодировщик совместимый с JSON](encoder.md).
///
@@ -156,12 +156,12 @@ $ pip install httpx
Далее Вам нужно установить `pytest`.
Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
Добавьте его в Ваш проект:
<div class="termy">
```console
$ pip install pytest
$ uv add pytest
---> 100%
```
@@ -170,12 +170,12 @@ $ 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
+10 -839
View File
@@ -1,864 +1,35 @@
# Виртуальные окружения { #virtual-environments }
При работе с проектами на Python рекомендуется использовать **виртуальное окружение** (или похожий механизм), чтобы изолировать пакеты, которые вы устанавливаете для каждого проекта.
При работе с проектами на Python рекомендуется использовать **виртуальное окружение**, чтобы изолировать пакеты, установленные для каждого проекта.
/// note | Примечание
Если вы уже знакомы с виртуальными окружениями, знаете, как их создавать и использовать, вы можете пропустить этот раздел. 🤓
///
/// tip | Подсказка
**Виртуальное окружение** — это не то же самое, что **переменная окружения**.
**Переменная окружения** — это переменная в системе, которую могут использовать программы.
**Виртуальное окружение** — это директория с файлами внутри.
///
/// note | Примечание
На этой странице вы узнаете, как пользоваться **виртуальными окружениями** и как они работают.
Если вы готовы начать использовать **инструмент, который управляет всем** за вас (включая установку Python), попробуйте [uv](https://github.com/astral-sh/uv).
///
Для проектов FastAPI я рекомендую использовать [uv](https://docs.astral.sh/uv/) для управления проектом, его зависимостями и виртуальным окружением.
## Создание проекта { #create-a-project }
Сначала создайте директорию для вашего проекта.
Обычно я создаю папку с именем `code` в моем домашнем каталоге.
А внутри неё создаю отдельную директорию для каждого проекта.
Установите `uv`, используя [официальное руководство по установке](https://docs.astral.sh/uv/getting-started/installation/), а затем создайте проект:
<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`
Для создания виртуального окружения вы можете использовать модуль `venv`, который поставляется вместе с Python.
Запускайте команды внутри окружения проекта с помощью `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
Или если вы используете Bash для Windows (например, [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>
Если отображается исполняемый файл `python` по пути `.venv/bin/python` внутри вашего проекта (в нашем случае `awesome-project`), значит всё сработало. 🎉
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
</div>
Если отображается исполняемый файл `python` по пути `.venv\Scripts\python` внутри вашего проекта (в нашем случае `awesome-project`), значит всё сработало. 🎉
////
## Обновление `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`, чтобы исключить из Git всё, что находится в вашей `.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 }
Чтобы работать с FastAPI, вам нужно установить [Python](https://www.python.org/).
После этого вам нужно будет **установить** FastAPI и другие **пакеты**, которые вы хотите использовать.
Для установки пакетов обычно используют команду `pip`, которая идет вместе с Python (или альтернативные инструменты).
Тем не менее, если просто использовать `pip` напрямую, пакеты будут установлены в **глобальное окружение Python** (глобально установленный Python).
### Проблема { #the-problem }
Так в чём проблема установки пакетов в глобальное окружение Python?
Со временем вы, вероятно, будете писать много разных программ, зависящих от **разных пакетов**. И некоторые из ваших проектов будут зависеть от **разных версий** одного и того же пакета. 😱
Например, вы можете создать проект `philosophers-stone`, который зависит от пакета **`harry` версии `1`**. Значит, нужно установить `harry`.
```mermaid
flowchart LR
stone(philosophers-stone) -->|requires| harry-1[harry v1]
```
Затем вы создаёте другой проект `prisoner-of-azkaban`, который тоже зависит от `harry`, но ему нужен **`harry` версии `3`**.
```mermaid
flowchart LR
azkaban(prisoner-of-azkaban) --> |requires| 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[global env]
harry-1[harry v1]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -->|requires| harry-1
end
```
Но если затем вы захотите запустить `prisoner-of-azkaban`, вам нужно будет удалить `harry` версии `1` и установить `harry` версии `3` (или просто установка версии `3` автоматически удалит версию `1`).
<div class="termy">
```console
$ pip install "harry==3"
```
</div>
В итоге у вас будет установлен `harry` версии `3` в глобальном окружении Python.
А если вы снова попробуете запустить `philosophers-stone`, есть шанс, что он **не будет работать**, так как ему нужен `harry` версии `1`.
```mermaid
flowchart LR
subgraph global[global env]
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 project]
stone(philosophers-stone) -.-x|⛔️| harry-1
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --> |requires| 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>
Будет загружен сжатый файл с кодом FastAPI, обычно с [PyPI](https://pypi.org/project/fastapi/).
Также будут **загружены** файлы для других пакетов, от которых зависит FastAPI.
Затем все эти файлы будут **распакованы** и помещены в директорию на вашем компьютере.
По умолчанию они попадут в директорию из вашей установки Python — это **глобальное окружение**.
## Что такое виртуальные окружения { #what-are-virtual-environments }
Решение проблемы с пакетами в глобальном окружении — использовать **виртуальное окружение для каждого проекта**, над которым вы работаете.
Виртуальное окружение — это **директория**, очень похожая на глобальную, куда вы можете устанавливать пакеты для конкретного проекта.
Таким образом, у каждого проекта будет своё виртуальное окружение (директория `.venv`) со своими пакетами.
```mermaid
flowchart TB
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) --->|requires| harry-1
subgraph venv1[.venv]
harry-1[harry v1]
end
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --->|requires| 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
Или если вы используете Bash для Windows (например, [Git Bash](https://gitforwindows.org/)):
<div class="termy">
```console
$ source .venv/Scripts/activate
```
</div>
////
Эта команда создаст или изменит некоторые [переменные окружения](environment-variables.md), которые будут доступны для следующих команд.
Одна из таких переменных — `PATH`.
/// tip | Подсказка
Вы можете узнать больше о переменной окружения `PATH` в разделе [Переменные окружения](environment-variables.md#path-environment-variable).
///
Активация виртуального окружения добавляет его путь `.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` (например, из глобального окружения).
Активация виртуального окружения также меняет ещё несколько вещей, но это — одна из важнейших.
## Проверка виртуального окружения { #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` в терминале он попытается использовать Python из `philosophers-stone`.
<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` он будет использовать Python из виртуального окружения `prisoner-of-azkaban`.
<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**, включая разные версии
* Управлять **виртуальным окружением** ваших проектов
* Устанавливать **пакеты**
* Управлять **зависимостями и версиями** пакетов вашего проекта
* Обеспечивать наличие **точного** набора пакетов и версий к установке, включая их зависимости, чтобы вы были уверены, что сможете запускать проект в продакшн точно так же, как и на компьютере при разработке — это называется **locking**
* И многое другое
## Заключение { #conclusion }
Если вы прочитали и поняли всё это, теперь **вы знаете гораздо больше** о виртуальных окружениях, чем многие разработчики. 🤓
Знание этих деталей, скорее всего, пригодится вам в будущем, когда вы будете отлаживать что‑то сложное: вы будете понимать, **как всё работает под капотом**. 😎
Прочитайте [руководство по виртуальным окружениям](https://tiangolo.com/guides/virtual-environments/), чтобы узнать, как виртуальные окружения работают под капотом, включая активацию и альтернативный workflow с `python -m venv` и `pip`.