mirror of
https://github.com/fastapi/fastapi.git
synced 2026-11-07 00:23:08 -05:00
🌐 Update translations for uk (update-outdated) (#16655)
Co-authored-by: pr-submit[bot] <pr-submit[bot]@users.noreply.github.com> Co-authored-by: pr-push[bot] <pr-push[bot]@users.noreply.github.com>
This commit is contained in:
22 files changed
+346
-191
No files matched your search
@@ -13,12 +13,12 @@ from typing import Union
|
||||
|
||||
|
||||
def say_hi(name: Union[str, None]):
|
||||
print(f"Hi {name}!")
|
||||
print(f"Hi {name}!")
|
||||
```
|
||||
|
||||
У `typing` також є скорочення, щоб оголосити, що щось може бути `None`, - `Optional`.
|
||||
|
||||
Ось порада з моєї дуже «суб'єктивної» точки зору:
|
||||
Ось порада з моєї дуже **суб'єктивної** точки зору:
|
||||
|
||||
- 🚨 Уникайте використання `Optional[SomeType]`
|
||||
- Натомість ✨ **використовуйте `Union[SomeType, None]`** ✨.
|
||||
@@ -39,13 +39,13 @@ def say_hi(name: Optional[str]):
|
||||
print(f"Hey {name}!")
|
||||
```
|
||||
|
||||
Параметр `name` визначено як `Optional[str]`, але він не є необов'язковим, ви не можете викликати функцію без цього параметра:
|
||||
Параметр `name` визначено як `Optional[str]`, але він **не є необов'язковим**, ви не можете викликати функцію без цього параметра:
|
||||
|
||||
```Python
|
||||
say_hi() # О ні, це викликає помилку! 😱
|
||||
```
|
||||
|
||||
Параметр `name` все ще обов'язковий (не «необов'язковий»), тому що не має значення за замовчуванням. Водночас `name` приймає `None` як значення:
|
||||
Параметр `name` **все ще обов'язковий** (не *необов'язковий*), тому що не має значення за замовчуванням. Водночас `name` приймає `None` як значення:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # Це працює, None припустимий 🎉
|
||||
|
||||
@@ -71,7 +71,7 @@ $ uv run pytest
|
||||
Це еквівалентно:
|
||||
|
||||
```Python
|
||||
response = client.get('/')
|
||||
response = client.get("/")
|
||||
```
|
||||
|
||||
...що ми раніше використовували для надсилання запитів за допомогою `TestClient`.
|
||||
@@ -94,6 +94,6 @@ response = client.get('/')
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Якщо ви натрапили на `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")`.
|
||||
Якщо ви натрапили на `RuntimeError: Task attached to a different loop` під час інтеграції асинхронних викликів у ваші тести (наприклад, при використанні [MotorClient від MongoDB](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), пам'ятайте створювати об'єкти, яким потрібен цикл подій, лише всередині асинхронних функцій, наприклад, у зворотному виклику `@app.on_event("startup")`.
|
||||
|
||||
///
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
**Представник** перед вашим застосунком зазвичай встановлює деякі заголовки на льоту перед відправленням запитів до вашого **сервера**, щоб повідомити серверу, що запит було **направлено** через представника, вказати оригінальну (публічну) URL-адресу, включно з доменом, що використовується HTTPS тощо.
|
||||
|
||||
Програмний **сервер** (наприклад, **Uvicorn** через **FastAPI CLI**) здатний інтерпретувати ці заголовки і передавати цю інформацію вашому застосунку.
|
||||
**Сервер**, запущений за допомогою `fastapi run`, здатний інтерпретувати ці заголовки і передавати цю інформацію вашому застосунку.
|
||||
|
||||
Але з міркувань безпеки, оскільки сервер не знає, що він працює за довіреним представником, він не інтерпретуватиме ці заголовки.
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
|
||||
```console
|
||||
$ 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)
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -101,7 +99,7 @@ sequenceDiagram
|
||||
|
||||
У вас може бути представник, що додає префікс шляху до вашого застосунку.
|
||||
|
||||
У таких випадках ви можете використати `root_path` для конфігурації застосунку.
|
||||
У таких випадках ви можете налаштувати сервер за допомогою `fastapi run --root-path`.
|
||||
|
||||
`root_path` - це механізм, наданий специфікацією ASGI (на якій побудовано FastAPI через Starlette).
|
||||
|
||||
@@ -117,7 +115,7 @@ sequenceDiagram
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
|
||||
|
||||
І представник буде **«зрізати»** **префікс шляху** на льоту перед передачею запиту серверу застосунку (ймовірно, Uvicorn через FastAPI CLI), зберігаючи переконання вашого застосунку, що його обслуговують за `/app`, тож вам не доведеться оновлювати весь код, щоб додати префікс `/api/v1`.
|
||||
І представник буде **«зрізати»** **префікс шляху** на льоту перед передачею запиту серверу, зберігаючи переконання вашого застосунку, що його обслуговують за `/app`, тож вам не доведеться оновлювати весь код, щоб додати префікс `/api/v1`.
|
||||
|
||||
Дотепер усе працювало б як зазвичай.
|
||||
|
||||
@@ -161,7 +159,7 @@ IP `0.0.0.0` зазвичай означає, що програма слухає
|
||||
}
|
||||
```
|
||||
|
||||
У цьому прикладі «Proxy» може бути чимось на кшталт **Traefik**. А сервером буде щось на кшталт FastAPI CLI з **Uvicorn**, який запускає ваш застосунок FastAPI.
|
||||
У цьому прикладі «Proxy» може бути чимось на кшталт **Traefik**. А `fastapi run` запустить сервер, на якому працює ваш застосунок FastAPI.
|
||||
|
||||
### Задання `root_path` { #providing-the-root-path }
|
||||
|
||||
@@ -171,14 +169,10 @@ IP `0.0.0.0` зазвичай означає, що програма слухає
|
||||
|
||||
```console
|
||||
$ 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)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Якщо ви використовуєте Hypercorn, у нього також є опція `--root-path`.
|
||||
|
||||
/// note | Технічні деталі
|
||||
|
||||
Специфікація ASGI визначає `root_path` для такого випадку використання.
|
||||
@@ -195,14 +189,12 @@ $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
|
||||
|
||||
Потім, якщо ви запустите Uvicorn так:
|
||||
Потім, якщо ви запустите сервер так:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ 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)
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -216,30 +208,11 @@ $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
}
|
||||
```
|
||||
|
||||
### Встановлення `root_path` у застосунку FastAPI { #setting-the-root-path-in-the-fastapi-app }
|
||||
/// warning | Застарілий параметр `root_path`
|
||||
|
||||
Альтернативно, якщо у вас немає способу передати опцію командного рядка на кшталт `--root-path` чи еквівалентну, ви можете встановити параметр `root_path` під час створення вашого застосунку FastAPI:
|
||||
У FastAPI 0.145.0 і попередніх версіях `root_path` також можна було налаштувати в `FastAPI()`. Цей параметр тепер застарілий, оскільки його поведінка не узгоджувалася з конфігурацією сервера. Натомість використовуйте `fastapi run --root-path /api/v1`.
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
|
||||
|
||||
Передача `root_path` до `FastAPI` еквівалентна передачі опції командного рядка `--root-path` до Uvicorn або Hypercorn.
|
||||
|
||||
### Про `root_path` { #about-root-path }
|
||||
|
||||
Майте на увазі, що сервер (Uvicorn) не використовуватиме `root_path` ні для чого, окрім передачі його застосунку.
|
||||
|
||||
Але якщо ви перейдете у вашому браузері на [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), ви побачите звичайну відповідь:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World",
|
||||
"root_path": "/api/v1"
|
||||
}
|
||||
```
|
||||
|
||||
Тобто він не очікуватиме доступу за адресою `http://127.0.0.1:8000/api/v1/app`.
|
||||
|
||||
Uvicorn очікуватиме, що представник буде звертатися до Uvicorn на `http://127.0.0.1:8000/app`, і тоді саме представник відповідатиме за додавання додаткового префікса `/api/v1` зверху.
|
||||
///
|
||||
|
||||
## Про представників із вилученим префіксом шляху { #about-proxies-with-a-stripped-path-prefix }
|
||||
|
||||
@@ -247,7 +220,7 @@ Uvicorn очікуватиме, що представник буде зверт
|
||||
|
||||
Ймовірно, в багатьох випадках за замовчуванням представник не матиме вилученого префікса шляху.
|
||||
|
||||
У такому випадку (без вилученого префікса шляху) представник слухатиме щось на кшталт `https://myawesomeapp.com`, і коли браузер перейде на `https://myawesomeapp.com/api/v1/app`, а ваш сервер (наприклад, Uvicorn) слухає на `http://127.0.0.1:8000`, представник (без вилученого префікса) звернеться до Uvicorn за тим самим шляхом: `http://127.0.0.1:8000/api/v1/app`.
|
||||
У такому випадку (без вилученого префікса шляху) представник слухатиме щось на кшталт `https://myawesomeapp.com`, і коли браузер перейде на `https://myawesomeapp.com/api/v1/app`, а ваш сервер слухає на `http://127.0.0.1:8000`, представник (без вилученого префікса) звернеться до сервера за тим самим шляхом: `http://127.0.0.1:8000/api/v1/app`.
|
||||
|
||||
## Локальне тестування з Traefik { #testing-locally-with-traefik }
|
||||
|
||||
@@ -302,7 +275,7 @@ Uvicorn очікуватиме, що представник буде зверт
|
||||
|
||||
Цей файл налаштовує Traefik на використання префікса шляху `/api/v1`.
|
||||
|
||||
Потім Traefik переспрямовуватиме свої запити до вашого Uvicorn, який працює на `http://127.0.0.1:8000`.
|
||||
Потім Traefik переспрямовуватиме свої запити до вашого сервера, який працює на `http://127.0.0.1:8000`.
|
||||
|
||||
Тепер запустіть Traefik:
|
||||
|
||||
@@ -322,15 +295,13 @@ INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
|
||||
|
||||
```console
|
||||
$ 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)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Перевірте відповіді { #check-the-responses }
|
||||
|
||||
Тепер, якщо ви перейдете за URL із портом Uvicorn: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), ви побачите звичайну відповідь:
|
||||
Тепер, якщо ви перейдете за URL із портом сервера: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), ви побачите звичайну відповідь:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -360,15 +331,15 @@ $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
Звісно, ідея полягає в тому, що всі мають доступатися до застосунку через представника, тож варіант із префіксом шляху `/api/v1` є «правильним».
|
||||
|
||||
А варіант без префікса шляху (`http://127.0.0.1:8000/app`), який надає безпосередньо Uvicorn, має бути виключно для того, щоб _представник_ (Traefik) звертався до нього.
|
||||
А варіант без префікса шляху (`http://127.0.0.1:8000/app`), який надає безпосередньо сервер, має бути виключно для того, щоб _представник_ (Traefik) звертався до нього.
|
||||
|
||||
Це демонструє, як Представник (Traefik) використовує префікс шляху і як сервер (Uvicorn) використовує `root_path` з опції `--root-path`.
|
||||
Це демонструє, як Представник (Traefik) використовує префікс шляху і як сервер використовує `root_path` з опції `--root-path`.
|
||||
|
||||
### Перевірте інтерфейс документації { #check-the-docs-ui }
|
||||
|
||||
А тепер до цікавої частини. ✨
|
||||
|
||||
«Офіційний» спосіб доступу до застосунку - через представника з префіксом шляху, який ми визначили. Тож, як і очікується, якщо ви спробуєте інтерфейс документації, який обслуговує безпосередньо Uvicorn без префікса шляху в URL, це не запрацює, оскільки він очікує доступу через представника.
|
||||
«Офіційний» спосіб доступу до застосунку - через представника з префіксом шляху, який ми визначили. Тож, як і очікується, якщо ви спробуєте інтерфейс документації, який обслуговує безпосередньо сервер без префікса шляху в URL, це не запрацює, оскільки він очікує доступу через представника.
|
||||
|
||||
Ви можете перевірити це на [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs):
|
||||
|
||||
@@ -394,11 +365,11 @@ $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
За замовчуванням **FastAPI** створить `server` у схемі OpenAPI з URL для `root_path`.
|
||||
|
||||
Але ви також можете надати інші альтернативні `servers`, наприклад, якщо хочете, щоб той самий інтерфейс документації взаємодіяв і зі стейджингом, і з продакшном.
|
||||
Але ви також можете надати інші альтернативні `servers`, наприклад, якщо хочете, щоб *той самий* інтерфейс документації взаємодіяв і зі стейджингом, і з продакшном.
|
||||
|
||||
Якщо ви передасте власний список `servers`, і є `root_path` (тому що ваш API знаходиться за представником), **FastAPI** вставить «server» з цим `root_path` на початок списку.
|
||||
|
||||
Наприклад:
|
||||
Наприклад, використовуючи ту саму конфігурацію сервера `fastapi run --root-path /api/v1`:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
|
||||
|
||||
@@ -455,7 +426,7 @@ $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
Якщо ви не хочете, щоб **FastAPI** додавав автоматичний сервер, використовуючи `root_path`, скористайтеся параметром `root_path_in_servers=False`:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[8] *}
|
||||
|
||||
і тоді він не буде включений у схему OpenAPI.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# HTTP Basic Auth { #http-basic-auth }
|
||||
# Базова автентифікація HTTP { #http-basic-auth }
|
||||
|
||||
Для найпростіших випадків ви можете використовувати HTTP Basic Auth.
|
||||
Для найпростіших випадків ви можете використовувати базову автентифікацію HTTP.
|
||||
|
||||
У HTTP Basic Auth застосунок очікує заголовок, що містить ім'я користувача та пароль.
|
||||
У базовій автентифікації HTTP застосунок очікує заголовок, що містить ім'я користувача та пароль.
|
||||
|
||||
Якщо він його не отримує, повертається помилка HTTP 401 «Unauthorized».
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
Потім, коли ви введете це ім'я користувача та пароль, браузер автоматично надішле їх у заголовку.
|
||||
|
||||
## Простий HTTP Basic Auth { #simple-http-basic-auth }
|
||||
## Проста базова автентифікація HTTP { #simple-http-basic-auth }
|
||||
|
||||
- Імпортуйте `HTTPBasic` і `HTTPBasicCredentials`.
|
||||
- Створіть «`security` scheme» за допомогою `HTTPBasic`.
|
||||
- Використайте цей `security` як залежність у вашій операції шляху.
|
||||
- Створіть «схему `security`» за допомогою `HTTPBasic`.
|
||||
- Використайте цей `security` як залежність у вашій *операції шляху*.
|
||||
- Він повертає об'єкт типу `HTTPBasicCredentials`:
|
||||
- Він містить надіслані `username` і `password`.
|
||||
|
||||
@@ -45,12 +45,14 @@
|
||||
Це було б подібно до:
|
||||
|
||||
```Python
|
||||
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
|
||||
if not (credentials.username == "stanleyjobson") or not (
|
||||
credentials.password == "swordfish"
|
||||
):
|
||||
# Поверніть якусь помилку
|
||||
...
|
||||
```
|
||||
|
||||
Але використовуючи `secrets.compare_digest()`, це буде захищено від типу атак, що називаються «атаки за часом» (timing attacks).
|
||||
Але використовуючи `secrets.compare_digest()`, це буде захищено від типу атак, що називаються «атаки за часом».
|
||||
|
||||
### Атаки за часом { #timing-attacks }
|
||||
|
||||
@@ -82,7 +84,7 @@ Python доведеться порівняти весь `stanleyjobso` у обо
|
||||
|
||||
#### Час відповіді допомагає зловмисникам { #the-time-to-answer-helps-the-attackers }
|
||||
|
||||
У цей момент, помітивши, що сервер витратив на кілька мікросекунд більше, щоб надіслати відповідь «Невірні ім'я користувача або пароль», зловмисники знатимуть, що вони щось вгадали, деякі початкові літери правильні.
|
||||
У цей момент, помітивши, що сервер витратив на кілька мікросекунд більше, щоб надіслати відповідь «Невірні ім'я користувача або пароль», зловмисники знатимуть, що вони _щось_ вгадали, деякі початкові літери правильні.
|
||||
|
||||
І тоді вони можуть спробувати знову, знаючи, що це, ймовірно, щось більш схоже на `stanleyjobsox`, ніж на `johndoe`.
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
render_macros: false
|
||||
---
|
||||
|
||||
# Шаблони { #templates }
|
||||
|
||||
Ви можете використовувати будь-який рушій шаблонів з **FastAPI**.
|
||||
@@ -63,14 +67,10 @@ $ uv add jinja2
|
||||
|
||||
У HTML, який містить:
|
||||
|
||||
{% raw %}
|
||||
|
||||
```jinja
|
||||
Item ID: {{ id }}
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
...буде показано `id`, взятий із «контексту» `dict`, який ви передали:
|
||||
|
||||
```Python
|
||||
@@ -89,22 +89,48 @@ Item ID: 42
|
||||
|
||||
Тож фрагмент:
|
||||
|
||||
{% raw %}
|
||||
|
||||
```jinja
|
||||
<a href="{{ url_for('read_item', id=id) }}">
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
...згенерує посилання на той самий URL, який оброблятиме *функція операції шляху* `read_item(id=id)`.
|
||||
|
||||
Наприклад, з ID `42` це буде відображено як:
|
||||
`url_for()` повертає абсолютний URL, включно зі схемою та хостом, на основі поточного запиту.
|
||||
|
||||
Наприклад, якщо ваш застосунок доступний за адресою `https://example.com`, з ID `42` це буде відображено як:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/items/42">
|
||||
```
|
||||
|
||||
### Шляхи URL у шаблонах { #url-paths-in-templates }
|
||||
|
||||
Для посилань на той самий сайт ви можете використовувати атрибут `.path`, щоб отримати лише шлях URL, наприклад, у `templates/item_path.html`:
|
||||
|
||||
```jinja hl_lines="4 7"
|
||||
{!../../docs_src/templates/templates/item_path.html!}
|
||||
```
|
||||
|
||||
Передайте назву шаблону до `TemplateResponse`:
|
||||
|
||||
{* ../../docs_src/templates/tutorial002_py310.py ln[14:18] hl[17] *}
|
||||
|
||||
У тому самому прикладі посилання на предмет буде відображено як:
|
||||
|
||||
```html
|
||||
<a href="/items/42">
|
||||
```
|
||||
|
||||
Початковий `/` робить цей шлях відносним до кореня поточного сайту.
|
||||
|
||||
Атрибут `.path` не включає схему, хост, параметри запиту та фрагмент. Використовуйте повний URL для посилань на інший хост.
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Якщо ваш застосунок працює за представником, налаштуйте направлені заголовки та `root_path`, як описано в розділі [За представником](behind-a-proxy.md).
|
||||
|
||||
///
|
||||
|
||||
## Шаблони і статичні файли { #templates-and-static-files }
|
||||
|
||||
Ви також можете використовувати `url_for()` у шаблоні, наприклад з `StaticFiles`, які ви змонтували з `name="static"`.
|
||||
|
||||
@@ -15,7 +15,7 @@ results = await some_library()
|
||||
Тоді оголошуйте ваші *функції операції шляху* з `async def`, наприклад:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
@app.get("/")
|
||||
async def read_results():
|
||||
results = await some_library()
|
||||
return results
|
||||
@@ -32,7 +32,7 @@ async def read_results():
|
||||
Якщо ви використовуєте сторонню бібліотеку, яка взаємодіє з чимось (база даних, API, файлова система тощо) і не підтримує використання `await` (наразі це стосується більшості бібліотек баз даних), тоді оголошуйте ваші *функції операції шляху* як зазвичай, просто з `def`, наприклад:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
@app.get("/")
|
||||
def results():
|
||||
results = some_library()
|
||||
return results
|
||||
@@ -343,7 +343,7 @@ burgers = get_burgers(2)
|
||||
Отже, якщо ви використовуєте бібліотеку, яку можна викликати з `await`, вам потрібно створити *функцію операції шляху*, що її використовує, з `async def`, як тут:
|
||||
|
||||
```Python hl_lines="2-3"
|
||||
@app.get('/burgers')
|
||||
@app.get("/burgers")
|
||||
async def read_burgers():
|
||||
burgers = await get_burgers(2)
|
||||
return burgers
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### На основі відкритих стандартів { #based-on-open-standards }
|
||||
|
||||
* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) для створення API, включаючи оголошення <dfn title="також відомі як: кінцеві точки, маршрути">шляхових</dfn> <dfn title="також відомі як методи HTTP, як-от POST, GET, PUT, DELETE">операцій</dfn>, параметрів, тіл запитів, безпеки тощо.
|
||||
* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) для створення API, включаючи оголошення <dfn title="також відомі як методи HTTP, як-от POST, GET, PUT, DELETE">операцій</dfn> <dfn title="також відомий як: кінцева точка, маршрут">шляху</dfn>, параметрів, тіл запитів, безпеки тощо.
|
||||
* Автоматична документація моделей даних за допомогою [**Схеми JSON**](https://json-schema.org/) (оскільки OpenAPI базується саме на Схемі JSON).
|
||||
* Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури.
|
||||
* Це також дає змогу використовувати автоматичну **генерацію клієнтського коду** багатьма мовами.
|
||||
@@ -36,6 +36,7 @@ from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
# Оголосіть змінну як str
|
||||
# та отримайте підтримку редактора всередині функції
|
||||
def main(user_id: str):
|
||||
@@ -105,7 +106,7 @@ FastAPI має розумні **налаштування за замовчува
|
||||
|
||||
* Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема:
|
||||
* JSON-об'єктів (`dict`).
|
||||
* JSON-масивів (`list`) із визначенням типів елементів.
|
||||
* JSON-масивів (`list`) із визначенням типів предметів.
|
||||
* Полів-строк (`str`) із визначенням мінімальної та максимальної довжини.
|
||||
* Чисел (`int`, `float`) з мінімальними та максимальними значеннями тощо.
|
||||
|
||||
@@ -123,8 +124,8 @@ FastAPI має розумні **налаштування за замовчува
|
||||
|
||||
Підтримуються всі схеми безпеки, визначені в OpenAPI, включно з:
|
||||
|
||||
* HTTP Basic.
|
||||
* **OAuth2** (також із підтримкою **JWT tokens**). Перегляньте навчальний посібник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md).
|
||||
* Базова автентифікація HTTP.
|
||||
* **OAuth2** (також із підтримкою **токенів JWT**). Перегляньте навчальний посібник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md).
|
||||
* Ключі API в:
|
||||
* Заголовках.
|
||||
* Параметрах запиту.
|
||||
@@ -170,7 +171,7 @@ FastAPI містить надзвичайно просту у використа
|
||||
* Фонові задачі у процесі.
|
||||
* Події запуску та вимкнення.
|
||||
* Клієнт для тестування, побудований на HTTPX.
|
||||
* Підтримка **CORS**, **GZip**, статичних файлів, потокових відповідей.
|
||||
* Підтримка **CORS**, GZip, статичних файлів, потокових відповідей.
|
||||
* Підтримка **сесій і кукі**.
|
||||
* 100% покриття тестами.
|
||||
* 100% анотована типами кодова база.
|
||||
@@ -190,7 +191,7 @@ FastAPI містить надзвичайно просту у використа
|
||||
* **Ніякої плутанини**:
|
||||
* Не потрібно вчити нову мікромову для визначення схем.
|
||||
* Якщо ви знаєте типи Python, ви знаєте, як використовувати Pydantic.
|
||||
* Легко працює з вашим **<abbr title="Integrated Development Environment - Інтегроване середовище розробки: схоже на код-редактор">IDE</abbr>/<dfn title="Програма, що перевіряє код на помилки">linter</dfn>/мозком**:
|
||||
* Легко працює з вашим **<abbr title="Integrated Development Environment - Інтегроване середовище розробки: схоже на код-редактор">IDE</abbr>/<dfn title="Програма, що перевіряє код на помилки">лінтером</dfn>/мозком**:
|
||||
* Оскільки структури даних pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними.
|
||||
* Валідує **складні структури**:
|
||||
* Використання ієрархічних моделей Pydantic, `List` і `Dict` з Python `typing` тощо.
|
||||
|
||||
+16
-16
@@ -17,16 +17,16 @@ include_yaml:
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Тест">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Покриття">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Версія пакета">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Підтримувані версії Python">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -43,7 +43,7 @@ FastAPI - це сучасний, швидкий (високопродуктив
|
||||
Ключові особливості:
|
||||
|
||||
* **Швидкий**: дуже висока продуктивність, на рівні з **NodeJS** та **Go** (завдяки Starlette та Pydantic). [Один із найшвидших Python-фреймворків](#performance).
|
||||
* **Швидке написання коду**: пришвидшує розробку функціоналу приблизно на 200%–300%. *
|
||||
* **Швидке написання коду**: пришвидшує розробку функціоналу приблизно на 200%-300%. *
|
||||
* **Менше помилок**: зменшує приблизно на 40% кількість помилок, спричинених людиною (розробником). *
|
||||
* **Інтуїтивний**: чудова підтримка редакторами коду. <dfn title="також відоме як автодоповнення, автозавершення, IntelliSense">Автодоповнення</dfn> всюди. Менше часу на налагодження.
|
||||
* **Простий**: спроєктований так, щоб бути простим у використанні та вивченні. Менше часу на читання документації.
|
||||
@@ -125,25 +125,25 @@ FastAPI - це сучасний, швидкий (високопродуктив
|
||||
|
||||
<div class="only-github" markdown="1">
|
||||
|
||||
"_[...] Я дуже часто використовую **FastAPI** останнім часом. [...] Я насправді планую використовувати його для всіх **ML-сервісів моєї команди в Microsoft**. Деякі з них інтегруються до основного продукту **Windows** і деяких продуктів **Office**._"
|
||||
«_[...] Я дуже часто використовую **FastAPI** останнім часом. [...] Я насправді планую використовувати його для всіх **ML-сервісів моєї команди в Microsoft**. Деякі з них інтегруються до основного продукту **Windows** і деяких продуктів **Office**._»
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(джерело)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Ми прийняли бібліотеку **FastAPI**, щоб запустити сервер **REST**, до якого можна надсилати запити для отримання **прогнозів**. [для Ludwig]_"
|
||||
«_Ми прийняли бібліотеку **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://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(джерело)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin та Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(джерело)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** із задоволенням оголошує про випуск з відкритим кодом нашого фреймворку оркестрації **керування кризами**: **Dispatch**! [побудовано з **FastAPI**]_"
|
||||
«_**Netflix** із задоволенням оголошує про випуск з відкритим кодом нашого фреймворку оркестрації **керування кризами**: **Dispatch**! [побудовано з **FastAPI**]_»
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(джерело)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Якщо хтось хоче створювати продакшн-API на Python, я дуже рекомендую **FastAPI**. Він **чудово спроєктований**, **простий у використанні** і **дуже масштабований**, він став **ключовим компонентом** у нашій стратегії розробки з пріоритетом API і забезпечує багато автоматизацій та сервісів, як-от наш Virtual TAC Engineer._"
|
||||
«_Якщо хтось хоче створювати продакшн-API на Python, я дуже рекомендую **FastAPI**. Він **чудово спроєктований**, **простий у використанні** і **дуже масштабований**, він став **ключовим компонентом** у нашій стратегії розробки з пріоритетом API і забезпечує багато автоматизацій та сервісів, як-от наш Virtual TAC Engineer._»
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(джерело)</small></a></div>
|
||||
|
||||
@@ -155,7 +155,7 @@ FastAPI - це сучасний, швидкий (високопродуктив
|
||||
|
||||
Наприкінці 2025 року вийшов [міні-документальний фільм про FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE), ви можете переглянути його онлайн:
|
||||
|
||||
<a class="fastapi-feature-banner" href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
||||
<a class="fastapi-feature-banner" href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="Міні-документальний фільм про FastAPI"></a>
|
||||
|
||||
## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis }
|
||||
|
||||
@@ -360,11 +360,11 @@ def update_item(item_id: int, item: Item):
|
||||
|
||||
* Натисніть кнопку «Try it out», вона дозволяє заповнити параметри та безпосередньо взаємодіяти з API:
|
||||
|
||||

|
||||

|
||||
|
||||
* Потім натисніть кнопку «Execute», інтерфейс користувача зв'яжеться з вашим API, надішле параметри, отримає результати та покаже їх на екрані:
|
||||
|
||||

|
||||

|
||||
|
||||
### Оновлення альтернативної документації API { #alternative-api-docs-upgrade }
|
||||
|
||||
@@ -467,7 +467,7 @@ item: Item
|
||||
|
||||
...і побачите, як ваш редактор автоматично доповнюватиме атрибути та знатиме їхні типи:
|
||||
|
||||

|
||||

|
||||
|
||||
Для більш повного прикладу, що включає більше можливостей, перегляньте <a href="https://fastapi.tiangolo.com/uk/tutorial/">Навчальний посібник - Посібник користувача</a>.
|
||||
|
||||
@@ -483,7 +483,7 @@ item: Item
|
||||
* **WebSockets**
|
||||
* надзвичайно прості тести на основі HTTPX та `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* **Сесії на основі кукі**
|
||||
* ...та більше.
|
||||
|
||||
### Розгортання застосунку (необовʼязково) { #deploy-your-app-optional }
|
||||
@@ -544,7 +544,7 @@ FastAPI залежить від Pydantic і Starlette.
|
||||
|
||||
Використовується Starlette:
|
||||
|
||||
* [`httpx`](https://www.python-httpx.org) - потрібно, якщо ви хочете використовувати `TestClient`.
|
||||
* [`httpx2`](https://pydantic.dev/docs/httpx2/) (або `httpx`) - використовується `TestClient`.
|
||||
* [`jinja2`](https://jinja.palletsprojects.com) - потрібно, якщо ви хочете використовувати конфігурацію шаблонів за замовчуванням.
|
||||
* [`python-multipart`](https://github.com/Kludex/python-multipart) - потрібно, якщо ви хочете підтримувати форми з <dfn title="перетворення строки, що надходить із HTTP-запиту, у дані Python">«парсингом»</dfn> через `request.form()`.
|
||||
|
||||
|
||||
@@ -58,17 +58,17 @@ from app.routers import items
|
||||
|
||||
```bash
|
||||
.
|
||||
├── app # «app» - це пакет Python
|
||||
│ ├── __init__.py # цей файл робить «app» «пакетом Python»
|
||||
│ ├── main.py # модуль «main», напр. import app.main
|
||||
│ ├── dependencies.py # модуль «dependencies», напр. import app.dependencies
|
||||
│ └── routers # «routers» - це «підпакет Python»
|
||||
│ │ ├── __init__.py # робить «routers» «підпакетом Python»
|
||||
│ │ ├── items.py # підмодуль «items», напр. import app.routers.items
|
||||
│ │ └── users.py # підмодуль «users», напр. import app.routers.users
|
||||
│ └── internal # «internal» - це «підпакет Python»
|
||||
│ ├── __init__.py # робить «internal» «підпакетом Python»
|
||||
│ └── admin.py # підмодуль «admin», напр. import app.internal.admin
|
||||
├── app # "app" - це пакет Python
|
||||
│ ├── __init__.py # цей файл робить "app" "пакетом Python"
|
||||
│ ├── main.py # модуль "main", напр. import app.main
|
||||
│ ├── dependencies.py # модуль "dependencies", напр. import app.dependencies
|
||||
│ └── routers # "routers" - це "підпакет Python"
|
||||
│ │ ├── __init__.py # робить "routers" "підпакетом Python"
|
||||
│ │ ├── items.py # підмодуль "items", напр. import app.routers.items
|
||||
│ │ └── users.py # підмодуль "users", напр. import app.routers.users
|
||||
│ └── internal # "internal" - це "підпакет Python"
|
||||
│ ├── __init__.py # робить "internal" "підпакетом Python"
|
||||
│ └── admin.py # підмодуль "admin", напр. import app.internal.admin
|
||||
```
|
||||
|
||||
## `APIRouter` { #apirouter }
|
||||
@@ -95,7 +95,7 @@ from app.routers import items
|
||||
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||
|
||||
Можете думати про `APIRouter` як про «міні `FastAPI`».
|
||||
Можете думати про `APIRouter` як про клас «міні `FastAPI`».
|
||||
|
||||
Підтримуються ті самі опції.
|
||||
|
||||
@@ -129,7 +129,7 @@ from app.routers import items
|
||||
|
||||
## Інший модуль з `APIRouter` { #another-module-with-apirouter }
|
||||
|
||||
Припустімо, у вас також є кінцеві точки для обробки «items» у модулі `app/routers/items.py`.
|
||||
Припустімо, у вас також є кінцеві точки для обробки «предметів» вашого застосунку в модулі `app/routers/items.py`.
|
||||
|
||||
У вас є *операції шляху* для:
|
||||
|
||||
@@ -155,8 +155,7 @@ from app.routers import items
|
||||
|
||||
```Python hl_lines="1"
|
||||
@router.get("/{item_id}")
|
||||
async def read_item(item_id: str):
|
||||
...
|
||||
async def read_item(item_id: str): ...
|
||||
```
|
||||
|
||||
...префікс не має містити кінцевий `/`.
|
||||
@@ -180,7 +179,7 @@ async def read_item(item_id: str):
|
||||
|
||||
...як ми і планували.
|
||||
|
||||
* Вони будуть позначені списком міток, що містить один рядок `"items"`.
|
||||
* Вони будуть позначені списком міток, що містить одну строку `"items"`.
|
||||
* Ці «мітки» особливо корисні для автоматичної інтерактивної документації (за допомогою OpenAPI).
|
||||
* Усі вони включатимуть наперед визначені `responses`.
|
||||
* Для всіх цих *операцій шляху* список `dependencies` буде оцінений/виконаний перед ними.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Тіло — Поля { #body-fields }
|
||||
# Тіло - Поля { #body-fields }
|
||||
|
||||
Так само як ви можете оголошувати додаткову валідацію та метадані в параметрах *функції операції шляху* за допомогою `Query`, `Path` та `Body`, ви можете оголошувати валідацію та метадані всередині моделей Pydantic, використовуючи `Field` від Pydantic.
|
||||
|
||||
@@ -43,13 +43,13 @@
|
||||
|
||||
## Додавання додаткової інформації { #add-extra-information }
|
||||
|
||||
Ви можете оголошувати додаткову інформацію в `Field`, `Query`, `Body` тощо. І вона буде включена до згенерованої JSON Schema.
|
||||
Ви можете оголошувати додаткову інформацію за допомогою `json_schema_extra` в `Field`, `Query`, `Body` тощо. І вона буде включена до згенерованої Схеми JSON.
|
||||
|
||||
Ви дізнаєтеся більше про додавання додаткової інформації пізніше в документації, коли вивчатимете, як оголошувати приклади.
|
||||
|
||||
/// warning | Попередження
|
||||
|
||||
Додаткові ключі, передані в `Field`, також будуть присутні в отриманій схемі OpenAPI для вашого застосунку.
|
||||
Додаткові ключі, передані в `json_schema_extra`, також будуть присутні в отриманій схемі OpenAPI для вашого застосунку.
|
||||
Оскільки ці ключі не обов'язково є частиною специфікації OpenAPI, деякі інструменти OpenAPI, наприклад [валідатор OpenAPI](https://validator.swagger.io/), можуть не працювати з вашою згенерованою схемою.
|
||||
|
||||
///
|
||||
@@ -58,4 +58,4 @@
|
||||
|
||||
Ви можете використовувати `Field` від Pydantic, щоб оголошувати додаткову валідацію та метадані для атрибутів моделі.
|
||||
|
||||
Ви також можете використовувати додаткові keyword arguments, щоб передавати додаткові метадані JSON Schema.
|
||||
Ви також можете використовувати `json_schema_extra`, щоб передавати додаткові метадані Схеми JSON.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Моделі параметрів Cookie { #cookie-parameter-models }
|
||||
# Моделі параметрів кукі { #cookie-parameter-models }
|
||||
|
||||
Якщо у вас є група **cookies**, які пов'язані між собою, ви можете створити **Pydantic-модель**, щоб оголосити їх. 🍪
|
||||
Якщо у вас є група **кукі**, які пов'язані між собою, ви можете створити **Pydantic-модель**, щоб оголосити їх. 🍪
|
||||
|
||||
Це дозволить вам повторно **використовувати модель** у **різних місцях**, а також оголосити валідацію та метадані для всіх параметрів одночасно. 😎
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
///
|
||||
|
||||
## Cookie з Pydantic-моделлю { #cookies-with-a-pydantic-model }
|
||||
## Кукі з Pydantic-моделлю { #cookies-with-a-pydantic-model }
|
||||
|
||||
Оголосіть **cookie**-параметри, які вам потрібні, у **Pydantic-моделі**, а потім оголосіть параметр як `Cookie`:
|
||||
Оголосіть параметри **кукі**, які вам потрібні, у **Pydantic-моделі**, а потім оголосіть параметр як `Cookie`:
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
|
||||
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **cookies**, отриманих у запиті, і передавати вам Pydantic-модель, яку ви визначили.
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **кукі**, отриманих у запиті, і передавати вам Pydantic-модель, яку ви визначили.
|
||||
|
||||
## Перевірка у документації { #check-the-docs }
|
||||
|
||||
Ви можете побачити визначені cookies в інтерфейсі документації за адресою `/docs`:
|
||||
Ви можете побачити визначені кукі в інтерфейсі документації за адресою `/docs`:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/cookie-param-models/image01.png">
|
||||
@@ -34,29 +34,29 @@
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
Майте на увазі, що оскільки **браузери обробляють cookies** особливим чином і «за лаштунками», вони **не** дозволяють **JavaScript** легко з ними працювати.
|
||||
Майте на увазі, що оскільки **браузери обробляють кукі** особливим чином і «за лаштунками», вони **не** дозволяють **JavaScript** легко з ними працювати.
|
||||
|
||||
Якщо ви зайдете до **інтерфейсу документації API** за адресою `/docs`, ви зможете побачити **документацію** для cookies у ваших *операціях шляху*.
|
||||
Якщо ви зайдете до **інтерфейсу документації API** за адресою `/docs`, ви зможете побачити **документацію** для кукі у ваших *операціях шляху*.
|
||||
|
||||
Але навіть якщо ви **заповните дані** й натиснете "Execute", оскільки інтерфейс документації працює з **JavaScript**, cookies не будуть відправлені, і ви побачите **помилку**, ніби ви не ввели жодних значень.
|
||||
Але навіть якщо ви **заповните дані** й натиснете «Execute», оскільки інтерфейс документації працює з **JavaScript**, кукі не будуть відправлені, і ви побачите **помилку**, ніби ви не ввели жодних значень.
|
||||
|
||||
///
|
||||
|
||||
## Заборона додаткових cookie { #forbid-extra-cookies }
|
||||
## Заборона додаткових кукі { #forbid-extra-cookies }
|
||||
|
||||
У деяких спеціальних випадках (ймовірно, не дуже поширених) ви можете захотіти **обмежити** cookies, які хочете отримувати.
|
||||
У деяких спеціальних випадках (ймовірно, не дуже поширених) ви можете захотіти **обмежити** кукі, які хочете отримувати.
|
||||
|
||||
Ваш API тепер має можливість контролювати власну <dfn title="Це жарт, про всяк випадок. Це не має стосунку до згоди на cookies, просто кумедно, що навіть API тепер може відхиляти бідні cookies. Візьміть печиво. 🍪">згоду на cookies</dfn>. 🤪🍪
|
||||
Ваш API тепер має можливість контролювати власну <dfn title="Це жарт, про всяк випадок. Це не має стосунку до згоди на кукі, просто кумедно, що навіть API тепер може відхиляти бідні кукі. Візьміть печиво. 🍪">згоду на кукі</dfn>. 🤪🍪
|
||||
|
||||
Ви можете використовувати налаштування моделі Pydantic, щоб `forbid` будь-які `extra` поля:
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
Якщо клієнт спробує надіслати якісь **додаткові cookies**, він отримає відповідь з **помилкою**.
|
||||
Якщо клієнт спробує надіслати якісь **додаткові кукі**, він отримає відповідь з **помилкою**.
|
||||
|
||||
Бідні банери cookie, які так старанно намагаються отримати вашу згоду, щоб <dfn title="Це ще один жарт. Не звертайте на мене уваги. Випийте трохи кави до свого печива. ☕">API її відхилила</dfn>. 🍪
|
||||
Бідні банери кукі, які так старанно намагаються отримати вашу згоду, щоб <dfn title="Це ще один жарт. Не звертайте на мене уваги. Випийте трохи кави до свого печива. ☕">API її відхилила</dfn>. 🍪
|
||||
|
||||
Наприклад, якщо клієнт спробує надіслати cookie `santa_tracker` зі значенням `good-list-please`, він отримає відповідь з помилкою, яка повідомить, що `santa_tracker` <dfn title="Санта не схвалює нестачу cookies. 🎅 Гаразд, досить жартів про cookies.">cookie не дозволено</dfn>:
|
||||
Наприклад, якщо клієнт спробує надіслати кукі `santa_tracker` зі значенням `good-list-please`, він отримає відповідь з **помилкою**, яка повідомить, що `santa_tracker` <dfn title="Санта не схвалює нестачу кукі. 🎅 Гаразд, досить жартів про кукі.">кукі не дозволено</dfn>:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -71,6 +71,22 @@
|
||||
}
|
||||
```
|
||||
|
||||
## Поєднання моделей параметрів { #combine-parameter-models }
|
||||
|
||||
Ви можете поєднувати кілька моделей параметрів кукі з окремими параметрами кукі та залежностями. Дані для кожної моделі витягуються та валідуються незалежно, як пояснено для [моделей параметрів запиту](query-param-models.md#combine-parameter-models).
|
||||
|
||||
Налаштування `extra` кожної моделі застосовується до всіх параметрів кукі, включно з оголошеними в інших моделях або залежностях. З `extra="forbid"` будь-які кукі поза цією моделлю відхиляються. З `extra="allow"` ці кукі включаються як додаткові поля моделі.
|
||||
|
||||
## Необов'язкові моделі параметрів кукі { #optional-cookie-parameter-models }
|
||||
|
||||
Оголосіть модель параметрів кукі з `| None` і значенням за замовчуванням `None`, щоб зробити групу необов'язковою.
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial003_an_py310.py hl[15] *}
|
||||
|
||||
Якщо не надіслано ні `theme`, ні `locale`, `preferences` має значення `None`. Якщо надіслано хоча б одне з них, FastAPI валідує модель і вимагає обидва поля.
|
||||
|
||||
Застосовуються ті самі правила щодо значень за замовчуванням, додаткових полів і OpenAPI, що й для [необов'язкових моделей параметрів запиту](query-param-models.md#optional-query-parameter-models).
|
||||
|
||||
## Підсумок { #summary }
|
||||
|
||||
Ви можете використовувати **Pydantic-моделі** для оголошення <dfn title="Візьміть останнє печиво перед тим, як підете. 🍪">**кукі**</dfn> у **FastAPI**. 😎
|
||||
@@ -1,14 +1,14 @@
|
||||
# Підзалежності { #sub-dependencies }
|
||||
|
||||
Ви можете створювати залежності, які мають підзалежності.
|
||||
Ви можете створювати залежності, які мають **підзалежності**.
|
||||
|
||||
Вони можуть бути настільки глибокими, наскільки потрібно.
|
||||
Вони можуть бути настільки **глибокими**, наскільки потрібно.
|
||||
|
||||
**FastAPI** подбає про їх розв'язання.
|
||||
|
||||
## Перша залежність «dependable» { #first-dependency-dependable }
|
||||
## Перша залежність «залежний» { #first-dependency-dependable }
|
||||
|
||||
Можна створити першу залежність («dependable») так:
|
||||
Можна створити першу залежність («залежний») так:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
Це досить просто (не дуже корисно), але допоможе зосередитися на тому, як працюють підзалежності.
|
||||
|
||||
## Друга залежність, «dependable» і «dependant» { #second-dependency-dependable-and-dependant }
|
||||
## Друга залежність, «залежний» і «залежний» { #second-dependency-dependable-and-dependant }
|
||||
|
||||
Далі ви можете створити іншу функцію залежності («dependable»), яка водночас оголошує власну залежність (тож вона також є «dependant»):
|
||||
Далі ви можете створити іншу функцію залежності («залежний»), яка водночас оголошує власну залежність (тож вона також є «залежною»):
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
|
||||
|
||||
Зосередьмося на оголошених параметрах:
|
||||
|
||||
- Хоча ця функція сама є залежністю («dependable»), вона також оголошує іншу залежність (вона «залежить» від чогось).
|
||||
- Хоча ця функція сама є залежністю («залежний»), вона також оголошує іншу залежність (вона «залежить» від чогось).
|
||||
- Вона залежить від `query_extractor` і присвоює значення, яке він повертає, параметру `q`.
|
||||
- Вона також оголошує необов'язкове кукі `last_query` типу `str`.
|
||||
- Якщо користувач не надав параметр запиту `q`, ми використовуємо останній запит, який зберегли раніше в кукі.
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
Зверніть увагу, що ми оголошуємо лише одну залежність у функції операції шляху — `query_or_cookie_extractor`.
|
||||
Зверніть увагу, що ми оголошуємо лише одну залежність у *функції операції шляху* - `query_or_cookie_extractor`.
|
||||
|
||||
Але **FastAPI** знатиме, що спочатку треба розв'язати `query_extractor`, щоб передати його результат у `query_or_cookie_extractor` під час виклику.
|
||||
|
||||
@@ -56,16 +56,18 @@ query_extractor --> query_or_cookie_extractor --> read_query
|
||||
|
||||
## Використання тієї ж залежності кілька разів { #using-the-same-dependency-multiple-times }
|
||||
|
||||
Якщо одна з ваших залежностей оголошена кілька разів для однієї операції шляху, наприклад, кілька залежностей мають спільну підзалежність, **FastAPI** знатиме, що цю підзалежність потрібно викликати лише один раз на запит.
|
||||
Якщо одна з ваших залежностей оголошена кілька разів для однієї *операції шляху*, наприклад, кілька залежностей мають спільну підзалежність, **FastAPI** знатиме, що цю підзалежність потрібно викликати лише один раз на запит.
|
||||
|
||||
І він збереже повернуте значення у <dfn title="Утиліта/система для збереження обчислених/згенерованих значень, щоб повторно використовувати їх замість повторного обчислення.">«кеш»</dfn> і передасть його всім «dependants», яким воно потрібне в цьому конкретному запиті, замість того щоб викликати залежність кілька разів для одного й того ж запиту.
|
||||
І він збереже повернуте значення у <dfn title="Утиліта/система для збереження обчислених/згенерованих значень, щоб повторно використовувати їх замість повторного обчислення.">«кеш»</dfn> і передасть його всім «залежним», яким воно потрібне в цьому конкретному запиті, замість того щоб викликати залежність кілька разів для одного й того ж запиту.
|
||||
|
||||
У просунутому сценарії, коли ви знаєте, що залежність має викликатися на кожному кроці (можливо, кілька разів) у межах того самого запиту замість використання «кешованого» значення, ви можете встановити параметр `use_cache=False` при використанні `Depends`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
||||
```Python hl_lines="2"
|
||||
async def needy_dependency(
|
||||
fresh_value: Annotated[str, Depends(get_value, use_cache=False)],
|
||||
):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
|
||||
@@ -90,7 +92,7 @@ async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False
|
||||
|
||||
Попри всі модні терміни, система **впровадження залежностей** досить проста.
|
||||
|
||||
Це просто функції, які виглядають так само, як функції операцій шляху.
|
||||
Це просто функції, які виглядають так само, як *функції операцій шляху*.
|
||||
|
||||
Втім вона дуже потужна і дозволяє оголошувати довільно глибоко вкладені «графи» залежностей (дерева).
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ print(user_dict)
|
||||
|
||||
```Python
|
||||
{
|
||||
'username': 'john',
|
||||
'password': 'secret',
|
||||
'email': 'john.doe@example.com',
|
||||
'full_name': None,
|
||||
"username": "john",
|
||||
"password": "secret",
|
||||
"email": "john.doe@example.com",
|
||||
"full_name": None,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,10 +86,10 @@ UserInDB(
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username = user_dict["username"],
|
||||
password = user_dict["password"],
|
||||
email = user_dict["email"],
|
||||
full_name = user_dict["full_name"],
|
||||
username=user_dict["username"],
|
||||
password=user_dict["password"],
|
||||
email=user_dict["email"],
|
||||
full_name=user_dict["full_name"],
|
||||
)
|
||||
```
|
||||
|
||||
@@ -124,11 +124,11 @@ UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username = user_dict["username"],
|
||||
password = user_dict["password"],
|
||||
email = user_dict["email"],
|
||||
full_name = user_dict["full_name"],
|
||||
hashed_password = hashed_password,
|
||||
username=user_dict["username"],
|
||||
password=user_dict["password"],
|
||||
email=user_dict["email"],
|
||||
full_name=user_dict["full_name"],
|
||||
hashed_password=hashed_password,
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
У деяких особливих випадках (ймовірно, не дуже поширених) ви можете захотіти **обмежити** заголовки, які хочете отримати.
|
||||
|
||||
Ви можете використати конфігурацію моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
|
||||
Ви можете використати конфігурацію моделі Pydantic, щоб заборонити (`forbid`) будь-які додаткові (`extra`) поля:
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
@@ -63,10 +63,30 @@
|
||||
|
||||
/// warning | Попередження
|
||||
|
||||
Перш ніж встановлювати `convert_underscores` у значення `False`, пам’ятайте, що деякі HTTP проксі та сервери забороняють використання заголовків із підкресленнями.
|
||||
Перш ніж встановлювати `convert_underscores` у значення `False`, пам’ятайте, що деякі HTTP представники та сервери забороняють використання заголовків із підкресленнями.
|
||||
|
||||
///
|
||||
|
||||
## Поєднати моделі параметрів { #combine-parameter-models }
|
||||
|
||||
Ви можете поєднувати кілька моделей параметрів заголовків з окремими параметрами заголовків і залежностями. Кожна модель витягується та перевіряється незалежно, як пояснено для [моделей параметрів запиту](query-param-models.md#combine-parameter-models).
|
||||
|
||||
Конфігурація `extra` кожної моделі застосовується до всіх параметрів заголовків, включно з тими, що оголошені в інших моделях або залежностях. З `extra="forbid"` будь-який заголовок поза цією моделлю відхиляється. З `extra="allow"` ці заголовки включаються як додаткові поля моделі.
|
||||
|
||||
Кожна модель використовує власне налаштування `Header(convert_underscores=...)` як під час читання запиту, так і під час генерування OpenAPI. Явно задані псевдоніми полів залишаються буквальними назвами заголовків.
|
||||
|
||||
## Необов’язкові моделі параметрів заголовків { #optional-header-parameter-models }
|
||||
|
||||
Оголосіть модель параметрів заголовків з `| None` і значенням за замовчуванням `None`, щоб зробити групу необов’язковою.
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial004_an_py310.py hl[15] *}
|
||||
|
||||
Якщо не надіслано ані `x-client-name`, ані `x-client-version`, `client` має значення `None`. Якщо надіслано хоча б один із них, FastAPI перевіряє модель і вимагає обидва поля.
|
||||
|
||||
Для значень за замовчуванням, додаткових полів і OpenAPI діють ті самі правила, що й для [необов’язкових моделей параметрів запиту](query-param-models.md#optional-query-parameter-models).
|
||||
|
||||
Заголовки на кшталт `Host` також підпорядковуються конфігурації `extra` моделі. З `extra="allow"` вони роблять модель присутньою, навіть якщо жодне з оголошених полів не передано.
|
||||
|
||||
## Підсумок { #summary }
|
||||
|
||||
Ви можете використовувати **Pydantic моделі** для оголошення **заголовків** у **FastAPI**. 😎
|
||||
@@ -1,6 +1,6 @@
|
||||
# Параметри шляху та валідація числових даних { #path-parameters-and-numeric-validations }
|
||||
|
||||
Так само як ви можете оголошувати додаткові перевірки та метадані для query параметрів за допомогою `Query`, ви можете оголошувати той самий тип перевірок і метаданих для параметрів шляху за допомогою `Path`.
|
||||
Так само як ви можете оголошувати додаткові перевірки та метадані для параметрів запиту за допомогою `Query`, ви можете оголошувати той самий тип перевірок і метаданих для параметрів шляху за допомогою `Path`.
|
||||
|
||||
## Імпорт `Path` { #import-path }
|
||||
|
||||
@@ -28,7 +28,7 @@ FastAPI додав підтримку `Annotated` (і почав рекомен
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
Параметр шляху завжди є обов’язковим, оскільки він має бути частиною шляху. Навіть якщо ви оголосите його зі значенням `None` або встановите значення за замовчуванням — це ні на що не вплине, він все одно завжди буде обов’язковим.
|
||||
Параметр шляху завжди є обов’язковим, оскільки він має бути частиною шляху URL. Додавання `None` до його типу не робить його необов’язковим. Параметр, оголошений за допомогою `Path`, не може мати значення за замовчуванням.
|
||||
|
||||
///
|
||||
|
||||
@@ -46,7 +46,7 @@ FastAPI додав підтримку `Annotated` (і почав рекомен
|
||||
|
||||
Але вам все одно потрібно використовувати `Path` для параметра шляху `item_id`. І з певних причин ви не хочете використовувати `Annotated`.
|
||||
|
||||
Python видасть помилку, якщо розмістити значення з "default" перед значенням, яке не має "default".
|
||||
Python видасть помилку, якщо розмістити значення зі «значенням за замовчуванням» перед значенням, яке не має «значення за замовчуванням».
|
||||
|
||||
Але ви можете змінити порядок і розмістити значення без значення за замовчуванням (параметр запиту `q`) першим.
|
||||
|
||||
@@ -81,7 +81,7 @@ Python видасть помилку, якщо розмістити значен
|
||||
|
||||
Передайте `*` як перший параметр функції.
|
||||
|
||||
Python нічого не зробить із цією `*`, але розпізнає, що всі наступні параметри слід викликати як аргументи за ключовим словом (пари ключ-значення), також відомі як <abbr title="Походить від: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Навіть якщо вони не мають значення за замовчуванням.
|
||||
Python нічого не зробить із цією `*`, але розпізнає, що всі наступні параметри слід викликати як аргументи за ключовим словом (пари ключ-значення), також відомі як <abbr title="Походить від: K-ey W-ord Arg-uments - аргументи за ключовим словом"><code>kwargs</code></abbr>. Навіть якщо вони не мають значення за замовчуванням.
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
|
||||
|
||||
@@ -95,7 +95,7 @@ Python нічого не зробить із цією `*`, але розпізн
|
||||
|
||||
За допомогою `Query` і `Path` (та інших, які ви побачите пізніше) можна оголошувати числові обмеження.
|
||||
|
||||
Тут, завдяки `ge=1`, `item_id` має бути цілим числом, яке "`g`reater than or `e`qual" (більше або дорівнює) `1`.
|
||||
Тут, завдяки `ge=1`, `item_id` має бути цілим числом, яке «`g`reater than or `e`qual» (більше або дорівнює) `1`.
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
|
||||
|
||||
@@ -114,7 +114,7 @@ Python нічого не зробить із цією `*`, але розпізн
|
||||
|
||||
Ось де стає важливо мати можливість оголошувати <abbr title="greater than - більше ніж"><code>gt</code></abbr>, а не тільки <abbr title="greater than or equal - більше або дорівнює"><code>ge</code></abbr>. Це дозволяє, наприклад, вимагати, щоб значення було більше `0`, навіть якщо воно менше `1`.
|
||||
|
||||
Таким чином, значення `0.5` буде допустимим. Але `0.0` або `0` — ні.
|
||||
Таким чином, значення `0.5` буде допустимим. Але `0.0` або `0` - ні.
|
||||
|
||||
Те саме стосується <abbr title="less than - менше ніж"><code>lt</code></abbr>.
|
||||
|
||||
@@ -122,7 +122,7 @@ Python нічого не зробить із цією `*`, але розпізн
|
||||
|
||||
## Підсумок { #recap }
|
||||
|
||||
За допомогою `Query`, `Path` (і інших параметрів, які ви ще не бачили) можна оголошувати метадані та перевірки рядків так само як у [Query параметри та валідація рядків](query-params-str-validations.md).
|
||||
За допомогою `Query`, `Path` (і інших параметрів, які ви ще не бачили) можна оголошувати метадані та перевірки строк так само як у [Параметри запиту та валідація строк](query-params-str-validations.md).
|
||||
|
||||
Також можна оголошувати числові перевірки:
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
|
||||
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **параметрів запиту** у запиті та передавати їх у визначену вами Pydantic-модель.
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **параметрів запиту** у запиті та надавати Вам визначену вами Pydantic-модель.
|
||||
|
||||
## Перевірте документацію { #check-the-docs }
|
||||
|
||||
@@ -57,12 +57,48 @@ https://example.com/items/?limit=10&tool=plumbus
|
||||
}
|
||||
```
|
||||
|
||||
## Поєднання моделей параметрів { #combine-parameter-models }
|
||||
|
||||
Ви можете оголосити кілька моделей параметрів запиту та поєднати їх з окремими параметрами запиту або залежностями.
|
||||
|
||||
{* ../../docs_src/query_param_models/tutorial003_an_py310.py hl[9:15,20:22] *}
|
||||
|
||||
Параметри запиту залишаються на одному рівні.
|
||||
|
||||
```http
|
||||
https://example.com/items/?limit=5&offset=10&tags=red&tags=blue&search=shirt
|
||||
```
|
||||
|
||||
У строці запиту немає ключів `pagination` або `filters`. Кожна модель перевіряє параметри запиту незалежно, зі своїми значеннями за замовчуванням, валідаторами полів і валідаторами моделі. Те саме стосується моделей або окремих параметрів, оголошених у залежностях.
|
||||
|
||||
Якщо моделі мають спільне ім’я або псевдонім параметра, кожна модель перевіряє цей параметр запиту незалежно. Використовуйте різні імена або псевдоніми для незалежних значень. OpenAPI перелічує спільний параметр один раз, як і для параметрів, спільних із залежностями, тому спільні оголошення мають описувати однаковий тип і обмеження.
|
||||
|
||||
Конфігурація `extra` кожної моделі застосовується до всіх параметрів запиту, зокрема оголошених в інших моделях або залежностях. З `extra="forbid"` будь-який параметр поза цією моделлю відхиляється. З `extra="allow"` ці параметри включаються як додаткові дані моделі.
|
||||
|
||||
Це також працює для моделей `Header` і `Cookie`.
|
||||
|
||||
## Необов’язкові моделі параметрів запиту { #optional-query-parameter-models }
|
||||
|
||||
Оголосіть модель параметрів запиту з `| None` і значенням за замовчуванням `None`, щоб зробити групу необов’язковою.
|
||||
|
||||
{* ../../docs_src/query_param_models/tutorial004_an_py310.py hl[18] *}
|
||||
|
||||
Якщо не надіслано ні `start`, ні `end`, значення `date_range` буде `None`. Якщо надіслано будь-який із них, FastAPI перевіряє модель і вимагає обидва поля.
|
||||
|
||||
Використання `| None` без значення за замовчуванням залишає параметр обов’язковим.
|
||||
|
||||
Додаткові параметри обробляються відповідно до конфігурації `extra` моделі. Ігноровані додаткові параметри не роблять модель присутньою.
|
||||
|
||||
OpenAPI перелічує поля групи окремо та позначає їх як необов’язкові.
|
||||
|
||||
Ви також можете оголосити необов’язкові [моделі параметрів заголовків](header-param-models.md#optional-header-parameter-models) і [моделі параметрів кукі](cookie-param-models.md#optional-cookie-parameter-models).
|
||||
|
||||
## Підсумок { #summary }
|
||||
|
||||
Ви можете використовувати **Pydantic-моделі** для оголошення **параметрів запиту** у **FastAPI**. 😎
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Спойлер: Ви також можете використовувати Pydantic-моделі для оголошення кукі та заголовків, але про це Ви дізнаєтеся пізніше в цьому посібнику. 🤫
|
||||
Спойлер: Ви також можете використовувати Pydantic-моделі для оголошення кукі та заголовків, але про це Ви дізнаєтеся пізніше в цьому навчальному посібнику. 🤫
|
||||
|
||||
///
|
||||
@@ -220,14 +220,22 @@ q: Annotated[str | None, Query(min_length=3)] = None
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
|
||||
|
||||
### Обов’язковий, може бути `None` { #required-can-be-none }
|
||||
### Обов’язкові параметри та `None` { #required-parameters-and-none }
|
||||
|
||||
Ви можете вказати, що параметр може приймати `None`, але при цьому залишається обов’язковим. Це змусить клієнтів надіслати значення, навіть якщо значення дорівнює `None`.
|
||||
|
||||
Щоб зробити це, оголосіть, що `None` є допустимим типом, але просто не вкажіть значення за замовчуванням:
|
||||
Тип `str | None` допускає `None` як значення Python, але не робить параметр запиту необов’язковим. Без значення за замовчуванням параметр залишається обов’язковим:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
|
||||
|
||||
Значення параметрів запиту надходять як строки й не мають вбудованого представлення `None`. Надсилання `?q=None` або `?q=null` передає строки `"None"` та `"null"` відповідно. Надсилання `?q=` передає порожню строку, яка не проходить валідацію `min_length=3` у цьому прикладі.
|
||||
|
||||
Щоб дозволити клієнтам не передавати `q` і використовувати `None` як його значення, задайте йому значення за замовчуванням `None`:
|
||||
|
||||
```Python
|
||||
q: Annotated[str | None, Query(min_length=3)] = None
|
||||
```
|
||||
|
||||
Тіла запитів у форматі JSON, на відміну від параметрів запиту, можуть містити явне значення `null`.
|
||||
|
||||
## Список параметрів запиту / кілька значень { #query-parameter-list-multiple-values }
|
||||
|
||||
Коли ви явно визначаєте параметр запиту за допомогою `Query`, ви також можете оголосити, що він має приймати список значень, або, іншими словами, кілька значень.
|
||||
|
||||
@@ -107,7 +107,13 @@ http://127.0.0.1:8000/items/foo?short=on
|
||||
http://127.0.0.1:8000/items/foo?short=yes
|
||||
```
|
||||
|
||||
або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` типу `bool`. В іншому випадку - `False`.
|
||||
або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` типу `bool`.
|
||||
|
||||
Такі значення, як `0`, `false`, `off` і `no` (включно з варіантами регістру), перетворюються на `False`.
|
||||
|
||||
Якщо `short` не вказано, **FastAPI** використовує його значення за замовчуванням, яке в цьому прикладі дорівнює `False`.
|
||||
|
||||
Порожнє значення (`?short=`) або нерозпізнане значення (наприклад, `?short=maybe`) спричиняє помилку валідації `422`.
|
||||
|
||||
|
||||
## Кілька параметрів шляху та запиту { #multiple-path-and-query-parameters }
|
||||
|
||||
@@ -28,6 +28,8 @@ $ uv add python-multipart
|
||||
|
||||
**FastAPI** **витягне** дані для **кожного поля** з **формових даних** у запиті та надасть вам Pydantic-модель, яку ви визначили.
|
||||
|
||||
Для [прапорців HTML](request-forms.md#boolean-form-fields) оголошуйте булеві поля зі значенням за замовчуванням `False`.
|
||||
|
||||
## Перевірте документацію { #check-the-docs }
|
||||
|
||||
Ви можете перевірити це в UI документації за `/docs`:
|
||||
@@ -73,6 +75,58 @@ $ uv add python-multipart
|
||||
}
|
||||
```
|
||||
|
||||
## Поєднуйте моделі форм { #combine-form-models }
|
||||
|
||||
Ви можете поєднувати кілька моделей форм з окремими параметрами `Form`.
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial003_an_py310.py hl[9:14,19:21] *}
|
||||
|
||||
Клієнт надсилає `name`, `tags` і `token` як поля форми. Кожна модель перевіряє поля форми незалежно.
|
||||
|
||||
Конфігурація `extra` кожної моделі застосовується до всіх полів форми, зокрема полів і файлів, оголошених в інших параметрах або залежностях. З `extra="forbid"` будь-яке поле поза цією моделлю відхиляється. З `extra="allow"` ці поля включаються як додаткові поля моделі.
|
||||
|
||||
Якщо кілька оголошень використовують однакове ім'я поля форми, кожне перевіряє значення цього поля. Використовуйте сумісні типи й обмеження для спільних полів, щоб схема OpenAPI могла описувати їх узгоджено.
|
||||
|
||||
## Необов'язкові моделі форм { #optional-form-models }
|
||||
|
||||
Оголосіть модель форми з `| None` і значенням за замовчуванням `None`, щоб зробити групу необов'язковою.
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial005_an_py310.py hl[17] *}
|
||||
|
||||
Якщо не надіслано ані `name`, ані `age`, `profile` має значення `None`. Якщо надіслано хоча б одне з них, FastAPI перевіряє модель і вимагає обидва поля. Надіслане порожнє значення також вважається наданням поля.
|
||||
|
||||
Використання `| None` без значення за замовчуванням залишає параметр обов'язковим.
|
||||
|
||||
Додаткові поля обробляються відповідно до конфігурації `extra` моделі. Ігноровані додаткові поля не роблять модель присутньою.
|
||||
|
||||
Необов'язкова модель, що містить лише невстановлені прапорці, пропускається. Надішліть значення, наприклад `enabled=false`, щоб надати її явно.
|
||||
|
||||
## Необов'язкові об'єднання моделей форм { #optional-unions-of-form-models }
|
||||
|
||||
Ви також можете використовувати необов'язкове об'єднання моделей.
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial006_an_py310.py hl[9:16,21] *}
|
||||
|
||||
Якщо жодного поля форми не надіслано, `contact` має значення `None`. Надішліть `kind=person` разом із `name` або `kind=company` разом із `company_name`. Дискримінатор вибирає модель для перевірки.
|
||||
|
||||
## Поєднуйте об'єднання моделей форм { #combine-unions-of-form-models }
|
||||
|
||||
Ви можете поєднувати об'єднання з іншими моделями форм, окремими параметрами `Form` і параметрами `File`. Кожне об'єднання перевіряється незалежно.
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial007_an_py310.py hl[31:35] *}
|
||||
|
||||
Надсилайте всі поля в одній формі. Наприклад, надішліть `contact_type=person`, `name=Rick`, `notification_type=email`, `email=rick@example.com` і `token=secret`.
|
||||
|
||||
Не надсилайте поля сповіщення, щоб залишити `notification` зі значенням `None`.
|
||||
|
||||
## Моделі форм і файли { #form-models-and-files }
|
||||
|
||||
Ви також можете поєднувати модель форми з [параметрами файлів](request-files.md).
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial004_an_py310.py hl[14] *}
|
||||
|
||||
Тут клієнт надсилає поле `name` і файл `avatar`, використовуючи `multipart/form-data`.
|
||||
|
||||
## Підсумок { #summary }
|
||||
|
||||
У FastAPI ви можете використовувати Pydantic-моделі для оголошення полів форми. 😎
|
||||
@@ -44,6 +44,14 @@ $ uv add python-multipart
|
||||
|
||||
///
|
||||
|
||||
## Булеві поля форми { #boolean-form-fields }
|
||||
|
||||
Браузери пропускають невстановлені прапорці під час надсилання HTML-форм. Оголосіть булевий параметр форми зі значенням за замовчуванням `False`, щоб отримувати `False`, коли прапорець не встановлено:
|
||||
|
||||
{* ../../docs_src/request_forms/tutorial002_an_py310.py hl[9] *}
|
||||
|
||||
Встановлений прапорець надсилає своє значення, яке за замовчуванням дорівнює `"on"`. **FastAPI** приймає `"on"` як `True`.
|
||||
|
||||
## Про «поля форми» { #about-form-fields }
|
||||
|
||||
HTML-форми (`<form></form>`) надсилають дані на сервер у «спеціальному» кодуванні, яке відрізняється від JSON.
|
||||
@@ -56,6 +64,8 @@ HTML-форми (`<form></form>`) надсилають дані на серве
|
||||
|
||||
Але якщо форма містить файли, вона кодується як `multipart/form-data`. Ви дізнаєтеся про обробку файлів у наступному розділі.
|
||||
|
||||
Ви можете використовувати `Form(media_type="multipart/form-data")`, щоб описати багаточастинну форму в OpenAPI. Під час поєднання параметрів форми або моделей достатньо встановити це для одного параметра.
|
||||
|
||||
Якщо ви хочете дізнатися більше про ці кодування та поля форм, зверніться до [<abbr title="Mozilla Developer Network - Мережа Розробників Mozilla">MDN</abbr> вебдокументації для `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
|
||||
|
||||
///
|
||||
|
||||
@@ -26,7 +26,7 @@ FastAPI використовуватиме цей тип повернення,
|
||||
|
||||
Наприклад, ви можете захотіти **повертати словник** або об’єкт бази даних, але **оголосити його як модель Pydantic**. Таким чином модель Pydantic виконуватиме всю документацію даних, валідацію тощо для об’єкта, який ви повернули (наприклад, словника або об’єкта бази даних).
|
||||
|
||||
Якщо ви додали анотацію типу повернення, інструменти та редактори скаржитимуться (коректною) помилкою, повідомляючи, що ваша функція повертає тип (наприклад, dict), який відрізняється від того, що ви оголосили (наприклад, модель Pydantic).
|
||||
Якщо ви додали анотацію типу повернення, інструменти та редактори скаржитимуться (коректною) помилкою, повідомляючи, що ваша функція повертає тип (наприклад, словник), який відрізняється від того, що ви оголосили (наприклад, модель Pydantic).
|
||||
|
||||
У таких випадках можна скористатися параметром *декоратора операції шляху* `response_model` замість типу повернення.
|
||||
|
||||
@@ -196,7 +196,7 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
|
||||
|
||||
Це теж працюватиме, бо `RedirectResponse` — підклас `Response`, і FastAPI автоматично обробить цей простий випадок.
|
||||
Це теж працюватиме, бо `RedirectResponse` - підклас `Response`, і FastAPI автоматично обробить цей простий випадок.
|
||||
|
||||
### Некоректні анотації типу повернення { #invalid-return-type-annotations }
|
||||
|
||||
@@ -206,7 +206,7 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
|
||||
|
||||
...це не працює, тому що анотація типу не є типом Pydantic і не є просто одним класом `Response` або його підкласом, це union (будь-який із двох) між `Response` і `dict`.
|
||||
...це не працює, тому що анотація типу не є типом Pydantic і не є просто одним класом `Response` або його підкласом, це об’єднання (будь-який із двох) між `Response` і `dict`.
|
||||
|
||||
### Вимкнути модель відповіді { #disable-response-model }
|
||||
|
||||
@@ -242,7 +242,7 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
|
||||
і ці значення за замовчуванням не будуть включені у відповідь, лише значення, які фактично встановлені.
|
||||
|
||||
Отже, якщо ви надішлете запит до цієї *операції шляху* для елемента з ID `foo`, відповідь (без включення значень за замовчуванням) буде:
|
||||
Отже, якщо ви надішлете запит до цієї *операції шляху* для предмета з ID `foo`, відповідь (без включення значень за замовчуванням) буде:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -264,8 +264,9 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
|
||||
#### Дані зі значеннями для полів із типовими значеннями { #data-with-values-for-fields-with-defaults }
|
||||
|
||||
Але якщо ваші дані мають значення для полів моделі з типовими значеннями, як у елемента з ID `bar`:
|
||||
Але якщо ваші дані мають значення для полів моделі з типовими значеннями, як у предмета з ID `bar`:
|
||||
|
||||
<!-- fmt:off -->
|
||||
```Python hl_lines="3 5"
|
||||
{
|
||||
"name": "Bar",
|
||||
@@ -274,13 +275,15 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
"tax": 20.2
|
||||
}
|
||||
```
|
||||
<!-- fmt:on -->
|
||||
|
||||
вони будуть включені у відповідь.
|
||||
|
||||
#### Дані з тими самими значеннями, що й типові { #data-with-the-same-values-as-the-defaults }
|
||||
|
||||
Якщо дані мають ті самі значення, що й типові, як у елемента з ID `baz`:
|
||||
Якщо дані мають ті самі значення, що й типові, як у предмета з ID `baz`:
|
||||
|
||||
<!-- fmt:off -->
|
||||
```Python hl_lines="3 5-6"
|
||||
{
|
||||
"name": "Baz",
|
||||
@@ -290,6 +293,7 @@ FastAPI виконує кілька внутрішніх операцій з Pyd
|
||||
"tags": []
|
||||
}
|
||||
```
|
||||
<!-- fmt:on -->
|
||||
|
||||
FastAPI достатньо розумний (насправді, Pydantic достатньо розумний), щоб зрозуміти, що, хоча `description`, `tax` і `tags` мають ті самі значення, що й типові, їх було встановлено явно (а не взято як значення за замовчуванням).
|
||||
|
||||
@@ -299,7 +303,7 @@ FastAPI достатньо розумний (насправді, Pydantic дос
|
||||
|
||||
Зверніть увагу, що типові значення можуть бути будь-якими, не лише `None`.
|
||||
|
||||
Це може бути list (`[]`), `float` зі значенням `10.5` тощо.
|
||||
Це може бути список (`[]`), `float` зі значенням `10.5` тощо.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -22,19 +22,19 @@ OAuth2 визначає, що під час використання «пото
|
||||
|
||||
Специфікація також каже, що клієнт може надіслати інше поле форми «`scope`».
|
||||
|
||||
Назва поля форми — `scope` (в однині), але насправді це довга строка зі «scopes», розділеними пробілами.
|
||||
Назва поля форми - `scope` (в однині), але насправді це довга строка зі «scopes», розділеними пробілами.
|
||||
|
||||
Кожен «scope» — це просто строка (без пробілів).
|
||||
Кожен «scope» - це просто строка (без пробілів).
|
||||
|
||||
Їх зазвичай використовують для оголошення конкретних прав доступу, наприклад:
|
||||
|
||||
* `users:read` або `users:write` — поширені приклади.
|
||||
* `users:read` або `users:write` - поширені приклади.
|
||||
* `instagram_basic` використовується Facebook / Instagram.
|
||||
* `https://www.googleapis.com/auth/drive` використовується Google.
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
У OAuth2 «scope» — це просто строка, що оголошує конкретний потрібний дозвіл.
|
||||
У OAuth2 «scope» - це просто строка, що оголошує конкретний потрібний дозвіл.
|
||||
|
||||
Не має значення, чи містить вона інші символи на кшталт `:` або чи це URL.
|
||||
|
||||
@@ -54,7 +54,7 @@ OAuth2 визначає, що під час використання «пото
|
||||
|
||||
{* ../../docs_src/security/tutorial003_an_py310.py hl[4,78] *}
|
||||
|
||||
`OAuth2PasswordRequestForm` — це клас залежності, що оголошує тіло форми з:
|
||||
`OAuth2PasswordRequestForm` - це клас залежності, що оголошує тіло форми з:
|
||||
|
||||
* `username`.
|
||||
* `password`.
|
||||
@@ -74,11 +74,11 @@ OAuth2 визначає, що під час використання «пото
|
||||
|
||||
/// note | Примітка
|
||||
|
||||
`OAuth2PasswordRequestForm` — не спеціальний клас для **FastAPI**, як `OAuth2PasswordBearer`.
|
||||
`OAuth2PasswordRequestForm` - не спеціальний клас для **FastAPI**, як `OAuth2PasswordBearer`.
|
||||
|
||||
`OAuth2PasswordBearer` робить так, що **FastAPI** знає, що це схема безпеки. Тому її додають таким чином до OpenAPI.
|
||||
|
||||
Але `OAuth2PasswordRequestForm` — це просто клас залежності, який ви могли б написати самі, або ви могли б напряму оголосити параметри `Form`.
|
||||
Але `OAuth2PasswordRequestForm` - це просто клас залежності, який ви могли б написати самі, або ви могли б напряму оголосити параметри `Form`.
|
||||
|
||||
Оскільки це типова задача, **FastAPI** надає його безпосередньо, щоб спростити роботу.
|
||||
|
||||
@@ -136,11 +136,11 @@ OAuth2 визначає, що під час використання «пото
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username = user_dict["username"],
|
||||
email = user_dict["email"],
|
||||
full_name = user_dict["full_name"],
|
||||
disabled = user_dict["disabled"],
|
||||
hashed_password = user_dict["hashed_password"],
|
||||
username=user_dict["username"],
|
||||
email=user_dict["email"],
|
||||
full_name=user_dict["full_name"],
|
||||
disabled=user_dict["disabled"],
|
||||
hashed_password=user_dict["hashed_password"],
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user