Sync fastapi docs from 50113da1 on 2026-09-11
This commit is contained in:
@@ -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`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
|
||||
@@ -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) мог к нему обращаться.
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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, которое можно использовать в других частях вашего кода.
|
||||
|
||||
|
||||
@@ -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 | Совет
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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`:
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -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/).
|
||||
|
||||
@@ -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` следующим образом:
|
||||
|
||||
|
||||
@@ -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 | Технические детали
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
/// note | Примечание
|
||||
|
||||
Для этого требуется установить `a2wsgi`, например с помощью `pip install a2wsgi`.
|
||||
Для этого требуется добавить `a2wsgi` в ваш проект, например с помощью `uv add a2wsgi`.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)):
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -86,7 +86,7 @@ $ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
|
||||
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
|
||||
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>]
|
||||
|
||||
@@ -1,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`.
|
||||
|
||||
@@ -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 поверх вашего приложения. Всё будет зависеть от того, как вы развертываете приложение: за вас это либо сделает ваш провайдер, либо вам придется сделать настройки самостоятельно.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||

|
||||
|
||||
* Альтернативная документация API в [**ReDoc**](https://github.com/Rebilly/ReDoc).
|
||||
* Альтернативная документация API в [**ReDoc**](https://github.com/Redocly/redoc).
|
||||
|
||||

|
||||
|
||||
@@ -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>’ы для баз данных.
|
||||
|
||||
|
||||
@@ -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. Вы можете попробовать его и рассмотреть для своих проектов.
|
||||
|
||||
@@ -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/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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
@@ -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)):
|
||||
|
||||

|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 и другие части современного фронтенд‑стека.
|
||||
|
||||
@@ -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/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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` с параметрами в *функциях‑обработчиках пути* и зависимостях, чтобы добавлять фоновые задачи.
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -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`:
|
||||
|
||||
|
||||
@@ -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) для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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]`.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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)):
|
||||
|
||||

|
||||
|
||||
@@ -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`.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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()` отдаёт файлы, уже сгенерированные сборкой вашего фронтенда.
|
||||
|
||||
@@ -81,7 +81,7 @@ HTTP статус-коды в диапазоне 400 означают, что п
|
||||
|
||||
## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
|
||||
|
||||
Вы можете добавить пользовательские обработчики исключений с помощью [тех же утилит обработки исключений из Starlette](https://www.starlette.dev/exceptions/).
|
||||
Вы можете добавить пользовательские обработчики исключений с помощью [тех же утилит обработки исключений из Starlette](https://starlette.dev/exceptions/).
|
||||
|
||||
Допустим, у вас есть пользовательское исключение `UnicornException`, которое вы (или используемая вами библиотека) можете вызвать с помощью `raise`.
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) и другие. 🤓
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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 | Технические детали
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -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 от имени их пользователей.
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -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/).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user