diff --git a/docs/uk/docs/_llm-test.md b/docs/uk/docs/_llm-test.md
new file mode 100644
index 0000000000..561a119ba7
--- /dev/null
+++ b/docs/uk/docs/_llm-test.md
@@ -0,0 +1,503 @@
+# Тестовий файл LLM { #llm-test-file }
+
+Цей документ перевіряє, чи LLM, який перекладає документацію, розуміє `general_prompt` у `scripts/translate.py` та мовно-специфічний prompt у `docs/{language code}/llm-prompt.md`. Мовно-специфічний prompt додається до `general_prompt`.
+
+Тести, додані тут, побачать усі розробники мовно-специфічних prompt.
+
+Використовуйте так:
+
+* Майте мовно-специфічний prompt — `docs/{language code}/llm-prompt.md`.
+* Зробіть «свіжий» переклад цього документа на бажану цільову мову (див., напр., команду `translate-page` у `translate.py`). Це створить переклад у `docs/{language code}/docs/_llm-test.md`.
+* Перевірте, чи все гаразд у перекладі.
+* За потреби поліпште мовно-специфічний prompt, загальний prompt або англомовний документ.
+* Потім вручну виправте решту проблем у перекладі, щоб це був якісний переклад.
+* Перекладіть знову, маючи якісний переклад на місці. Ідеальний результат — LLM більше не вносить жодних змін у переклад. Це означає, що загальний prompt і ваш мовно-специфічний prompt — настільки добрі, наскільки це можливо (інколи він усе ж робитиме кілька на вигляд випадкових змін, причина в тому, що LLM не є детермінованими алгоритмами).
+
+Тести:
+
+## Фрагменти коду { #code-snippets }
+
+//// tab | Тест
+
+Ось фрагмент коду: `foo`. А ось ще один фрагмент коду: `bar`. І ще один: `baz quux`.
+
+////
+
+//// tab | Інформація
+
+Вміст фрагментів коду слід залишати без змін.
+
+Див. розділ `### Content of code snippets` у загальному prompt у `scripts/translate.py`.
+
+////
+
+## Лапки { #quotes }
+
+//// tab | Тест
+
+Учора мій друг написав: "If you spell incorrectly correctly, you have spelled it incorrectly". На що я відповів: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'" .
+
+/// note | Примітка
+
+LLM, імовірно, перекладе це неправильно. Цікаво лише, чи збереже він виправлений переклад під час повторного перекладання.
+
+///
+
+////
+
+//// tab | Інформація
+
+Автор prompt може вирішити, чи перетворювати нейтральні лапки на типографські. Можна залишити як є.
+
+Див., наприклад, розділ `### Quotes` у `docs/de/llm-prompt.md`.
+
+////
+
+## Лапки у фрагментах коду { #quotes-in-code-snippets }
+
+//// tab | Тест
+
+`pip install "foo[bar]"`
+
+Приклади рядкових літералів у фрагментах коду: `"this"`, `'that'`.
+
+Складний приклад рядкових літералів у фрагментах коду: `f"I like {'oranges' if orange else "apples"}"`
+
+Хардкор: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"`
+
+////
+
+//// tab | Інформація
+
+... Однак лапки всередині фрагментів коду мають залишатися як є.
+
+////
+
+## Блоки коду { #code-blocks }
+
+//// tab | Тест
+
+Приклад коду Bash...
+
+```bash
+# Print a greeting to the universe
+echo "Hello universe"
+```
+
+...і приклад коду консолі...
+
+```console
+$ fastapi run main.py
+ FastAPI Starting server
+ Searching for package file structure
+```
+
+...і ще один приклад коду консолі...
+
+```console
+// Create a directory "Code"
+$ mkdir code
+// Switch into that directory
+$ cd code
+```
+
+...і приклад коду Python...
+
+```Python
+wont_work() # This won't work 😱
+works(foo="bar") # This works 🎉
+```
+
+...і на цьому все.
+
+////
+
+//// tab | Інформація
+
+Код у блоках коду не слід змінювати, за винятком коментарів.
+
+Див. розділ `### Content of code blocks` у загальному prompt у `scripts/translate.py`.
+
+////
+
+## Вкладки та кольорові блоки { #tabs-and-colored-boxes }
+
+//// tab | Тест
+
+/// info | Інформація
+Деякий текст
+///
+
+/// note | Примітка
+Деякий текст
+///
+
+/// note | Технічні деталі
+Деякий текст
+///
+
+/// check
+Деякий текст
+///
+
+/// tip | Порада
+Деякий текст
+///
+
+/// warning | Попередження
+Деякий текст
+///
+
+/// danger | Обережно
+Деякий текст
+///
+
+////
+
+//// tab | Інформація
+
+Для вкладок і блоків `Info`/`Note`/`Warning`/тощо слід додавати переклад їхньої назви після вертикальної риски (`|`).
+
+Див. розділи `### Special blocks` і `### Tab blocks` у загальному prompt у `scripts/translate.py`.
+
+////
+
+## Вебпосилання та внутрішні посилання { #web-and-internal-links }
+
+//// tab | Тест
+
+Текст посилання слід перекладати, а адресу посилання — залишати без змін:
+
+* [Посилання на заголовок вище](#code-snippets)
+* [Внутрішнє посилання](index.md#installation){.internal-link target=_blank}
+* Зовнішнє посилання
+* Посилання на стилі
+* Посилання на скрипт
+* Посилання на зображення
+
+Текст посилання слід перекладати, а адреса посилання має вказувати на переклад:
+
+* Посилання на FastAPI
+
+////
+
+//// tab | Інформація
+
+Посилання слід перекладати, але їхня адреса має залишатися без змін. Виняток — абсолютні посилання на сторінки документації FastAPI. У такому разі посилання має вести на переклад.
+
+Див. розділ `### Links` у загальному prompt у `scripts/translate.py`.
+
+////
+
+## HTML-елементи «abbr» { #html-abbr-elements }
+
+//// tab | Тест
+
+Тут наведено кілька речей, обгорнутих в HTML-елементи «abbr» (деякі вигадані):
+
+### abbr задає повну фразу { #the-abbr-gives-a-full-phrase }
+
+* GTD
+* lt
+* XWT
+* PSGI
+
+### abbr задає пояснення { #the-abbr-gives-an-explanation }
+
+* cluster
+* Deep Learning
+
+### abbr задає повну фразу та пояснення { #the-abbr-gives-a-full-phrase-and-an-explanation }
+
+* MDN
+* I/O.
+
+////
+
+//// tab | Інформація
+
+Атрибути `title` в елементах `abbr` перекладаються за певними інструкціями.
+
+Переклади можуть додавати власні елементи `abbr`, які LLM не повинен вилучати. Напр., щоб пояснювати англійські слова.
+
+Див. розділ `### HTML abbr elements` у загальному prompt у `scripts/translate.py`.
+
+////
+
+## Заголовки { #headings }
+
+//// tab | Тест
+
+### Розробка вебзастосунку — навчальний посібник { #develop-a-webapp-a-tutorial }
+
+Привіт.
+
+### Підказки типів і -анотації { #type-hints-and-annotations }
+
+Привіт ще раз.
+
+### Супер- і підкласи { #super-and-subclasses }
+
+Привіт ще раз.
+
+////
+
+//// tab | Інформація
+
+Єдине жорстке правило для заголовків — LLM має залишати частину хешу в фігурних дужках без змін, що гарантує, що посилання не зламаються.
+
+Див. розділ `### Headings` у загальному prompt у `scripts/translate.py`.
+
+Для деяких мовно-специфічних інструкцій див., напр., розділ `### Headings` у `docs/de/llm-prompt.md`.
+
+////
+
+## Терміни, що використовуються в документації { #terms-used-in-the-docs }
+
+//// tab | Тест
+
+* ви
+* ваш
+
+* напр.
+* тощо
+
+* `foo` як `int`
+* `bar` як `str`
+* `baz` як `list`
+
+* Tutorial — Посібник користувача
+* Advanced User Guide
+* документація SQLModel
+* документація API
+* автоматична документація
+
+* Data Science
+* Deep Learning
+* Machine Learning
+* Dependency Injection
+* автентифікація HTTP Basic
+* HTTP Digest
+* формат ISO
+* стандарт JSON Schema
+* JSON schema
+* визначення schema
+* Password Flow
+* Mobile
+
+* застарілий
+* спроєктований
+* недійсний
+* на льоту
+* стандартний
+* за замовчуванням
+* чутливий до регістру
+* нечутливий до регістру
+
+* обслуговувати застосунок
+* обслуговувати сторінку
+
+* застосунок
+* застосунок
+
+* запит
+* відповідь
+* відповідь про помилку
+
+* операція шляху
+* декоратор операції шляху
+* функція операції шляху
+
+* body
+* тіло запиту
+* тіло відповіді
+* JSON body
+* form body
+* file body
+* тіло функції
+
+* параметр
+* body-параметр
+* path-параметр
+* query-параметр
+* cookie-параметр
+* header-параметр
+* form-параметр
+* параметр функції
+
+* подія
+* подія startup
+* запуск сервера
+* подія shutdown
+* подія lifespan
+
+* обробник
+* обробник подій
+* обробник винятків
+* обробляти
+
+* модель
+* модель Pydantic
+* модель даних
+* модель бази даних
+* модель форми
+* об’єкт моделі
+
+* клас
+* базовий клас
+* батьківський клас
+* підклас
+* дочірній клас
+* споріднений клас
+* метод класу
+
+* заголовок
+* заголовки
+* заголовок authorization
+* заголовок `Authorization`
+* forwarded header
+
+* система dependency injection
+* залежність
+* dependable
+* dependant
+
+* I/O bound
+* CPU bound
+* concurrency
+* parallelism
+* multiprocessing
+
+* env var
+* змінна оточення
+* `PATH`
+* змінна `PATH`
+
+* автентифікація
+* провайдер автентифікації
+* авторизація
+* форма авторизації
+* провайдер авторизації
+* користувач автентифікується
+* система автентифікує користувача
+
+* CLI
+* інтерфейс командного рядка
+
+* сервер
+* клієнт
+
+* хмарний провайдер
+* хмарний сервіс
+
+* розробка
+* етапи розробки
+
+* dict
+* словник
+* перелічення
+* enum
+* елемент enum
+
+* енкодер
+* декодер
+* кодувати
+* декодувати
+
+* виняток
+* підняти
+
+* вираз
+* інструкція
+
+* frontend
+* backend
+
+* обговорення GitHub
+* issue GitHub
+
+* продуктивність
+* оптимізація продуктивності
+
+* тип повернення
+* значення повернення
+
+* безпека
+* схема безпеки
+
+* завдання
+* фонове завдання
+* функція завдання
+
+* шаблон
+* рушій шаблонів
+
+* анотація типів
+* підказка типів
+
+* server worker
+* worker Uvicorn
+* Worker Gunicorn
+* процес worker
+* клас worker
+* робоче навантаження
+
+* розгортання
+* розгортати
+
+* SDK
+* software development kit
+
+* `APIRouter`
+* `requirements.txt`
+* Bearer Token
+* breaking change
+* bug
+* button
+* callable
+* code
+* commit
+* context manager
+* coroutine
+* сесія бази даних
+* диск
+* домен
+* engine
+* fake X
+* метод HTTP GET
+* item
+* бібліотека
+* lifespan
+* lock
+* middleware
+* мобільний застосунок
+* модуль
+* mounting
+* мережа
+* origin
+* override
+* payload
+* processor
+* property
+* proxy
+* pull request
+* query
+* RAM
+* віддалена машина
+* status code
+* string
+* tag
+* вебфреймворк
+* wildcard
+* повертати
+* валідувати
+
+////
+
+//// tab | Інформація
+
+Це неповний і не нормативний список (переважно) технічних термінів, які зустрічаються в документації. Він може бути корисним автору prompt, щоб зрозуміти, для яких термінів LLM потрібна підказка. Наприклад, коли він постійно відкотить якісний переклад до гіршого варіанта. Або коли він має проблеми з відмінюванням/узгодженням терміна вашою мовою.
+
+Див., напр., розділ `### List of English terms and their preferred German translations` у `docs/de/llm-prompt.md`.
+
+////
diff --git a/docs/uk/docs/about/index.md b/docs/uk/docs/about/index.md
new file mode 100644
index 0000000000..6a58250cba
--- /dev/null
+++ b/docs/uk/docs/about/index.md
@@ -0,0 +1,3 @@
+# Про { #about }
+
+Про FastAPI, його дизайн, натхнення та інше. 🤓
diff --git a/docs/uk/docs/advanced/additional-responses.md b/docs/uk/docs/advanced/additional-responses.md
new file mode 100644
index 0000000000..4ce5f94c7f
--- /dev/null
+++ b/docs/uk/docs/advanced/additional-responses.md
@@ -0,0 +1,247 @@
+# Додаткові відповіді в OpenAPI { #additional-responses-in-openapi }
+
+/// warning | Попередження
+
+Це доволі просунута тема.
+
+Якщо ви тільки починаєте з **FastAPI**, вам це може бути не потрібно.
+
+///
+
+Ви можете оголошувати додаткові відповіді з додатковими кодами статусу, media types, описами тощо.
+
+Ці додаткові відповіді буде включено до схеми OpenAPI, тож вони також з’являться в документації API.
+
+Але для цих додаткових відповідей вам потрібно переконатися, що ви повертаєте `Response`, як-от `JSONResponse`, безпосередньо, із вашим кодом статусу та вмістом.
+
+## Додаткова відповідь із `model` { #additional-response-with-model }
+
+Ви можете передати в *декоратори операції шляху* параметр `responses`.
+
+Він приймає `dict`: ключі — це коди статусу для кожної відповіді (наприклад, `200`), а значення — інші `dict` з інформацією для кожної з них.
+
+Кожен із цих `dict` відповіді може мати ключ `model`, що містить Pydantic model, так само як `response_model`.
+
+**FastAPI** візьме цю модель, згенерує її JSON Schema та включить у правильне місце в OpenAPI.
+
+Наприклад, щоб оголосити ще одну відповідь із кодом статусу `404` і Pydantic model `Message`, ви можете написати:
+
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
+
+/// note | Примітка
+
+Пам’ятайте, що потрібно повертати `JSONResponse` безпосередньо.
+
+///
+
+/// info | Інформація
+
+Ключ `model` не є частиною OpenAPI.
+
+**FastAPI** візьме Pydantic model звідти, згенерує JSON Schema і помістить його в правильне місце.
+
+Правильне місце:
+
+* У ключі `content`, значенням якого є інший JSON-об’єкт (`dict`), що містить:
+ * Ключ із media type, наприклад `application/json`, значенням якого є інший JSON-об’єкт, що містить:
+ * Ключ `schema`, значенням якого є JSON Schema з моделі — ось правильне місце.
+ * **FastAPI** додає тут посилання на глобальні JSON Schemas в іншому місці вашого OpenAPI, замість того щоб включати схему безпосередньо. Так інші застосунки та клієнти можуть використовувати ці JSON Schemas напряму, надавати кращі інструменти генерації коду тощо.
+
+///
+
+Згенеровані відповіді в OpenAPI для цієї *операції шляху* будуть:
+
+```JSON hl_lines="3-12"
+{
+ "responses": {
+ "404": {
+ "description": "Additional Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Message"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Item"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+Схеми мають посилання на інше місце всередині схеми OpenAPI:
+
+```JSON hl_lines="4-16"
+{
+ "components": {
+ "schemas": {
+ "Message": {
+ "title": "Message",
+ "required": [
+ "message"
+ ],
+ "type": "object",
+ "properties": {
+ "message": {
+ "title": "Message",
+ "type": "string"
+ }
+ }
+ },
+ "Item": {
+ "title": "Item",
+ "required": [
+ "id",
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "id": {
+ "title": "Id",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "type": "string"
+ }
+ }
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": [
+ "loc",
+ "msg",
+ "type"
+ ],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "msg": {
+ "title": "Message",
+ "type": "string"
+ },
+ "type": {
+ "title": "Error Type",
+ "type": "string"
+ }
+ }
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+## Додаткові media types для основної відповіді { #additional-media-types-for-the-main-response }
+
+Ви можете використати цей самий параметр `responses`, щоб додати різні media types для тієї самої основної відповіді.
+
+Наприклад, ви можете додати додатковий media type `image/png`, оголосивши, що ваша *операція шляху* може повертати JSON-об’єкт (із media type `application/json`) або PNG-зображення:
+
+{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
+
+/// note | Примітка
+
+Зверніть увагу, що потрібно повертати зображення безпосередньо через `FileResponse`.
+
+///
+
+/// info | Інформація
+
+Якщо ви явно не вкажете інший media type у параметрі `responses`, FastAPI вважатиме, що відповідь має той самий media type, що й основний клас відповіді (типово `application/json`).
+
+Але якщо ви вказали власний клас відповіді з `None` як media type, FastAPI використає `application/json` для будь-якої додаткової відповіді, що має пов’язану модель.
+
+///
+
+## Об’єднання інформації { #combining-information }
+
+Ви також можете об’єднувати інформацію про відповіді з кількох місць, зокрема з параметрів `response_model`, `status_code` і `responses`.
+
+Ви можете оголосити `response_model`, використовуючи типовий код статусу `200` (або власний, якщо потрібно), а потім оголосити додаткову інформацію для цієї ж відповіді в `responses` — безпосередньо в схемі OpenAPI.
+
+**FastAPI** збереже додаткову інформацію з `responses` і об’єднає її з JSON Schema вашої моделі.
+
+Наприклад, ви можете оголосити відповідь із кодом статусу `404`, яка використовує Pydantic model і має власний `description`.
+
+А також відповідь із кодом статусу `200`, яка використовує ваш `response_model`, але містить власний `example`:
+
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
+
+Усе це буде об’єднано й включено до вашого OpenAPI та показано в документації API:
+
+
+
+## Поєднання попередньо визначених відповідей і власних { #combine-predefined-responses-and-custom-ones }
+
+Можливо, ви хочете мати деякі попередньо визначені відповіді, що застосовуються до багатьох *операцій шляху*, але при цьому поєднати їх із власними відповідями, потрібними для кожної *операції шляху*.
+
+Для таких випадків можна використати Python-техніку «розпакування» `dict` за допомогою `**dict_to_unpack`:
+
+```Python
+old_dict = {
+ "old key": "old value",
+ "second old key": "second old value",
+}
+new_dict = {**old_dict, "new key": "new value"}
+```
+
+Тут `new_dict` міститиме всі пари ключ-значення з `old_dict`, плюс нову пару ключ-значення:
+
+```Python
+{
+ "old key": "old value",
+ "second old key": "second old value",
+ "new key": "new value",
+}
+```
+
+Ви можете застосувати цю техніку, щоб повторно використати деякі попередньо визначені відповіді у ваших *операціях шляху* та поєднати їх із додатковими власними.
+
+Наприклад:
+
+{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
+
+## Докладніше про відповіді OpenAPI { #more-information-about-openapi-responses }
+
+Щоб побачити, що саме можна включати до відповідей, перегляньте ці розділи специфікації OpenAPI:
+
+* OpenAPI Responses Object — містить `Response Object`.
+* OpenAPI Response Object — ви можете включити будь-що з цього безпосередньо в кожну відповідь у параметрі `responses`, зокрема `description`, `headers`, `content` (усередині нього ви оголошуєте різні media types і JSON Schemas) та `links`.
diff --git a/docs/uk/docs/advanced/additional-status-codes.md b/docs/uk/docs/advanced/additional-status-codes.md
new file mode 100644
index 0000000000..c6d960eb01
--- /dev/null
+++ b/docs/uk/docs/advanced/additional-status-codes.md
@@ -0,0 +1,41 @@
+# Додаткові коди статусу { #additional-status-codes }
+
+За замовчуванням **FastAPI** повертатиме відповіді, використовуючи `JSONResponse`, поміщаючи вміст, який ви повертаєте з вашої *операції шляху*, всередину цього `JSONResponse`.
+
+Він використає код статусу за замовчуванням або той, який ви встановили у вашій *операції шляху*.
+
+## Додаткові коди статусу { #additional-status-codes_1 }
+
+Якщо ви хочете повертати додаткові коди статусу, окрім основного, ви можете зробити це, повертаючи `Response` безпосередньо, наприклад `JSONResponse`, і встановити додатковий код статусу напряму.
+
+Наприклад, припустімо, що ви хочете мати *операцію шляху*, яка дозволяє оновлювати елементи, і повертає HTTP-код статусу 200 «OK» у разі успіху.
+
+Але ви також хочете, щоб вона приймала нові елементи. І коли елементів раніше не існувало, вона створює їх і повертає HTTP-код статусу 201 «Created».
+
+Щоб цього досягти, імпортуйте `JSONResponse` і повертайте ваш вміст безпосередньо там, встановивши `status_code`, який вам потрібен:
+
+{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
+
+/// warning | Попередження
+
+Коли ви повертаєте `Response` безпосередньо, як у прикладі вище, його буде повернуто напряму.
+
+Його не буде серіалізовано моделлю тощо.
+
+Переконайтеся, що він містить дані, які ви хочете повернути, і що значення є валідним JSON (якщо ви використовуєте `JSONResponse`).
+
+///
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette.responses import JSONResponse`.
+
+**FastAPI** надає ті самі `starlette.responses` як `fastapi.responses` просто для вашої зручності як розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette. Те саме стосується `status`.
+
+///
+
+## OpenAPI і документація API { #openapi-and-api-docs }
+
+Якщо ви повертаєте додаткові коди статусу та відповіді безпосередньо, їх не буде включено до схеми OpenAPI (документації API), адже FastAPI не має способу заздалегідь знати, що саме ви збираєтеся повертати.
+
+Але ви можете задокументувати це у вашому коді, використовуючи: [Додаткові відповіді](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/advanced/advanced-dependencies.md b/docs/uk/docs/advanced/advanced-dependencies.md
new file mode 100644
index 0000000000..e158440ef3
--- /dev/null
+++ b/docs/uk/docs/advanced/advanced-dependencies.md
@@ -0,0 +1,163 @@
+# Розширені залежності { #advanced-dependencies }
+
+## Параметризовані залежності { #parameterized-dependencies }
+
+Усі залежності, які ми бачили, — це фіксована функція або клас.
+
+Але можуть бути випадки, коли ви хочете мати змогу задавати параметри для залежності, не оголошуючи багато різних функцій або класів.
+
+Уявімо, що ми хочемо мати залежність, яка перевіряє, чи містить параметр запиту `q` певний фіксований вміст.
+
+Але ми хочемо мати змогу параметризувати цей фіксований вміст.
+
+## «Callable» екземпляр { #a-callable-instance }
+
+У Python є спосіб зробити екземпляр класу «callable».
+
+Не сам клас (який уже є callable), а екземпляр цього класу.
+
+Для цього ми оголошуємо метод `__call__`:
+
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
+
+У цьому випадку саме `__call__` **FastAPI** використовуватиме, щоб перевіряти додаткові параметри та підзалежності, і саме його буде викликано, щоб передати значення параметру у вашій *функції операції шляху* пізніше.
+
+## Параметризуйте екземпляр { #parameterize-the-instance }
+
+А тепер ми можемо використати `__init__`, щоб оголосити параметри екземпляра, які ми зможемо використати для «параметризації» залежності:
+
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
+
+У цьому випадку **FastAPI** ніколи не чіпатиме й не «цікавитиметься» `__init__` — ми використаємо його безпосередньо у своєму коді.
+
+## Створіть екземпляр { #create-an-instance }
+
+Ми можемо створити екземпляр цього класу так:
+
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
+
+Таким чином ми можемо «параметризувати» нашу залежність, яка тепер містить `"bar"` як атрибут `checker.fixed_content`.
+
+## Використайте екземпляр як залежність { #use-the-instance-as-a-dependency }
+
+Далі ми можемо використати цей `checker` у `Depends(checker)` замість `Depends(FixedContentQueryChecker)`, адже залежністю є екземпляр `checker`, а не сам клас.
+
+І під час розв’язання залежності **FastAPI** викличе цей `checker` так:
+
+```Python
+checker(q="somequery")
+```
+
+...і передасть те, що він поверне, як значення залежності у нашій *функції операції шляху* в параметр `fixed_content_included`:
+
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
+
+/// tip | Порада
+
+Усе це може здаватися надуманим. І поки що може бути не дуже зрозуміло, у чому користь.
+
+Ці приклади навмисно прості, але показують, як це все працює.
+
+У розділах про безпеку є допоміжні функції, які реалізовані так само.
+
+Якщо ви все це зрозуміли, то вже знаєте, як «під капотом» працюють ті утиліти для безпеки.
+
+///
+
+## Залежності з `yield`, `HTTPException`, `except` і Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
+
+/// warning | Попередження
+
+Швидше за все, вам не потрібні ці технічні деталі.
+
+Вони корисні переважно, якщо у вас був застосунок FastAPI старіший за 0.121.0 і ви стикаєтесь із проблемами в залежностях з `yield`.
+
+///
+
+Залежності з `yield` еволюціонували з часом, щоб врахувати різні сценарії використання та виправити деякі проблеми. Нижче наведено підсумок змін.
+
+### Залежності з `yield` і `scope` { #dependencies-with-yield-and-scope }
+
+У версії 0.121.0 FastAPI додав підтримку `Depends(scope="function")` для залежностей з `yield`.
+
+Використовуючи `Depends(scope="function")`, вихідний код після `yield` виконується одразу після завершення *функції операції шляху*, до того як відповідь буде надіслана клієнту.
+
+А при використанні `Depends(scope="request")` (за замовчуванням) вихідний код після `yield` виконується після того, як відповідь надіслано.
+
+Докладніше про це читайте в документації: [Залежності з `yield` — Ранній вихід і `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).
+
+### Залежності з `yield` і `StreamingResponse`, технічні деталі { #dependencies-with-yield-and-streamingresponse-technical-details }
+
+До FastAPI 0.118.0, якщо ви використовували залежність з `yield`, вихідний код виконувався після того, як *функція операції шляху* повертала результат, але прямо перед надсиланням відповіді.
+
+Мета була — не утримувати ресурси довше, ніж потрібно, очікуючи, поки відповідь пройде мережею.
+
+Ця зміна також означала, що якщо ви повертали `StreamingResponse`, вихідний код залежності з `yield` уже був би виконаний.
+
+Наприклад, якщо у вас була сесія бази даних у залежності з `yield`, то `StreamingResponse` не зміг би використовувати цю сесію під час стримінгу даних, бо сесію вже було б закрито у вихідному коді після `yield`.
+
+Цю поведінку було повернуто у 0.118.0, щоб вихідний код після `yield` виконувався після надсилання відповіді.
+
+/// info | Інформація
+
+Як ви побачите нижче, це дуже схоже на поведінку до версії 0.106.0, але з кількома покращеннями та виправленнями помилок для крайніх випадків.
+
+///
+
+#### Сценарії з раннім виконанням вихідного коду { #use-cases-with-early-exit-code }
+
+Є деякі сценарії з особливими умовами, у яких могла б бути корисною стара поведінка — виконувати вихідний код залежностей з `yield` перед надсиланням відповіді.
+
+Наприклад, уявімо, що у вас є код, який використовує сесію бази даних у залежності з `yield` лише для перевірки користувача, але сесія більше ніколи не використовується у *функції операції шляху* — лише в залежності — **і** відповідь надсилається довго, як `StreamingResponse`, що повільно передає дані, але з певної причини не використовує базу даних.
+
+У такому випадку сесія бази даних утримуватиметься до завершення надсилання відповіді, але якщо ви її не використовуєте, то це не потрібно.
+
+Ось як це могло б виглядати:
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py *}
+
+Вихідний код, автоматичне закриття `Session` у:
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
+
+...було б виконано після того, як відповідь завершить надсилати повільні дані:
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}
+
+Але оскільки `generate_stream()` не використовує сесію бази даних, насправді немає потреби тримати сесію відкритою під час надсилання відповіді.
+
+Якщо у вас є саме такий сценарій із SQLModel (або SQLAlchemy), ви можете явно закрити сесію після того, як вона вам більше не потрібна:
+
+{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}
+
+Тоді сесія вивільнить з’єднання з базою даних, і його зможуть використати інші запити.
+
+Якщо у вас є інший сценарій, що потребує раннього виходу із залежності з `yield`, будь ласка, створіть питання в GitHub Discussions з вашим конкретним сценарієм і поясненням, чому вам було б корисне раннє закриття для залежностей з `yield`.
+
+Якщо знайдуться переконливі сценарії для раннього закриття в залежностях з `yield`, я розгляну можливість додати новий спосіб явно вмикати раннє закриття.
+
+### Залежності з `yield` і `except`, технічні деталі { #dependencies-with-yield-and-except-technical-details }
+
+До FastAPI 0.110.0, якщо ви використовували залежність з `yield`, а потім перехоплювали виняток через `except` у цій залежності і не піднімали виняток знову, виняток автоматично піднімався/передавався будь-яким обробникам винятків або обробнику внутрішньої помилки сервера.
+
+У версії 0.110.0 це було змінено, щоб виправити неконтрольоване споживання пам’яті через переспрямовані винятки без обробника (внутрішні помилки сервера), і щоб узгодити поведінку зі звичайним Python-кодом.
+
+### Background Tasks і залежності з `yield`, технічні деталі { #background-tasks-and-dependencies-with-yield-technical-details }
+
+До FastAPI 0.106.0 піднімати винятки після `yield` було неможливо: вихідний код у залежностях з `yield` виконувався *після* надсилання відповіді, тож [Обробники винятків](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже відпрацьовували.
+
+Так було спроєктовано переважно для того, щоб дозволити використовувати ті самі об’єкти, «yield»-нуті залежностями, усередині фонових завдань, бо вихідний код виконувався після завершення фонових завдань.
+
+Це було змінено у FastAPI 0.106.0 з наміром не утримувати ресурси під час очікування, поки відповідь пройде мережею.
+
+/// tip | Порада
+
+Крім того, фонове завдання зазвичай є незалежним набором логіки, який слід обробляти окремо, з власними ресурсами (наприклад, власним з’єднанням з базою даних).
+
+Тож у такий спосіб ваш код, імовірно, буде чистішим.
+
+///
+
+Якщо ви раніше покладалися на таку поведінку, тепер вам слід створювати ресурси для фонових завдань усередині самого фонового завдання та використовувати всередині лише дані, які не залежать від ресурсів залежностей з `yield`.
+
+Наприклад, замість використання тієї самої сесії бази даних, ви створите нову сесію бази даних усередині фонового завдання і отримаєте об’єкти з бази даних, використовуючи цю нову сесію. А потім, замість передачі об’єкта з бази даних як параметра у функцію фонового завдання, ви передасте ID цього об’єкта й повторно отримаєте об’єкт усередині функції фонового завдання.
diff --git a/docs/uk/docs/advanced/async-tests.md b/docs/uk/docs/advanced/async-tests.md
new file mode 100644
index 0000000000..1d1aedab4d
--- /dev/null
+++ b/docs/uk/docs/advanced/async-tests.md
@@ -0,0 +1,99 @@
+# Асинхронні тести { #async-tests }
+
+Ви вже бачили, як тестувати ваші застосунки **FastAPI** за допомогою наданого `TestClient`. До цього моменту ви бачили лише те, як писати синхронні тести, без використання `async`-функцій.
+
+Можливість використовувати асинхронні функції у ваших тестах може бути корисною, наприклад, коли ви асинхронно виконуєте запити до бази даних. Уявіть, що ви хочете протестувати надсилання запитів до вашого застосунку FastAPI, а потім перевірити, що ваш backend успішно записав правильні дані в базу даних, використовуючи async-бібліотеку для роботи з БД.
+
+Подивімося, як це реалізувати.
+
+## pytest.mark.anyio { #pytest-mark-anyio }
+
+Якщо ми хочемо викликати асинхронні функції в наших тестах, наші тестові функції теж мають бути асинхронними. AnyIO надає зручний плагін для цього, який дозволяє нам вказати, що деякі тестові функції слід викликати асинхронно.
+
+## HTTPX { #httpx }
+
+Навіть якщо ваш застосунок **FastAPI** використовує звичайні `def`-функції замість `async def`, під капотом це все одно `async`-застосунок.
+
+`TestClient` виконує певну «магію» всередині, щоб викликати асинхронний застосунок FastAPI у ваших звичайних `def` тестових функціях, використовуючи стандартний pytest. Але ця магія більше не працює, коли ми використовуємо його всередині асинхронних функцій. Запускаючи наші тести асинхронно, ми більше не можемо використовувати `TestClient` усередині тестових функцій.
+
+`TestClient` базується на HTTPX, і, на щастя, ми можемо використовувати його напряму для тестування API.
+
+## Приклад { #example }
+
+Для простого прикладу розгляньмо структуру файлів, схожу на описану в [Більші застосунки](../tutorial/bigger-applications.md){.internal-link target=_blank} та [Тестування](../tutorial/testing.md){.internal-link target=_blank}:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Файл `main.py` матиме:
+
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
+
+Файл `test_main.py` матиме тести для `main.py`, і тепер він може виглядати так:
+
+{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
+
+## Запуск { #run-it }
+
+Ви можете запускати тести як зазвичай, через:
+
+
+
+Але якщо ми звернемося до UI документації за «офіційною» URL через проксі на порту `9999`, за адресою `/api/v1/docs`, він працює коректно! 🎉
+
+Ви можете перевірити це за адресою http://127.0.0.1:9999/api/v1/docs:
+
+
+
+Саме так, як ми й хотіли. ✔️
+
+Це тому, що FastAPI використовує цей `root_path`, щоб створити `server` за замовчуванням в OpenAPI з URL, наданим через `root_path`.
+
+## Додаткові сервери { #additional-servers }
+
+/// warning | Попередження
+
+Це більш просунутий сценарій. За бажанням можете його пропустити.
+
+///
+
+За замовчуванням **FastAPI** створює `server` у схемі OpenAPI з URL для `root_path`.
+
+Але ви також можете надати інші альтернативні `servers`, наприклад, якщо хочете, щоб *той самий* UI документації взаємодіяв і зі staging-, і з production-середовищем.
+
+Якщо ви передаєте власний список `servers` і є `root_path` (бо ваш API знаходиться за проксі), **FastAPI** вставить «server» з цим `root_path` на початок списку.
+
+Наприклад:
+
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
+
+Згенерує схему OpenAPI на кшталт:
+
+```JSON hl_lines="5-7"
+{
+ "openapi": "3.1.0",
+ // More stuff here
+ "servers": [
+ {
+ "url": "/api/v1"
+ },
+ {
+ "url": "https://stag.example.com",
+ "description": "Staging environment"
+ },
+ {
+ "url": "https://prod.example.com",
+ "description": "Production environment"
+ }
+ ],
+ "paths": {
+ // More stuff here
+ }
+}
+```
+
+/// tip | Порада
+
+Зверніть увагу на автоматично згенерований server зі значенням `url` `/api/v1`, узятим з `root_path`.
+
+///
+
+У UI документації за адресою http://127.0.0.1:9999/api/v1/docs це виглядатиме так:
+
+
+
+/// tip | Порада
+
+UI документації взаємодіятиме з тим сервером, який ви виберете.
+
+///
+
+/// note | Технічні деталі
+
+Властивість `servers` у специфікації OpenAPI є необов’язковою.
+
+Якщо ви не вказуєте параметр `servers` і `root_path` дорівнює `/`, властивість `servers` у згенерованій схемі OpenAPI буде повністю пропущена за замовчуванням, що еквівалентно одному server зі значенням `url` `/`.
+
+///
+
+### Вимкнення автоматичного server з `root_path` { #disable-automatic-server-from-root-path }
+
+Якщо ви не хочете, щоб **FastAPI** включав автоматичний server з `root_path`, можете використати параметр `root_path_in_servers=False`:
+
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
+
+і тоді він не включатиметься в схему OpenAPI.
+
+## Монтування підзастосунку { #mounting-a-sub-application }
+
+Якщо вам потрібно змонтувати підзастосунок (як описано в [Підзастосунки — монтування](sub-applications.md){.internal-link target=_blank}), водночас використовуючи проксі з `root_path`, ви можете зробити це у звичний спосіб.
+
+FastAPI внутрішньо «розумно» використовує `root_path`, тож усе просто працюватиме. ✨
diff --git a/docs/uk/docs/advanced/custom-response.md b/docs/uk/docs/advanced/custom-response.md
new file mode 100644
index 0000000000..36c7e21991
--- /dev/null
+++ b/docs/uk/docs/advanced/custom-response.md
@@ -0,0 +1,312 @@
+# Користувацька відповідь — HTML, Stream, File та інше { #custom-response-html-stream-file-others }
+
+За замовчуванням **FastAPI** повертатиме відповіді, використовуючи `JSONResponse`.
+
+Ви можете перевизначити це, повернувши `Response` напряму, як показано в розділі [Повернути Response напряму](response-directly.md){.internal-link target=_blank}.
+
+Але якщо ви повертаєте `Response` напряму (або будь-який підклас, як-от `JSONResponse`), дані не будуть автоматично конвертовані (навіть якщо ви оголосили `response_model`), і документація не буде автоматично згенерована (наприклад, із включенням конкретного «media type» у HTTP-заголовок `Content-Type` як частини згенерованого OpenAPI).
+
+Втім, ви також можете оголосити `Response`, яку потрібно використовувати (наприклад, будь-який підклас `Response`), у *декораторі операції шляху* через параметр `response_class`.
+
+Вміст, який ви повертаєте з вашої *функції операції шляху*, буде вкладено всередину цього `Response`.
+
+І якщо цей `Response` має JSON media type (`application/json`), як у випадку з `JSONResponse` та `UJSONResponse`, дані, які ви повертаєте, будуть автоматично конвертовані (і відфільтровані) за допомогою будь-якого Pydantic `response_model`, який ви оголосили в *декораторі операції шляху*.
+
+/// note | Примітка
+
+Якщо ви використовуєте клас відповіді без media type, FastAPI очікуватиме, що ваша відповідь не матиме вмісту, тож не документуватиме формат відповіді у згенерованій OpenAPI-документації.
+
+///
+
+## Використання `ORJSONResponse` { #use-orjsonresponse }
+
+Наприклад, якщо ви «вичавлюєте» продуктивність, можете встановити й використати `orjson` та налаштувати відповідь як `ORJSONResponse`.
+
+Імпортуйте клас `Response` (підклас), який хочете використовувати, та оголосіть його в *декораторі операції шляху*.
+
+Для великих відповідей повертати `Response` напряму набагато швидше, ніж повертати словник.
+
+Це тому, що за замовчуванням FastAPI перевірятиме кожен елемент усередині та переконуватиметься, що його можна серіалізувати в JSON, використовуючи той самий [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}, пояснений у підручнику. Саме це дозволяє вам повертати **довільні об’єкти**, наприклад моделі бази даних.
+
+Але якщо ви впевнені, що вміст, який ви повертаєте, **можна серіалізувати в JSON**, ви можете передати його безпосередньо класу відповіді та уникнути додаткових витрат, які FastAPI матиме, пропускаючи результат через `jsonable_encoder` перед передаванням його класу відповіді.
+
+{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
+
+/// info | Інформація
+
+Параметр `response_class` також буде використано, щоб визначити «media type» відповіді.
+
+У цьому випадку HTTP-заголовок `Content-Type` буде встановлено в `application/json`.
+
+І це буде задокументовано відповідним чином в OpenAPI.
+
+///
+
+/// tip | Порада
+
+`ORJSONResponse` доступний лише у FastAPI, а не в Starlette.
+
+///
+
+## HTML-відповідь { #html-response }
+
+Щоб повертати відповідь з HTML напряму з **FastAPI**, використовуйте `HTMLResponse`.
+
+* Імпортуйте `HTMLResponse`.
+* Передайте `HTMLResponse` як параметр `response_class` вашого *декоратора операції шляху*.
+
+{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
+
+/// info | Інформація
+
+Параметр `response_class` також буде використано, щоб визначити «media type» відповіді.
+
+У цьому випадку HTTP-заголовок `Content-Type` буде встановлено в `text/html`.
+
+І це буде задокументовано відповідним чином в OpenAPI.
+
+///
+
+### Повернути `Response` { #return-a-response }
+
+Як показано в [Повернути Response напряму](response-directly.md){.internal-link target=_blank}, ви також можете перевизначити відповідь напряму у вашій *операції шляху*, повернувши її.
+
+Той самий приклад з вище, який повертає `HTMLResponse`, може виглядати так:
+
+{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
+
+/// warning | Попередження
+
+`Response`, повернений напряму вашою *функцією операції шляху*, не буде задокументований в OpenAPI (наприклад, `Content-Type` не буде задокументовано) і не буде видимий в автоматичних інтерактивних документах.
+
+///
+
+/// info | Інформація
+
+Звісно, фактичний заголовок `Content-Type`, status code тощо будуть взяті з об’єкта `Response`, який ви повернули.
+
+///
+
+### Документувати в OpenAPI і перевизначити `Response` { #document-in-openapi-and-override-response }
+
+Якщо ви хочете перевизначити відповідь усередині функції, але водночас задокументувати «media type» в OpenAPI, ви можете використати параметр `response_class` І повернути об’єкт `Response`.
+
+Тоді `response_class` буде використано лише для документування OpenAPI *операції шляху*, а ваш `Response` буде використано як є.
+
+#### Повернути `HTMLResponse` напряму { #return-an-htmlresponse-directly }
+
+Наприклад, це може виглядати так:
+
+{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
+
+У цьому прикладі функція `generate_html_response()` вже генерує та повертає `Response` замість повернення HTML як `str`.
+
+Повертаючи результат виклику `generate_html_response()`, ви вже повертаєте `Response`, який перевизначить стандартну поведінку **FastAPI**.
+
+Але оскільки ви також передали `HTMLResponse` у `response_class`, **FastAPI** знатиме, як задокументувати це в OpenAPI та інтерактивній документації як HTML з `text/html`:
+
+
+
+## Доступні відповіді { #available-responses }
+
+Ось деякі з доступних відповідей.
+
+Майте на увазі, що ви можете використати `Response`, щоб повернути будь-що інше, або навіть створити власний підклас.
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette.responses import HTMLResponse`.
+
+**FastAPI** надає ті самі `starlette.responses` як `fastapi.responses` просто для вашої зручності як розробника. Але більшість доступних відповідей надходить безпосередньо зі Starlette.
+
+///
+
+### `Response` { #response }
+
+Основний клас `Response`, від нього наслідуються всі інші відповіді.
+
+Ви можете повертати його напряму.
+
+Він приймає такі параметри:
+
+* `content` — `str` або `bytes`.
+* `status_code` — HTTP status code типу `int`.
+* `headers` — `dict` зі строк.
+* `media_type` — `str`, що задає media type. Напр. `"text/html"`.
+
+FastAPI (насправді Starlette) автоматично додасть заголовок Content-Length. Також буде додано заголовок Content-Type на основі `media_type` із додаванням charset для текстових типів.
+
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+
+### `HTMLResponse` { #htmlresponse }
+
+Приймає текст або байти та повертає HTML-відповідь, як ви читали вище.
+
+### `PlainTextResponse` { #plaintextresponse }
+
+Приймає текст або байти та повертає відповідь звичайним текстом.
+
+{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
+
+### `JSONResponse` { #jsonresponse }
+
+Приймає деякі дані та повертає відповідь, закодовану як `application/json`.
+
+Це відповідь за замовчуванням, яку використовує **FastAPI**, як ви читали вище.
+
+### `ORJSONResponse` { #orjsonresponse }
+
+Швидка альтернативна JSON-відповідь з використанням `orjson`, як ви читали вище.
+
+/// info | Інформація
+
+Для цього потрібно встановити `orjson`, наприклад командою `pip install orjson`.
+
+///
+
+### `UJSONResponse` { #ujsonresponse }
+
+Альтернативна JSON-відповідь з використанням `ujson`.
+
+/// info | Інформація
+
+Для цього потрібно встановити `ujson`, наприклад командою `pip install ujson`.
+
+///
+
+/// warning | Попередження
+
+`ujson` менш обережний, ніж вбудована реалізація Python, у тому, як він обробляє деякі крайові випадки.
+
+///
+
+{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
+
+/// tip | Порада
+
+Можливо, `ORJSONResponse` буде швидшою альтернативою.
+
+///
+
+### `RedirectResponse` { #redirectresponse }
+
+Повертає HTTP-перенаправлення. За замовчуванням використовує status code 307 (Temporary Redirect).
+
+Ви можете повернути `RedirectResponse` напряму:
+
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
+
+---
+
+Або ви можете використати його в параметрі `response_class`:
+
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
+
+Якщо ви зробите так, то з вашої *функції операції шляху* можна повертати URL напряму.
+
+У цьому випадку використаний `status_code` буде стандартним для `RedirectResponse`, тобто `307`.
+
+---
+
+Також можна використати параметр `status_code` у поєднанні з параметром `response_class`:
+
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
+
+### `StreamingResponse` { #streamingresponse }
+
+Приймає async generator або звичайний generator/iterator і стрімить тіло відповіді.
+
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
+
+#### Використання `StreamingResponse` з file-like об’єктами { #using-streamingresponse-with-file-like-objects }
+
+Якщо у вас є file-like об’єкт (наприклад, об’єкт, який повертає `open()`), ви можете створити generator function, щоб ітеруватися по цьому file-like об’єкту.
+
+Так вам не потрібно спочатку повністю зчитувати його в пам’ять; ви можете передати цю generator function у `StreamingResponse` і повернути її.
+
+Це охоплює багато бібліотек для роботи з хмарним сховищем, обробки відео та інші.
+
+{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
+
+1. Це generator function. Це «generator function», бо всередині містить інструкції `yield`.
+2. Використовуючи блок `with`, ми гарантуємо, що file-like об’єкт буде закрито після завершення generator function. Тобто після того, як вона завершить надсилання відповіді.
+3. Цей `yield from` каже функції ітеруватися по об’єкту з назвою `file_like`. А потім для кожної проітерованої частини робити `yield` цієї частини так, ніби вона походить з цієї generator function (`iterfile`).
+
+ Отже, це generator function, яка «делегує» роботу генерації чомусь іншому всередині.
+
+ Роблячи це таким чином, ми можемо помістити все в блок `with` і так гарантувати, що file-like об’єкт буде закрито після завершення.
+
+/// tip | Порада
+
+Зверніть увагу: оскільки тут ми використовуємо стандартний `open()`, який не підтримує `async` та `await`, ми оголошуємо операцію шляху звичайним `def`.
+
+///
+
+### `FileResponse` { #fileresponse }
+
+Асинхронно стрімить файл як відповідь.
+
+Має інший набір аргументів для створення екземпляра, ніж інші типи відповідей:
+
+* `path` — шлях до файлу, який потрібно стрімити.
+* `headers` — будь-які користувацькі заголовки для включення, як словник.
+* `media_type` — рядок, що задає media type. Якщо не задано, ім’я файлу або шлях буде використано для визначення media type.
+* `filename` — якщо задано, буде включено у відповідь `Content-Disposition`.
+
+Файлові відповіді включатимуть відповідні заголовки `Content-Length`, `Last-Modified` та `ETag`.
+
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
+
+Ви також можете використати параметр `response_class`:
+
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
+
+У цьому випадку ви можете повертати шлях до файлу напряму з вашої *функції операції шляху*.
+
+## Користувацький клас відповіді { #custom-response-class }
+
+Ви можете створити власний клас відповіді, успадкувавши його від `Response`, і використовувати.
+
+Наприклад, припустімо, ви хочете використовувати `orjson`, але з деякими користувацькими налаштуваннями, яких немає у включеному класі `ORJSONResponse`.
+
+Скажімо, ви хочете, щоб він повертав JSON з відступами та форматуванням, тож хочете використати опцію orjson `orjson.OPT_INDENT_2`.
+
+Ви можете створити `CustomORJSONResponse`. Головне, що потрібно зробити, — створити метод `Response.render(content)`, який повертає вміст як `bytes`:
+
+{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
+
+Тепер замість повернення:
+
+```json
+{"message": "Hello World"}
+```
+
+...ця відповідь повертатиме:
+
+```json
+{
+ "message": "Hello World"
+}
+```
+
+Звісно, імовірно, ви знайдете значно кращі способи скористатися цим, ніж форматування JSON. 😉
+
+## Клас відповіді за замовчуванням { #default-response-class }
+
+Під час створення екземпляра класу **FastAPI** або `APIRouter` ви можете вказати, який клас відповіді використовувати за замовчуванням.
+
+Параметр, який це визначає, — `default_response_class`.
+
+У прикладі нижче **FastAPI** використовуватиме `ORJSONResponse` за замовчуванням у всіх *операціях шляху* замість `JSONResponse`.
+
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
+
+/// tip | Порада
+
+Ви все одно можете перевизначати `response_class` в *операціях шляху*, як і раніше.
+
+///
+
+## Додаткова документація { #additional-documentation }
+
+Ви також можете оголосити media type та багато інших деталей в OpenAPI через `responses`: [Додаткові відповіді в OpenAPI](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/advanced/dataclasses.md b/docs/uk/docs/advanced/dataclasses.md
new file mode 100644
index 0000000000..7109628f7f
--- /dev/null
+++ b/docs/uk/docs/advanced/dataclasses.md
@@ -0,0 +1,95 @@
+# Використання dataclasses { #using-dataclasses }
+
+FastAPI побудовано поверх **Pydantic**, і я показував вам, як використовувати моделі Pydantic для оголошення запитів і відповідей.
+
+Але FastAPI також підтримує використання `dataclasses` так само:
+
+{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
+
+Це й досі підтримується завдяки **Pydantic**, оскільки він має внутрішню підтримку для `dataclasses`.
+
+Тож навіть із наведеним вище кодом, який явно не використовує Pydantic, FastAPI застосовує Pydantic, щоб перетворити ці стандартні dataclasses на власний різновид dataclasses у Pydantic.
+
+І, звісно, це підтримує те саме:
+
+* валідацію даних
+* серіалізацію даних
+* документацію даних тощо
+
+Це працює так само, як і з моделями Pydantic. І фактично під капотом це реалізовано так само — за допомогою Pydantic.
+
+/// info | Інформація
+
+Майте на увазі, що dataclasses не можуть робити все те, що можуть моделі Pydantic.
+
+Тож вам усе одно може знадобитися використовувати моделі Pydantic.
+
+Але якщо у вас є багато dataclasses, це гарний прийом, щоб використати їх для побудови web API за допомогою FastAPI. 🤓
+
+///
+
+## Dataclasses у `response_model` { #dataclasses-in-response-model }
+
+Ви також можете використовувати `dataclasses` у параметрі `response_model`:
+
+{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
+
+Dataclass буде автоматично перетворено на Pydantic dataclass.
+
+У такий спосіб його схема відображатиметься в інтерфейсі документації API:
+
+
+
+## Dataclasses у вкладених структурах даних { #dataclasses-in-nested-data-structures }
+
+Ви також можете поєднувати `dataclasses` з іншими анотаціями типів, щоб створювати вкладені структури даних.
+
+У деяких випадках вам усе ж доведеться використовувати версію `dataclasses` від Pydantic. Наприклад, якщо виникають помилки з автоматично згенерованою документацією API.
+
+У такому разі ви можете просто замінити стандартні `dataclasses` на `pydantic.dataclasses` — це повна (drop-in) заміна:
+
+{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
+
+1. Ми все ще імпортуємо `field` зі стандартного `dataclasses`.
+
+2. `pydantic.dataclasses` — це повна (drop-in) заміна для `dataclasses`.
+
+3. Dataclass `Author` містить список dataclasses `Item`.
+
+4. Dataclass `Author` використовується як параметр `response_model`.
+
+5. Ви можете використовувати інші стандартні анотації типів із dataclasses як тіло запиту.
+
+ У цьому випадку це список dataclasses `Item`.
+
+6. Тут ми повертаємо словник, який містить `items` — список dataclasses.
+
+ FastAPI все ще здатний серіалізувати дані в JSON.
+
+7. Тут `response_model` використовує анотацію типу — список dataclasses `Author`.
+
+ Знову ж таки, ви можете поєднувати `dataclasses` зі стандартними анотаціями типів.
+
+8. Зверніть увагу, що ця *функція операції шляху* використовує звичайний `def` замість `async def`.
+
+ Як завжди, у FastAPI ви можете поєднувати `def` і `async def` за потреби.
+
+ Якщо вам потрібно освіжити в пам’яті, коли що використовувати, перегляньте розділ _«Поспішаєте?»_ у документації про [`async` і `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+9. Ця *функція операції шляху* не повертає dataclasses (хоча могла б), а список словників із внутрішніми даними.
+
+ FastAPI використає параметр `response_model` (який включає dataclasses), щоб перетворити відповідь.
+
+Ви можете поєднувати `dataclasses` з іншими анотаціями типів у багатьох різних комбінаціях, щоб формувати складні структури даних.
+
+Перегляньте підказки в анотаціях у коді вище, щоб побачити конкретніші деталі.
+
+## Дізнатися більше { #learn-more }
+
+Ви також можете поєднувати `dataclasses` з іншими моделями Pydantic, успадковуватися від них, включати їх у власні моделі тощо.
+
+Щоб дізнатися більше, перегляньте документацію Pydantic про dataclasses.
+
+## Версія { #version }
+
+Це доступно починаючи з версії FastAPI `0.67.0`. 🔖
diff --git a/docs/uk/docs/advanced/events.md b/docs/uk/docs/advanced/events.md
new file mode 100644
index 0000000000..6fe2ebf46b
--- /dev/null
+++ b/docs/uk/docs/advanced/events.md
@@ -0,0 +1,165 @@
+# Події життєвого циклу { #lifespan-events }
+
+Ви можете визначити логіку (код), яку слід виконати перед **запуском** застосунку. Це означає, що цей код буде виконано **один раз**, **до того**, як застосунок **почне приймати запити**.
+
+Так само ви можете визначити логіку (код), яку слід виконати під час **завершення роботи** застосунку. У цьому разі цей код буде виконано **один раз**, **після** обробки, ймовірно, **багатьох запитів**.
+
+Оскільки цей код виконується до того, як застосунок **почне** приймати запити, і одразу після того, як він **завершить** їх обробку, він охоплює весь **життєвий цикл** застосунку (слово «lifespan» за мить стане важливим).
+
+Це може бути дуже корисно для налаштування **ресурсів**, які потрібні вам для всього застосунку, які є **спільними** для запитів, та/або які потрібно потім **очистити**. Наприклад, пул підключень до бази даних або завантаження спільної моделі машинного навчання.
+
+## Випадок використання { #use-case }
+
+Почнімо з прикладу **випадку використання**, а потім подивімося, як це розв’язати.
+
+Уявімо, що у вас є кілька **моделей машинного навчання**, які ви хочете використовувати для обробки запитів.
+
+Ці самі моделі є спільними для запитів, тобто це не одна модель на запит чи одна на користувача або щось подібне.
+
+Уявімо, що завантаження моделі може **займати досить багато часу**, бо потрібно читати багато **даних із диска**. Тож ви не хочете робити це для кожного запиту.
+
+Ви могли б завантажувати її на верхньому рівні модуля/файлу, але це також означало б, що модель **завантажуватиметься** навіть тоді, коли ви просто запускаєте простий автоматизований тест. Тоді тест був би **повільним**, бо йому довелося б чекати на завантаження моделі перед запуском незалежної частини коду.
+
+Саме це ми й розв’яжемо: завантажимо модель до початку обробки запитів, але лише безпосередньо перед тим, як застосунок почне їх приймати, а не під час завантаження коду.
+
+## Lifespan { #lifespan }
+
+Ви можете визначити цю логіку *startup* і *shutdown* за допомогою параметра `lifespan` застосунку `FastAPI` та «context manager» (за мить покажу, що це таке).
+
+Почнімо з прикладу, а потім розберемо його детально.
+
+Створімо асинхронну функцію `lifespan()` з `yield` ось так:
+
+{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
+
+Тут ми імітуємо дорогу операцію *startup* із завантаженням моделі, додаючи (фейкову) функцію моделі в словник із моделями машинного навчання перед `yield`. Цей код буде виконано **до того**, як застосунок **почне приймати запити**, під час *startup*.
+
+А потім, одразу після `yield`, ми вивантажуємо модель. Цей код буде виконано **після** того, як застосунок **завершить обробку запитів**, безпосередньо перед *shutdown*. Це може, наприклад, звільнити ресурси на кшталт пам’яті або GPU.
+
+/// tip | Порада
+
+`shutdown` відбудеться, коли ви **зупиняєте** застосунок.
+
+Можливо, вам потрібно запустити нову версію, або ви просто втомилися його запускати.
+
+///
+
+### Функція lifespan { #lifespan-function }
+
+Перше, на що слід звернути увагу: ми визначаємо асинхронну функцію з `yield`. Це дуже схоже на залежності з `yield`.
+
+{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
+
+Перша частина функції, до `yield`, буде виконана **до** запуску застосунку.
+
+А частина після `yield` буде виконана **після** того, як застосунок завершить роботу.
+
+### Async Context Manager { #async-context-manager }
+
+Якщо перевірити, функція декорована `@asynccontextmanager`.
+
+Це перетворює функцію на те, що називають «**async context manager**».
+
+{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
+
+**Context manager** у Python — це те, що ви можете використати в операторі `with`, наприклад, `open()` можна використати як context manager:
+
+```Python
+with open("file.txt") as file:
+ file.read()
+```
+
+У нових версіях Python також є **async context manager**. Його слід використовувати з `async with`:
+
+```Python
+async with lifespan(app):
+ await do_stuff()
+```
+
+Коли ви створюєте context manager або async context manager, як вище, він робить таке: перед входом у блок `with` виконає код до `yield`, а після виходу з блоку `with` виконає код після `yield`.
+
+У нашому прикладі коду вище ми не використовуємо його напряму, але передаємо FastAPI, щоб він використовував його.
+
+Параметр `lifespan` застосунку `FastAPI` приймає **async context manager**, тож ми можемо передати йому наш новий async context manager `lifespan`.
+
+{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
+
+## Альтернативні події (застаріло) { #alternative-events-deprecated }
+
+/// warning | Попередження
+
+Рекомендований спосіб обробляти *startup* і *shutdown* — використовувати параметр `lifespan` застосунку `FastAPI`, як описано вище. Якщо ви надасте параметр `lifespan`, обробники подій `startup` і `shutdown` більше не викликатимуться. Або весь підхід через `lifespan`, або весь підхід через події — не обидва одночасно.
+
+Ймовірно, ви можете пропустити цю частину.
+
+///
+
+Є альтернативний спосіб визначити цю логіку, яка має виконуватися під час *startup* і під час *shutdown*.
+
+Ви можете визначити обробники подій (функції), які потрібно виконати до запуску застосунку або під час завершення його роботи.
+
+Ці функції можна оголошувати як `async def` або як звичайні `def`.
+
+### Подія `startup` { #startup-event }
+
+Щоб додати функцію, яку потрібно запустити перед стартом застосунку, оголосіть її з подією `"startup"`:
+
+{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
+
+У цьому випадку функція-обробник події `startup` ініціалізує елемент `"database"` (це просто `dict`) деякими значеннями.
+
+Ви можете додати більше ніж одну функцію-обробник події.
+
+І ваш застосунок не почне приймати запити, доки не завершаться всі обробники події `startup`.
+
+### Подія `shutdown` { #shutdown-event }
+
+Щоб додати функцію, яку потрібно запустити під час завершення роботи застосунку, оголосіть її з подією `"shutdown"`:
+
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
+
+Тут функція-обробник події `shutdown` запише рядок тексту `"Application shutdown"` у файл `log.txt`.
+
+/// info | Інформація
+
+У функції `open()` параметр `mode="a"` означає «append», тобто рядок буде додано після того, що вже є у файлі, без перезапису попереднього вмісту.
+
+///
+
+/// tip | Порада
+
+Зверніть увагу: у цьому випадку ми використовуємо стандартну функцію Python `open()`, яка взаємодіє з файлом.
+
+Отже, тут є I/O (input/output), що потребує «очікування», доки дані будуть записані на диск.
+
+Але `open()` не використовує `async` та `await`.
+
+Тому ми оголошуємо функцію-обробник події як звичайну `def`, а не `async def`.
+
+///
+
+### `startup` і `shutdown` разом { #startup-and-shutdown-together }
+
+Є висока ймовірність, що логіка для ваших *startup* і *shutdown* пов’язана: ви можете хотіти щось запустити, а потім завершити, отримати ресурс, а потім звільнити його тощо.
+
+Робити це в розділених функціях, які не ділять між собою логіку або змінні, складніше, бо доведеться зберігати значення в глобальних змінних або застосовувати подібні прийоми.
+
+Тому зараз рекомендується натомість використовувати `lifespan`, як пояснено вище.
+
+## Технічні деталі { #technical-details }
+
+Лише технічна деталь для допитливих ґіків.
+
+Під капотом, у технічній специфікації ASGI, це частина Lifespan Protocol, і вона визначає події з назвами `startup` та `shutdown`.
+
+/// info | Інформація
+
+Докладніше про обробники `lifespan` у Starlette читайте в документації Lifespan у Starlette.
+
+Зокрема, як обробляти стан lifespan, який можна використовувати в інших частинах вашого коду.
+
+///
+
+## Підзастосунки { #sub-applications }
+
+🚨 Майте на увазі, що ці події життєвого циклу (startup і shutdown) виконуватимуться лише для головного застосунку, а не для [Підзастосунків — монтування](sub-applications.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/advanced/generate-clients.md b/docs/uk/docs/advanced/generate-clients.md
new file mode 100644
index 0000000000..3bc1cfbb4b
--- /dev/null
+++ b/docs/uk/docs/advanced/generate-clients.md
@@ -0,0 +1,208 @@
+# Генерація SDK { #generating-sdks }
+
+Оскільки **FastAPI** базується на специфікації **OpenAPI**, його API можна описати у стандартному форматі, який розуміє багато інструментів.
+
+Це спрощує генерацію актуальної **документації**, клієнтських бібліотек (**SDKs**) кількома мовами, а також **тестування** чи **workflow для автоматизації**, які залишаються синхронізованими з вашим кодом.
+
+У цьому посібнику ви дізнаєтеся, як згенерувати **TypeScript SDK** для вашого FastAPI бекенду.
+
+## Open Source генератори SDK { #open-source-sdk-generators }
+
+Універсальний варіант — OpenAPI Generator, який підтримує **багато мов програмування** і може генерувати SDK з вашої OpenAPI специфікації.
+
+Для **TypeScript-клієнтів** Hey API — спеціалізоване рішення, що забезпечує оптимізований досвід для екосистеми TypeScript.
+
+Більше генераторів SDK можна знайти на OpenAPI.Tools.
+
+/// tip | Порада
+
+FastAPI автоматично генерує специфікації **OpenAPI 3.1**, тож будь-який інструмент, який ви використовуєте, має підтримувати цю версію.
+
+///
+
+## Генератори SDK від спонсорів FastAPI { #sdk-generators-from-fastapi-sponsors }
+
+У цьому розділі зібрано рішення, що **підтримуються венчурним капіталом** і **компаніями**, від компаній-спонсорів FastAPI. Ці продукти надають **додаткові можливості** та **інтеграції** поверх якісно згенерованих SDK.
+
+Спонсоруючи ✨ [**FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, ці компанії допомагають зберігати фреймворк та його **екосистему** здоровими й **стійкими**.
+
+Їхнє спонсорство також демонструє сильну відданість **спільноті** FastAPI (вам), показуючи, що їм важливо не лише пропонувати **якісний сервіс**, а й підтримувати **надійний і процвітаючий фреймворк** FastAPI.
+
+Наприклад, ви можете спробувати:
+
+* Speakeasy
+* Stainless
+* liblab
+
+Деякі з цих рішень також можуть бути open source або мати безплатні тарифи, тож ви можете спробувати їх без фінансових зобов’язань. Також доступні інші комерційні генератори SDK, їх можна знайти онлайн.
+
+## Створення TypeScript SDK { #create-a-typescript-sdk }
+
+Почнімо з простого застосунку FastAPI:
+
+{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
+
+Зверніть увагу, що *операції шляху* визначають моделі, які вони використовують для тіла запиту та тіла відповіді, використовуючи моделі `Item` і `ResponseMessage`.
+
+### Документація API { #api-docs }
+
+Якщо перейти на `/docs`, ви побачите **схеми** для даних, які надсилаються в запитах і отримуються у відповідях:
+
+
+
+Ви бачите ці схеми, тому що їх було оголошено моделями в застосунку.
+
+Ця інформація доступна в **OpenAPI схемі** застосунку, а далі відображається в документації API.
+
+Саме ця інформація з моделей, включена в OpenAPI, і може бути використана для **генерації клієнтського коду**.
+
+### Hey API { #hey-api }
+
+Коли у нас є застосунок FastAPI з моделями, ми можемо використати Hey API для генерації TypeScript-клієнта. Найшвидший спосіб — через npx.
+
+```sh
+npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
+```
+
+Це згенерує TypeScript SDK у `./src/client`.
+
+Ви можете дізнатися, як встановити `@hey-api/openapi-ts`, а також прочитати про згенерований результат на їхньому сайті.
+
+### Використання SDK { #using-the-sdk }
+
+Тепер ви можете імпортувати та використовувати клієнтський код. Це може виглядати так — зверніть увагу, що ви отримуєте автодоповнення для методів:
+
+
+
+Ви також отримаєте автодоповнення для payload, який потрібно надіслати:
+
+
+
+/// tip | Порада
+
+Зверніть увагу на автодоповнення для `name` і `price` — це було визначено в застосунку FastAPI, у моделі `Item`.
+
+///
+
+Також ви матимете inline-помилки для даних, які надсилаєте:
+
+
+
+Об’єкт відповіді також матиме автодоповнення:
+
+
+
+## Застосунок FastAPI з тегами { #fastapi-app-with-tags }
+
+У багатьох випадках ваш застосунок FastAPI буде більшим, і ви, ймовірно, використовуватимете теги, щоб розділяти різні групи *операцій шляху*.
+
+Наприклад, у вас може бути секція для **items** і інша секція для **users**, і їх можна розділити тегами:
+
+{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
+
+### Генерація TypeScript-клієнта з тегами { #generate-a-typescript-client-with-tags }
+
+Якщо ви генеруєте клієнт для застосунку FastAPI з використанням тегів, зазвичай клієнтський код також буде розділено відповідно до тегів.
+
+Так ви зможете мати впорядковане й коректно згруповане клієнтське API:
+
+
+
+У цьому випадку у вас є:
+
+* `ItemsService`
+* `UsersService`
+
+### Назви методів клієнта { #client-method-names }
+
+Зараз згенеровані назви методів на кшталт `createItemItemsPost` виглядають не дуже охайно:
+
+```TypeScript
+ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
+```
+
+...це тому, що генератор клієнта використовує внутрішній **operation ID** OpenAPI для кожної *операції шляху*.
+
+OpenAPI вимагає, щоб кожен operation ID був унікальним серед усіх *операцій шляху*, тож FastAPI використовує **ім’я функції**, **шлях** і **HTTP метод/операцію**, щоб згенерувати цей operation ID — так він може гарантувати унікальність.
+
+Але далі я покажу, як це покращити.
+
+## Власні Operation ID і кращі назви методів { #custom-operation-ids-and-better-method-names }
+
+Ви можете **змінити** спосіб **генерації** цих operation ID, щоб зробити їх простішими та отримати **простішi назви методів** у клієнтах.
+
+У такому разі вам потрібно забезпечити, щоб кожен operation ID був **унікальним** іншим способом.
+
+Наприклад, ви можете гарантувати, що кожна *операція шляху* має тег, а потім генерувати operation ID на основі **тега** та **назви** *операції шляху* (імені функції).
+
+### Власна функція генерації унікального ID { #custom-generate-unique-id-function }
+
+FastAPI використовує **унікальний ID** для кожної *операції шляху*, який застосовується для **operation ID**, а також для назв потрібних кастомних моделей для запитів або відповідей.
+
+Ви можете налаштувати цю функцію. Вона приймає `APIRoute` і повертає рядок.
+
+Наприклад, тут вона використовує перший тег (у вас, імовірно, буде лише один тег) і назву *операції шляху* (ім’я функції).
+
+Потім ви можете передати цю функцію в **FastAPI** як параметр `generate_unique_id_function`:
+
+{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
+
+### Генерація TypeScript-клієнта з власними Operation ID { #generate-a-typescript-client-with-custom-operation-ids }
+
+Тепер, якщо згенерувати клієнт знову, ви побачите, що він має покращені назви методів:
+
+
+
+Як бачите, назви методів тепер містять тег, а далі — ім’я функції; вони більше не включають інформацію з URL-шляху та HTTP-операції.
+
+### Попередня обробка OpenAPI специфікації для генератора клієнта { #preprocess-the-openapi-specification-for-the-client-generator }
+
+Згенерований код усе ще містить деяку **дубльовану інформацію**.
+
+Ми вже знаємо, що цей метод пов’язаний з **items**, бо це слово є в `ItemsService` (взято з тега), але в назві методу все ще є префікс із назвою тега.
+
+Ймовірно, для OpenAPI загалом ми все одно захочемо це зберегти, адже це забезпечить **унікальність** operation ID.
+
+Але для згенерованого клієнта ми можемо **змінити** operation ID в OpenAPI прямо перед генерацією клієнтів — лише щоб зробити назви методів гарнішими та **чистішими**.
+
+Можна завантажити OpenAPI JSON у файл `openapi.json`, а потім **прибрати цей префікс тега** скриптом на кшталт такого:
+
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
+
+//// tab | Node.js
+
+```Javascript
+{!> ../../docs_src/generate_clients/tutorial004.js!}
+```
+
+////
+
+Після цього operation ID буде перейменовано з варіантів на кшталт `items-get_items` просто на `get_items`, і генератор клієнта зможе створювати простіші назви методів.
+
+### Генерація TypeScript-клієнта з попередньо обробленим OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi }
+
+Оскільки кінцевий результат тепер у файлі `openapi.json`, вам потрібно оновити шлях до вхідних даних:
+
+```sh
+npx @hey-api/openapi-ts -i ./openapi.json -o src/client
+```
+
+Після генерації нового клієнта ви матимете **чисті назви методів** з усім **автодоповненням**, **inline-помилками** тощо:
+
+
+
+## Переваги { #benefits }
+
+Використовуючи автоматично згенеровані клієнти, ви отримуєте **автодоповнення** для:
+
+* Методів.
+* Payload запиту в тілі, query-параметрів тощо.
+* Payload відповіді.
+
+Також ви матимете **inline-помилки** для всього.
+
+І щоразу, коли ви оновлюєте код бекенду та **перегенеровуєте** фронтенд, нові *операції шляху* будуть доступні як методи, старі — видалені, а будь-які інші зміни відобразяться в згенерованому коді.
+
+Це також означає, що якщо щось змінилося, це автоматично **відобразиться** в клієнтському коді. А якщо ви **збираєте** (build) клієнт, збірка завершиться помилкою, якщо є будь-яка **невідповідність** у використовуваних даних.
+
+Отже, ви зможете **виявляти багато помилок** дуже рано в циклі розробки, замість того щоб чекати, поки помилки проявляться у ваших кінцевих користувачів у production, а потім намагатися відлагодити, де саме проблема.
diff --git a/docs/uk/docs/advanced/index.md b/docs/uk/docs/advanced/index.md
new file mode 100644
index 0000000000..6dc7f8795e
--- /dev/null
+++ b/docs/uk/docs/advanced/index.md
@@ -0,0 +1,21 @@
+# Розширений посібник користувача { #advanced-user-guide }
+
+## Додаткові можливості { #additional-features }
+
+Основного [Підручника — Посібника користувача](../tutorial/index.md){.internal-link target=_blank} має бути достатньо, щоб ознайомити вас з усіма основними можливостями **FastAPI**.
+
+У наступних розділах ви побачите інші варіанти, конфігурації та додаткові можливості.
+
+/// tip | Порада
+
+Наступні розділи **не обов’язково є «розширеними»**.
+
+І цілком можливо, що для вашого випадку використання рішення міститься в одному з них.
+
+///
+
+## Спочатку прочитайте підручник { #read-the-tutorial-first }
+
+Ви все одно можете використовувати більшість можливостей **FastAPI**, маючи знання з основного [Підручника — Посібника користувача](../tutorial/index.md){.internal-link target=_blank}.
+
+А наступні розділи припускають, що ви вже прочитали його та знаєте ці основні ідеї.
diff --git a/docs/uk/docs/advanced/middleware.md b/docs/uk/docs/advanced/middleware.md
new file mode 100644
index 0000000000..df07ceb7d4
--- /dev/null
+++ b/docs/uk/docs/advanced/middleware.md
@@ -0,0 +1,97 @@
+# Розширені middleware { #advanced-middleware }
+
+У головному посібнику ви прочитали, як додати [власний Middleware](../tutorial/middleware.md){.internal-link target=_blank} до вашого застосунку.
+
+Також ви прочитали, як обробляти [CORS за допомогою `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
+
+У цьому розділі ми розглянемо, як використовувати інші middleware.
+
+## Додавання ASGI middleware { #adding-asgi-middlewares }
+
+Оскільки **FastAPI** базується на Starlette і реалізує специфікацію ASGI, ви можете використовувати будь-який ASGI middleware.
+
+Middleware не обов’язково має бути зроблений спеціально для FastAPI або Starlette, головне — щоб він відповідав специфікації ASGI.
+
+Загалом, ASGI middleware — це класи, які очікують отримати ASGI застосунок як перший аргумент.
+
+Тож у документації сторонніх ASGI middleware вам, імовірно, скажуть зробити щось на кшталт:
+
+```Python
+from unicorn import UnicornMiddleware
+
+app = SomeASGIApp()
+
+new_app = UnicornMiddleware(app, some_config="rainbow")
+```
+
+Але FastAPI (фактично Starlette) надає простіший спосіб, який гарантує, що внутрішні middleware коректно обробляють помилки сервера, а користувацькі обробники винятків працюють правильно.
+
+Для цього використовуйте `app.add_middleware()` (як у прикладі для CORS).
+
+```Python
+from fastapi import FastAPI
+from unicorn import UnicornMiddleware
+
+app = FastAPI()
+
+app.add_middleware(UnicornMiddleware, some_config="rainbow")
+```
+
+`app.add_middleware()` отримує клас middleware як перший аргумент і будь-які додаткові аргументи, які буде передано middleware.
+
+## Інтегровані middleware { #integrated-middlewares }
+
+**FastAPI** містить кілька middleware для поширених випадків використання; далі розглянемо, як ними користуватися.
+
+/// note | Технічні деталі
+
+Для наступних прикладів ви також можете використати `from starlette.middleware.something import SomethingMiddleware`.
+
+**FastAPI** надає кілька middleware у `fastapi.middleware` лише для зручності для вас, розробника. Але більшість доступних middleware походять безпосередньо зі Starlette.
+
+///
+
+## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
+
+Гарантує, що всі вхідні запити мають бути або `https`, або `wss`.
+
+Будь-який вхідний запит до `http` або `ws` буде перенаправлено на безпечну схему.
+
+{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
+
+## `TrustedHostMiddleware` { #trustedhostmiddleware }
+
+Гарантує, що всі вхідні запити мають коректно встановлений заголовок `Host`, щоб захиститися від атак на HTTP Host Header.
+
+{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
+
+Підтримуються такі аргументи:
+
+* `allowed_hosts` — список доменних імен, які слід дозволити як імена хостів. Підтримуються домени з wildcard, як-от `*.example.com`, для зіставлення піддоменів. Щоб дозволити будь-яке ім’я хоста, використайте `allowed_hosts=["*"]` або не додавайте цей middleware.
+* `www_redirect` — якщо встановлено в True, запити до версій дозволених хостів без `www` буде перенаправлено на відповідні версії з `www`. За замовчуванням `True`.
+
+Якщо вхідний запит не проходить перевірку, буде надіслано відповідь `400`.
+
+## `GZipMiddleware` { #gzipmiddleware }
+
+Обробляє GZip-відповіді для будь-якого запиту, що містить `"gzip"` у заголовку `Accept-Encoding`.
+
+Middleware оброблятиме як стандартні, так і потокові відповіді.
+
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
+
+Підтримуються такі аргументи:
+
+* `minimum_size` — не застосовувати GZip до відповідей, менших за цей мінімальний розмір у байтах. За замовчуванням `500`.
+* `compresslevel` — використовується під час стиснення GZip. Це ціле число в діапазоні від 1 до 9. За замовчуванням `9`. Менше значення дає швидше стиснення, але більший розмір файлів, тоді як більше значення — повільніше стиснення, але менший розмір файлів.
+
+## Інші middleware { #other-middlewares }
+
+Існує багато інших ASGI middleware.
+
+Наприклад:
+
+* `ProxyHeadersMiddleware` в Uvicorn
+* MessagePack
+
+Щоб переглянути інші доступні middleware, ознайомтеся з документацією Starlette щодо Middleware та ASGI Awesome List.
diff --git a/docs/uk/docs/advanced/openapi-callbacks.md b/docs/uk/docs/advanced/openapi-callbacks.md
new file mode 100644
index 0000000000..88473ca34b
--- /dev/null
+++ b/docs/uk/docs/advanced/openapi-callbacks.md
@@ -0,0 +1,186 @@
+# OpenAPI callbacks { #openapi-callbacks }
+
+Ви можете створити API з *операцією шляху*, яка може запускати запит до *зовнішнього API*, створеного кимось іншим (ймовірно, тим самим розробником, який буде *використовувати* ваше API).
+
+Процес, що відбувається, коли ваш застосунок API викликає *зовнішнє API*, називається «callback». Тому що програмне забезпечення, яке написав зовнішній розробник, надсилає запит до вашого API, а потім ваше API «викликає у відповідь», надсилаючи запит до *зовнішнього API* (яке, ймовірно, створив той самий розробник).
+
+У цьому випадку вам може знадобитися задокументувати, як *має* виглядати це зовнішнє API. Яку *операцію шляху* воно повинно мати, яке тіло має очікувати, яку відповідь має повертати тощо.
+
+## Застосунок із callbacks { #an-app-with-callbacks }
+
+Розгляньмо це на прикладі.
+
+Уявіть, що ви розробляєте застосунок, який дає змогу створювати рахунки.
+
+Ці рахунки матимуть `id`, `title` (необов’язково), `customer` і `total`.
+
+Користувач вашого API (зовнішній розробник) створить рахунок у вашому API за допомогою POST-запиту.
+
+Потім ваше API (уявімо) буде:
+
+* Надсилати рахунок якомусь клієнту зовнішнього розробника.
+* Отримувати оплату.
+* Надсилати сповіщення назад користувачу API (зовнішньому розробнику).
+ * Це буде зроблено шляхом надсилання POST-запиту (від *вашого API*) до певного *зовнішнього API*, наданого цим зовнішнім розробником (це і є «callback»).
+
+## Звичайний застосунок **FastAPI** { #the-normal-fastapi-app }
+
+Спочатку подивімося, як виглядатиме звичайний застосунок API до додавання callback.
+
+Він матиме *операцію шляху*, яка отримуватиме тіло `Invoice`, і query-параметр `callback_url`, що міститиме URL для callback.
+
+Ця частина доволі стандартна, більшість коду вам, ймовірно, уже знайома:
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
+
+/// tip | Порада
+
+Query-параметр `callback_url` використовує тип Pydantic Url.
+
+///
+
+Єдине нове тут — це `callbacks=invoices_callback_router.routes` як аргумент для *декоратора операції шляху*. Далі подивимося, що це таке.
+
+## Документування callback { #documenting-the-callback }
+
+Фактичний код callback сильно залежатиме від вашого застосунку API.
+
+І, ймовірно, значно відрізнятиметься від застосунку до застосунку.
+
+Це може бути лише один або два рядки коду, наприклад:
+
+```Python
+callback_url = "https://example.com/api/v1/invoices/events/"
+httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
+```
+
+Але, можливо, найважливіша частина callback — переконатися, що користувач вашого API (зовнішній розробник) реалізує *зовнішнє API* правильно, відповідно до даних, які *ваше API* надсилатиме в тілі запиту callback тощо.
+
+Тож далі ми додамо код, щоб задокументувати, як має виглядати це *зовнішнє API*, аби приймати callback від *вашого API*.
+
+Ця документація з’явиться в Swagger UI за адресою `/docs` у вашому API і дасть змогу зовнішнім розробникам зрозуміти, як побудувати *зовнішнє API*.
+
+Цей приклад не реалізує сам callback (це може бути просто один рядок коду), лише частину документації.
+
+/// tip | Порада
+
+Фактичний callback — це просто HTTP-запит.
+
+Під час реалізації callback ви можете використати щось на кшталт HTTPX або Requests.
+
+///
+
+## Напишіть код документації для callback { #write-the-callback-documentation-code }
+
+Цей код не виконуватиметься у вашому застосунку, він потрібен лише для *документування* того, як має виглядати *зовнішнє API*.
+
+Але ви вже знаєте, як легко створювати автоматичну документацію для API з **FastAPI**.
+
+Тож ми використаємо ті самі знання, щоб задокументувати, як має виглядати *зовнішнє API*… створивши *операцію(ї) шляху*, які зовнішнє API повинно реалізувати (ті, які викликатиме ваше API).
+
+/// tip | Порада
+
+Під час написання коду для документування callback може бути корисно уявити, що ви — той *зовнішній розробник*. І що зараз ви реалізуєте *зовнішнє API*, а не *ваше API*.
+
+Тимчасово прийнявши цю точку зору (з позиції *зовнішнього розробника*), вам може бути очевидніше, куди розміщувати параметри, Pydantic-модель для тіла, для відповіді тощо для цього *зовнішнього API*.
+
+///
+
+### Створіть callback `APIRouter` { #create-a-callback-apirouter }
+
+Спочатку створіть новий `APIRouter`, який міститиме один або більше callbacks.
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
+
+### Створіть callback *операцію шляху* { #create-the-callback-path-operation }
+
+Щоб створити callback *операцію шляху*, використайте той самий `APIRouter`, який ви створили вище.
+
+Вона має виглядати як звичайна *операція шляху* FastAPI:
+
+* Ймовірно, вона має оголошувати тіло, яке повинна отримувати, наприклад `body: InvoiceEvent`.
+* Також вона може оголошувати відповідь, яку повинна повертати, наприклад `response_model=InvoiceEventReceived`.
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
+
+Є 2 основні відмінності від звичайної *операції шляху*:
+
+* Їй не потрібен жоден фактичний код, бо ваш застосунок ніколи не викликатиме цей код. Його використовують лише для документування *зовнішнього API*. Тому функція може просто містити `pass`.
+* *Шлях* може містити вираз OpenAPI 3 (див. більше нижче), де можна використовувати змінні з параметрами та частинами початкового запиту, надісланого до *вашого API*.
+
+### Вираз шляху для callback { #the-callback-path-expression }
+
+Callback-*шлях* може містити вираз OpenAPI 3, який може включати частини початкового запиту, надісланого до *вашого API*.
+
+У цьому випадку це `str`:
+
+```Python
+"{$callback_url}/invoices/{$request.body.id}"
+```
+
+Отже, якщо користувач вашого API (зовнішній розробник) надсилає запит до *вашого API* на:
+
+```
+https://yourapi.com/invoices/?callback_url=https://www.external.org/events
+```
+
+з JSON-тілом:
+
+```JSON
+{
+ "id": "2expen51ve",
+ "customer": "Mr. Richie Rich",
+ "total": "9999"
+}
+```
+
+тоді *ваше API* обробить рахунок і в якийсь момент пізніше надішле callback-запит на `callback_url` (до *зовнішнього API*):
+
+```
+https://www.external.org/events/invoices/2expen51ve
+```
+
+з JSON-тілом, яке міститиме щось на кшталт:
+
+```JSON
+{
+ "description": "Payment celebration",
+ "paid": true
+}
+```
+
+і воно очікуватиме відповідь від цього *зовнішнього API* з JSON-тілом на кшталт:
+
+```JSON
+{
+ "ok": true
+}
+```
+
+/// tip | Порада
+
+Зверніть увагу: використаний URL для callback містить URL, отриманий як query-параметр у `callback_url` (`https://www.external.org/events`), а також `id` рахунку зсередини JSON-тіла (`2expen51ve`).
+
+///
+
+### Додайте callback router { #add-the-callback-router }
+
+На цьому етапі у вас є потрібні *callback-операції шляху* (ті, які *зовнішній розробник* має реалізувати в *зовнішньому API*) у callback router, який ви створили вище.
+
+Тепер використайте параметр `callbacks` у *декораторі операції шляху вашого API*, щоб передати атрибут `.routes` (це фактично просто `list` маршрутів/*операцій шляху*) з цього callback router:
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
+
+/// tip | Порада
+
+Зверніть увагу, що ви передаєте не сам router (`invoices_callback_router`) у `callback=`, а атрибут `.routes`, тобто `invoices_callback_router.routes`.
+
+///
+
+### Перевірте документацію { #check-the-docs }
+
+Тепер ви можете запустити застосунок і перейти за адресою http://127.0.0.1:8000/docs.
+
+Ви побачите вашу документацію, зокрема розділ «Callbacks» для вашої *операції шляху*, який показує, як має виглядати *зовнішнє API*:
+
+
diff --git a/docs/uk/docs/advanced/openapi-webhooks.md b/docs/uk/docs/advanced/openapi-webhooks.md
new file mode 100644
index 0000000000..8bcd53d57a
--- /dev/null
+++ b/docs/uk/docs/advanced/openapi-webhooks.md
@@ -0,0 +1,55 @@
+# OpenAPI вебхуки { #openapi-webhooks }
+
+Бувають випадки, коли ви хочете повідомити **користувачам** вашого API, що ваш застосунок може викликати *їхній* застосунок (надсилаючи запит) з певними даними, зазвичай щоб **сповістити** про певний **івент**.
+
+Це означає, що замість звичного процесу, коли користувачі надсилають запити до вашого API, **ваше API** (або ваш застосунок) може **надсилати запити до їхньої системи** (до їхнього API, їхнього застосунку).
+
+Зазвичай це називають **webhook**.
+
+## Кроки роботи вебхуків { #webhooks-steps }
+
+Зазвичай процес такий: **ви визначаєте** у своєму коді, яке саме повідомлення ви надсилатимете — **тіло запиту**.
+
+Також ви певним чином визначаєте, у які **моменти** ваш застосунок надсилатиме ці запити або івенти.
+
+А **ваші користувачі** певним чином (наприклад, у вебпанелі керування десь) визначають **URL**, куди ваш застосунок має надсилати ці запити.
+
+Уся **логіка** щодо реєстрації URL для вебхуків і код, який фактично надсилає ці запити, залишається на ваш розсуд. Ви пишете це так, як хочете, у **власному коді**.
+
+## Документування вебхуків за допомогою **FastAPI** та OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
+
+У **FastAPI**, використовуючи OpenAPI, ви можете визначати назви цих вебхуків, типи HTTP-операцій, які ваш застосунок може надсилати (наприклад, `POST`, `PUT` тощо), і **тіла** запитів, які ваш застосунок надсилатиме.
+
+Це може значно спростити для ваших користувачів **реалізацію їхніх API** для отримання ваших запитів **webhook** — вони навіть можуть згенерувати частину власного коду API автоматично.
+
+/// info | Інформація
+
+Webhooks доступні в OpenAPI 3.1.0 і вище, підтримуються FastAPI `0.99.0` і вище.
+
+///
+
+## Застосунок із вебхуками { #an-app-with-webhooks }
+
+Коли ви створюєте застосунок **FastAPI**, є атрибут `webhooks`, який можна використовувати для визначення *webhooks* так само, як ви визначаєте *операції шляху*, наприклад за допомогою `@app.webhooks.post()`.
+
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
+
+Визначені вами webhooks потраплять до схеми **OpenAPI** та автоматичного **інтерфейсу документації**.
+
+/// info | Інформація
+
+Об’єкт `app.webhooks` насправді є просто `APIRouter`, тим самим типом, який ви використовуєте під час структурування застосунку на кілька файлів.
+
+///
+
+Зверніть увагу, що з webhooks ви фактично не оголошуєте *path* (як-от `/items/`) — текст, який ви передаєте, є лише **ідентифікатором** вебхука (назвою івенту). Наприклад, у `@app.webhooks.post("new-subscription")` назва вебхука — `new-subscription`.
+
+Це тому, що очікується, що **ваші користувачі** визначать фактичний **шлях URL**, за яким вони хочуть отримувати запит webhook, якимось іншим способом (наприклад, у вебпанелі керування).
+
+### Перевірте документацію { #check-the-docs }
+
+Тепер ви можете запустити застосунок і перейти на http://127.0.0.1:8000/docs.
+
+Ви побачите, що у документації є звичайні *операції шляху*, а також деякі **webhooks**:
+
+
diff --git a/docs/uk/docs/advanced/path-operation-advanced-configuration.md b/docs/uk/docs/advanced/path-operation-advanced-configuration.md
new file mode 100644
index 0000000000..ee2768dafb
--- /dev/null
+++ b/docs/uk/docs/advanced/path-operation-advanced-configuration.md
@@ -0,0 +1,172 @@
+# Розширена конфігурація операцій шляху { #path-operation-advanced-configuration }
+
+## OpenAPI operationId { #openapi-operationid }
+
+/// warning | Попередження
+
+Якщо ви не є «експертом» з OpenAPI, імовірно, вам це не потрібно.
+
+///
+
+Ви можете встановити OpenAPI `operationId`, який буде використано у вашій *операції шляху*, за допомогою параметра `operation_id`.
+
+Потрібно переконатися, що він унікальний для кожної операції.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
+
+### Використання назви *функції операції шляху* як operationId { #using-the-path-operation-function-name-as-the-operationid }
+
+Якщо ви хочете використовувати назви функцій вашого API як `operationId`, ви можете пройтися по всіх них і перевизначити `operation_id` кожної *операції шляху*, використовуючи `APIRoute.name`.
+
+Це слід робити після додавання всіх ваших *операцій шляху*.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
+
+/// tip | Порада
+
+Якщо ви викликаєте `app.openapi()` вручну, вам слід оновити `operationId` до цього.
+
+///
+
+/// warning | Попередження
+
+Якщо ви робите це, потрібно переконатися, що кожна з ваших *функцій операції шляху* має унікальне ім’я.
+
+Навіть якщо вони розташовані в різних модулях (файлах Python).
+
+///
+
+## Виключення з OpenAPI { #exclude-from-openapi }
+
+Щоб виключити *операцію шляху* зі згенерованої схеми OpenAPI (а отже, і з автоматичних систем документації), використайте параметр `include_in_schema` і встановіть його в `False`:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
+
+## Розширений опис із docstring { #advanced-description-from-docstring }
+
+Ви можете обмежити кількість рядків docstring *функції операції шляху*, які використовуються для OpenAPI.
+
+Додавання `\f` (екранованого символу «form feed») змушує **FastAPI** обрізати вивід, що використовується для OpenAPI, у цьому місці.
+
+Це не відображатиметься в документації, але інші інструменти (наприклад, Sphinx) зможуть використати решту.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
+
+## Додаткові відповіді { #additional-responses }
+
+Ви, ймовірно, бачили, як оголошувати `response_model` і `status_code` для *операції шляху*.
+
+Це визначає метадані про основну відповідь *операції шляху*.
+
+Ви також можете оголосити додаткові відповіді з їхніми моделями, кодами стану тощо.
+
+У документації є цілий розділ про це, прочитайте його тут: [Додаткові відповіді в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+
+## OpenAPI Extra { #openapi-extra }
+
+Коли ви оголошуєте *операцію шляху* у вашому застосунку, **FastAPI** автоматично генерує відповідні метадані про цю *операцію шляху* для включення в схему OpenAPI.
+
+/// note | Технічні деталі
+
+У специфікації OpenAPI це називається Operation Object.
+
+///
+
+Він містить усю інформацію про *операцію шляху* та використовується для генерації автоматичної документації.
+
+Він включає `tags`, `parameters`, `requestBody`, `responses` тощо.
+
+Ця частина схеми OpenAPI, специфічна для *операції шляху*, зазвичай генерується **FastAPI** автоматично, але ви також можете її розширити.
+
+/// tip | Порада
+
+Це низькорівнева точка розширення.
+
+Якщо вам потрібно лише оголосити додаткові відповіді, зручніший спосіб — через [Додаткові відповіді в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+
+///
+
+Ви можете розширити схему OpenAPI для *операції шляху* за допомогою параметра `openapi_extra`.
+
+### Розширення OpenAPI { #openapi-extensions }
+
+Цей `openapi_extra` може бути корисним, наприклад, щоб оголосити [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
+
+Якщо ви відкриєте автоматичну документацію API, ваше розширення з’явиться внизу конкретної *операції шляху*.
+
+
+
+А якщо ви подивитеся на результуючий OpenAPI (за адресою `/openapi.json` у вашому API), ви також побачите ваше розширення як частину конкретної *операції шляху*:
+
+```JSON hl_lines="22"
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ }
+ },
+ "x-aperture-labs-portal": "blue"
+ }
+ }
+ }
+}
+```
+
+### Власна OpenAPI-схема для *операції шляху* { #custom-openapi-path-operation-schema }
+
+Словник у `openapi_extra` буде глибоко об’єднано з автоматично згенерованою схемою OpenAPI для *операції шляху*.
+
+Тож ви можете додати додаткові дані до автоматично згенерованої схеми.
+
+Наприклад, ви можете вирішити читати й перевіряти запит власним кодом, не використовуючи автоматичні можливості FastAPI з Pydantic, але все одно хотіти визначити запит у схемі OpenAPI.
+
+Це можна зробити за допомогою `openapi_extra`:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
+
+У цьому прикладі ми не оголошували жодної моделі Pydantic. Фактично тіло запиту навіть не parsed як JSON — його читають безпосередньо як `bytes`, а функція `magic_data_reader()` відповідала б за його розбір певним способом.
+
+Попри це, ми можемо оголосити очікувану схему для тіла запиту.
+
+### Власний тип вмісту OpenAPI { #custom-openapi-content-type }
+
+Використовуючи цей самий підхід, ви можете застосувати модель Pydantic, щоб визначити JSON Schema, яку потім буде включено до власної секції схеми OpenAPI для *операції шляху*.
+
+І ви можете зробити це навіть тоді, коли тип даних у запиті — не JSON.
+
+Наприклад, у цьому застосунку ми не використовуємо інтегровану функціональність FastAPI для витягування JSON Schema з моделей Pydantic, а також автоматичну валідацію для JSON. Насправді ми оголошуємо тип вмісту запиту як YAML, а не JSON:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
+
+Попри це, хоча ми не використовуємо стандартну інтегровану функціональність, ми все одно використовуємо модель Pydantic, щоб вручну згенерувати JSON Schema для даних, які ми хочемо отримати в YAML.
+
+Далі ми використовуємо запит безпосередньо й витягаємо тіло як `bytes`. Це означає, що FastAPI навіть не намагатиметься розбирати корисне навантаження запиту як JSON.
+
+А потім у нашому коді ми напряму розбираємо цей YAML-вміст і знову використовуємо ту саму модель Pydantic, щоб валідувати YAML-вміст:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
+
+/// tip | Порада
+
+Тут ми повторно використовуємо ту саму модель Pydantic.
+
+Але так само ми могли б валідувати це іншим способом.
+
+///
diff --git a/docs/uk/docs/advanced/response-change-status-code.md b/docs/uk/docs/advanced/response-change-status-code.md
new file mode 100644
index 0000000000..efbf9449f2
--- /dev/null
+++ b/docs/uk/docs/advanced/response-change-status-code.md
@@ -0,0 +1,31 @@
+# Відповідь — змінення коду статусу { #response-change-status-code }
+
+Ймовірно, ви вже читали, що можна встановити типовий [Код статусу відповіді](../tutorial/response-status-code.md){.internal-link target=_blank}.
+
+Але в деяких випадках потрібно повернути інший код статусу, ніж типовий.
+
+## Випадок використання { #use-case }
+
+Наприклад, уявіть, що ви хочете типово повертати HTTP-код статусу «OK» `200`.
+
+Але якщо дані не існували, ви хочете створити їх і повернути HTTP-код статусу «CREATED» `201`.
+
+Водночас ви все одно хочете мати змогу фільтрувати та перетворювати дані, які повертаєте, за допомогою `response_model`.
+
+Для таких випадків можна використати параметр `Response`.
+
+## Використайте параметр `Response` { #use-a-response-parameter }
+
+Ви можете оголосити параметр типу `Response` у вашій *функції операції шляху* (так само, як це можна зробити для cookies і headers).
+
+Після цього ви можете встановити `status_code` у цьому *тимчасовому* об’єкті відповіді.
+
+{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
+
+Потім ви можете повернути будь-який потрібний об’єкт, як зазвичай (наприклад, `dict`, модель бази даних тощо).
+
+І якщо ви оголосили `response_model`, його й надалі буде використано для фільтрації та перетворення об’єкта, який ви повернули.
+
+**FastAPI** використає цю *тимчасову* відповідь, щоб отримати код статусу (а також cookies і headers), і додасть їх до фінальної відповіді, що містить значення, яке ви повернули, відфільтроване через будь-який `response_model`.
+
+Також можна оголосити параметр `Response` у залежностях і встановлювати в них код статусу. Але майте на увазі: спрацює останнє встановлене значення.
diff --git a/docs/uk/docs/advanced/response-cookies.md b/docs/uk/docs/advanced/response-cookies.md
new file mode 100644
index 0000000000..474a74200f
--- /dev/null
+++ b/docs/uk/docs/advanced/response-cookies.md
@@ -0,0 +1,51 @@
+# Cookies у відповіді { #response-cookies }
+
+## Використовуйте параметр `Response` { #use-a-response-parameter }
+
+Ви можете оголосити параметр типу `Response` у вашій *функції операції шляху*.
+
+Після цього ви можете встановлювати cookies в цьому *тимчасовому* об’єкті відповіді.
+
+{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
+
+Далі ви можете повертати будь-який потрібний об’єкт, як зазвичай (наприклад, `dict`, модель бази даних тощо).
+
+І якщо ви оголосили `response_model`, він усе одно використовуватиметься для фільтрації та перетворення об’єкта, який ви повернули.
+
+**FastAPI** використає цю *тимчасову* відповідь, щоб витягнути cookies (а також заголовки та код статусу), і додасть їх до фінальної відповіді, що містить значення, яке ви повернули, відфільтроване згідно з будь-яким `response_model`.
+
+Також ви можете оголосити параметр `Response` у залежностях і встановлювати в них cookies (і заголовки).
+
+## Повертайте `Response` напряму { #return-a-response-directly }
+
+Ви також можете створювати cookies, повертаючи `Response` напряму у вашому коді.
+
+Для цього створіть відповідь, як описано в [Повертайте Response напряму](response-directly.md){.internal-link target=_blank}.
+
+Потім встановіть у ній Cookies і поверніть її:
+
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
+
+/// tip | Порада
+
+Пам’ятайте: якщо ви повертаєте відповідь напряму замість використання параметра `Response`, FastAPI поверне її безпосередньо.
+
+Тож вам потрібно переконатися, що ваші дані мають правильний тип. Наприклад, вони сумісні з JSON, якщо ви повертаєте `JSONResponse`.
+
+Також переконайтеся, що ви не надсилаєте дані, які мали бути відфільтровані через `response_model`.
+
+///
+
+### Докладніше { #more-info }
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.responses import Response` або `from starlette.responses import JSONResponse`.
+
+**FastAPI** надає ті самі `starlette.responses` як `fastapi.responses` просто для зручності для вас, розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette.
+
+І оскільки `Response` часто використовують для встановлення заголовків і cookies, **FastAPI** також надає його як `fastapi.Response`.
+
+///
+
+Щоб переглянути всі доступні параметри й опції, ознайомтеся з документацією Starlette.
diff --git a/docs/uk/docs/advanced/response-directly.md b/docs/uk/docs/advanced/response-directly.md
new file mode 100644
index 0000000000..25ae65356c
--- /dev/null
+++ b/docs/uk/docs/advanced/response-directly.md
@@ -0,0 +1,65 @@
+# Повертайте відповідь напряму { #return-a-response-directly }
+
+Коли ви створюєте **FastAPI** *операцію шляху*, зазвичай ви можете повертати з неї будь-які дані: `dict`, `list`, модель Pydantic, модель бази даних тощо.
+
+За замовчуванням **FastAPI** автоматично перетворює це значення, що повертається, на JSON за допомогою `jsonable_encoder`, описаного в розділі [JSON-сумісний енкодер](../tutorial/encoder.md){.internal-link target=_blank}.
+
+Потім «за лаштунками» він помістить ці JSON-сумісні дані (наприклад, `dict`) всередину `JSONResponse`, який буде використано для надсилання відповіді клієнту.
+
+Але ви можете повертати `JSONResponse` безпосередньо з ваших *операцій шляху*.
+
+Це може бути корисно, наприклад, щоб повертати власні заголовки або cookies.
+
+## Повернення `Response` { #return-a-response }
+
+Насправді ви можете повернути будь-який `Response` або будь-який його підклас.
+
+/// tip | Порада
+
+`JSONResponse` сам по собі є підкласом `Response`.
+
+///
+
+І коли ви повертаєте `Response`, **FastAPI** передасть його напряму.
+
+Він не виконуватиме жодних перетворень даних за допомогою моделей Pydantic, не конвертуватиме вміст у будь-які типи тощо.
+
+Це дає вам багато гнучкості. Ви можете повертати будь-який тип даних, перевизначати будь-які декларації даних або валідацію тощо.
+
+## Використання `jsonable_encoder` у `Response` { #using-the-jsonable-encoder-in-a-response }
+
+Оскільки **FastAPI** не вносить жодних змін у `Response`, який ви повертаєте, вам потрібно переконатися, що його вміст уже готовий.
+
+Наприклад, ви не можете покласти модель Pydantic у `JSONResponse`, не перетворивши її спочатку на `dict` із конвертацією всіх типів даних (як-от `datetime`, `UUID` тощо) у JSON-сумісні типи.
+
+Для таких випадків ви можете використати `jsonable_encoder`, щоб перетворити ваші дані перед передаванням їх у відповідь:
+
+{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette.responses import JSONResponse`.
+
+**FastAPI** надає ті самі `starlette.responses` як `fastapi.responses` лише для зручності для вас, розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette.
+
+///
+
+## Повернення власного `Response` { #returning-a-custom-response }
+
+Приклад вище показує всі потрібні частини, але він поки що не дуже корисний, адже ви могли б просто повернути `item` напряму, і **FastAPI** помістив би його в `JSONResponse` для вас, перетворивши його на `dict` тощо. Усе це — за замовчуванням.
+
+Тепер подивімося, як ви могли б використати це, щоб повернути власну відповідь.
+
+Скажімо, ви хочете повернути відповідь у форматі XML.
+
+Ви можете помістити ваш XML-вміст у рядок, покласти його в `Response` і повернути:
+
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+
+## Примітки { #notes }
+
+Коли ви повертаєте `Response` напряму, його дані не валідовуються, не конвертуються (серіалізуються) і не документуються автоматично.
+
+Але ви все одно можете задокументувати це, як описано в [Додаткові відповіді в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+
+У наступних розділах ви побачите, як використовувати/оголошувати ці власні `Response`, зберігаючи при цьому автоматичну конвертацію даних, документацію тощо.
diff --git a/docs/uk/docs/advanced/response-headers.md b/docs/uk/docs/advanced/response-headers.md
new file mode 100644
index 0000000000..6740d77d60
--- /dev/null
+++ b/docs/uk/docs/advanced/response-headers.md
@@ -0,0 +1,41 @@
+# Заголовки відповіді { #response-headers }
+
+## Використовуйте параметр `Response` { #use-a-response-parameter }
+
+Ви можете оголосити параметр типу `Response` у вашій *функції операції шляху* (так само, як і для cookies).
+
+Після цього ви можете встановлювати заголовки в цьому *тимчасовому* об’єкті відповіді.
+
+{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
+
+Далі ви можете повертати будь-який потрібний об’єкт, як зазвичай (наприклад, `dict`, модель бази даних тощо).
+
+Якщо ви оголосили `response_model`, він усе одно буде використаний, щоб відфільтрувати та перетворити повернений об’єкт.
+
+**FastAPI** використає цю *тимчасову* відповідь, щоб витягти заголовки (а також cookies і код стану), і додасть їх до фінальної відповіді, що містить значення, яке ви повернули, відфільтроване через `response_model`.
+
+Також ви можете оголосити параметр `Response` у залежностях і встановлювати в них заголовки (та cookies).
+
+## Повертайте `Response` напряму { #return-a-response-directly }
+
+Ви також можете додавати заголовки, коли повертаєте `Response` безпосередньо.
+
+Створіть відповідь, як описано в [Повернути Response напряму](response-directly.md){.internal-link target=_blank}, і передайте заголовки як додатковий параметр:
+
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
+
+/// note | Технічні деталі
+
+Ви також можете використовувати `from starlette.responses import Response` або `from starlette.responses import JSONResponse`.
+
+**FastAPI** надає ті самі `starlette.responses` як `fastapi.responses` просто для зручності для вас, розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette.
+
+А оскільки `Response` часто використовується для встановлення заголовків і cookies, **FastAPI** також надає його як `fastapi.Response`.
+
+///
+
+## Користувацькі заголовки { #custom-headers }
+
+Пам’ятайте, що власні пропрієтарні заголовки можна додавати використовуючи префікс `X-`.
+
+Але якщо у вас є користувацькі заголовки, які ви хочете зробити видимими для клієнта в браузері, вам потрібно додати їх у налаштування CORS (докладніше в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), використовуючи параметр `expose_headers`, описаний у документації Starlette про CORS.
diff --git a/docs/uk/docs/advanced/security/http-basic-auth.md b/docs/uk/docs/advanced/security/http-basic-auth.md
new file mode 100644
index 0000000000..eb9500e465
--- /dev/null
+++ b/docs/uk/docs/advanced/security/http-basic-auth.md
@@ -0,0 +1,107 @@
+# HTTP Basic Auth { #http-basic-auth }
+
+Для найпростіших випадків ви можете використати HTTP Basic Auth.
+
+У HTTP Basic Auth застосунок очікує заголовок, що містить ім’я користувача та пароль.
+
+Якщо він його не отримує, то повертає помилку HTTP 401 «Unauthorized».
+
+Також повертає заголовок `WWW-Authenticate` зі значенням `Basic` і необов’язковим параметром `realm`.
+
+Це повідомляє браузеру показати вбудоване вікно запиту імені користувача та пароля.
+
+Далі, коли ви вводите це ім’я користувача та пароль, браузер автоматично надсилає їх у заголовку.
+
+## Простий HTTP Basic Auth { #simple-http-basic-auth }
+
+* Імпортуйте `HTTPBasic` і `HTTPBasicCredentials`.
+* Створіть «`security` scheme», використовуючи `HTTPBasic`.
+* Використайте цей `security` із залежністю у вашій *операції шляху*.
+* Він повертає об’єкт типу `HTTPBasicCredentials`:
+ * Він містить надіслані `username` і `password`.
+
+{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
+
+Коли ви намагаєтеся відкрити URL уперше (або натискаєте кнопку «Execute» в документації), браузер попросить вас ввести ім’я користувача та пароль:
+
+
+
+## Перевірка імені користувача { #check-the-username }
+
+Ось більш повний приклад.
+
+Використайте залежність, щоб перевірити, чи правильні ім’я користувача та пароль.
+
+Для цього використайте стандартний модуль Python `secrets`, щоб перевірити ім’я користувача та пароль.
+
+`secrets.compare_digest()` має отримувати `bytes` або `str`, що містить лише ASCII-символи (англійські), тобто він не працюватиме з такими символами, як `á`, наприклад у `Sebastián`.
+
+Щоб це обійти, спочатку перетворимо `username` і `password` на `bytes`, закодувавши їх у UTF-8.
+
+Після цього можна використати `secrets.compare_digest()`, щоб переконатися, що `credentials.username` дорівнює `"stanleyjobson"`, а `credentials.password` — `"swordfish"`.
+
+{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
+
+Це було б схоже на:
+
+```Python
+if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
+ # Return some error
+ ...
+```
+
+Але завдяки використанню `secrets.compare_digest()` це буде захищено від типу атак, що називаються «timing attacks».
+
+### Timing Attacks { #timing-attacks }
+
+Але що таке «timing attack»?
+
+Уявімо, що зловмисники намагаються вгадати ім’я користувача та пароль.
+
+І вони надсилають запит з іменем користувача `johndoe` і паролем `love123`.
+
+Тоді Python-код у вашому застосунку буде еквівалентний приблизно такому:
+
+```Python
+if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+Але в момент, коли Python порівнює першу літеру `j` у `johndoe` з першою літерою `s` у `stanleyjobson`, він одразу поверне `False`, бо вже знає, що ці два рядки не однакові, і вважає, що «немає потреби витрачати додаткові обчислення на порівняння решти літер». І ваш застосунок скаже: «Incorrect username or password».
+
+Потім зловмисники пробують ім’я користувача `stanleyjobsox` і пароль `love123`.
+
+І код вашого застосунку робить щось на кшталт:
+
+```Python
+if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+Python доведеться порівняти весь фрагмент `stanleyjobso` в `stanleyjobsox` і `stanleyjobson`, перш ніж зрозуміти, що рядки відрізняються. Тож відповідь «Incorrect username or password» займе на кілька мікросекунд більше.
+
+#### Час відповіді допомагає зловмисникам { #the-time-to-answer-helps-the-attackers }
+
+У цей момент, помітивши, що сервер витратив на кілька мікросекунд більше на надсилання відповіді «Incorrect username or password», зловмисники зрозуміють, що вони _в чомусь_ праві — деякі початкові літери збіглися.
+
+І тоді вони можуть повторити спробу, знаючи, що правильне значення, ймовірно, ближче до `stanleyjobsox`, ніж до `johndoe`.
+
+#### «Професійна» атака { #a-professional-attack }
+
+Звісно, зловмисники не робитимуть це вручну — вони напишуть програму, можливо, з тисячами або мільйонами перевірок за секунду. І щоразу отримуватимуть лише одну додаткову правильну літеру.
+
+Але так, за кілька хвилин або годин, зловмисники вгадають правильні ім’я користувача та пароль за «допомогою» нашого застосунку, використовуючи лише час, потрібний для відповіді.
+
+#### Виправлення за допомогою `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest }
+
+Але в нашому коді ми фактично використовуємо `secrets.compare_digest()`.
+
+Коротко кажучи, він витрачатиме однаковий час на порівняння `stanleyjobsox` із `stanleyjobson`, як і на порівняння `johndoe` із `stanleyjobson`. І так само для пароля.
+
+Таким чином, використовуючи `secrets.compare_digest()` у коді вашого застосунку, ви будете захищені від усього цього класу атак безпеки.
+
+### Повернення помилки { #return-the-error }
+
+Після виявлення, що облікові дані некоректні, поверніть `HTTPException` зі статус-кодом 401 (таким самим, як і коли облікові дані не надано) і додайте заголовок `WWW-Authenticate`, щоб браузер знову показав запит на вхід:
+
+{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
diff --git a/docs/uk/docs/advanced/security/index.md b/docs/uk/docs/advanced/security/index.md
new file mode 100644
index 0000000000..2cf2e37809
--- /dev/null
+++ b/docs/uk/docs/advanced/security/index.md
@@ -0,0 +1,19 @@
+# Розширена безпека { #advanced-security }
+
+## Додаткові можливості { #additional-features }
+
+Є кілька додаткових можливостей для обробки безпеки, окрім тих, що розглянуті в розділі [Підручник — Посібник користувача: Безпека](../../tutorial/security/index.md){.internal-link target=_blank}.
+
+/// tip | Порада
+
+Наступні розділи **не обов’язково є «розширеними»**.
+
+І можливо, для вашого випадку використання рішення є в одному з них.
+
+///
+
+## Спочатку прочитайте підручник { #read-the-tutorial-first }
+
+Наступні розділи припускають, що ви вже прочитали основний розділ [Підручник — Посібник користувача: Безпека](../../tutorial/security/index.md){.internal-link target=_blank}.
+
+Усі вони ґрунтуються на тих самих концепціях, але дають змогу використовувати додаткові можливості.
diff --git a/docs/uk/docs/advanced/security/oauth2-scopes.md b/docs/uk/docs/advanced/security/oauth2-scopes.md
new file mode 100644
index 0000000000..b61bb9824a
--- /dev/null
+++ b/docs/uk/docs/advanced/security/oauth2-scopes.md
@@ -0,0 +1,274 @@
+# Області OAuth2 { #oauth2-scopes }
+
+Ви можете використовувати області OAuth2 безпосередньо з **FastAPI** — вони інтегровані так, щоб працювати безшовно.
+
+Це дає змогу мати більш деталізовану систему дозволів, дотримуючись стандарту OAuth2, інтегровану у ваш застосунок OpenAPI (і документацію API).
+
+OAuth2 з областями — це механізм, який використовують багато великих провайдерів автентифікації, як-от Facebook, Google, GitHub, Microsoft, X (Twitter) тощо. Вони застосовують його, щоб надавати користувачам і застосункам конкретні дозволи.
+
+Щоразу, коли ви «входите через» Facebook, Google, GitHub, Microsoft, X (Twitter), цей застосунок використовує OAuth2 з областями.
+
+У цьому розділі ви побачите, як керувати автентифікацією та авторизацією за допомогою того самого OAuth2 з областями у вашому застосунку **FastAPI**.
+
+/// warning | Попередження
+
+Це більш-менш просунутий розділ. Якщо ви лише починаєте, можете його пропустити.
+
+Вам не обов’язково потрібні області OAuth2, і ви можете організувати автентифікацію та авторизацію так, як вам потрібно.
+
+Але OAuth2 з областями можна гарно інтегрувати у ваш API (з OpenAPI) і документацію API.
+
+Водночас ці області, або будь-які інші вимоги безпеки/авторизації, ви все одно застосовуєте так, як потрібно, у вашому коді.
+
+У багатьох випадках OAuth2 з областями може бути надлишковим.
+
+Але якщо ви знаєте, що вам це потрібно, або вам цікаво — читайте далі.
+
+///
+
+## Області OAuth2 та OpenAPI { #oauth2-scopes-and-openapi }
+
+Специфікація OAuth2 визначає «scopes» як список рядків, розділених пробілами.
+
+Вміст кожного з цих рядків може мати будь-який формат, але не повинен містити пробілів.
+
+Ці області представляють «permissions» (дозволи).
+
+В OpenAPI (наприклад, у документації API) ви можете визначати «security schemes».
+
+Коли одна з таких схем безпеки використовує OAuth2, ви також можете оголошувати та використовувати області.
+
+Кожна «scope» — це просто рядок (без пробілів).
+
+Зазвичай їх використовують, щоб оголосити конкретні дозволи безпеки, наприклад:
+
+* `users:read` або `users:write` — поширені приклади.
+* `instagram_basic` — використовує Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` — використовує Google.
+
+/// info | Інформація
+
+В OAuth2 «scope» — це просто рядок, що оголошує конкретний необхідний дозвіл.
+
+Не має значення, чи містить він інші символи, як-от `:` або чи є він URL.
+
+Ці деталі залежать від реалізації.
+
+Для OAuth2 це просто рядки.
+
+///
+
+## Загальний огляд { #global-view }
+
+Спочатку швидко подивімося на частини, які змінюються порівняно з прикладами в основному **Підручнику — Посібнику користувача** для [OAuth2 з паролем (і хешуванням), Bearer з JWT токенами](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Тепер із використанням областей OAuth2:
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
+
+Тепер розгляньмо ці зміни крок за кроком.
+
+## Схема безпеки OAuth2 { #oauth2-security-scheme }
+
+Перша зміна — тепер ми оголошуємо схему безпеки OAuth2 з двома доступними областями: `me` і `items`.
+
+Параметр `scopes` отримує `dict`, де кожна область є ключем, а опис — значенням:
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *}
+
+Оскільки ми тепер оголошуємо ці області, вони з’являться в документації API, коли ви виконаєте вхід/авторизацію.
+
+І ви зможете вибрати, до яких областей хочете надати доступ: `me` і `items`.
+
+Це той самий механізм, який використовується, коли ви надаєте дозволи під час входу через Facebook, Google, GitHub тощо:
+
+
+
+## JWT токен з областями { #jwt-token-with-scopes }
+
+Тепер змініть *операцію шляху* токена так, щоб вона повертала запитані області.
+
+Ми й далі використовуємо той самий `OAuth2PasswordRequestForm`. Він має властивість `scopes` з `list` із `str`, з кожною областю, яку він отримав у запиті.
+
+І ми повертаємо області як частину JWT токена.
+
+/// danger | Обережно
+
+Для простоти тут ми просто додаємо області, отримані з запиту, безпосередньо до токена.
+
+Але у вашому застосунку, з міркувань безпеки, слід переконатися, що ви додаєте лише ті області, які користувач справді може мати, або ті, які ви попередньо визначили.
+
+///
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}
+
+## Оголошення областей в *операціях шляху* та залежностях { #declare-scopes-in-path-operations-and-dependencies }
+
+Тепер ми оголошуємо, що *операція шляху* для `/users/me/items/` потребує область `items`.
+
+Для цього ми імпортуємо та використовуємо `Security` з `fastapi`.
+
+Ви можете використовувати `Security`, щоб оголошувати залежності (так само, як `Depends`), але `Security` також отримує параметр `scopes` зі списком областей (рядків).
+
+У цьому випадку ми передаємо функцію залежності `get_current_active_user` до `Security` (так само, як зробили б із `Depends`).
+
+Але також передаємо `list` областей — у цьому випадку лише одну: `items` (може бути й більше).
+
+І функція залежності `get_current_active_user` також може оголошувати підзалежності — не лише через `Depends`, а й через `Security`. Оголошуючи власну функцію підзалежності (`get_current_user`) та додаткові вимоги до областей.
+
+У цьому випадку потрібна область `me` (може вимагатися більше ніж одна область).
+
+/// note | Примітка
+
+Вам не обов’язково додавати різні області в різних місцях.
+
+Ми робимо це тут, щоб показати, як **FastAPI** обробляє області, оголошені на різних рівнях.
+
+///
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
+
+/// info | Технічні деталі
+
+`Security` насправді є підкласом `Depends` і має лише один додатковий параметр, який ми побачимо пізніше.
+
+Але використовуючи `Security` замість `Depends`, **FastAPI** знатиме, що може оголошувати області безпеки, використовувати їх внутрішньо та документувати API через OpenAPI.
+
+Але коли ви імпортуєте `Query`, `Path`, `Depends`, `Security` та інші з `fastapi`, то це фактично функції, які повертають спеціальні класи.
+
+///
+
+## Використання `SecurityScopes` { #use-securityscopes }
+
+Тепер оновіть залежність `get_current_user`.
+
+Саме її використовують залежності вище.
+
+Тут ми використовуємо ту саму схему OAuth2, яку створили раніше, оголошуючи її як залежність: `oauth2_scheme`.
+
+Оскільки ця функція залежності сама по собі не має вимог до областей, ми можемо використати `Depends` з `oauth2_scheme` — не потрібно використовувати `Security`, коли не треба вказувати області безпеки.
+
+Ми також оголошуємо спеціальний параметр типу `SecurityScopes`, імпортований з `fastapi.security`.
+
+Клас `SecurityScopes` схожий на `Request` (`Request` використовувався для отримання об’єкта запиту напряму).
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
+
+## Використання `scopes` { #use-the-scopes }
+
+Параметр `security_scopes` матиме тип `SecurityScopes`.
+
+Він матиме властивість `scopes` зі списком, який містить усі області, потрібні для нього самого та для всіх залежностей, що використовують його як підзалежність. Тобто для всіх «dependants»... це може звучати заплутано — нижче це ще раз пояснюється.
+
+Об’єкт `security_scopes` (класу `SecurityScopes`) також надає атрибут `scope_str` з одним рядком, що містить ці області, розділені пробілами (ми будемо це використовувати).
+
+Ми створюємо `HTTPException`, який можемо повторно використовувати (`raise`) у кількох місцях.
+
+У цьому винятку ми включаємо потрібні області (якщо є) у вигляді рядка, розділеного пробілами (використовуючи `scope_str`). Цей рядок з областями ми поміщаємо в заголовок `WWW-Authenticate` (це частина специфікації).
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
+
+## Перевірка `username` і структури даних { #verify-the-username-and-data-shape }
+
+Ми перевіряємо, що отримали `username`, і витягаємо області.
+
+Далі валідуюємо ці дані за допомогою Pydantic-моделі (перехоплюючи виняток `ValidationError`), і якщо під час читання JWT токена або перевірки даних через Pydantic виникає помилка — піднімаємо `HTTPException`, який створили раніше.
+
+Для цього ми оновлюємо Pydantic-модель `TokenData`, додаючи нову властивість `scopes`.
+
+Валідуючи дані через Pydantic, ми можемо переконатися, що маємо, наприклад, рівно `list` із `str` для областей та `str` для `username`.
+
+А не, наприклад, `dict` чи щось інше, що могло б зламати застосунок пізніше і створити ризик безпеки.
+
+Ми також перевіряємо, що існує користувач із таким `username`, і якщо ні — піднімаємо той самий виняток, який створили раніше.
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}
+
+## Перевірка `scopes` { #verify-the-scopes }
+
+Тепер ми перевіряємо, що всі області, потрібні для цієї залежності та всіх «dependants» (включно з *операціями шляху*), присутні в областях, наданих у отриманому токені. Інакше піднімаємо `HTTPException`.
+
+Для цього використовуємо `security_scopes.scopes`, що містить `list` усіх цих областей як `str`.
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}
+
+## Дерево залежностей та області { #dependency-tree-and-scopes }
+
+Розгляньмо ще раз це дерево залежностей та області.
+
+Оскільки залежність `get_current_active_user` має підзалежність `get_current_user`, область `"me"`, оголошена в `get_current_active_user`, буде включена до списку потрібних областей у `security_scopes.scopes`, переданому в `get_current_user`.
+
+Сама *операція шляху* також оголошує область `"items"`, тож вона теж буде в списку `security_scopes.scopes`, переданому в `get_current_user`.
+
+Ось як виглядає ієрархія залежностей та областей:
+
+* *Операція шляху* `read_own_items` має:
+ * Потрібні області `["items"]` із залежністю:
+ * `get_current_active_user`:
+ * Функція залежності `get_current_active_user` має:
+ * Потрібні області `["me"]` із залежністю:
+ * `get_current_user`:
+ * Функція залежності `get_current_user` має:
+ * Немає областей, потрібних для неї самої.
+ * Залежність, що використовує `oauth2_scheme`.
+ * Параметр `security_scopes` типу `SecurityScopes`:
+ * Цей параметр `security_scopes` має властивість `scopes` із `list`, який містить усі оголошені вище області, отже:
+ * `security_scopes.scopes` міститиме `["me", "items"]` для *операції шляху* `read_own_items`.
+ * `security_scopes.scopes` міститиме `["me"]` для *операції шляху* `read_users_me`, бо вона оголошена в залежності `get_current_active_user`.
+ * `security_scopes.scopes` міститиме `[]` (нічого) для *операції шляху* `read_system_status`, бо вона не оголосила жодного `Security` зі `scopes`, і її залежність `get_current_user` також не оголошує жодних `scopes`.
+
+/// tip | Порада
+
+Важлива й «магічна» річ тут у тому, що `get_current_user` матиме різний список `scopes` для перевірки для кожної *операції шляху*.
+
+Усе залежить від `scopes`, оголошених у кожній *операції шляху* та в кожній залежності в дереві залежностей для цієї конкретної *операції шляху*.
+
+///
+
+## Докладніше про `SecurityScopes` { #more-details-about-securityscopes }
+
+Ви можете використовувати `SecurityScopes` у будь-якій точці й у кількох місцях — він не обов’язково має бути в «кореневій» залежності.
+
+Він завжди міститиме області безпеки, оголошені в поточних залежностях `Security`, та у всіх «dependants» для **саме цієї** *операції шляху* і **саме цього** дерева залежностей.
+
+Оскільки `SecurityScopes` міститиме всі області, оголошені «dependants», ви можете використати його, щоб перевіряти наявність потрібних областей у токені в центральній функції залежності, а потім оголошувати різні вимоги до областей у різних *операціях шляху*.
+
+Вони перевірятимуться незалежно для кожної *операції шляху*.
+
+## Перевірте { #check-it }
+
+Якщо ви відкриєте документацію API, ви зможете автентифікуватися та вказати, які області ви хочете авторизувати.
+
+
+
+Якщо ви не виберете жодної області, ви будете «автентифіковані», але коли спробуєте отримати доступ до `/users/me/` або `/users/me/items/`, отримаєте помилку про недостатні дозволи. Водночас ви все ще зможете отримати доступ до `/status/`.
+
+А якщо ви виберете область `me`, але не область `items`, ви зможете отримати доступ до `/users/me/`, але не до `/users/me/items/`.
+
+Саме так поводитиметься сторонній застосунок, який спробував би отримати доступ до однієї з цих *операцій шляху* з токеном, наданим користувачем, залежно від того, скільки дозволів користувач надав цьому застосунку.
+
+## Про інтеграції зі сторонніми застосунками { #about-third-party-integrations }
+
+У цьому прикладі ми використовуємо OAuth2 «password» flow.
+
+Це доречно, коли ми входимо у власний застосунок — імовірно, через власний frontend.
+
+Тому що ми можемо довіряти йому отримання `username` та `password`, адже ми його контролюємо.
+
+Але якщо ви створюєте OAuth2-застосунок, до якого підключатимуться інші (тобто якщо ви створюєте провайдера автентифікації на кшталт Facebook, Google, GitHub тощо), вам слід використати один з інших flow.
+
+Найпоширеніший — implicit flow.
+
+Найбезпечніший — code flow, але його складніше реалізувати, бо він вимагає більше кроків. Через цю складність багато провайдерів у підсумку рекомендують implicit flow.
+
+/// note | Примітка
+
+Часто кожен провайдер автентифікації називає свої flow по-різному, роблячи це частиною бренду.
+
+Але зрештою вони реалізують той самий стандарт OAuth2.
+
+///
+
+**FastAPI** містить утиліти для всіх цих OAuth2 flow автентифікації в `fastapi.security.oauth2`.
+
+## `Security` у параметрі декоратора `dependencies` { #security-in-decorator-dependencies }
+
+Так само, як ви можете визначити `list` із `Depends` у параметрі декоратора `dependencies` (як пояснено в [Залежності в декораторах операцій шляху](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), ви також можете використати там `Security` зі `scopes`.
diff --git a/docs/uk/docs/advanced/settings.md b/docs/uk/docs/advanced/settings.md
new file mode 100644
index 0000000000..dc5d0c4d8d
--- /dev/null
+++ b/docs/uk/docs/advanced/settings.md
@@ -0,0 +1,302 @@
+# Налаштування та змінні середовища { #settings-and-environment-variables }
+
+У багатьох випадках вашому застосунку можуть знадобитися зовнішні налаштування або конфігурації, наприклад секретні ключі, облікові дані бази даних, облікові дані для email-сервісів тощо.
+
+Більшість із цих налаштувань є змінними (можуть змінюватися), як-от URL бази даних. І багато з них можуть бути чутливими, як-от секрети.
+
+Тому зазвичай їх передають через змінні середовища, які застосунок зчитує.
+
+/// tip | Порада
+
+Щоб зрозуміти змінні середовища, можете прочитати [Змінні середовища](../environment-variables.md){.internal-link target=_blank}.
+
+///
+
+## Типи та валідація { #types-and-validation }
+
+Ці змінні середовища можуть містити лише текстові рядки, адже вони зовнішні для Python і мають бути сумісними з іншими програмами та рештою системи (і навіть із різними операційними системами, як-от Linux, Windows, macOS).
+
+Це означає, що будь-яке значення, зчитане в Python зі змінної середовища, буде `str`, а будь-яке перетворення на інший тип або будь-яку валідацію потрібно виконувати в коді.
+
+## Pydantic `Settings` { #pydantic-settings }
+
+На щастя, Pydantic надає чудову утиліту для обробки цих налаштувань, що надходять зі змінних середовища, за допомогою Pydantic: Settings management.
+
+### Встановіть `pydantic-settings` { #install-pydantic-settings }
+
+Спочатку переконайтеся, що ви створили своє [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановіть пакет `pydantic-settings`:
+
+
+
+А потім відкрийте документацію для підзастосунку за адресою http://127.0.0.1:8000/subapi/docs.
+
+Ви побачите автоматичну документацію API для підзастосунку, яка включає лише його власні _операції шляху_, і все це під правильним префіксом підшляху `/subapi`:
+
+
+
+Якщо ви спробуєте взаємодіяти з будь-яким із двох інтерфейсів, вони працюватимуть коректно, тому що браузер зможе спілкуватися з кожним конкретним застосунком або підзастосунком.
+
+### Технічні деталі: `root_path` { #technical-details-root-path }
+
+Коли ви монтуєте підзастосунок, як описано вище, FastAPI подбає про передавання шляху монтування для підзастосунку, використовуючи механізм зі специфікації ASGI під назвою `root_path`.
+
+Так підзастосунок знатиме, що потрібно використовувати цей префікс шляху для UI документації.
+
+А підзастосунок також може мати власні змонтовані підзастосунки, і все працюватиме коректно, тому що FastAPI автоматично обробляє всі ці `root_path`.
+
+Детальніше про `root_path` і про те, як явно його використовувати, ви дізнаєтеся в розділі [За проксі](behind-a-proxy.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/advanced/templates.md b/docs/uk/docs/advanced/templates.md
new file mode 100644
index 0000000000..c7b4da534f
--- /dev/null
+++ b/docs/uk/docs/advanced/templates.md
@@ -0,0 +1,126 @@
+# Шаблони { #templates }
+
+Ви можете використовувати з **FastAPI** будь-який рушій шаблонів.
+
+Поширений вибір — Jinja2, той самий, що використовується у Flask та інших інструментах.
+
+Є утиліти для простого налаштування, які ви можете напряму використовувати у своєму застосунку **FastAPI** (надаються Starlette).
+
+## Встановіть залежності { #install-dependencies }
+
+Переконайтеся, що ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його та встановили `jinja2`:
+
+
+
+Ви можете вводити повідомлення в полі вводу та надсилати їх:
+
+
+
+І ваш застосунок **FastAPI** з WebSockets надішле відповідь у відповідь:
+
+
+
+Ви можете надсилати (і отримувати) багато повідомлень:
+
+
+
+І всі вони використовуватимуть одне й те саме WebSocket-з’єднання.
+
+## Використання `Depends` та інших { #using-depends-and-others }
+
+У WebSocket endpoints ви можете імпортувати з `fastapi` та використовувати:
+
+* `Depends`
+* `Security`
+* `Cookie`
+* `Header`
+* `Path`
+* `Query`
+
+Вони працюють так само, як і для інших endpoints FastAPI/*операцій шляху*:
+
+{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
+
+/// info | Інформація
+
+Оскільки це WebSocket, піднімати `HTTPException` насправді не має сенсу — натомість ми піднімаємо `WebSocketException`.
+
+Ви можете використати код закриття зі списку валідних кодів, визначених у специфікації.
+
+///
+
+### Спробуйте WebSockets із залежностями { #try-the-websockets-with-dependencies }
+
+Якщо ваш файл має назву `main.py`, запустіть застосунок командою:
+
+
+
+## Обробка роз’єднань і кількох клієнтів { #handling-disconnections-and-multiple-clients }
+
+Коли WebSocket-з’єднання закрито, `await websocket.receive_text()` підніме виняток `WebSocketDisconnect`, який ви можете перехопити та обробити, як у цьому прикладі.
+
+{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
+
+Щоб спробувати:
+
+* Відкрийте застосунок у кількох вкладках браузера.
+* Надсилайте повідомлення з них.
+* Потім закрийте одну з вкладок.
+
+Це підніме виняток `WebSocketDisconnect`, і всі інші клієнти отримають повідомлення на кшталт:
+
+```
+Client #1596980209979 left the chat
+```
+
+/// tip | Порада
+
+Застосунок вище — мінімальний і простий приклад, що демонструє, як обробляти та транслювати повідомлення на кілька WebSocket-з’єднань.
+
+Але майте на увазі, що оскільки все обробляється в пам’яті, в одному списку, це працюватиме лише доки працює процес, і лише з одним процесом.
+
+Якщо вам потрібно щось, що легко інтегрується з FastAPI, але є більш надійним і підтримується Redis, PostgreSQL чи іншими, перегляньте encode/broadcaster.
+
+///
+
+## Додаткова інформація { #more-info }
+
+Щоб дізнатися більше про можливості, перегляньте документацію Starlette щодо:
+
+* класу `WebSocket`.
+* обробки WebSocket на основі класів.
diff --git a/docs/uk/docs/advanced/wsgi.md b/docs/uk/docs/advanced/wsgi.md
new file mode 100644
index 0000000000..b4cf6160c6
--- /dev/null
+++ b/docs/uk/docs/advanced/wsgi.md
@@ -0,0 +1,35 @@
+# Підключення WSGI — Flask, Django та інші { #including-wsgi-flask-django-others }
+
+Ви можете монтувати WSGI-застосунки так само, як ви бачили в [Підзастосунки — монтування](sub-applications.md){.internal-link target=_blank}, [За проксі](behind-a-proxy.md){.internal-link target=_blank}.
+
+Для цього ви можете використати `WSGIMiddleware` і обгорнути ним ваш WSGI-застосунок, наприклад Flask, Django тощо.
+
+## Використання `WSGIMiddleware` { #using-wsgimiddleware }
+
+Потрібно імпортувати `WSGIMiddleware`.
+
+Потім обгорнути WSGI-застосунок (наприклад, Flask) цим middleware.
+
+І після цього змонтувати його за певним шляхом.
+
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
+
+## Перевірка { #check-it }
+
+Тепер кожен запит за шляхом `/v1/` буде оброблятися застосунком Flask.
+
+А решта — **FastAPI**.
+
+Якщо ви запустите це й перейдете на http://localhost:8000/v1/, ви побачите відповідь від Flask:
+
+```txt
+Hello, World from Flask!
+```
+
+А якщо ви перейдете на http://localhost:8000/v2, ви побачите відповідь від FastAPI:
+
+```JSON
+{
+ "message": "Hello World"
+}
+```
diff --git a/docs/uk/docs/async.md b/docs/uk/docs/async.md
new file mode 100644
index 0000000000..514c56e1e9
--- /dev/null
+++ b/docs/uk/docs/async.md
@@ -0,0 +1,444 @@
+# Конкурентність і async / await { #concurrency-and-async-await }
+
+Деталі про синтаксис `async def` для *функцій операцій шляху* та деякі пояснення щодо асинхронного коду, конкурентності й паралелізму.
+
+## Поспішаєте { #in-a-hurry }
+
+TL;DR:
+
+Якщо ви використовуєте сторонні бібліотеки, які кажуть викликати їх з `await`, наприклад:
+
+```Python
+results = await some_library()
+```
+
+Тоді оголошуйте ваші *функції операцій шляху* через `async def`, наприклад:
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+/// note | Примітка
+
+Ви можете використовувати `await` лише всередині функцій, створених за допомогою `async def`.
+
+///
+
+---
+
+Якщо ви використовуєте сторонню бібліотеку, яка взаємодіє з чимось (базою даних, API, файловою системою тощо) і не підтримує використання `await` (зараз це стосується більшості бібліотек для баз даних), тоді оголошуйте ваші *функції операцій шляху* звичайно, тобто просто з `def`, наприклад:
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+Якщо вашому застосунку (якимось чином) не потрібно спілкуватися ні з чим іншим і чекати на відповідь, використовуйте `async def`, навіть якщо вам не потрібно використовувати `await` всередині.
+
+---
+
+Якщо ви просто не знаєте — використовуйте звичайний `def`.
+
+---
+
+**Примітка**: Ви можете змішувати `def` і `async def` у ваших *функціях операцій шляху* стільки, скільки потрібно, і визначати кожну з них, обираючи найкращий для вас варіант. FastAPI зробить усе правильно.
+
+У будь-якому разі, у всіх наведених ситуаціях FastAPI все одно працюватиме асинхронно й буде надзвичайно швидким.
+
+Але якщо дотримуватися кроків вище, він зможе виконати деякі оптимізації продуктивності.
+
+## Технічні деталі { #technical-details }
+
+Сучасні версії Python підтримують **«асинхронний код»** за допомогою того, що називається **«coroutines»**, із синтаксисом **`async` і `await`**.
+
+Розберімо цю фразу по частинах у розділах нижче:
+
+* **Асинхронний код**
+* **`async` і `await`**
+* **Coroutines**
+
+## Асинхронний код { #asynchronous-code }
+
+Асинхронний код означає, що мова 💬 має спосіб сказати комп’ютеру / програмі 🤖, що в певний момент у коді їй 🤖 доведеться чекати, поки *щось інше* десь в іншому місці завершиться. Скажімо, це *щось інше* називається «slow-file» 📝.
+
+Отже, протягом цього часу комп’ютер може піти й виконувати іншу роботу, поки «slow-file» 📝 завершується.
+
+Потім комп’ютер / програма 🤖 повертатиметься щоразу, коли матиме змогу — тому що знову чекає, або коли 🤖 завершить всю роботу, яку мав у той момент. І 🤖 перевірить, чи вже завершилися якісь із завдань, на які він чекав, виконуючи те, що потрібно.
+
+Далі 🤖 бере перше завдання, яке завершилося (скажімо, наш «slow-file» 📝), і продовжує робити те, що потрібно, вже з ним.
+
+Це «очікування чогось іншого» зазвичай стосується операцій I/O, які є відносно «повільними» (порівняно зі швидкістю процесора й оперативної пам’яті), наприклад очікування:
+
+* даних від клієнта, що надсилаються мережею
+* даних, відправлених вашою програмою, щоб клієнт отримав їх через мережу
+* вмісту файлу на диску, який система має прочитати та передати вашій програмі
+* вмісту, який ваша програма передала системі, щоб записати на диск
+* операції віддаленого API
+* завершення операції з базою даних
+* повернення результатів запиту до бази даних
+* тощо
+
+Оскільки час виконання здебільшого витрачається на очікування операцій I/O, їх називають операціями «I/O bound».
+
+Це називають «асинхронним», бо комп’ютеру / програмі не потрібно бути «синхронізованими» з повільним завданням — чекати точного моменту завершення завдання, нічого не роблячи, щоб забрати результат і продовжити роботу.
+
+Натомість, будучи «асинхронною» системою, після завершення завдання може трохи почекати в черзі (кілька мікросекунд), доки комп’ютер / програма завершить те, що пішов робити, а потім повернеться, забере результати та продовжить роботу з ними.
+
+Для «синхронного» (на противагу «асинхронному») також часто використовують термін «послідовний», бо комп’ютер / програма виконує всі кроки послідовно перед тим, як перемкнутися на інше завдання, навіть якщо ці кроки містять очікування.
+
+### Конкурентність і бургери { #concurrency-and-burgers }
+
+Описану вище ідею **асинхронного** коду інколи також називають **«конкурентністю»**. Вона відрізняється від **«паралелізму»**.
+
+І **конкурентність**, і **паралелізм** стосуються того, що «різні речі відбуваються більш-менш одночасно».
+
+Але деталі між *конкурентністю* та *паралелізмом* доволі різні.
+
+Щоб побачити різницю, уявіть таку історію про бургери:
+
+### Конкурентні бургери { #concurrent-burgers }
+
+Ви йдете зі своєю симпатією по фастфуд, стоїте в черзі, поки касир приймає замовлення в людей перед вами. 😍
+
+
+
+Потім настає ваша черга, ви робите замовлення з 2 дуже вишуканих бургерів для вашої симпатії та для вас. 🍔🍔
+
+
+
+Касир щось каже кухарю на кухні, щоб ті знали, що мають приготувати ваші бургери (навіть якщо зараз вони готують для попередніх клієнтів).
+
+
+
+Ви платите. 💸
+
+Касир дає вам номер вашої черги.
+
+
+
+Поки ви чекаєте, ви разом зі своєю симпатією знаходите столик, сідаєте й довго розмовляєте (бо ваші бургери дуже вишукані й готуються певний час).
+
+Поки ви сидите за столиком зі своєю симпатією та чекаєте на бургери, ви можете витратити цей час, милуючись тим, яка чудова, мила й розумна ваша симпатія ✨😍✨.
+
+
+
+Під час очікування й розмови зі своєю симпатією, час від часу ви перевіряєте номер, який показує табло на прилавку, щоб побачити, чи вже ваша черга.
+
+І в якийсь момент нарешті стає ваша черга. Ви підходите до прилавка, берете бургери та повертаєтеся до столика.
+
+
+
+Ви зі своєю симпатією їсте бургери й гарно проводите час. ✨
+
+
+
+/// info | Інформація
+
+Чудові ілюстрації від Ketrina Thompson. 🎨
+
+///
+
+---
+
+Уявіть, що в цій історії ви — це комп’ютер / програма 🤖.
+
+Поки ви в черзі, ви просто простоюєте 😴, чекаючи своєї черги й не роблячи нічого особливо «продуктивного». Але черга рухається швидко, бо касир лише приймає замовлення (а не готує їх), тож це нормально.
+
+Потім, коли настає ваша черга, ви робите справді «продуктивну» роботу: дивитеся меню, вирішуєте, що хочете, дізнаєтеся вибір вашої симпатії, платите, перевіряєте, що віддаєте правильну купюру чи картку, перевіряєте, що з вас списали правильно, перевіряєте, що в замовленні правильні позиції, тощо.
+
+Але далі, навіть якщо у вас ще немає бургерів, ваша робота з касиром «на паузі» ⏸, бо вам треба чекати 🕙, доки бургери будуть готові.
+
+Та оскільки ви відходите від прилавка й сідаєте за столик з номером своєї черги, ви можете перемкнути 🔀 увагу на свою симпатію й «працювати» ⏯ 🤓 над цим. Тоді ви знову робите щось дуже «продуктивне» — наприклад, фліртуєте зі своєю симпатією 😍.
+
+Потім касир 💁 каже «я закінчив готувати бургери», виставляючи ваш номер на табло, але ви не стрибаєте одразу, щойно номер змінюється на ваш. Ви знаєте, що ніхто не вкраде ваші бургери, бо у вас є ваш номер, а в інших — їхній.
+
+Тож ви чекаєте, поки ваша симпатія закінчить історію (завершить поточну роботу ⏯ / завдання, яке обробляється 🤓), лагідно усміхаєтеся й кажете, що підете по бургери ⏸.
+
+Потім ви йдете до прилавка 🔀, до початкового завдання, яке вже завершене ⏯, забираєте бургери, дякуєте та несете їх до столика. Це завершує цей крок / завдання взаємодії з прилавком ⏹. І, своєю чергою, створює нове завдання — «їсти бургери» 🔀 ⏯, але попереднє «отримати бургери» вже завершене ⏹.
+
+### Паралельні бургери { #parallel-burgers }
+
+А тепер уявімо, що це не «конкурентні бургери», а «паралельні бургери».
+
+Ви йдете зі своєю симпатією по паралельний фастфуд.
+
+Ви стоїте в черзі, поки кілька (скажімо, 8) касирів, які одночасно є кухарями, приймають замовлення у людей перед вами.
+
+Кожен перед вами чекає, доки його бургери будуть готові, перш ніж відійти від прилавка, бо кожен із 8 касирів одразу йде готувати бургер, перш ніж взяти наступне замовлення.
+
+
+
+Нарешті настає ваша черга, ви робите замовлення з 2 дуже вишуканих бургерів для вашої симпатії та для вас.
+
+Ви платите 💸.
+
+
+
+Касир іде на кухню.
+
+Ви чекаєте, стоячи перед прилавком 🕙, щоб ніхто інший не забрав ваші бургери раніше за вас, адже немає номерів черги.
+
+
+
+Оскільки ви та ваша симпатія зайняті тим, щоб ніхто не проліз уперед і не забрав ваші бургери, коли вони з’являться, ви не можете приділяти увагу своїй симпатії. 😞
+
+Це «синхронна» робота: ви «синхронізовані» з касиром/кухарем 👨🍳. Вам треба чекати 🕙 й бути там у точний момент, коли касир/кухар 👨🍳 закінчить бургери й віддасть їх вам, інакше хтось інший може забрати їх.
+
+
+
+Потім ваш касир/кухар 👨🍳 нарешті повертається з вашими бургерами, після довгого очікування 🕙 там, перед прилавком.
+
+
+
+Ви берете бургери й ідете до столика зі своєю симпатією.
+
+Ви просто їсте їх, і все. ⏹
+
+
+
+Розмов чи флірту було небагато, бо більшість часу витратили на очікування 🕙 перед прилавком. 😞
+
+/// info | Інформація
+
+Чудові ілюстрації від Ketrina Thompson. 🎨
+
+///
+
+---
+
+У сценарії з паралельними бургерами ви — комп’ютер / програма 🤖 із двома процесорами (ви та ваша симпатія), обидва чекають 🕙 і утримують увагу ⏯ на «очікуванні біля прилавка» 🕙 протягом тривалого часу.
+
+У закладі фастфуду є 8 процесорів (касири/кухарі). Тоді як у закладі з конкурентними бургерами могло бути лише 2 (один касир і один кухар).
+
+Але все одно, підсумковий досвід не найкращий. 😞
+
+---
+
+Це була паралельна «бургерна» історія. 🍔
+
+Для більш «життєвого» прикладу уявіть банк.
+
+Ще донедавна в більшості банків було багато касирів 👨💼👨💼👨💼👨💼 і велика черга 🕙🕙🕙🕙🕙🕙🕙🕙.
+
+Усі касири виконували всю роботу з одним клієнтом за іншим 👨💼⏯.
+
+А вам треба чекати 🕙 у черзі довго, інакше ви втрачаєте свою чергу.
+
+Ймовірно, ви б не хотіли брати свою симпатію 😍 з собою у справах до банку 🏦.
+
+### Висновок про бургери { #burger-conclusion }
+
+У цьому сценарії «фастфуд із бургерами зі своєю симпатією», оскільки є багато очікування 🕙, значно логічніше мати конкурентну систему ⏸🔀⏯.
+
+Так буває для більшості вебзастосунків.
+
+Дуже багато користувачів, але ваш сервер чекає 🕙, поки їхнє не дуже хороше з’єднання надішле їхні запити.
+
+А потім знову чекає 🕙, поки повернуться відповіді.
+
+Це «очікування» 🕙 вимірюється мікросекундами, але якщо все підсумувати, зрештою це багато часу очікування.
+
+Саме тому має сенс використовувати асинхронний ⏸🔀⏯ код для веб-API.
+
+Саме така асинхронність зробила NodeJS популярним (хоча NodeJS не є паралельним), і це сильна сторона Go як мови програмування.
+
+І це той самий рівень продуктивності, який ви отримуєте з **FastAPI**.
+
+А оскільки ви можете мати паралелізм і асинхронність одночасно, ви отримуєте вищу продуктивність, ніж у більшості протестованих NodeJS-фреймворків, і рівень, порівняний з Go, який є компільованою мовою, ближчою до C (усе завдяки Starlette).
+
+### Чи конкурентність краща за паралелізм { #is-concurrency-better-than-parallelism }
+
+Ні! Це не мораль історії.
+
+Конкурентність відрізняється від паралелізму. І вона краща в **певних** сценаріях, які включають багато очікування. Через це вона зазвичай значно краща за паралелізм для розробки вебзастосунків. Але не для всього.
+
+Тож, щоб урівноважити це, уявіть таку коротку історію:
+
+> Вам треба прибрати великий, брудний будинок.
+
+*Так, це вся історія*.
+
+---
+
+Немає жодного очікування 🕙, лише багато роботи, яку треба виконати в різних місцях будинку.
+
+Ви могли б робити «черги», як у прикладі з бургерами: спочатку вітальня, потім кухня, але оскільки ви ні на що не чекаєте 🕙 — лише прибираєте й прибираєте — черговість нічого б не змінила.
+
+Це зайняло б стільки ж часу із «чергами» (конкурентністю) або без них, і ви виконали б ту саму кількість роботи.
+
+Але в цьому випадку, якби ви могли привести 8 колишніх касирів/кухарів/тепер-прибиральників, і кожен із них (плюс ви) взяв би зону будинку, ви могли б виконувати всю роботу **паралельно**, з додатковою допомогою, і закінчити набагато швидше.
+
+У цьому сценарії кожен прибиральник (включно з вами) був би процесором, що робить свою частину роботи.
+
+І оскільки більшість часу виконання займає реальна робота (а не очікування), а робота в комп’ютері виконується CPU, такі задачі називають «CPU bound».
+
+---
+
+Поширені приклади CPU bound операцій — це те, що потребує складної математичної обробки.
+
+Наприклад:
+
+* **Обробка аудіо** або **зображень**.
+* **Комп’ютерний зір**: зображення складається з мільйонів пікселів, кожен піксель має 3 значення/кольори; обробка зазвичай вимагає обчислювати щось над цими пікселями — усіма одночасно.
+* **Machine Learning**: зазвичай потребує великої кількості множень «матриць» і «векторів». Уявіть величезну електронну таблицю з числами та множення їх усіх одночасно.
+* **Deep Learning**: це підгалузь Machine Learning, тож діє те саме. Просто це не одна таблиця чисел для множення, а величезний набір таких таблиць, і в багатьох випадках ви використовуєте спеціальний процесор для побудови та/або використання цих моделей.
+
+### Конкурентність + паралелізм: веб + Machine Learning { #concurrency-parallelism-web-machine-learning }
+
+З **FastAPI** ви можете скористатися конкурентністю, яка дуже типова для веброзробки (це та сама головна перевага NodeJS).
+
+Але ви також можете використовувати переваги паралелізму та multiprocessing (коли кілька процесів працюють паралельно) для **CPU bound** навантажень, як у системах Machine Learning.
+
+Це, плюс простий факт, що Python — головна мова для **Data Science**, Machine Learning і особливо Deep Learning, робить FastAPI дуже вдалим вибором для веб-API та застосунків у Data Science / Machine Learning (серед багатьох інших).
+
+Щоб побачити, як досягти цього паралелізму у production, дивіться розділ про [Розгортання](deployment/index.md){.internal-link target=_blank}.
+
+## `async` і `await` { #async-and-await }
+
+Сучасні версії Python мають дуже інтуїтивний спосіб визначати асинхронний код. Це робить його схожим на звичайний «послідовний» код і виконує «очікування» за вас у потрібні моменти.
+
+Коли є операція, яка вимагатиме очікування перед тим, як надати результати, і має підтримку цих нових можливостей Python, ви можете написати так:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+Ключове тут — `await`. Він каже Python, що треба зачекати ⏸, доки `get_burgers(2)` завершить свою справу 🕙, перш ніж зберегти результат у `burgers`. Завдяки цьому Python знатиме, що тим часом може піти й зробити щось інше 🔀 ⏯ (наприклад, прийняти інший запит).
+
+Щоб `await` працював, він має бути всередині функції, яка підтримує цю асинхронність. Для цього ви просто оголошуєте її через `async def`:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...замість `def`:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+З `async def` Python знає, що всередині цієї функції треба враховувати вирази `await`, і що він може «призупинити» ⏸ виконання цієї функції та піти зробити щось інше 🔀, перш ніж повернутися.
+
+Коли ви хочете викликати функцію `async def`, вам треба її «await». Тож це не працюватиме:
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+Отже, якщо ви використовуєте бібліотеку, яка каже, що її можна викликати з `await`, вам потрібно створювати *функції операцій шляху*, які її використовують, через `async def`, як тут:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### Більш технічні деталі { #more-technical-details }
+
+Ви могли помітити, що `await` можна використовувати лише всередині функцій, визначених через `async def`.
+
+Але водночас функції, визначені через `async def`, потрібно «await». Тож функції з `async def` можна викликати лише всередині функцій, визначених через `async def`.
+
+Тож щодо «курки й яйця»: як викликати першу `async`-функцію?
+
+Якщо ви працюєте з **FastAPI**, вам не потрібно про це турбуватися, бо «першою» функцією буде ваша *функція операції шляху*, і FastAPI знатиме, як зробити все правильно.
+
+Але якщо ви хочете використовувати `async` / `await` без FastAPI — ви теж можете.
+
+### Пишіть власний async-код { #write-your-own-async-code }
+
+Starlette (і **FastAPI**) базуються на AnyIO, що робить їх сумісними і зі стандартною бібліотекою Python asyncio, і з Trio.
+
+Зокрема, ви можете безпосередньо використовувати AnyIO для ваших просунутих сценаріїв конкурентності, які потребують складніших шаблонів у власному коді.
+
+І навіть якщо ви не використовуєте FastAPI, ви також можете писати власні async-застосунки з AnyIO, щоб мати високу сумісність і отримати його переваги (наприклад, *structured concurrency*).
+
+Я створив ще одну бібліотеку поверх AnyIO як тонкий шар, щоб трохи покращити type annotations і отримати кращі **autocompletion**, **inline errors** тощо. Вона також має дружній вступ і навчальний посібник, щоб допомогти вам **зрозуміти** та писати **власний async-код**: Asyncer. Вона буде особливо корисною, якщо вам потрібно **поєднувати async-код зі звичайним** (blocking/synchronous) кодом.
+
+### Інші форми асинхронного коду { #other-forms-of-asynchronous-code }
+
+Цей стиль використання `async` і `await` є відносно новим у мові.
+
+Але він значно спрощує роботу з асинхронним кодом.
+
+Подібний (або майже ідентичний) синтаксис нещодавно з’явився також у сучасних версіях JavaScript (у Browser і NodeJS).
+
+Але до цього обробка асинхронного коду була значно складнішою.
+
+У попередніх версіях Python ви могли використовувати потоки (threads) або Gevent. Але такий код значно складніше розуміти, налагоджувати й продумувати.
+
+У попередніх версіях NodeJS / Browser JavaScript ви б використовували «callbacks», що призводить до «callback hell».
+
+## Coroutines { #coroutines }
+
+**Coroutine** — це просто дуже «пишний» термін для того, що повертає функція `async def`. Python знає, що це щось на кшталт функції, яку можна запустити й яка колись завершиться, але яка також може бути призупинена ⏸ всередині, коли є `await`.
+
+Але всю цю функціональність використання асинхронного коду з `async` і `await` часто узагальнюють як використання «coroutines». Це можна порівняти з головною фішкою Go — «Goroutines».
+
+## Підсумок { #conclusion }
+
+Подивімося на ту саму фразу з вище:
+
+> Сучасні версії Python підтримують **«асинхронний код»** за допомогою того, що називається **«coroutines»**, із синтаксисом **`async` і `await`**.
+
+Тепер це має бути зрозумілішим. ✨
+
+Усе це — те, що «живить» FastAPI (через Starlette) і дає йому таку вражаючу продуктивність.
+
+## Дуже технічні деталі { #very-technical-details }
+
+/// warning | Попередження
+
+Ймовірно, ви можете пропустити це.
+
+Це дуже технічні деталі того, як **FastAPI** працює всередині.
+
+Якщо ви маєте достатньо технічних знань (coroutines, threads, blocking тощо) і вам цікаво, як FastAPI обробляє `async def` проти звичайного `def`, продовжуйте.
+
+///
+
+### Функції операцій шляху { #path-operation-functions }
+
+Коли ви оголошуєте *функцію операції шляху* звичайним `def` замість `async def`, вона виконується в зовнішньому threadpool, і вже його «await», замість прямого виклику (бо це заблокувало б сервер).
+
+Якщо ви переходите з іншого async-фреймворку, який не працює так, як описано вище, і звикли визначати тривіальні *функції операцій шляху* лише з обчисленнями через простий `def` заради невеликого виграшу продуктивності (приблизно 100 наносекунд), зверніть увагу, що в **FastAPI** ефект буде протилежним. У таких випадках краще використовувати `async def`, якщо тільки ваші *функції операцій шляху* не використовують код, що виконує блокувальні I/O.
+
+Утім, у обох ситуаціях, найімовірніше, **FastAPI** буде [все одно швидшим](index.md#performance){.internal-link target=_blank}, ніж (або принаймні порівнянним із) ваш попередній фреймворк.
+
+### Залежності { #dependencies }
+
+Те саме стосується [залежностей](tutorial/dependencies/index.md){.internal-link target=_blank}. Якщо залежність — це стандартна функція `def`, а не `async def`, вона виконується в зовнішньому threadpool.
+
+### Підзалежності { #sub-dependencies }
+
+Ви можете мати кілька залежностей і [підзалежностей](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank}, які потребують одна одну (як параметри у визначеннях функцій); деякі з них можуть бути створені через `async def`, а деякі — через звичайний `def`. Це все одно працюватиме, а ті, що створені через звичайний `def`, будуть викликані в зовнішньому потоці (із threadpool), замість того щоб їх «await».
+
+### Інші допоміжні функції { #other-utility-functions }
+
+Будь-яка інша допоміжна функція, яку ви викликаєте безпосередньо, може бути створена як звичайним `def`, так і `async def`, і FastAPI не впливатиме на те, як ви її викликаєте.
+
+Це відрізняється від функцій, які FastAPI викликає за вас: *функцій операцій шляху* та залежностей.
+
+Якщо ваша допоміжна функція — звичайна з `def`, вона буде викликана напряму (як ви написали у своєму коді), не в threadpool; якщо функція створена через `async def`, тоді під час виклику у вашому коді вам слід зробити `await`.
+
+---
+
+Знову ж таки, це дуже технічні деталі, які, ймовірно, корисні, якщо ви спеціально їх шукали.
+
+Інакше вам має вистачити рекомендацій із розділу вище: Поспішаєте?.
diff --git a/docs/uk/docs/benchmarks.md b/docs/uk/docs/benchmarks.md
new file mode 100644
index 0000000000..8851fce13f
--- /dev/null
+++ b/docs/uk/docs/benchmarks.md
@@ -0,0 +1,34 @@
+# Бенчмарки { #benchmarks }
+
+Незалежні бенчмарки TechEmpower показують, що застосунки **FastAPI**, які працюють під Uvicorn, є одними з найшвидших доступних Python-фреймворків, поступаючись лише Starlette та самому Uvicorn (які FastAPI використовує всередині).
+
+Але, переглядаючи бенчмарки та порівняння, варто пам’ятати про таке.
+
+## Бенчмарки та швидкість { #benchmarks-and-speed }
+
+Коли ви переглядаєте бенчмарки, часто можна побачити, що кілька інструментів різних типів порівнюють так, ніби вони рівноцінні.
+
+Зокрема, можна побачити порівняння Uvicorn, Starlette і FastAPI разом (серед багатьох інших інструментів).
+
+Що простішу задачу розв’язує інструмент, то кращу продуктивність він покаже. А більшість бенчмарків не тестує додаткові можливості, які надає інструмент.
+
+Ієрархія така:
+
+* **Uvicorn**: ASGI-сервер
+ * **Starlette**: (використовує Uvicorn) веб-мікрофреймворк
+ * **FastAPI**: (використовує Starlette) API-мікрофреймворк із кількома додатковими можливостями для побудови API, із валідацією даних тощо
+
+* **Uvicorn**:
+ * Матиме найкращу продуктивність, адже майже не містить додаткового коду, окрім самого сервера.
+ * Ви не будете писати застосунок безпосередньо на Uvicorn. Це означало б, що у ваш код довелося б включити більш-менш принаймні весь код, який надає Starlette (або **FastAPI**). А якщо зробити так, ваш фінальний застосунок матиме таке саме накладне навантаження, як і при використанні фреймворку, але без переваг мінімізації коду застосунку та кількості помилок.
+ * Якщо ви порівнюєте Uvicorn, порівнюйте його з Daphne, Hypercorn, uWSGI тощо — серверами застосунків.
+* **Starlette**:
+ * Матиме наступну найкращу продуктивність після Uvicorn. Фактично Starlette використовує Uvicorn для запуску. Тож, імовірно, він може бути лише «повільнішим» за Uvicorn через потребу виконувати більше коду.
+ * Але він надає вам інструменти для побудови простих вебзастосунків, з маршрутизацією за шляхами тощо.
+ * Якщо ви порівнюєте Starlette, порівнюйте його з Sanic, Flask, Django тощо — вебфреймворками (або мікрофреймворками).
+* **FastAPI**:
+ * Так само як Starlette використовує Uvicorn і не може бути швидшим за нього, **FastAPI** використовує Starlette, тож не може бути швидшим за нього.
+ * FastAPI надає більше можливостей поверх Starlette. Це можливості, які майже завжди потрібні під час побудови API, як-от валідація та серіалізація даних. А використовуючи його, ви отримуєте автоматичну документацію без додаткових зусиль (автоматична документація навіть не додає накладних витрат під час виконання застосунків — вона генерується під час запуску).
+ * Якби ви не використовували FastAPI й застосовували Starlette напряму (або інший інструмент, як-от Sanic, Flask, Responder тощо), вам довелося б реалізувати всю валідацію та серіалізацію даних самостійно. Тож ваш фінальний застосунок усе одно мав би таке саме накладне навантаження, як і застосунок, побудований із FastAPI. І в багатьох випадках саме ця валідація та серіалізація є найбільшим обсягом коду, який пишуть у застосунках.
+ * Отже, використовуючи FastAPI, ви заощаджуєте час розробки, зменшуєте кількість помилок і рядків коду та, ймовірно, отримаєте таку саму продуктивність (або кращу), як і без нього (бо все одно довелося б реалізувати все це у вашому коді).
+ * Якщо ви порівнюєте FastAPI, порівнюйте його з фреймворком вебзастосунків (або набором інструментів), який надає валідацію даних, серіалізацію та документацію, як-от Flask-apispec, NestJS, Molten тощо — фреймворками з інтегрованими автоматичними валідацією даних, серіалізацією та документацією.
diff --git a/docs/uk/docs/deployment/cloud.md b/docs/uk/docs/deployment/cloud.md
new file mode 100644
index 0000000000..25a1f9d8e5
--- /dev/null
+++ b/docs/uk/docs/deployment/cloud.md
@@ -0,0 +1,24 @@
+# Розгортання FastAPI у хмарних провайдерів { #deploy-fastapi-on-cloud-providers }
+
+Ви можете використовувати практично **будь-якого хмарного провайдера** для розгортання вашого застосунку FastAPI.
+
+У більшості випадків основні хмарні провайдери мають інструкції з розгортання FastAPI у їхньому середовищі.
+
+## FastAPI Cloud { #fastapi-cloud }
+
+**FastAPI Cloud** створено тим самим автором і командою, що стоять за **FastAPI**.
+
+Він спрощує процес **збирання**, **розгортання** та **доступу** до API з мінімальними зусиллями.
+
+Він забезпечує такий самий **досвід розробника** під час розробки застосунків на FastAPI, і під час **розгортання** їх у хмарі. 🎉
+
+FastAPI Cloud — основний спонсор і джерело фінансування для open source проєктів *FastAPI and friends*. ✨
+
+## Хмарні провайдери — спонсори { #cloud-providers-sponsors }
+
+Деякі інші хмарні провайдери ✨ також [**спонсорують FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨. 🙇
+
+Ви також можете розглянути їх, щоб скористатися їхніми інструкціями та спробувати їхні сервіси:
+
+* Render
+* Railway
diff --git a/docs/uk/docs/deployment/concepts.md b/docs/uk/docs/deployment/concepts.md
new file mode 100644
index 0000000000..477c21ab2a
--- /dev/null
+++ b/docs/uk/docs/deployment/concepts.md
@@ -0,0 +1,321 @@
+# Концепції розгортання { #deployments-concepts }
+
+Під час розгортання застосунку **FastAPI** (або будь-якого веб-API) є кілька концепцій, які, ймовірно, вас цікавлять. Спираючись на них, ви зможете знайти **найбільш відповідний** спосіб **розгорнути ваш застосунок**.
+
+Деякі з важливих концепцій:
+
+* Безпека — HTTPS
+* Запуск під час старту
+* Перезапуски
+* Реплікація (кількість запущених процесів)
+* Пам’ять
+* Попередні кроки перед запуском
+
+Розглянемо, як вони впливають на **розгортання**.
+
+Зрештою, головна мета — **обслуговувати клієнтів вашого API** так, щоб це було **безпечно**, **уникати простоїв** і якнайефективніше використовувати **обчислювальні ресурси** (наприклад, віддалені сервери/віртуальні машини). 🚀
+
+Далі я трохи докладніше розповім про ці **концепції** — це, сподіваюся, дасть вам **інтуїтивне розуміння**, потрібне для вибору способу розгортання вашого API в дуже різних середовищах, можливо навіть у **майбутніх**, яких ще не існує.
+
+Розглядаючи ці концепції, ви зможете **оцінити та спроєктувати** найкращий спосіб розгортання **власних API**.
+
+У наступних розділах я наведу більш **конкретні рецепти** розгортання застосунків FastAPI.
+
+А поки що розгляньмо ці важливі **концептуальні ідеї**. Вони також застосовні до будь-якого іншого типу веб-API. 💡
+
+## Безпека — HTTPS { #security-https }
+
+У [попередньому розділі про HTTPS](https.md){.internal-link target=_blank} ми дізналися, як HTTPS забезпечує шифрування для вашого API.
+
+Ми також побачили, що HTTPS зазвичай надається компонентом, **зовнішнім** щодо вашого сервера застосунку — **TLS Termination Proxy**.
+
+І має бути щось, відповідальне за **оновлення HTTPS-сертифікатів** — це може бути той самий компонент або інший.
+
+### Приклади інструментів для HTTPS { #example-tools-for-https }
+
+Деякі інструменти, які ви можете використати як TLS Termination Proxy:
+
+* Traefik
+ * Автоматично виконує оновлення сертифікатів ✨
+* Caddy
+ * Автоматично виконує оновлення сертифікатів ✨
+* Nginx
+ * Із зовнішнім компонентом на кшталт Certbot для оновлення сертифікатів
+* HAProxy
+ * Із зовнішнім компонентом на кшталт Certbot для оновлення сертифікатів
+* Kubernetes з Ingress Controller на кшталт Nginx
+ * Із зовнішнім компонентом на кшталт cert-manager для оновлення сертифікатів
+* Внутрішньо обробляється хмарним провайдером як частина їхніх сервісів (читайте нижче 👇)
+
+Інший варіант — використати **хмарний сервіс**, який бере на себе більше роботи, зокрема налаштування HTTPS. Це може мати обмеження або коштувати дорожче тощо. Але в такому разі вам не доведеться налаштовувати TLS Termination Proxy самостійно.
+
+Кілька конкретних прикладів я покажу в наступних розділах.
+
+---
+
+Далі йдуть концепції, пов’язані з програмою, що запускає ваш фактичний API (наприклад, Uvicorn).
+
+## Програма і процес { #program-and-process }
+
+Ми багато говоритимемо про запущений «**процес**», тож корисно чітко розуміти, що це означає, і в чому різниця з терміном «**програма**».
+
+### Що таке програма { #what-is-a-program }
+
+Слово **програма** часто використовують для опису багатьох речей:
+
+* **Код**, який ви пишете, **файли Python**.
+* **Файл**, який може **виконуватися** операційною системою, наприклад: `python`, `python.exe` або `uvicorn`.
+* Конкретна програма, коли вона **виконується** в операційній системі, використовуючи CPU та зберігаючи дані в пам’яті. Це також називається **процесом**.
+
+### Що таке процес { #what-is-a-process }
+
+Слово **процес** зазвичай використовується більш конкретно — лише для того, що виконується в операційній системі (як в останньому пункті вище):
+
+* Конкретна програма, коли вона **виконується** в операційній системі.
+ * Це не про файл і не про код — це **саме** те, що **виконується** та керується операційною системою.
+* Будь-яка програма, будь-який код **може щось робити** лише тоді, коли він **виконується**. Тобто коли **працює процес**.
+* Процес може бути **завершений** (або «вбитий») вами або операційною системою. Після цього він перестає виконуватися і **більше не може нічого робити**.
+* Кожен застосунок, який у вас запущений на комп’ютері, має свій процес: кожна запущена програма, кожне вікно тощо. І зазвичай одночасно працює багато процесів, доки комп’ютер увімкнений.
+* Може бути **кілька процесів** **однієї й тієї самої програми**, запущених одночасно.
+
+Якщо у вашій операційній системі відкрити «task manager» або «system monitor» (чи подібні інструменти), ви зможете побачити багато таких процесів.
+
+І, наприклад, ви, ймовірно, побачите кілька процесів одного браузера (Firefox, Chrome, Edge тощо). Зазвичай він запускає один процес на вкладку плюс деякі додаткові процеси.
+
+
+
+---
+
+Тепер, коли ми знаємо різницю між термінами **процес** і **програма**, продовжимо говорити про розгортання.
+
+## Запуск під час старту { #running-on-startup }
+
+У більшості випадків, коли ви створюєте веб-API, ви хочете, щоб воно **працювало завжди**, без перерв, аби клієнти могли постійно мати доступ. Звісно, якщо у вас немає конкретної причини запускати його лише в певних ситуаціях, найчастіше ви хочете, щоб воно було постійно запущене й **доступне**.
+
+### На віддаленому сервері { #in-a-remote-server }
+
+Коли ви налаштовуєте віддалений сервер (хмарний сервер, віртуальну машину тощо), найпростіше — запускати `fastapi run` (який використовує Uvicorn) або щось подібне вручну, так само як під час локальної розробки.
+
+Це працюватиме й буде корисним **під час розробки**.
+
+Але якщо ваше з’єднання із сервером буде втрачено, **запущений процес**, імовірно, завершиться.
+
+І якщо сервер перезапуститься (наприклад, після оновлень або міграцій у хмарного провайдера), ви, ймовірно, **цього не помітите**. Через це ви навіть не знатимете, що процес треба перезапустити вручну. Тож ваш API просто залишиться «мертвим». 😱
+
+### Автоматичний запуск під час старту { #run-automatically-on-startup }
+
+Загалом, вам, ймовірно, потрібно, щоб серверна програма (наприклад, Uvicorn) запускалася автоматично під час старту сервера, без будь-якого **втручання людини**, і щоб процес із вашим API завжди працював (наприклад, Uvicorn, який запускає ваш застосунок FastAPI).
+
+### Окрема програма { #separate-program }
+
+Щоб цього досягти, зазвичай використовують **окрему програму**, яка гарантуватиме запуск вашого застосунку під час старту. У багатьох випадках вона також подбає про запуск інших компонентів або застосунків, наприклад бази даних.
+
+### Приклади інструментів для запуску під час старту { #example-tools-to-run-at-startup }
+
+Ось кілька прикладів інструментів, які можуть виконувати цю роль:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker у режимі Swarm Mode
+* Systemd
+* Supervisor
+* Внутрішньо обробляється хмарним провайдером як частина їхніх сервісів
+* Інші...
+
+Більш конкретні приклади я наведу в наступних розділах.
+
+## Перезапуски { #restarts }
+
+Подібно до того, як ви хочете забезпечити запуск застосунку під час старту, ви, ймовірно, також хочете, щоб він **перезапускався** після збоїв.
+
+### Ми помиляємося { #we-make-mistakes }
+
+Ми, люди, **помиляємося** постійно. У програмному забезпеченні майже *завжди* є приховані **помилки** в різних місцях. 🐛
+
+А ми, як розробники, продовжуємо покращувати код, знаходячи ці помилки та додаючи нові функції (можливо, додаючи й нові баги 😅).
+
+### Невеликі помилки обробляються автоматично { #small-errors-automatically-handled }
+
+Під час побудови веб-API з FastAPI, якщо в нашому коді трапляється помилка, FastAPI зазвичай ізолює її до одного запиту, який спричинив помилку. 🛡
+
+Клієнт отримає **500 Internal Server Error** для цього запиту, але застосунок продовжить працювати для наступних запитів замість повного падіння.
+
+### Більші помилки — падіння { #bigger-errors-crashes }
+
+Втім, можуть бути випадки, коли ми напишемо код, що **завалює весь застосунок**, змушуючи Uvicorn і Python аварійно завершитися. 💥
+
+І все одно, ви, ймовірно, не хочете, щоб застосунок залишався «мертвим» через помилку в одному місці — ви хочете, щоб він **продовжував працювати** принаймні для тих *операцій шляху*, які не зламані.
+
+### Перезапуск після падіння { #restart-after-crash }
+
+Але в таких випадках із дійсно серйозними помилками, які «валять» запущений **процес**, вам потрібен зовнішній компонент, відповідальний за **перезапуск** процесу, принаймні кілька разів...
+
+/// tip | Порада
+
+...Хоча якщо весь застосунок **падає одразу**, то, ймовірно, немає сенсу перезапускати його безкінечно. Але в таких випадках ви, швидше за все, помітите це під час розробки або принаймні одразу після розгортання.
+
+Тож зосередьмося на основних випадках: коли він може повністю впасти у певних ситуаціях **у майбутньому**, і тоді перезапуск усе ще має сенс.
+
+///
+
+Ви, ймовірно, захочете, щоб компонент, відповідальний за перезапуск вашого застосунку, був **зовнішнім**, бо на той момент сам застосунок із Uvicorn і Python уже впав, тож у тому ж коді цього ж застосунку не залишиться нічого, що могло б на це вплинути.
+
+### Приклади інструментів для автоматичного перезапуску { #example-tools-to-restart-automatically }
+
+У більшості випадків той самий інструмент, який використовується для **запуску програми під час старту**, також застосовується для автоматичних **перезапусків**.
+
+Наприклад, це можуть робити:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker у режимі Swarm Mode
+* Systemd
+* Supervisor
+* Внутрішньо обробляється хмарним провайдером як частина їхніх сервісів
+* Інші...
+
+## Реплікація — процеси та пам’ять { #replication-processes-and-memory }
+
+Для застосунку FastAPI, якщо запускати його через серверну програму на кшталт команди `fastapi`, що запускає Uvicorn, одного запуску **в одному процесі** достатньо, щоб обслуговувати кількох клієнтів одночасно.
+
+Але в багатьох випадках ви захочете запускати одразу кілька worker-процесів.
+
+### Кілька процесів — workers { #multiple-processes-workers }
+
+Якщо клієнтів більше, ніж може обробити один процес (наприклад, якщо віртуальна машина не надто потужна) і на сервері є **кілька ядер** CPU, тоді ви можете запустити **кілька процесів** з одним і тим самим застосунком і розподіляти між ними всі запити.
+
+Коли ви запускаєте **кілька процесів** однієї програми API, їх зазвичай називають **workers**.
+
+### Worker-процеси та порти { #worker-processes-and-ports }
+
+Пам’ятаєте з документації [Про HTTPS](https.md){.internal-link target=_blank}, що лише один процес може «слухати» одну комбінацію порту й IP-адреси на сервері?
+
+Це все ще так.
+
+Отже, щоб мати **кілька процесів** одночасно, має бути **один процес, що слухає порт**, і який потім якимось чином передає комунікацію кожному worker-процесу.
+
+### Пам’ять на процес { #memory-per-process }
+
+Коли програма завантажує дані в пам’ять, наприклад модель машинного навчання у змінну або вміст великого файлу в змінну, усе це **споживає частину пам’яті (RAM)** сервера.
+
+А кілька процесів зазвичай **не ділять пам’ять**. Це означає, що кожен запущений процес має свої дані, змінні та пам’ять. І якщо ваш код споживає багато пам’яті, **кожен процес** споживатиме приблизно таку саму кількість пам’яті.
+
+### Пам’ять сервера { #server-memory }
+
+Наприклад, якщо ваш код завантажує модель машинного навчання розміром **1 GB**, то під час запуску одного процесу з вашим API він споживатиме щонайменше 1 GB RAM. А якщо ви запустите **4 процеси** (4 workers), кожен споживатиме 1 GB RAM. Тобто загалом ваш API споживатиме **4 GB RAM**.
+
+І якщо на вашому віддаленому сервері або віртуальній машині є лише 3 GB RAM, спроба завантажити понад 4 GB RAM спричинить проблеми. 🚨
+
+### Кілька процесів — приклад { #multiple-processes-an-example }
+
+У цьому прикладі є **керівний процес (Manager Process)**, який запускає та контролює два **worker-процеси (Worker Processes)**.
+
+Цей керівний процес, імовірно, буде тим, хто «слухає» **порт** на IP. І він передаватиме всю комунікацію worker-процесам.
+
+А worker-процеси запускатимуть ваш застосунок, виконуватимуть основні обчислення для отримання **запиту** й повернення **відповіді**, та завантажуватимуть у RAM усе, що ви зберігаєте у змінних.
+
++ +**FastAPI** не існував би без попередньої роботи інших людей. + +До цього було створено багато інструментів, які допомогли надихнути його появу. + +Я уникав створення нового framework протягом кількох років. Спочатку я намагався реалізувати всі можливості, які охоплює **FastAPI**, використовуючи багато різних frameworks, plug-ins та інструментів. + +Але в певний момент не залишилося іншого варіанту, окрім як створити щось, що надає всі ці можливості: взяти найкращі ідеї з попередніх інструментів і поєднати їх найкращим можливим способом, використовуючи можливості мови, яких раніше навіть не було (type hints у Python 3.6+). + ++ +## Дослідження { #investigation } + +Використовуючи всі попередні альтернативи, я мав можливість повчитися на кожній із них, взяти ідеї та поєднати їх найкращим способом, який я зміг знайти для себе та команд розробників, з якими працював. + +Наприклад, було очевидно, що в ідеалі все має базуватися на стандартних Python type hints. + +Також найкращим підходом було використання вже наявних стандартів. + +Тож ще до того, як почати писати код **FastAPI**, я витратив кілька місяців на вивчення специфікацій OpenAPI, JSON Schema, OAuth2 тощо. Щоб зрозуміти їхні взаємозв’язки, перетини та відмінності. + +## Дизайн { #design } + +Потім я витратив певний час на проєктування «API» для розробника, яке я хотів мати як користувач (як розробник, що використовує FastAPI). + +Я протестував кілька ідей у найпопулярніших Python-редакторах: PyCharm, VS Code, редакторах на базі Jedi. + +Згідно з останнім Python Developer Survey, який охоплює близько 80% користувачів. + +Це означає, що **FastAPI** спеціально тестували в редакторах, якими користуються 80% Python-розробників. А оскільки більшість інших редакторів зазвичай працюють подібно, усі його переваги мають працювати практично в усіх редакторах. + +Так я зміг знайти найкращі способи максимально зменшити дублювання коду, мати автодоповнення всюди, перевірки типів і помилок тощо. + +Усе це — так, щоб забезпечити найкращий досвід розробки для всіх розробників. + +## Вимоги { #requirements } + +Після тестування кількох альтернатив я вирішив, що використовуватиму **Pydantic** через його переваги. + +Потім я зробив внесок у його розвиток, щоб забезпечити повну відповідність JSON Schema, підтримати різні способи визначення декларацій обмежень і покращити підтримку редакторів (перевірки типів, автодоповнення) на основі тестів у кількох редакторах. + +Під час розробки я також зробив внесок у **Starlette** — іншу ключову вимогу. + +## Розробка { #development } + +На момент, коли я почав створювати сам **FastAPI**, більшість частин уже були на місці: дизайн визначено, вимоги та інструменти готові, а знання про стандарти й специфікації були чіткими та свіжими. + +## Майбутнє { #future } + +На цьому етапі вже зрозуміло, що **FastAPI** з його ідеями є корисним для багатьох людей. + +Його обирають замість попередніх альтернатив, бо він краще підходить для багатьох сценаріїв використання. + +Багато розробників і команд уже залежать від **FastAPI** у своїх проєктах (включно зі мною та моєю командою). + +Але попереду ще багато покращень і нових можливостей. + +**FastAPI** має чудове майбутнє. + +І [ваша допомога](help-fastapi.md){.internal-link target=_blank} буде дуже цінною. diff --git a/docs/uk/docs/how-to/authentication-error-status-code.md b/docs/uk/docs/how-to/authentication-error-status-code.md new file mode 100644 index 0000000000..0d5a6c5a6c --- /dev/null +++ b/docs/uk/docs/how-to/authentication-error-status-code.md @@ -0,0 +1,17 @@ +# Використання старих кодів стану 403 для помилок автентифікації { #use-old-403-authentication-error-status-codes } + +До версії FastAPI `0.122.0`, коли вбудовані утиліти безпеки повертали клієнту помилку після невдалої автентифікації, вони використовували код стану HTTP `403 Forbidden`. + +Починаючи з FastAPI `0.122.0`, вони використовують більш доречний код стану HTTP `401 Unauthorized` і повертають у відповіді коректний заголовок `WWW-Authenticate`, дотримуючись специфікацій HTTP, RFC 7235, RFC 9110. + +Але якщо з певної причини ваші клієнти залежать від старої поведінки, ви можете повернути її, перевизначивши метод `make_not_authenticated_error` у ваших класах безпеки. + +Наприклад, ви можете створити підклас `HTTPBearer`, який повертає помилку `403 Forbidden` замість типової `401 Unauthorized`: + +{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *} + +/// tip | Порада + +Зверніть увагу: функція повертає екземпляр винятку, а не піднімає його. Підняття виконується в іншій частині внутрішнього коду. + +/// diff --git a/docs/uk/docs/how-to/conditional-openapi.md b/docs/uk/docs/how-to/conditional-openapi.md new file mode 100644 index 0000000000..c548c3b0f5 --- /dev/null +++ b/docs/uk/docs/how-to/conditional-openapi.md @@ -0,0 +1,56 @@ +# Умовний OpenAPI { #conditional-openapi } + +За потреби ви можете використати налаштування та змінні середовища, щоб умовно конфігурувати OpenAPI залежно від середовища, і навіть повністю його вимкнути. + +## Про безпеку, API та документацію { #about-security-apis-and-docs } + +Приховування інтерфейсів документації у production *не повинно* бути способом захисту вашого API. + +Це не додає жодної додаткової безпеки для вашого API — *операції шляху* усе одно будуть доступні там, де вони є. + +Якщо у вашому коді є вразливість безпеки, вона все одно існуватиме. + +Приховування документації лише ускладнює розуміння того, як взаємодіяти з вашим API, і може ускладнити вам налагодження в production. Це можна розглядати просто як форму безпеки через неочевидність. + +Якщо ви хочете захистити свій API, є кілька кращих речей, які ви можете зробити, наприклад: + +* Переконайтеся, що у вас є чітко визначені моделі Pydantic для тіл запитів і відповідей. +* Налаштуйте всі необхідні дозволи та ролі за допомогою залежностей. +* Ніколи не зберігайте паролі у відкритому вигляді, лише хеші паролів. +* Реалізуйте та використовуйте добре відомі криптографічні інструменти, як-от pwdlib і JWT tokens тощо. +* Додайте більш деталізований контроль доступу за допомогою OAuth2 scopes там, де це потрібно. +* ...тощо. + +Втім, у вас може бути дуже специфічний випадок використання, коли вам справді потрібно вимкнути документацію API для певного середовища (наприклад, для production) або залежно від конфігурацій зі змінних середовища. + +## Умовний OpenAPI з налаштувань і змінних середовища { #conditional-openapi-from-settings-and-env-vars } + +Ви можете легко використати ті самі налаштування Pydantic, щоб налаштувати згенерований OpenAPI та UI документації. + +Наприклад: + +{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *} + +Тут ми оголошуємо налаштування `openapi_url` з тим самим значенням за замовчуванням `"/openapi.json"`. + +А потім використовуємо його під час створення застосунку `FastAPI`. + +Далі ви можете вимкнути OpenAPI (включно з UI документації), встановивши змінну середовища `OPENAPI_URL` в порожній рядок, ось так: + +
+
+Але ви можете вимкнути його, встановивши `syntaxHighlight` у `False`:
+
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
+
+...і тоді Swagger UI більше не показуватиме підсвічування синтаксису:
+
+
+
+## Зміна теми { #change-the-theme }
+
+Так само ви можете встановити тему підсвічування синтаксису ключем `"syntaxHighlight.theme"` (зверніть увагу, що посередині є крапка):
+
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
+
+Ця конфігурація змінить колірну тему підсвічування синтаксису:
+
+
+
+## Зміна параметрів Swagger UI за замовчуванням { #change-default-swagger-ui-parameters }
+
+FastAPI містить деякі стандартні параметри конфігурації, придатні для більшості випадків використання.
+
+Він включає такі конфігурації за замовчуванням:
+
+{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
+
+Ви можете перевизначити будь-яку з них, встановивши інше значення в аргументі `swagger_ui_parameters`.
+
+Наприклад, щоб вимкнути `deepLinking`, ви можете передати такі налаштування в `swagger_ui_parameters`:
+
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
+
+## Інші параметри Swagger UI { #other-swagger-ui-parameters }
+
+Щоб переглянути всі інші можливі конфігурації, які ви можете використати, прочитайте офіційну документацію з параметрів Swagger UI.
+
+## Налаштування лише для JavaScript { #javascript-only-settings }
+
+Swagger UI також дозволяє інші конфігурації у вигляді об’єктів, що є **лише для JavaScript** (наприклад, функції JavaScript).
+
+FastAPI також включає ці налаштування `presets`, що є лише для JavaScript:
+
+```JavaScript
+presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIBundle.SwaggerUIStandalonePreset
+]
+```
+
+Це об’єкти **JavaScript**, а не рядки, тож ви не можете передати їх напряму з Python-коду.
+
+Якщо вам потрібно використати конфігурації лише для JavaScript, подібні до цих, ви можете застосувати один із методів вище: перевизначити всі операції шляху Swagger UI та вручну написати потрібний вам JavaScript.
diff --git a/docs/uk/docs/how-to/custom-docs-ui-assets.md b/docs/uk/docs/how-to/custom-docs-ui-assets.md
new file mode 100644
index 0000000000..32373d7795
--- /dev/null
+++ b/docs/uk/docs/how-to/custom-docs-ui-assets.md
@@ -0,0 +1,185 @@
+# Власні статичні ресурси для UI документації (самостійне хостингування) { #custom-docs-ui-static-assets-self-hosting }
+
+Документація API використовує **Swagger UI** і **ReDoc**, і кожному з них потрібні деякі файли JavaScript і CSS.
+
+За замовчуванням ці файли віддаються через CDN.
+
+Але це можна налаштувати: ви можете вказати конкретний CDN або віддавати файли самостійно.
+
+## Власний CDN для JavaScript і CSS { #custom-cdn-for-javascript-and-css }
+
+Припустімо, ви хочете використовувати інший CDN, наприклад `https://unpkg.com/`.
+
+Це може бути корисно, наприклад, якщо ви живете в країні, яка обмежує доступ до деяких URL.
+
+### Вимкнути автоматичну документацію { #disable-the-automatic-docs }
+
+Перший крок — вимкнути автоматичну документацію, адже за замовчуванням вона використовує стандартний CDN.
+
+Щоб вимкнути її, встановіть її URL у `None` під час створення застосунку `FastAPI`:
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
+
+### Додати власну документацію { #include-the-custom-docs }
+
+Тепер ви можете створити *операції шляху* для власної документації.
+
+Ви можете повторно використати внутрішні функції FastAPI для створення HTML-сторінок документації та передати їм потрібні аргументи:
+
+* `openapi_url`: URL, звідки HTML-сторінка документації може отримати схему OpenAPI для вашого API. Тут можна використати атрибут `app.openapi_url`.
+* `title`: заголовок вашого API.
+* `oauth2_redirect_url`: тут можна використати `app.swagger_ui_oauth2_redirect_url`, щоб застосувати значення за замовчуванням.
+* `swagger_js_url`: URL, звідки HTML для документації Swagger UI може отримати файл **JavaScript**. Це URL вашого власного CDN.
+* `swagger_css_url`: URL, звідки HTML для документації Swagger UI може отримати файл **CSS**. Це URL вашого власного CDN.
+
+І так само для ReDoc...
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
+
+/// tip | Порада
+
+*Операція шляху* для `swagger_ui_redirect` — це допоміжний обробник для випадку, коли ви використовуєте OAuth2.
+
+Якщо ви інтегруєте ваш API з OAuth2-провайдером, ви зможете пройти автентифікацію, повернутися до документації API з отриманими обліковими даними та взаємодіяти з ним, використовуючи справжню OAuth2-автентифікацію.
+
+Swagger UI зробить це «за лаштунками» для вас, але для цього йому потрібен цей допоміжний «redirect».
+
+///
+
+### Створити *операцію шляху* для перевірки { #create-a-path-operation-to-test-it }
+
+Тепер, щоб мати змогу перевірити, що все працює, створіть *операцію шляху*:
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
+
+### Перевірка { #test-it }
+
+Тепер ви маєте змогу перейти до документації за адресою http://127.0.0.1:8000/docs і перезавантажити сторінку — вона завантажить ці ресурси з нового CDN.
+
+## Самостійне хостингування JavaScript і CSS для документації { #self-hosting-javascript-and-css-for-docs }
+
+Самостійне хостингування JavaScript і CSS може бути корисним, наприклад, якщо ваш застосунок має продовжувати працювати навіть офлайн — без доступу до відкритого Інтернету — або в локальній мережі.
+
+Тут ви побачите, як віддавати ці файли самостійно, у тому ж застосунку FastAPI, і налаштувати документацію так, щоб вона їх використовувала.
+
+### Структура файлів проєкту { #project-file-structure }
+
+Припустімо, структура файлів вашого проєкту виглядає так:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+```
+
+Тепер створіть директорію для зберігання цих статичних файлів.
+
+Нова структура файлів може виглядати так:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static/
+```
+
+### Завантажити файли { #download-the-files }
+
+Завантажте статичні файли, потрібні для документації, і покладіть їх у директорію `static/`.
+
+Ймовірно, ви можете натиснути правою кнопкою миші на кожне посилання та вибрати щось на кшталт «Save link as...».
+
+**Swagger UI** використовує файли:
+
+* `swagger-ui-bundle.js`
+* `swagger-ui.css`
+
+А **ReDoc** використовує файл:
+
+* `redoc.standalone.js`
+
+Після цього структура файлів може виглядати так:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static
+ ├── redoc.standalone.js
+ ├── swagger-ui-bundle.js
+ └── swagger-ui.css
+```
+
+### Віддавати статичні файли { #serve-the-static-files }
+
+* Імпортуйте `StaticFiles`.
+* «Змонтуйте» екземпляр `StaticFiles()` на конкретному шляху.
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
+
+### Перевірити статичні файли { #test-the-static-files }
+
+Запустіть ваш застосунок і перейдіть за адресою http://127.0.0.1:8000/static/redoc.standalone.js.
+
+Ви маєте побачити дуже довгий JavaScript-файл для **ReDoc**.
+
+Він може починатися приблизно так:
+
+```JavaScript
+/*! For license information please see redoc.standalone.js.LICENSE.txt */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
+...
+```
+
+Це підтверджує, що ви можете віддавати статичні файли зі свого застосунку і що ви розмістили статичні файли для документації в правильному місці.
+
+Тепер ми можемо налаштувати застосунок так, щоб він використовував ці статичні файли для документації.
+
+### Вимкнути автоматичну документацію для статичних файлів { #disable-the-automatic-docs-for-static-files }
+
+Так само, як і при використанні власного CDN, перший крок — вимкнути автоматичну документацію, адже за замовчуванням вона використовує CDN.
+
+Щоб вимкнути її, встановіть її URL у `None` під час створення застосунку `FastAPI`:
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
+
+### Додати власну документацію для статичних файлів { #include-the-custom-docs-for-static-files }
+
+І так само, як із власним CDN, тепер ви можете створити *операції шляху* для власної документації.
+
+Знову ж таки, ви можете повторно використати внутрішні функції FastAPI для створення HTML-сторінок документації та передати їм потрібні аргументи:
+
+* `openapi_url`: URL, звідки HTML-сторінка документації може отримати схему OpenAPI для вашого API. Тут можна використати атрибут `app.openapi_url`.
+* `title`: заголовок вашого API.
+* `oauth2_redirect_url`: тут можна використати `app.swagger_ui_oauth2_redirect_url`, щоб застосувати значення за замовчуванням.
+* `swagger_js_url`: URL, звідки HTML для документації Swagger UI може отримати файл **JavaScript**. **Тепер його віддає ваш власний застосунок**.
+* `swagger_css_url`: URL, звідки HTML для документації Swagger UI може отримати файл **CSS**. **Тепер його віддає ваш власний застосунок**.
+
+І так само для ReDoc...
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
+
+/// tip | Порада
+
+*Операція шляху* для `swagger_ui_redirect` — це допоміжний обробник для випадку, коли ви використовуєте OAuth2.
+
+Якщо ви інтегруєте ваш API з OAuth2-провайдером, ви зможете пройти автентифікацію, повернутися до документації API з отриманими обліковими даними та взаємодіяти з ним, використовуючи справжню OAuth2-автентифікацію.
+
+Swagger UI зробить це «за лаштунками» для вас, але для цього йому потрібен цей допоміжний «redirect».
+
+///
+
+### Створити *операцію шляху* для перевірки статичних файлів { #create-a-path-operation-to-test-static-files }
+
+Тепер, щоб мати змогу перевірити, що все працює, створіть *операцію шляху*:
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
+
+### Перевірити UI зі статичними файлами { #test-static-files-ui }
+
+Тепер ви маєте змогу від’єднати WiFi, перейти до документації за адресою http://127.0.0.1:8000/docs і перезавантажити сторінку.
+
+І навіть без Інтернету ви зможете бачити документацію вашого API та взаємодіяти з ним.
diff --git a/docs/uk/docs/how-to/custom-request-and-route.md b/docs/uk/docs/how-to/custom-request-and-route.md
new file mode 100644
index 0000000000..99cc5eeb91
--- /dev/null
+++ b/docs/uk/docs/how-to/custom-request-and-route.md
@@ -0,0 +1,109 @@
+# Власні класи Request і APIRoute { #custom-request-and-apiroute-class }
+
+У деяких випадках ви можете захотіти перевизначити логіку, яку використовують класи `Request` і `APIRoute`.
+
+Зокрема, це може бути хорошою альтернативою логіці в middleware.
+
+Наприклад, якщо ви хочете прочитати або змінити тіло запиту до того, як його обробить ваш застосунок.
+
+/// danger | Обережно
+
+Це «просунута» можливість.
+
+Якщо ви лише починаєте працювати з **FastAPI**, вам, імовірно, варто пропустити цей розділ.
+
+///
+
+## Випадки використання { #use-cases }
+
+Деякі випадки використання:
+
+* Перетворення не-JSON тіл запитів на JSON (наприклад, `msgpack`).
+* Розпаковування gzip-стиснених тіл запитів.
+* Автоматичне логування всіх тіл запитів.
+
+## Обробка власних кодувань тіла запиту { #handling-custom-request-body-encodings }
+
+Розгляньмо, як використати власний підклас `Request`, щоб розпаковувати gzip-запити.
+
+А також підклас `APIRoute`, щоб використовувати цей власний клас запиту.
+
+### Створіть власний клас `GzipRequest` { #create-a-custom-gziprequest-class }
+
+/// tip | Порада
+
+Це навчальний приклад, щоб продемонструвати, як це працює. Якщо вам потрібна підтримка Gzip, ви можете використати наданий [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}.
+
+///
+
+Спочатку створюємо клас `GzipRequest`, який перевизначить метод `Request.body()`, щоб розпаковувати тіло за наявності відповідного заголовка.
+
+Якщо в заголовку немає `gzip`, він не намагатиметься розпаковувати тіло.
+
+Так один і той самий клас маршруту може обробляти як gzip-стиснені, так і нестиснені запити.
+
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
+
+### Створіть власний клас `GzipRoute` { #create-a-custom-gziproute-class }
+
+Далі створюємо власний підклас `fastapi.routing.APIRoute`, який використовуватиме `GzipRequest`.
+
+Цього разу він перевизначить метод `APIRoute.get_route_handler()`.
+
+Цей метод повертає функцію. І саме ця функція отримуватиме запит і повертатиме відповідь.
+
+Тут ми використовуємо її, щоб створити `GzipRequest` з початкового запиту.
+
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
+
+/// note | Технічні деталі
+
+`Request` має атрибут `request.scope` — це просто Python-`dict`, що містить метадані, пов’язані із запитом.
+
+`Request` також має `request.receive` — це функція для «отримання» тіла запиту.
+
+`dict` `scope` і функція `receive` обидва є частиною специфікації ASGI.
+
+І саме ці дві речі — `scope` та `receive` — потрібні, щоб створити новий екземпляр `Request`.
+
+Щоб дізнатися більше про `Request`, перегляньте документацію Starlette про Requests.
+
+///
+
+Єдина відмінність у роботі функції, яку повертає `GzipRequest.get_route_handler`, — це перетворення `Request` на `GzipRequest`.
+
+Завдяки цьому наш `GzipRequest` подбає про розпаковування даних (за потреби) перед тим, як передати їх у наші *операції шляху*.
+
+Після цього вся логіка обробки залишається тією самою.
+
+Але через наші зміни в `GzipRequest.body` тіло запиту буде автоматично розпаковане, коли **FastAPI** завантажуватиме його за потреби.
+
+## Доступ до тіла запиту в обробнику винятків { #accessing-the-request-body-in-an-exception-handler }
+
+/// tip | Порада
+
+Щоб розв’язати цю саму задачу, ймовірно, значно простіше використати `body` у власному обробнику для `RequestValidationError` ([Обробка помилок](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
+
+Але цей приклад усе одно коректний і показує, як взаємодіяти з внутрішніми компонентами.
+
+///
+
+Ми також можемо використати цей самий підхід, щоб отримати доступ до тіла запиту в обробнику винятків.
+
+Усе, що потрібно зробити, — обробляти запит усередині блоку `try`/`except`:
+
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
+
+Якщо станеться виняток, екземпляр `Request` усе ще буде в області видимості, тож ми зможемо прочитати та використати тіло запиту під час обробки помилки:
+
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
+
+## Власний клас `APIRoute` у router { #custom-apiroute-class-in-a-router }
+
+Ви також можете встановити параметр `route_class` для `APIRouter`:
+
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
+
+У цьому прикладі *операції шляху* під `router` використовуватимуть власний клас `TimedRoute` і матимуть додатковий заголовок `X-Response-Time` у відповіді з часом, який знадобився для генерування відповіді:
+
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
diff --git a/docs/uk/docs/how-to/extending-openapi.md b/docs/uk/docs/how-to/extending-openapi.md
new file mode 100644
index 0000000000..b3c4f76b8a
--- /dev/null
+++ b/docs/uk/docs/how-to/extending-openapi.md
@@ -0,0 +1,80 @@
+# Розширення OpenAPI { #extending-openapi }
+
+У деяких випадках вам може знадобитися змінити згенеровану схему OpenAPI.
+
+У цьому розділі ви побачите, як це зробити.
+
+## Звичайний процес { #the-normal-process }
+
+Звичайний (типовий) процес виглядає так.
+
+Застосунок `FastAPI` (екземпляр) має метод `.openapi()`, який має повертати схему OpenAPI.
+
+Під час створення об’єкта застосунку реєструється *операція шляху* для `/openapi.json` (або для того, що ви вкажете в `openapi_url`).
+
+Вона просто повертає JSON-відповідь з результатом методу `.openapi()` застосунку.
+
+Типово метод `.openapi()` перевіряє властивість `.openapi_schema`, щоб з’ясувати, чи містить вона дані, і повертає їх.
+
+Якщо даних немає, він генерує їх за допомогою утилітарної функції `fastapi.openapi.utils.get_openapi`.
+
+І ця функція `get_openapi()` отримує як параметри:
+
+* `title`: заголовок OpenAPI, який показується в документації.
+* `version`: версія вашого API, напр. `2.5.0`.
+* `openapi_version`: версія специфікації OpenAPI, що використовується. Типово — найновіша: `3.1.0`.
+* `summary`: короткий підсумок API.
+* `description`: опис вашого API; може містити markdown і буде показаний у документації.
+* `routes`: список маршрутів; кожен з них — це зареєстрована *операція шляху*. Їх беруть з `app.routes`.
+
+/// info | Інформація
+
+Параметр `summary` доступний в OpenAPI 3.1.0 і вище, підтримується у FastAPI 0.99.0 і вище.
+
+///
+
+## Перевизначення типових значень { #overriding-the-defaults }
+
+Використовуючи наведені вище відомості, ви можете застосувати ту саму утилітарну функцію, щоб згенерувати схему OpenAPI і перевизначити кожну потрібну вам частину.
+
+Наприклад, додаймо розширення OpenAPI для ReDoc, щоб включити власний логотип.
+
+### Звичайний **FastAPI** { #normal-fastapi }
+
+Спочатку напишіть увесь ваш застосунок **FastAPI** як зазвичай:
+
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
+
+### Згенеруйте схему OpenAPI { #generate-the-openapi-schema }
+
+Потім використайте ту саму утилітарну функцію, щоб згенерувати схему OpenAPI всередині функції `custom_openapi()`:
+
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
+
+### Змініть схему OpenAPI { #modify-the-openapi-schema }
+
+Тепер ви можете додати розширення ReDoc, додавши власний `x-logo` до «об’єкта» `info` у схемі OpenAPI:
+
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
+
+### Кешуйте схему OpenAPI { #cache-the-openapi-schema }
+
+Ви можете використати властивість `.openapi_schema` як «кеш», щоб зберігати згенеровану схему.
+
+Так ваш застосунок не муситиме генерувати схему щоразу, коли користувач відкриває вашу документацію API.
+
+Її буде згенеровано лише один раз, а потім для наступних запитів використовуватиметься та сама закешована схема.
+
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
+
+### Перевизначте метод { #override-the-method }
+
+Тепер ви можете замінити метод `.openapi()` вашою новою функцією.
+
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
+
+### Перевірте { #check-it }
+
+Після переходу за посиланням http://127.0.0.1:8000/redoc ви побачите, що використовується ваш власний логотип (у цьому прикладі — логотип **FastAPI**):
+
+
diff --git a/docs/uk/docs/how-to/general.md b/docs/uk/docs/how-to/general.md
new file mode 100644
index 0000000000..8106f9653c
--- /dev/null
+++ b/docs/uk/docs/how-to/general.md
@@ -0,0 +1,39 @@
+# Загальне — Як зробити — Рецепти { #general-how-to-recipes }
+
+Ось кілька посилань на інші місця в документації для загальних або частих запитань.
+
+## Фільтрування даних — Безпека { #filter-data-security }
+
+Щоб гарантувати, що ви не повернете більше даних, ніж слід, прочитайте документацію: [Підручник — Модель відповіді — Тип повернення](../tutorial/response-model.md){.internal-link target=_blank}.
+
+## Теги документації — OpenAPI { #documentation-tags-openapi }
+
+Щоб додати теги до ваших *операцій шляху* та згрупувати їх в інтерфейсі документації, прочитайте документацію: [Підручник — Налаштування операцій шляху — Теги](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
+
+## Підсумок і опис документації — OpenAPI { #documentation-summary-and-description-openapi }
+
+Щоб додати підсумок і опис до ваших *операцій шляху* та показувати їх в інтерфейсі документації, прочитайте документацію: [Підручник — Налаштування операцій шляху — Підсумок і опис](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
+
+## Опис відповіді в документації — OpenAPI { #documentation-response-description-openapi }
+
+Щоб визначити опис відповіді, який показується в інтерфейсі документації, прочитайте документацію: [Підручник — Налаштування операцій шляху — Опис відповіді](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
+
+## Позначення *операції шляху* як застарілої — OpenAPI { #documentation-deprecate-a-path-operation-openapi }
+
+Щоб позначити *операцію шляху* як застарілу та показувати це в інтерфейсі документації, прочитайте документацію: [Підручник — Налаштування операцій шляху — Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
+
+## Перетворення будь-яких даних на JSON-сумісні { #convert-any-data-to-json-compatible }
+
+Щоб перетворити будь-які дані на JSON-сумісні, прочитайте документацію: [Підручник — JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+
+## Метадані OpenAPI — Документація { #openapi-metadata-docs }
+
+Щоб додати метадані до вашої схеми OpenAPI, включно з ліцензією, версією, контактами тощо, прочитайте документацію: [Підручник — Метадані та URL-адреси документації](../tutorial/metadata.md){.internal-link target=_blank}.
+
+## Користувацька URL-адреса OpenAPI { #openapi-custom-url }
+
+Щоб налаштувати URL-адресу OpenAPI (або прибрати її), прочитайте документацію: [Підручник — Метадані та URL-адреси документації](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
+
+## URL-адреси документації OpenAPI { #openapi-docs-urls }
+
+Щоб оновити URL-адреси, які використовуються для автоматично згенерованих інтерфейсів документації, прочитайте документацію: [Підручник — Метадані та URL-адреси документації](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
diff --git a/docs/uk/docs/how-to/graphql.md b/docs/uk/docs/how-to/graphql.md
new file mode 100644
index 0000000000..ef578b5249
--- /dev/null
+++ b/docs/uk/docs/how-to/graphql.md
@@ -0,0 +1,60 @@
+# GraphQL { #graphql }
+
+Оскільки **FastAPI** базується на стандарті **ASGI**, дуже легко інтегрувати будь-яку бібліотеку **GraphQL**, яка також сумісна з ASGI.
+
+Ви можете поєднувати звичайні FastAPI *операції шляху* з GraphQL в одному застосунку.
+
+/// tip | Порада
+
+**GraphQL** розв’язує деякі дуже специфічні випадки використання.
+
+Він має **переваги** та **недоліки** порівняно зі звичними **web API**.
+
+Переконайтеся, що ви оцінили, чи **переваги** для вашого випадку використання компенсують **недоліки**. 🤓
+
+///
+
+## Бібліотеки GraphQL { #graphql-libraries }
+
+Ось деякі бібліотеки **GraphQL**, які мають підтримку **ASGI**. Ви можете використовувати їх із **FastAPI**:
+
+* Strawberry 🍓
+ * З документацією для FastAPI
+* Ariadne
+ * З документацією для FastAPI
+* Tartiflette
+ * Із Tartiflette ASGI для забезпечення інтеграції з ASGI
+* Graphene
+ * Із starlette-graphene3
+
+## GraphQL зі Strawberry { #graphql-with-strawberry }
+
+Якщо вам потрібно або ви хочете працювати з **GraphQL**, **Strawberry** — **рекомендована** бібліотека, адже її дизайн найближчий до дизайну **FastAPI**: усе базується на **анотаціях типів**.
+
+Залежно від вашого випадку використання, ви можете віддати перевагу іншій бібліотеці, але якби ви запитали мене, я б, імовірно, порадив вам спробувати **Strawberry**.
+
+Ось невеликий приклад того, як ви можете інтегрувати Strawberry з FastAPI:
+
+{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
+
+Докладніше про Strawberry можна дізнатися в документації Strawberry.
+
+А також у документації про Strawberry з FastAPI.
+
+## Старий `GraphQLApp` зі Starlette { #older-graphqlapp-from-starlette }
+
+Попередні версії Starlette містили клас `GraphQLApp` для інтеграції з Graphene.
+
+Його позначили застарілим у Starlette, але якщо у вас є код, який його використовував, ви можете легко **мігрувати** на starlette-graphene3, що покриває той самий випадок використання та має **майже ідентичний інтерфейс**.
+
+/// tip | Порада
+
+Якщо вам потрібен GraphQL, я все одно рекомендую вам звернути увагу на Strawberry, адже він базується на анотаціях типів, а не на власних класах і типах.
+
+///
+
+## Дізнатися більше { #learn-more }
+
+Детальніше про **GraphQL** можна дізнатися в офіційній документації GraphQL.
+
+Ви також можете прочитати більше про кожну з бібліотек, описаних вище, за наведеними посиланнями.
diff --git a/docs/uk/docs/how-to/index.md b/docs/uk/docs/how-to/index.md
new file mode 100644
index 0000000000..273087b683
--- /dev/null
+++ b/docs/uk/docs/how-to/index.md
@@ -0,0 +1,13 @@
+# Як зробити — Рецепти { #how-to-recipes }
+
+Тут ви знайдете різні рецепти або інструкції «how to» для **кількох тем**.
+
+Більшість цих ідей є більш-менш **незалежними**, і в більшості випадків вам потрібно буде вивчати їх лише тоді, коли вони безпосередньо стосуються **вашого проєкту**.
+
+Якщо щось здається цікавим і корисним для вашого проєкту — перегляньте це, а інакше, ймовірно, можете просто пропустити.
+
+/// tip | Порада
+
+Якщо ви хочете **вивчати FastAPI** структуровано (рекомендовано), натомість читайте розділ [Підручник — Посібник користувача](../tutorial/index.md){.internal-link target=_blank} главу за главою.
+
+///
diff --git a/docs/uk/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md b/docs/uk/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
new file mode 100644
index 0000000000..f7068f2df6
--- /dev/null
+++ b/docs/uk/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
@@ -0,0 +1,135 @@
+# Міграція з Pydantic v1 на Pydantic v2 { #migrate-from-pydantic-v1-to-pydantic-v2 }
+
+Якщо у вас старий застосунок FastAPI, можливо, ви використовуєте Pydantic версії 1.
+
+FastAPI версії 0.100.0 підтримував або Pydantic v1, або v2. Він використовував ту версію, яку ви встановили.
+
+FastAPI версії 0.119.0 представив часткову підтримку Pydantic v1 усередині Pydantic v2 (як `pydantic.v1`), щоб полегшити міграцію на v2.
+
+FastAPI 0.126.0 припинив підтримку Pydantic v1, водночас ще деякий час підтримуючи `pydantic.v1`.
+
+/// warning | Попередження
+
+Команда Pydantic припинила підтримку Pydantic v1 для найновіших версій Python, починаючи з **Python 3.14**.
+
+Це також стосується `pydantic.v1`, який більше не підтримується в Python 3.14 і вище.
+
+Якщо ви хочете використовувати найновіші можливості Python, вам потрібно переконатися, що ви використовуєте Pydantic v2.
+
+///
+
+Якщо у вас старий застосунок FastAPI з Pydantic v1, тут я покажу, як мігрувати на Pydantic v2, і **можливості у FastAPI 0.119.0**, що допомагають виконати поступову міграцію.
+
+## Офіційний посібник { #official-guide }
+
+Pydantic має офіційний посібник з міграції з v1 на v2.
+
+Він також містить інформацію про те, що змінилося, як валідації тепер є коректнішими та суворішими, можливі застереження тощо.
+
+Ви можете прочитати його, щоб краще зрозуміти, що змінилося.
+
+## Тести { #tests }
+
+Переконайтеся, що у вас є [тести](../tutorial/testing.md){.internal-link target=_blank} для вашого застосунку та ви запускаєте їх у безперервній інтеграції (CI).
+
+Так ви зможете виконати оновлення й переконатися, що все й далі працює як очікується.
+
+## `bump-pydantic` { #bump-pydantic }
+
+У багатьох випадках, коли ви використовуєте звичайні моделі Pydantic без налаштувань, ви зможете автоматизувати більшість процесу міграції з Pydantic v1 на Pydantic v2.
+
+Ви можете використати `bump-pydantic` від тієї ж команди Pydantic.
+
+Цей інструмент допоможе вам автоматично змінити більшість коду, який потрібно змінити.
+
+Після цього ви можете запустити тести й перевірити, чи все працює. Якщо так — готово. 😎
+
+## Pydantic v1 у v2 { #pydantic-v1-in-v2 }
+
+Pydantic v2 включає все з Pydantic v1 як підмодуль `pydantic.v1`. Але це більше не підтримується у версіях вище Python 3.13.
+
+Це означає, що ви можете встановити найновішу версію Pydantic v2, імпортувати та використовувати старі компоненти Pydantic v1 з цього підмодуля — так, ніби у вас встановлено старий Pydantic v1.
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *}
+
+### Підтримка FastAPI для Pydantic v1 у v2 { #fastapi-support-for-pydantic-v1-in-v2 }
+
+Починаючи з FastAPI 0.119.0, також є часткова підтримка Pydantic v1 усередині Pydantic v2, щоб полегшити міграцію на v2.
+
+Тож ви могли б оновити Pydantic до найновішої версії 2, змінити імпорти, щоб використовувати підмодуль `pydantic.v1`, і в багатьох випадках це просто працюватиме.
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py hl[2,5,15] *}
+
+/// warning | Попередження
+
+Майте на увазі: оскільки команда Pydantic більше не підтримує Pydantic v1 у нових версіях Python, починаючи з Python 3.14, використання `pydantic.v1` також не підтримується в Python 3.14 і вище.
+
+///
+
+### Pydantic v1 і v2 в одному застосунку { #pydantic-v1-and-v2-on-the-same-app }
+
+Pydantic **не підтримує** модель Pydantic v2, у якій власні поля визначені як моделі Pydantic v1, або навпаки.
+
+```mermaid
+graph TB
+ subgraph "❌ Not Supported"
+ direction TB
+ subgraph V2["Pydantic v2 Model"]
+ V1Field["Pydantic v1 Model"]
+ end
+ subgraph V1["Pydantic v1 Model"]
+ V2Field["Pydantic v2 Model"]
+ end
+ end
+
+ style V2 fill:#f9fff3
+ style V1 fill:#fff6f0
+ style V1Field fill:#fff6f0
+ style V2Field fill:#f9fff3
+```
+
+...але ви можете мати розділені моделі, використовуючи Pydantic v1 і v2 в одному застосунку.
+
+```mermaid
+graph TB
+ subgraph "✅ Supported"
+ direction TB
+ subgraph V2["Pydantic v2 Model"]
+ V2Field["Pydantic v2 Model"]
+ end
+ subgraph V1["Pydantic v1 Model"]
+ V1Field["Pydantic v1 Model"]
+ end
+ end
+
+ style V2 fill:#f9fff3
+ style V1 fill:#fff6f0
+ style V1Field fill:#fff6f0
+ style V2Field fill:#f9fff3
+```
+
+У деяких випадках навіть можливо мати і моделі Pydantic v1, і v2 в одній **операції шляху** у вашому застосунку FastAPI:
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
+
+У наведеному вище прикладі вхідна модель — це модель Pydantic v1, а вихідна модель (визначена в `response_model=ItemV2`) — це модель Pydantic v2.
+
+### Параметри Pydantic v1 { #pydantic-v1-parameters }
+
+Якщо вам потрібно використовувати деякі специфічні для FastAPI інструменти для параметрів, як-от `Body`, `Query`, `Form` тощо, з моделями Pydantic v1, ви можете імпортувати їх із `fastapi.temp_pydantic_v1_params`, доки завершуєте міграцію на Pydantic v2:
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py hl[4,18] *}
+
+### Міграція поетапно { #migrate-in-steps }
+
+/// tip | Порада
+
+Спочатку спробуйте `bump-pydantic`: якщо ваші тести проходять і це працює, тоді ви завершили все однією командою. ✨
+
+///
+
+Якщо `bump-pydantic` не підходить для вашого випадку, ви можете використати підтримку одночасно моделей Pydantic v1 і v2 в одному застосунку, щоб виконувати міграцію на Pydantic v2 поступово.
+
+Спочатку ви можете оновити Pydantic до найновішої версії 2 і змінити імпорти, щоб використовувати `pydantic.v1` для всіх ваших моделей.
+
+Далі ви можете почати мігрувати ваші моделі з Pydantic v1 на v2 групами, крок за кроком. 🚶
diff --git a/docs/uk/docs/how-to/separate-openapi-schemas.md b/docs/uk/docs/how-to/separate-openapi-schemas.md
new file mode 100644
index 0000000000..9069d65b7f
--- /dev/null
+++ b/docs/uk/docs/how-to/separate-openapi-schemas.md
@@ -0,0 +1,102 @@
+# Окремі схеми OpenAPI для введення та виведення чи ні { #separate-openapi-schemas-for-input-and-output-or-not }
+
+Починаючи з виходу **Pydantic v2**, згенерований OpenAPI став трохи точнішим і **правильнішим**, ніж раніше. 😎
+
+Фактично, у деяких випадках для однієї й тієї ж моделі Pydantic в OpenAPI може бути навіть **дві JSON Schema** — для введення та для виведення — залежно від того, чи мають поля **значення за замовчуванням**.
+
+Розгляньмо, як це працює і як це змінити, якщо вам потрібно.
+
+## Моделі Pydantic для введення та виведення { #pydantic-models-for-input-and-output }
+
+Припустімо, у вас є модель Pydantic зі значеннями за замовчуванням, як-от ця:
+
+{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
+
+### Модель для введення { #model-for-input }
+
+Якщо ви використовуєте цю модель як вхідні дані, як тут:
+
+{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
+
+...тоді поле `description` **не буде обов’язковим**. Тому що воно має значення за замовчуванням `None`.
+
+### Вхідна модель у документації { #input-model-in-docs }
+
+Ви можете підтвердити це в документації: поле `description` не має **червоної зірочки**, тобто не позначене як обов’язкове:
+
+
+
+
+
+
+
+
+## Підключайте той самий router кілька разів з різними `prefix` { #include-the-same-router-multiple-times-with-different-prefix }
+
+Ви також можете викликати `.include_router()` кілька разів для *того самого* router, використовуючи різні prefix.
+
+Це може бути корисно, наприклад, щоб надавати той самий API під різними prefix, наприклад `/api/v1` і `/api/latest`.
+
+Це просунуте використання, яке вам, можливо, не знадобиться, але воно доступне, якщо потрібно.
+
+## Підключіть `APIRouter` в інший { #include-an-apirouter-in-another }
+
+Так само, як ви можете підключити `APIRouter` у застосунок `FastAPI`, ви можете підключити `APIRouter` в інший `APIRouter`, використовуючи:
+
+```Python
+router.include_router(other_router)
+```
+
+Переконайтеся, що ви зробили це перед підключенням `router` у застосунок `FastAPI`, щоб *операції шляху* з `other_router` також були включені.
diff --git a/docs/uk/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/uk/docs/tutorial/dependencies/classes-as-dependencies.md
new file mode 100644
index 0000000000..7e840e2e3b
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -0,0 +1,288 @@
+# Класи як залежності { #classes-as-dependencies }
+
+Перш ніж занурюватися глибше в систему **Dependency Injection**, покращімо попередній приклад.
+
+## `dict` з попереднього прикладу { #a-dict-from-the-previous-example }
+
+У попередньому прикладі ми повертали `dict` з нашої залежності («dependable»):
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
+
+Але потім ми отримуємо `dict` у параметрі `commons` *функції операції шляху*.
+
+І ми знаємо, що редактори не можуть надати багато підтримки (як-от автодоповнення) для `dict`, бо вони не знають його ключів і типів значень.
+
+Можна зробити краще...
+
+## Що робить щось залежністю { #what-makes-a-dependency }
+
+Досі ви бачили залежності, оголошені як функції.
+
+Але це не єдиний спосіб оголошувати залежності (хоча, ймовірно, найпоширеніший).
+
+Ключовий фактор — залежність має бути «callable».
+
+«**callable**» у Python — це будь-що, що Python може «викликати» як функцію.
+
+Тобто, якщо у вас є об’єкт `something` (який може _не_ бути функцією) і ви можете «викликати» його (виконати) так:
+
+```Python
+something()
+```
+
+або
+
+```Python
+something(some_argument, some_keyword_argument="foo")
+```
+
+то це «callable».
+
+## Класи як залежності { #classes-as-dependencies_1 }
+
+Ви могли помітити, що для створення екземпляра класу Python використовується той самий синтаксис.
+
+Наприклад:
+
+```Python
+class Cat:
+ def __init__(self, name: str):
+ self.name = name
+
+
+fluffy = Cat(name="Mr Fluffy")
+```
+
+У цьому випадку `fluffy` — екземпляр класу `Cat`.
+
+А щоб створити `fluffy`, ви «викликаєте» `Cat`.
+
+Отже, клас Python також є **callable**.
+
+Тоді у **FastAPI** ви можете використати клас Python як залежність.
+
+Насправді FastAPI перевіряє, що це «callable» (функція, клас або щось інше) і які параметри визначені.
+
+Якщо ви передасте «callable» як залежність у **FastAPI**, він проаналізує параметри цього «callable» і обробить їх так само, як параметри *функції операції шляху*. Включно з підзалежностями.
+
+Це також стосується callables взагалі без параметрів. Так само, як і для *функцій операції шляху* без параметрів.
+
+Тож ми можемо змінити залежність «dependable» `common_parameters` з прикладу вище на клас `CommonQueryParams`:
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
+
+Зверніть увагу на метод `__init__`, який використовується для створення екземпляра класу:
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[12] *}
+
+...він має ті самі параметри, що й наш попередній `common_parameters`:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8] *}
+
+Саме ці параметри **FastAPI** використає, щоб «розв’язати» залежність.
+
+В обох випадках буде:
+
+* Необов’язковий query-параметр `q`, який є `str`.
+* Query-параметр `skip`, який є `int`, зі значенням за замовчуванням `0`.
+* Query-параметр `limit`, який є `int`, зі значенням за замовчуванням `100`.
+
+В обох випадках дані буде перетворено, валідовано, задокументовано в схемі OpenAPI тощо.
+
+## Використайте це { #use-it }
+
+Тепер ви можете оголосити вашу залежність, використовуючи цей клас.
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[19] *}
+
+**FastAPI** викликає клас `CommonQueryParams`. Це створює «екземпляр» цього класу, і екземпляр буде передано як параметр `commons` у вашу функцію.
+
+## Анотація типу vs `Depends` { #type-annotation-vs-depends }
+
+Зверніть увагу, що в коді вище ми пишемо `CommonQueryParams` двічі:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+Останній `CommonQueryParams` у:
+
+```Python
+... Depends(CommonQueryParams)
+```
+
+...це те, що **FastAPI** фактично використає, щоб зрозуміти, що є залежністю.
+
+Саме з нього FastAPI витягне оголошені параметри і саме його FastAPI реально викличе.
+
+---
+
+У цьому випадку перший `CommonQueryParams` у:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, ...
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons: CommonQueryParams ...
+```
+
+////
+
+...не має жодного спеціального значення для **FastAPI**. FastAPI не використовуватиме його для перетворення даних, валідації тощо (оскільки для цього він використовує `Depends(CommonQueryParams)`).
+
+Ви фактично могли б написати просто:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[Any, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons = Depends(CommonQueryParams)
+```
+
+////
+
+...як тут:
+
+{* ../../docs_src/dependencies/tutorial003_an_py310.py hl[19] *}
+
+Але оголошувати тип заохочується, адже так ваш редактор знатиме, що буде передано як параметр `commons`, і зможе допомогти вам з автодоповненням коду, перевірками типів тощо:
+
+
+
+## Скорочення { #shortcut }
+
+Але ви бачите, що тут є повторення коду — ми пишемо `CommonQueryParams` двічі:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+**FastAPI** надає скорочення для таких випадків, коли залежність *саме* є класом, який **FastAPI** «викликає», щоб створити екземпляр цього класу.
+
+Для цих конкретних випадків ви можете зробити таке:
+
+Замість того, щоб писати:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+...ви пишете:
+
+//// tab | Python 3.9+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends()]
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу варіанту з `Annotated`.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends()
+```
+
+////
+
+Ви оголошуєте залежність як тип параметра і використовуєте `Depends()` без жодного параметра, замість того щоб писати повний клас *ще раз* всередині `Depends(CommonQueryParams)`.
+
+Тоді цей самий приклад виглядатиме так:
+
+{* ../../docs_src/dependencies/tutorial004_an_py310.py hl[19] *}
+
+...і **FastAPI** знатиме, що робити.
+
+/// tip | Порада
+
+Якщо це здається вам більш заплутаним, ніж корисним, просто ігноруйте це — вам це *не* потрібно.
+
+Це лише скорочення. Адже **FastAPI** прагне допомогти вам мінімізувати повторення коду.
+
+///
diff --git a/docs/uk/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/uk/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
new file mode 100644
index 0000000000..5bc7c3a0c1
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -0,0 +1,69 @@
+# Залежності в декораторах операцій шляху { #dependencies-in-path-operation-decorators }
+
+У деяких випадках вам насправді не потрібне значення, яке повертає залежність, всередині вашої *функції операції шляху*.
+
+Або залежність взагалі не повертає значення.
+
+Але вам усе одно потрібно, щоб її було виконано/розв’язано.
+
+Для таких випадків, замість оголошення параметра *функції операції шляху* з `Depends`, ви можете додати `list` із `dependencies` до *декоратора операції шляху*.
+
+## Додайте `dependencies` до *декоратора операції шляху* { #add-dependencies-to-the-path-operation-decorator }
+
+*Декоратор операції шляху* приймає необов’язковий аргумент `dependencies`.
+
+Він має бути `list` із `Depends()`:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
+
+Ці залежності буде виконано/розв’язано так само, як і звичайні залежності. Але їхнє значення (якщо вони щось повертають) не буде передано у вашу *функцію операції шляху*.
+
+/// tip | Порада
+
+Деякі редактори перевіряють наявність невикористаних параметрів функцій і показують їх як помилки.
+
+Використовуючи ці `dependencies` у *декораторі операції шляху*, ви можете переконатися, що їх буде виконано, уникаючи при цьому помилок редактора/інструментів.
+
+Це також може допомогти уникнути плутанини для нових розробників, які бачать невикористаний параметр у вашому коді й можуть подумати, що він зайвий.
+
+///
+
+/// info | Інформація
+
+У цьому прикладі ми використовуємо вигадані користувацькі заголовки `X-Key` і `X-Token`.
+
+Але в реальних випадках, під час реалізації безпеки, ви отримаєте більше переваг, використовуючи вбудовані [утиліти Security (наступний розділ)](../security/index.md){.internal-link target=_blank}.
+
+///
+
+## Помилки залежностей і значення, що повертаються { #dependencies-errors-and-return-values }
+
+Ви можете використовувати ті самі *функції* залежностей, які зазвичай використовуєте.
+
+### Вимоги залежності { #dependency-requirements }
+
+Вони можуть оголошувати вимоги до запиту (наприклад, заголовки) або інші підзалежності:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
+
+### Підіймання винятків { #raise-exceptions }
+
+Ці залежності можуть `raise` винятки так само, як і звичайні залежності:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+
+### Значення, що повертаються { #return-values }
+
+І вони можуть повертати значення або ні — ці значення не використовуватимуться.
+
+Тож ви можете повторно використати звичайну залежність (яка повертає значення), яку вже десь застосовуєте, і навіть якщо значення не буде використано, залежність буде виконано:
+
+{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+
+## Залежності для групи *операцій шляху* { #dependencies-for-a-group-of-path-operations }
+
+Пізніше, читаючи про те, як структурувати більші застосунки ([Більші застосунки — кілька файлів](../../tutorial/bigger-applications.md){.internal-link target=_blank}), можливо з кількома файлами, ви дізнаєтеся, як оголосити один параметр `dependencies` для групи *операцій шляху*.
+
+## Глобальні залежності { #global-dependencies }
+
+Далі ми побачимо, як додати залежності до всього застосунку `FastAPI`, щоб вони застосовувалися до кожної *операції шляху*.
diff --git a/docs/uk/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/uk/docs/tutorial/dependencies/dependencies-with-yield.md
new file mode 100644
index 0000000000..96e418ebe7
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -0,0 +1,290 @@
+# Залежності з `yield` { #dependencies-with-yield }
+
+FastAPI підтримує залежності, які виконують деякі додаткові кроки після завершення.
+
+Щоб зробити це, використовуйте `yield` замість `return` і напишіть додаткові кроки (код) після нього.
+
+/// tip | Порада
+
+Переконайтеся, що використовуєте `yield` лише один раз на одну залежність.
+
+///
+
+/// note | Технічні деталі
+
+Будь-яка функція, яку коректно використовувати з:
+
+* `@contextlib.contextmanager` або
+* `@contextlib.asynccontextmanager`
+
+також буде коректною як залежність **FastAPI**.
+
+Насправді FastAPI внутрішньо використовує ці два декоратори.
+
+///
+
+## Залежність бази даних з `yield` { #a-database-dependency-with-yield }
+
+Наприклад, ви можете використати це, щоб створити сесію бази даних і закрити її після завершення.
+
+Лише код до оператора `yield` включно виконується перед створенням відповіді:
+
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
+
+Значення, повернуте через `yield`, — це те, що буде інʼєктовано в *операції шляху* та інші залежності:
+
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
+
+Код після оператора `yield` виконується після відповіді:
+
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
+
+/// tip | Порада
+
+Ви можете використовувати `async` або звичайні функції.
+
+**FastAPI** коректно обробить кожен варіант — так само, як і зі звичайними залежностями.
+
+///
+
+## Залежність з `yield` і `try` { #a-dependency-with-yield-and-try }
+
+Якщо ви використовуєте блок `try` у залежності з `yield`, ви отримаєте будь-який виняток, який було згенеровано під час використання залежності.
+
+Наприклад, якщо якийсь код десь посередині, в іншій залежності або в *операції шляху*, виконав «rollback» транзакції бази даних або створив будь-який інший виняток, ви отримаєте цей виняток у вашій залежності.
+
+Тож ви можете обробити конкретний виняток усередині залежності через `except SomeException`.
+
+Так само ви можете використати `finally`, щоб переконатися, що кроки виходу буде виконано незалежно від того, був виняток чи ні.
+
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
+
+## Підзалежності з `yield` { #sub-dependencies-with-yield }
+
+Ви можете мати підзалежності та «дерева» підзалежностей будь-якого розміру й форми, і будь-яка з них (або всі) можуть використовувати `yield`.
+
+**FastAPI** подбає, щоб «exit code» у кожній залежності з `yield` виконувався в правильному порядку.
+
+Наприклад, `dependency_c` може залежати від `dependency_b`, а `dependency_b` — від `dependency_a`:
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+
+І всі вони можуть використовувати `yield`.
+
+У цьому випадку `dependency_c`, щоб виконати свій код виходу, потребує, щоб значення з `dependency_b` (тут назване `dep_b`) усе ще було доступне.
+
+А `dependency_b`, своєю чергою, потребує, щоб значення з `dependency_a` (тут назване `dep_a`) було доступне для її коду виходу.
+
+{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+
+Так само ви можете мати частину залежностей з `yield`, а інші — з `return`, і щоб деякі з них залежали від інших.
+
+Також ви можете мати одну залежність, яка потребує кілька інших залежностей з `yield`, тощо.
+
+Ви можете мати будь-які комбінації залежностей, які вам потрібні.
+
+**FastAPI** забезпечить виконання всього в правильному порядку.
+
+/// note | Технічні деталі
+
+Це працює завдяки Context Managers у Python.
+
+**FastAPI** використовує їх внутрішньо, щоб досягти цього.
+
+///
+
+## Залежності з `yield` і `HTTPException` { #dependencies-with-yield-and-httpexception }
+
+Ви бачили, що можете використовувати залежності з `yield` і мати блоки `try`, які намагаються виконати певний код, а потім запускають код виходу після `finally`.
+
+Ви також можете використовувати `except`, щоб перехопити виняток, який було згенеровано, і зробити з ним щось.
+
+Наприклад, ви можете згенерувати інший виняток, як-от `HTTPException`.
+
+/// tip | Порада
+
+Це дещо просунута техніка, і в більшості випадків вона вам насправді не знадобиться, адже ви можете піднімати винятки (включно з `HTTPException`) з решти коду вашого застосунку, наприклад у *функції операції шляху*.
+
+Але вона доступна, якщо вам це потрібно. 🤓
+
+///
+
+{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
+
+Якщо ви хочете перехоплювати винятки й створювати кастомну відповідь на їхній основі, створіть [кастомний обробник винятків](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+## Залежності з `yield` і `except` { #dependencies-with-yield-and-except }
+
+Якщо ви перехопите виняток через `except` у залежності з `yield` і не піднімете його знову (або не піднімете новий виняток), FastAPI не зможе помітити, що був виняток — так само, як це відбувається у звичайному Python:
+
+{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+
+У цьому випадку клієнт побачить відповідь *HTTP 500 Internal Server Error*, як і має бути, з огляду на те, що ми не піднімаємо `HTTPException` або подібне, але сервер **не матиме жодних логів** чи будь-яких інших вказівок на те, в чому була помилка. 😱
+
+### Завжди робіть `raise` у залежностях з `yield` і `except` { #always-raise-in-dependencies-with-yield-and-except }
+
+Якщо ви перехопили виняток у залежності з `yield`, то, якщо ви не піднімаєте інший `HTTPException` або подібний виняток, **вам слід повторно підняти початковий виняток**.
+
+Ви можете повторно підняти той самий виняток за допомогою `raise`:
+
+{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+
+Тепер клієнт отримає ту саму відповідь *HTTP 500 Internal Server Error*, але на сервері в логах буде наш кастомний `InternalError`. 😎
+
+## Виконання залежностей з `yield` { #execution-of-dependencies-with-yield }
+
+Послідовність виконання приблизно така, як на цій діаграмі. Час іде зверху вниз. А кожна колонка — це одна зі сторін, які взаємодіють або виконують код.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant handler as Exception handler
+participant dep as Dep with yield
+participant operation as Path Operation
+participant tasks as Background tasks
+
+ Note over client,operation: Can raise exceptions, including HTTPException
+ client ->> dep: Start request
+ Note over dep: Run code up to yield
+ opt raise Exception
+ dep -->> handler: Raise Exception
+ handler -->> client: HTTP error response
+ end
+ dep ->> operation: Run dependency, e.g. DB session
+ opt raise
+ operation -->> dep: Raise Exception (e.g. HTTPException)
+ opt handle
+ dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
+ end
+ handler -->> client: HTTP error response
+ end
+
+ operation ->> client: Return response to client
+ Note over client,operation: Response is already sent, can't change it anymore
+ opt Tasks
+ operation -->> tasks: Send background tasks
+ end
+ opt Raise other exception
+ tasks -->> tasks: Handle exceptions in the background task code
+ end
+```
+
+/// info | Інформація
+
+Клієнту буде надіслано лише **одну відповідь**. Це може бути одна з відповідей про помилку або відповідь від *операції шляху*.
+
+Після надсилання однієї з цих відповідей жодної іншої відповіді надіслати вже не можна.
+
+///
+
+/// tip | Порада
+
+Якщо ви піднімете будь-який виняток у коді *функції операції шляху*, його буде передано залежностям із yield, включно з `HTTPException`. У більшості випадків ви захочете повторно підняти той самий виняток або новий із залежності з `yield`, щоб забезпечити його коректну обробку.
+
+///
+
+## Ранній вихід і `scope` { #early-exit-and-scope }
+
+Зазвичай код виходу залежностей з `yield` виконується **після того**, як відповідь надіслано клієнту.
+
+Але якщо ви знаєте, що не потребуватимете залежність після повернення з *функції операції шляху*, ви можете використати `Depends(scope="function")`, щоб сказати FastAPI, що він має закрити залежність після того, як *функція операції шляху* завершиться, але **до того**, як **відповідь буде надіслано**.
+
+{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
+
+`Depends()` приймає параметр `scope`, який може бути:
+
+* `"function"`: запустити залежність перед *функцією операції шляху*, що обробляє запит, завершити залежність після завершення *функції операції шляху*, але **до того**, як відповідь буде надіслано назад клієнту. Тобто функція залежності виконуватиметься **навколо** *функції операції шляху*.
+* `"request"`: запустити залежність перед *функцією операції шляху*, що обробляє запит (подібно до `"function"`), але завершити **після того**, як відповідь буде надіслано назад клієнту. Тобто функція залежності виконуватиметься **навколо** циклу **запит-відповідь**.
+
+Якщо не вказано і залежність має `yield`, за замовчуванням вона матиме `scope="request"`.
+
+### `scope` для підзалежностей { #scope-for-sub-dependencies }
+
+Коли ви оголошуєте залежність із `scope="request"` (за замовчуванням), будь-яка підзалежність також має мати `scope="request"`.
+
+Але залежність із `scope="function"` може мати залежності як із `scope="function"`, так і з `scope="request"`.
+
+Це тому, що будь-яка залежність має мати змогу виконати свій код виходу раніше за підзалежності, адже вона може все ще потребувати їх під час виконання коду виходу.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant dep_req as Dep scope="request"
+participant dep_func as Dep scope="function"
+participant operation as Path Operation
+
+ client ->> dep_req: Start request
+ Note over dep_req: Run code up to yield
+ dep_req ->> dep_func: Pass dependency
+ Note over dep_func: Run code up to yield
+ dep_func ->> operation: Run path operation with dependency
+ operation ->> dep_func: Return from path operation
+ Note over dep_func: Run code after yield
+ Note over dep_func: ✅ Dependency closed
+ dep_func ->> client: Send response to client
+ Note over client: Response sent
+ Note over dep_req: Run code after yield
+ Note over dep_req: ✅ Dependency closed
+```
+
+## Залежності з `yield`, `HTTPException`, `except` і Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
+
+Залежності з `yield` еволюціонували з часом, щоб покрити різні сценарії використання та виправити деякі проблеми.
+
+Якщо ви хочете побачити, що змінювалося в різних версіях FastAPI, можете прочитати про це більше в розширеному посібнику: [Розширені залежності — залежності з `yield`, `HTTPException`, `except` і Background Tasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
+
+## Context Managers { #context-managers }
+
+### Що таке «Context Managers» { #what-are-context-managers }
+
+«Context Managers» — це будь-які об’єкти Python, які ви можете використовувати в операторі `with`.
+
+Наприклад, ви можете використати `with`, щоб прочитати файл:
+
+```Python
+with open("./somefile.txt") as f:
+ contents = f.read()
+ print(contents)
+```
+
+Під капотом `open("./somefile.txt")` створює об’єкт, який називають «Context Manager».
+
+Коли блок `with` завершується, він гарантує закриття файлу, навіть якщо виникали винятки.
+
+Коли ви створюєте залежність з `yield`, **FastAPI** внутрішньо створить для неї context manager і поєднає його з деякими іншими пов’язаними інструментами.
+
+### Використання context managers у залежностях з `yield` { #using-context-managers-in-dependencies-with-yield }
+
+/// warning | Попередження
+
+Це, більш-менш, «просунута» ідея.
+
+Якщо ви лише починаєте працювати з **FastAPI**, можливо, вам варто поки що її пропустити.
+
+///
+
+У Python ви можете створювати Context Managers, створивши клас із двома методами: `__enter__()` і `__exit__()`.
+
+Ви також можете використовувати їх усередині залежностей **FastAPI** з `yield`, застосовуючи оператори
+`with` або `async with` усередині функції залежності:
+
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
+
+/// tip | Порада
+
+Інший спосіб створити context manager — це:
+
+* `@contextlib.contextmanager` або
+* `@contextlib.asynccontextmanager`
+
+використати їх як декоратори для функції з одним `yield`.
+
+Саме так **FastAPI** внутрішньо працює із залежностями з `yield`.
+
+Але вам не потрібно використовувати ці декоратори для залежностей FastAPI (і не слід).
+
+FastAPI зробить це за вас внутрішньо.
+
+///
diff --git a/docs/uk/docs/tutorial/dependencies/global-dependencies.md b/docs/uk/docs/tutorial/dependencies/global-dependencies.md
new file mode 100644
index 0000000000..c11dc0f3d6
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/global-dependencies.md
@@ -0,0 +1,16 @@
+# Глобальні залежності { #global-dependencies }
+
+Для деяких типів застосунків ви можете захотіти додати залежності для всього застосунку.
+
+Подібно до того, як ви можете [додати `dependencies` до *декораторів операцій шляху*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, ви можете додати їх і до застосунку `FastAPI`.
+
+У такому разі вони будуть застосовані до всіх *операцій шляху* в застосунку:
+
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
+
+
+І всі ідеї з розділу про [додавання `dependencies` до *декораторів операцій шляху*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} усе ще застосовні, але в цьому випадку — до всіх *операцій шляху* в застосунку.
+
+## Залежності для груп *операцій шляху* { #dependencies-for-groups-of-path-operations }
+
+Пізніше, читаючи про те, як структурувати більші застосунки ([Більші застосунки — кілька файлів](../../tutorial/bigger-applications.md){.internal-link target=_blank}), можливо з кількома файлами, ви дізнаєтеся, як оголосити один параметр `dependencies` для групи *операцій шляху*.
diff --git a/docs/uk/docs/tutorial/dependencies/index.md b/docs/uk/docs/tutorial/dependencies/index.md
new file mode 100644
index 0000000000..dc08f477ab
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/index.md
@@ -0,0 +1,250 @@
+# Залежності { #dependencies }
+
+**FastAPI** має дуже потужну, але інтуїтивну систему **Dependency Injection**.
+
+Її спроєктовано так, щоб вона була дуже простою у використанні та щоб будь-якому розробнику було дуже легко інтегрувати інші компоненти з **FastAPI**.
+
+## Що таке «Dependency Injection» { #what-is-dependency-injection }
+
+**«Dependency Injection»** у програмуванні означає, що є спосіб, за допомогою якого ваш код (у цьому випадку ваші *функції операції шляху*) може оголошувати речі, які йому потрібні для роботи та використання: «dependencies».
+
+А потім ця система (у цьому випадку **FastAPI**) подбає про все необхідне, щоб надати вашому коду потрібні залежності (тобто «інʼєктувати» залежності).
+
+Це дуже корисно, коли вам потрібно:
+
+* Мати спільну логіку (одна й та сама логіка коду знову і знову).
+* Спільно використовувати підключення до бази даних.
+* Забезпечувати безпеку, автентифікацію, вимоги ролей тощо.
+* І багато інших речей...
+
+Усе це — мінімізуючи повторення коду.
+
+## Перші кроки { #first-steps }
+
+Розгляньмо дуже простий приклад. Наразі він буде настільки простим, що не надто корисним.
+
+Але так ми зможемо зосередитися на тому, як працює система **Dependency Injection**.
+
+### Створіть залежність, або «dependable» { #create-a-dependency-or-dependable }
+
+Спочатку зосередьмося на залежності.
+
+Це просто функція, яка може приймати всі ті самі параметри, що й *функція операції шляху*:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
+
+От і все.
+
+**2 рядки**.
+
+І вона має ту саму форму та структуру, що й усі ваші *функції операції шляху*.
+
+Ви можете думати про неї як про *функцію операції шляху* без «декоратора» (без `@app.get("/some-path")`).
+
+І вона може повертати будь-що, що ви захочете.
+
+У цьому випадку ця залежність очікує:
+
+* Необов’язковий query-параметр `q`, який є `str`.
+* Необов’язковий query-параметр `skip`, який є `int`, і за замовчуванням дорівнює `0`.
+* Необов’язковий query-параметр `limit`, який є `int`, і за замовчуванням дорівнює `100`.
+
+А потім вона просто повертає `dict`, що містить ці значення.
+
+/// info | Інформація
+
+FastAPI додав підтримку `Annotated` (і почав рекомендувати її) у версії 0.95.0.
+
+Якщо у вас старіша версія, ви отримаєте помилки під час спроби використати `Annotated`.
+
+Переконайтеся, що ви [оновили версію FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} щонайменше до 0.95.1, перш ніж використовувати `Annotated`.
+
+///
+
+### Імпортуйте `Depends` { #import-depends }
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
+
+### Оголосіть залежність у «dependant» { #declare-the-dependency-in-the-dependant }
+
+Так само, як ви використовуєте `Body`, `Query` тощо з параметрами вашої *функції операції шляху*, використовуйте `Depends` з новим параметром:
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
+
+Хоча ви використовуєте `Depends` у параметрах вашої функції так само, як `Body`, `Query` тощо, `Depends` працює трохи інакше.
+
+Ви передаєте в `Depends` лише один параметр.
+
+Цей параметр має бути чимось на кшталт функції.
+
+Ви **не викликаєте її** напряму (не додаєте круглі дужки в кінці), ви просто передаєте її як параметр у `Depends()`.
+
+І ця функція приймає параметри так само, як *функції операції шляху*.
+
+/// tip | Порада
+
+У наступному розділі ви побачите, які ще «речі», окрім функцій, можна використовувати як залежності.
+
+///
+
+Щоразу, коли надходить новий запит, **FastAPI** подбає про:
+
+* Виклик вашої функції залежності («dependable») з правильними параметрами.
+* Отримання результату з вашої функції.
+* Присвоєння цього результату параметру у вашій *функції операції шляху*.
+
+```mermaid
+graph TB
+
+common_parameters(["common_parameters"])
+read_items["/items/"]
+read_users["/users/"]
+
+common_parameters --> read_items
+common_parameters --> read_users
+```
+
+Таким чином ви пишете спільний код один раз, а **FastAPI** подбає про його виклик для ваших *операцій шляху*.
+
+/// check
+
+Зверніть увагу, що вам не потрібно створювати спеціальний клас і передавати його кудись у **FastAPI**, щоб «зареєструвати» його чи зробити щось подібне.
+
+Ви просто передаєте його в `Depends`, і **FastAPI** знає, як зробити все інше.
+
+///
+
+## Спільне використання залежностей `Annotated` { #share-annotated-dependencies }
+
+У прикладах вище ви бачите, що є маленька частка **дублювання коду**.
+
+Коли вам потрібно використати залежність `common_parameters()`, вам треба написати весь параметр із type annotation та `Depends()`:
+
+```Python
+commons: Annotated[dict, Depends(common_parameters)]
+```
+
+Але оскільки ми використовуємо `Annotated`, ми можемо зберегти це значення `Annotated` у змінній і використати його в кількох місцях:
+
+{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
+
+/// tip | Порада
+
+Це просто стандартний Python — це називається «type alias» і насправді не є чимось специфічним для **FastAPI**.
+
+Але оскільки **FastAPI** базується на стандартах Python, зокрема на `Annotated`, ви можете використати цей прийом у своєму коді. 😎
+
+///
+
+Залежності й надалі працюватимуть як очікується, а **найкраща частина** в тому, що **інформація про типи буде збережена**, тобто ваш редактор зможе й надалі надавати **автодоповнення**, **inline-помилки** тощо. Те саме стосується й інших інструментів, як-от `mypy`.
+
+Це буде особливо корисно, коли ви використовуєте це у **великій кодовій базі**, де ви використовуєте **ті самі залежності** знову і знову в **багатьох *операціях шляху***.
+
+## `async` чи не `async` { #to-async-or-not-to-async }
+
+Оскільки залежності також будуть викликатися **FastAPI** (так само, як і ваші *функції операції шляху*), під час визначення ваших функцій діють ті самі правила.
+
+Ви можете використовувати `async def` або звичайний `def`.
+
+І ви можете оголошувати залежності з `async def` всередині звичайних `def` *функцій операції шляху*, або залежності з `def` всередині `async def` *функцій операції шляху* тощо.
+
+Це не має значення. **FastAPI** знатиме, що робити.
+
+/// note | Примітка
+
+Якщо ви не знаєте, перегляньте розділ [Async: *«Поспішаєте?»*](../../async.md#in-a-hurry){.internal-link target=_blank} про `async` і `await` у документації.
+
+///
+
+## Інтеграція з OpenAPI { #integrated-with-openapi }
+
+Усі оголошення запитів, валідації та вимоги ваших залежностей (і підзалежностей) будуть інтегровані в ту саму схему OpenAPI.
+
+Отже, інтерактивна документація також матиме всю інформацію з цих залежностей:
+
+
+
+## Просте використання { #simple-usage }
+
+Якщо придивитися, *функції операції шляху* оголошуються для використання щоразу, коли збігаються *шлях* і *операція*, а потім **FastAPI** подбає про виклик функції з правильними параметрами, витягуючи дані із запиту.
+
+Насправді всі (або більшість) вебфреймворків працюють так само.
+
+Ви ніколи не викликаєте ці функції напряму. Їх викликає ваш фреймворк (у цьому випадку **FastAPI**).
+
+Із системою Dependency Injection ви також можете сказати **FastAPI**, що ваша *функція операції шляху* також «залежить» від чогось іншого, що має бути виконано перед вашою *функцією операції шляху*, і **FastAPI** подбає про виконання цього та «інʼєкцію» результатів.
+
+Інші поширені терміни для цієї самої ідеї «dependency injection»:
+
+* resources
+* providers
+* services
+* injectables
+* components
+
+## Плагіни **FastAPI** { #fastapi-plug-ins }
+
+Інтеграції та «plug-ins» можна будувати за допомогою системи **Dependency Injection**. Але насправді **немає потреби створювати «plug-ins»**, адже, використовуючи залежності, можна оголосити нескінченну кількість інтеграцій і взаємодій, які стануть доступними вашим *функціям операції шляху*.
+
+А залежності можна створювати дуже просто й інтуїтивно, так що ви можете просто імпортувати потрібні пакети Python і інтегрувати їх з вашими API-функціями буквально в кілька рядків коду.
+
+Приклади цього ви побачите в наступних розділах — про реляційні та NoSQL бази даних, безпеку тощо.
+
+## Сумісність **FastAPI** { #fastapi-compatibility }
+
+Простота системи dependency injection робить **FastAPI** сумісним з:
+
+* усіма реляційними базами даних
+* NoSQL базами даних
+* зовнішніми пакетами
+* зовнішніми API
+* системами автентифікації та авторизації
+* системами моніторингу використання API
+* системами інʼєкції даних відповіді
+* тощо.
+
+## Простота та потужність { #simple-and-powerful }
+
+Хоча ієрархічна система dependency injection дуже проста в оголошенні та використанні, вона все одно дуже потужна.
+
+Ви можете визначати залежності, які своєю чергою можуть визначати власні залежності.
+
+Зрештою будується ієрархічне дерево залежностей, і система **Dependency Injection** подбає про розв’язання всіх цих залежностей для вас (і їхніх підзалежностей) та про надання (інʼєкцію) результатів на кожному кроці.
+
+Наприклад, скажімо, у вас є 4 API endpoint-и (*операції шляху*):
+
+* `/items/public/`
+* `/items/private/`
+* `/users/{user_id}/activate`
+* `/items/pro/`
+
+тоді ви могли б додати різні вимоги щодо дозволів для кожного з них лише за допомогою залежностей і підзалежностей:
+
+```mermaid
+graph TB
+
+current_user(["current_user"])
+active_user(["active_user"])
+admin_user(["admin_user"])
+paying_user(["paying_user"])
+
+public["/items/public/"]
+private["/items/private/"]
+activate_user["/users/{user_id}/activate"]
+pro_items["/items/pro/"]
+
+current_user --> active_user
+active_user --> admin_user
+active_user --> paying_user
+
+current_user --> public
+active_user --> private
+admin_user --> activate_user
+paying_user --> pro_items
+```
+
+## Інтеграція з **OpenAPI** { #integrated-with-openapi_1 }
+
+Усі ці залежності, оголошуючи свої вимоги, також додають параметри, валідації тощо до ваших *операцій шляху*.
+
+**FastAPI** подбає про додавання всього цього до схеми OpenAPI, щоб це відображалося в інтерактивних системах документації.
diff --git a/docs/uk/docs/tutorial/dependencies/sub-dependencies.md b/docs/uk/docs/tutorial/dependencies/sub-dependencies.md
new file mode 100644
index 0000000000..fe7f74d3e3
--- /dev/null
+++ b/docs/uk/docs/tutorial/dependencies/sub-dependencies.md
@@ -0,0 +1,105 @@
+# Підзалежності { #sub-dependencies }
+
+Ви можете створювати залежності, які мають **підзалежності**.
+
+Вони можуть бути настільки **глибокими**, наскільки вам потрібно.
+
+**FastAPI** подбає про їх розв’язання.
+
+## Перша залежність «dependable» { #first-dependency-dependable }
+
+Ви можете створити першу залежність («dependable») так:
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
+
+Вона оголошує необов’язковий query-параметр `q` як `str`, а потім просто повертає його.
+
+Це доволі просто (не надто корисно), але допоможе нам зосередитися на тому, як працюють підзалежності.
+
+## Друга залежність, «dependable» і «dependant» { #second-dependency-dependable-and-dependant }
+
+Далі ви можете створити іншу функцію залежності (тобто «dependable»), яка водночас оголошує власну залежність (тобто також є «dependant»):
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
+
+Зосередьмося на оголошених параметрах:
+
+* Хоча ця функція сама є залежністю («dependable»), вона також оголошує іншу залежність (вона «depends» від чогось іншого).
+ * Вона залежить від `query_extractor` і присвоює значення, повернене ним, параметру `q`.
+* Вона також оголошує необов’язковий cookie `last_query` як `str`.
+ * Якщо користувач не надав жодного query `q`, ми використовуємо останній використаний запит, який раніше зберегли в cookie.
+
+## Використання залежності { #use-the-dependency }
+
+Тоді ми можемо використати залежність так:
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
+
+/// info | Інформація
+
+Зверніть увагу, що ми оголошуємо лише одну залежність у *функції операції шляху* — `query_or_cookie_extractor`.
+
+Але **FastAPI** знатиме, що спочатку потрібно розв’язати `query_extractor`, щоб передати його результат у `query_or_cookie_extractor` під час виклику.
+
+///
+
+```mermaid
+graph TB
+
+query_extractor(["query_extractor"])
+query_or_cookie_extractor(["query_or_cookie_extractor"])
+
+read_query["/items/"]
+
+query_extractor --> query_or_cookie_extractor --> read_query
+```
+
+## Використання однієї залежності кілька разів { #using-the-same-dependency-multiple-times }
+
+Якщо одну з ваших залежностей оголошено кілька разів для тієї самої *операції шляху* (наприклад, кілька залежностей мають спільну підзалежність), **FastAPI** знатиме, що цю підзалежність потрібно викликати лише один раз на запит.
+
+І він збереже повернене значення в «cache» та передасть його всім «dependants», яким воно потрібно в межах цього запиту, замість виклику залежності кілька разів для одного й того самого запиту.
+
+У просунутому сценарії, коли ви знаєте, що залежність має викликатися на кожному кроці (можливо, кілька разів) у межах одного запиту, замість використання «cached» значення, ви можете встановити параметр `use_cache=False` під час використання `Depends`:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+//// tab | Python 3.9+ без Annotated
+
+/// tip | Порада
+
+За можливості надавайте перевагу версії з `Annotated`.
+
+///
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+## Підсумок { #recap }
+
+Окрім усіх «модних» слів, використаних тут, система **Dependency Injection** доволі проста.
+
+Це просто функції, що виглядають так само, як і *функції операцій шляху*.
+
+Але водночас вона дуже потужна й дозволяє оголошувати довільно глибоко вкладені «графи» залежностей (дерева).
+
+/// tip | Порада
+
+Може здаватися, що з цими простими прикладами все це не надто корисно.
+
+Але ви побачите, наскільки це корисно, у розділах про **security**.
+
+І також побачите, скільки коду це вам зекономить.
+
+///
diff --git a/docs/uk/docs/tutorial/extra-models.md b/docs/uk/docs/tutorial/extra-models.md
new file mode 100644
index 0000000000..1a41612aa3
--- /dev/null
+++ b/docs/uk/docs/tutorial/extra-models.md
@@ -0,0 +1,211 @@
+# Додаткові моделі { #extra-models }
+
+Продовжуючи попередній приклад, зазвичай буде потрібно мати більше ніж одну пов’язану модель.
+
+Особливо це стосується моделей користувача, тому що:
+
+* **Вхідна модель** має мати можливість містити пароль.
+* **Вихідна модель** не повинна містити пароль.
+* **Модель бази даних** імовірно має містити хешований пароль.
+
+/// danger | Обережно
+
+Ніколи не зберігайте пароль користувача у відкритому вигляді. Завжди зберігайте «безпечний хеш», який потім можна перевірити.
+
+Якщо ви не знаєте, що таке «хеш пароля», ви дізнаєтесь про це в [розділах про безпеку](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+
+///
+
+## Кілька моделей { #multiple-models }
+
+Ось загальна ідея того, як можуть виглядати моделі з їхніми полями пароля та місцями, де вони використовуються:
+
+{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
+
+### Про `**user_in.model_dump()` { #about-user-in-model-dump }
+
+#### `.model_dump()` у Pydantic { #pydantics-model-dump }
+
+`user_in` — це Pydantic-модель класу `UserIn`.
+
+Pydantic-моделі мають метод `.model_dump()`, який повертає `dict` з даними моделі.
+
+Отже, якщо ми створимо Pydantic-об’єкт `user_in`, як:
+
+```Python
+user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
+```
+
+а потім викличемо:
+
+```Python
+user_dict = user_in.model_dump()
+```
+
+то отримаємо `dict` з даними у змінній `user_dict` (це `dict`, а не об’єкт Pydantic-моделі).
+
+І якщо викликати:
+
+```Python
+print(user_dict)
+```
+
+ми отримаємо Python `dict` із:
+
+```Python
+{
+ 'username': 'john',
+ 'password': 'secret',
+ 'email': 'john.doe@example.com',
+ 'full_name': None,
+}
+```
+
+#### Розпакування `dict` { #unpacking-a-dict }
+
+Якщо взяти `dict`, як-от `user_dict`, і передати його у функцію (або клас) через `**user_dict`, Python «розпакує» його. Він передасть ключі й значення `user_dict` безпосередньо як іменовані аргументи ключ-значення.
+
+Отже, продовжуючи з `user_dict` вище, запис:
+
+```Python
+UserInDB(**user_dict)
+```
+
+дасть результат, еквівалентний:
+
+```Python
+UserInDB(
+ username="john",
+ password="secret",
+ email="john.doe@example.com",
+ full_name=None,
+)
+```
+
+Або, точніше, використовуючи `user_dict` напряму з будь-яким вмістом, який він може мати в майбутньому:
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ password = user_dict["password"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+)
+```
+
+#### Pydantic-модель із вмісту іншої { #a-pydantic-model-from-the-contents-of-another }
+
+Як у прикладі вище, ми отримали `user_dict` з `user_in.model_dump()`, цей код:
+
+```Python
+user_dict = user_in.model_dump()
+UserInDB(**user_dict)
+```
+
+буде еквівалентним:
+
+```Python
+UserInDB(**user_in.model_dump())
+```
+
+...тому що `user_in.model_dump()` — це `dict`, а потім ми змушуємо Python «розпакувати» його, передаючи в `UserInDB` з префіксом `**`.
+
+Таким чином, ми отримуємо Pydantic-модель з даних іншої Pydantic-моделі.
+
+#### Розпакування `dict` і додаткові ключові слова { #unpacking-a-dict-and-extra-keywords }
+
+А потім, додаючи додатковий іменований аргумент `hashed_password=hashed_password`, як у:
+
+```Python
+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,
+)
+```
+
+/// warning | Попередження
+
+Допоміжні додаткові функції `fake_password_hasher` і `fake_save_user` потрібні лише для демонстрації можливого потоку даних, але, звісно, не забезпечують жодної реальної безпеки.
+
+///
+
+## Зменшення дублювання { #reduce-duplication }
+
+Зменшення дублювання коду — одна з ключових ідей **FastAPI**.
+
+Адже дублювання коду збільшує ймовірність багів, проблем безпеки, розсинхронізації коду (коли ви оновлюєте в одному місці, але не в інших) тощо.
+
+І всі ці моделі мають багато спільних даних та дублюють назви атрибутів і типи.
+
+Можна зробити краще.
+
+Ми можемо оголосити модель `UserBase`, що слугуватиме базою для інших моделей. А потім створити підкласи цієї моделі, які успадковуватимуть її атрибути (оголошення типів, валідацію тощо).
+
+Усі перетворення даних, валідація, документація тощо й надалі працюватимуть як зазвичай.
+
+Таким чином, ми зможемо оголошувати лише відмінності між моделями (з відкритим `password`, з `hashed_password` і без пароля):
+
+{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
+
+## `Union` або `anyOf` { #union-or-anyof }
+
+Ви можете оголосити відповідь як `Union` з двох або більше типів, тобто відповідь може бути будь-яким із них.
+
+У OpenAPI це буде визначено як `anyOf`.
+
+Для цього використовуйте стандартну підказку типів Python `typing.Union`:
+
+/// note | Примітка
+
+Під час визначення `Union` спочатку вказуйте найбільш специфічний тип, а потім менш специфічний. У прикладі нижче більш специфічний `PlaneItem` іде перед `CarItem` у `Union[PlaneItem, CarItem]`.
+
+///
+
+{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
+
+### `Union` у Python 3.10 { #union-in-python-3-10 }
+
+У цьому прикладі ми передаємо `Union[PlaneItem, CarItem]` як значення аргументу `response_model`.
+
+Оскільки ми передаємо це як **значення аргументу**, а не розміщуємо у **типовій анотації**, нам потрібно використовувати `Union` навіть у Python 3.10.
+
+Якби це було в типовій анотації, ми могли б використати вертикальну риску:
+
+```Python
+some_variable: PlaneItem | CarItem
+```
+
+Але якщо записати це в присвоєнні `response_model=PlaneItem | CarItem`, ми отримаємо помилку, тому що Python спробує виконати **некоректну операцію** між `PlaneItem` і `CarItem`, замість того щоб інтерпретувати це як типову анотацію.
+
+## Список моделей { #list-of-models }
+
+Так само ви можете оголошувати відповіді як списки об’єктів.
+
+Для цього використовуйте стандартний Python `typing.List` (або просто `list` у Python 3.9 і вище):
+
+{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
+
+## Відповідь із довільним `dict` { #response-with-arbitrary-dict }
+
+Ви також можете оголосити відповідь, використовуючи звичайний довільний `dict`, вказавши лише тип ключів і значень, без використання Pydantic-моделі.
+
+Це корисно, якщо ви заздалегідь не знаєте коректні назви полів/атрибутів (які були б потрібні для Pydantic-моделі).
+
+У цьому випадку можна використати `typing.Dict` (або просто `dict` у Python 3.9 і вище):
+
+{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
+
+## Підсумок { #recap }
+
+Використовуйте кілька Pydantic-моделей і вільно застосовуйте успадкування для кожного випадку.
+
+Вам не потрібно мати одну-єдину модель даних на сутність, якщо ця сутність може мати різні «стани». Як у випадку з «сутністю» користувача зі станом, що включає `password`, `password_hash` і без пароля.
diff --git a/docs/uk/docs/tutorial/path-operation-configuration.md b/docs/uk/docs/tutorial/path-operation-configuration.md
new file mode 100644
index 0000000000..e38e9cec28
--- /dev/null
+++ b/docs/uk/docs/tutorial/path-operation-configuration.md
@@ -0,0 +1,107 @@
+# Налаштування операції шляху { #path-operation-configuration }
+
+Є кілька параметрів, які ви можете передати вашому *декоратору операції шляху*, щоб налаштувати його.
+
+/// warning | Попередження
+
+Зверніть увагу, що ці параметри передаються безпосередньо *декоратору операції шляху*, а не вашій *функції операції шляху*.
+
+///
+
+## Код статусу відповіді { #response-status-code }
+
+Ви можете визначити (HTTP) `status_code`, який буде використано у відповіді вашої *операції шляху*.
+
+Ви можете передати безпосередньо код `int`, наприклад `404`.
+
+Але якщо ви не пам’ятаєте, для чого призначений кожен числовий код, можете використати скорочені константи в `status`:
+
+{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
+
+Цей код статусу буде використано у відповіді та додано до схеми OpenAPI.
+
+/// note | Технічні деталі
+
+Ви також можете використати `from starlette import status`.
+
+**FastAPI** надає той самий `starlette.status` як `fastapi.status` просто для зручності для вас, розробника. Але він надходить безпосередньо зі Starlette.
+
+///
+
+## Теги { #tags }
+
+Ви можете додати теги до вашої *операції шляху*: передайте параметр `tags` зі значенням `list` із `str` (зазвичай лише один `str`):
+
+{* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *}
+
+Їх буде додано до схеми OpenAPI та використано інтерфейсами автоматичної документації:
+
+
+
+### Теги з Enum { #tags-with-enums }
+
+Якщо у вас великий застосунок, у вас може накопичитися **кілька тегів**, і ви захочете переконатися, що завжди використовуєте **той самий тег** для пов’язаних *операцій шляху*.
+
+У таких випадках може мати сенс зберігати теги в `Enum`.
+
+**FastAPI** підтримує це так само, як і зі звичайними рядками:
+
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
+
+## Підсумок і опис { #summary-and-description }
+
+Ви можете додати `summary` і `description`:
+
+{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *}
+
+## Опис із docstring { #description-from-docstring }
+
+Оскільки описи зазвичай довгі та займають кілька рядків, ви можете оголосити опис *операції шляху* у docstring функції, і **FastAPI** прочитає його звідти.
+
+Ви можете писати Markdown у docstring — його буде інтерпретовано та правильно показано (з урахуванням відступів docstring).
+
+{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
+
+Це буде використано в інтерактивній документації:
+
+
+
+## Опис відповіді { #response-description }
+
+Ви можете вказати опис відповіді за допомогою параметра `response_description`:
+
+{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *}
+
+/// info | Інформація
+
+Зверніть увагу, що `response_description` стосується конкретно відповіді, а `description` — *операції шляху* загалом.
+
+///
+
+/// check
+
+OpenAPI визначає, що кожна *операція шляху* потребує опису відповіді.
+
+Тож якщо ви його не надасте, **FastAPI** автоматично згенерує «Successful response».
+
+///
+
+
+
+## Позначення *операції шляху* як застарілої { #deprecate-a-path-operation }
+
+Якщо вам потрібно позначити *операцію шляху* як deprecated, але без її видалення, передайте параметр `deprecated`:
+
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
+
+В інтерактивній документації її буде чітко позначено як застарілу:
+
+
+
+Перевірте, як виглядають застарілі й не застарілі *операції шляху*:
+
+
+
+## Підсумок { #recap }
+
+Ви можете легко налаштовувати та додавати метадані для ваших *операцій шляху*, передаючи параметри *декораторам операцій шляху*.
diff --git a/docs/uk/docs/tutorial/security/first-steps.md b/docs/uk/docs/tutorial/security/first-steps.md
new file mode 100644
index 0000000000..442bde86bf
--- /dev/null
+++ b/docs/uk/docs/tutorial/security/first-steps.md
@@ -0,0 +1,203 @@
+# Безпека — перші кроки { #security-first-steps }
+
+Уявімо, що у вас є **backend** API в якомусь домені.
+
+І у вас є **frontend** в іншому домені або в іншому шляху того самого домену (або в мобільному застосунку).
+
+І ви хочете мати спосіб, щоб frontend міг автентифікуватися з backend, використовуючи **username** і **password**.
+
+Ми можемо використати **OAuth2**, щоб реалізувати це з **FastAPI**.
+
+Але давайте заощадимо вам час на читання повної довгої специфікації лише для того, щоб знайти ті невеликі фрагменти інформації, які вам потрібні.
+
+Скористаймося інструментами, які надає **FastAPI**, щоб обробляти безпеку.
+
+## Як це виглядає { #how-it-looks }
+
+Спочатку просто використаймо код і подивімося, як він працює, а потім повернемося, щоб зрозуміти, що відбувається.
+
+## Створіть `main.py` { #create-main-py }
+
+Скопіюйте приклад у файл `main.py`:
+
+{* ../../docs_src/security/tutorial001_an_py39.py *}
+
+## Запустіть { #run-it }
+
+/// info | Інформація
+
+Пакет `python-multipart` автоматично встановлюється разом із **FastAPI**, коли ви виконуєте команду `pip install "fastapi[standard]"`.
+
+Однак, якщо ви використовуєте команду `pip install fastapi`, пакет `python-multipart` типово не включається.
+
+Щоб встановити його вручну, переконайтеся, що ви створили [віртуальне середовище](../../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановіть пакет командою:
+
+```console
+$ pip install python-multipart
+```
+
+Це тому, що **OAuth2** використовує «form data» для надсилання `username` і `password`.
+
+///
+
+Запустіть приклад командою:
+
+
+
+/// check | Кнопка Authorize
+
+У вас уже є блискуча нова кнопка «Authorize».
+
+І ваша *операція шляху* має маленький замок у правому верхньому куті, на який можна натиснути.
+
+///
+
+А якщо ви натиснете її, ви побачите невелику форму авторизації, де можна ввести `username` і `password` (та інші необов’язкові поля):
+
+
+
+/// note | Примітка
+
+Неважливо, що ви введете у формі — наразі це ще не працюватиме. Але ми до цього дійдемо.
+
+///
+
+Звісно, це не frontend для кінцевих користувачів, але це чудовий автоматичний інструмент, щоб інтерактивно документувати весь ваш API.
+
+Ним може користуватися команда frontend (це також можете бути ви самі).
+
+Ним можуть користуватися сторонні застосунки та системи.
+
+І ним також можете користуватися ви самі, щоб налагоджувати, перевіряти й тестувати той самий застосунок.
+
+## Flow `password` { #the-password-flow }
+
+Тепер повернімося трохи назад і розберімося, що це все таке.
+
+«Flow» `password` — це один зі способів («flows»), визначених в OAuth2, для обробки безпеки та автентифікації.
+
+OAuth2 спроєктовано так, щоб backend або API могли бути незалежними від сервера, який автентифікує користувача.
+
+Але в цьому випадку той самий застосунок **FastAPI** оброблятиме і API, і автентифікацію.
+
+Тож розгляньмо це з такого спрощеного погляду:
+
+* Користувач вводить `username` і `password` у frontend та натискає `Enter`.
+* Frontend (що працює в браузері користувача) надсилає ці `username` і `password` на конкретний URL у нашому API (оголошений як `tokenUrl="token"`).
+* API перевіряє `username` і `password` та відповідає «token» (ми ще нічого з цього не реалізували).
+ * «Token» — це просто рядок з певним вмістом, який ми зможемо використати пізніше, щоб перевірити цього користувача.
+ * Зазвичай token налаштовано так, щоб він ставав недійсним після певного часу.
+ * Тож користувачу доведеться знову увійти через деякий час.
+ * І якщо token буде вкрадено, ризик менший. Це не як постійний ключ, який працюватиме вічно (у більшості випадків).
+* Frontend тимчасово десь зберігає token.
+* Користувач у frontend клікає, щоб перейти до іншого розділу вебзастосунку.
+* Frontend потрібно отримати ще дані з API.
+ * Але для цього конкретного endpoint потрібна автентифікація.
+ * Тож, щоб автентифікуватися з нашим API, він надсилає заголовок `Authorization` зі значенням `Bearer ` плюс token.
+ * Якщо token містить `foobar`, то вміст заголовка `Authorization` буде: `Bearer foobar`.
+
+## `OAuth2PasswordBearer` у **FastAPI** { #fastapis-oauth2passwordbearer }
+
+**FastAPI** надає кілька інструментів на різних рівнях абстракції для реалізації цих можливостей безпеки.
+
+У цьому прикладі ми використаємо **OAuth2** з flow **Password**, застосовуючи **Bearer** token. Для цього використаємо клас `OAuth2PasswordBearer`.
+
+/// info | Інформація
+
+Bearer token — не єдиний варіант.
+
+Але для нашого випадку це найкращий варіант.
+
+І він може бути найкращим для більшості випадків, якщо тільки ви не експерт з OAuth2 і точно не знаєте, чому існує інший варіант, який краще підходить вашим потребам.
+
+У такому разі **FastAPI** також надає вам інструменти, щоб це реалізувати.
+
+///
+
+Коли ми створюємо екземпляр класу `OAuth2PasswordBearer`, ми передаємо параметр `tokenUrl`. Цей параметр містить URL, який клієнт (frontend, що працює в браузері користувача) використовуватиме, щоб надіслати `username` і `password` та отримати token.
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
+
+/// tip | Порада
+
+Тут `tokenUrl="token"` посилається на відносний URL `token`, який ми ще не створили. Оскільки це відносний URL, він еквівалентний `./token`.
+
+Тому що ми використовуємо відносний URL, якщо ваш API розміщено за адресою `https://example.com/`, тоді це посилатиметься на `https://example.com/token`. Але якщо ваш API розміщено за адресою `https://example.com/api/v1/`, тоді це посилатиметься на `https://example.com/api/v1/token`.
+
+Використання відносного URL важливе, щоб ваш застосунок продовжував працювати навіть у складніших сценаріях, як-от [Behind a Proxy](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+
+///
+
+Цей параметр не створює той endpoint / *операцію шляху*, але оголошує, що URL `/token` буде тим, який клієнт має використовувати для отримання token. Ця інформація використовується в OpenAPI, а потім — в інтерактивних системах документації API.
+
+Незабаром ми також створимо реальну операцію шляху.
+
+/// info | Інформація
+
+Якщо ви дуже суворий «Pythonista», вам може не подобатися стиль імені параметра `tokenUrl` замість `token_url`.
+
+Це тому, що тут використано те саме ім’я, що й у специфікації OpenAPI. Тож якщо вам потрібно буде дослідити більше про будь-яку з цих security scheme, ви зможете просто скопіювати й вставити це, щоб знайти більше інформації.
+
+///
+
+Змінна `oauth2_scheme` — це екземпляр `OAuth2PasswordBearer`, але це також «callable».
+
+Її можна викликати так:
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+Отже, її можна використовувати з `Depends`.
+
+### Використайте це { #use-it }
+
+Тепер ви можете передати `oauth2_scheme` у залежність через `Depends`.
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+
+Ця залежність надасть `str`, який буде призначено параметру `token` *функції операції шляху*.
+
+**FastAPI** знатиме, що цю залежність можна використати для визначення «security scheme» в схемі OpenAPI (і в автоматичній документації API).
+
+/// info | Технічні деталі
+
+**FastAPI** знатиме, що може використати клас `OAuth2PasswordBearer` (оголошений у залежності) для визначення security scheme в OpenAPI, тому що він успадковується від `fastapi.security.oauth2.OAuth2`, який, своєю чергою, успадковується від `fastapi.security.base.SecurityBase`.
+
+Усі утиліти безпеки, які інтегруються з OpenAPI (і з автоматичною документацією API), успадковуються від `SecurityBase` — саме так **FastAPI** знає, як інтегрувати їх в OpenAPI.
+
+///
+
+## Що це робить { #what-it-does }
+
+Воно знайде в запиті заголовок `Authorization`, перевірить, чи має значення вигляд `Bearer ` плюс якийсь token, і поверне token як `str`.
+
+Якщо заголовка `Authorization` немає, або значення не містить token з `Bearer `, воно одразу відповість помилкою зі статус-кодом 401 (`UNAUTHORIZED`).
+
+Вам навіть не потрібно перевіряти, чи існує token, щоб повернути помилку. Ви можете бути впевнені, що якщо вашу функцію виконано, у цьому token буде `str`.
+
+Ви вже можете спробувати це в інтерактивній документації:
+
+
+
+Ми ще не перевіряємо валідність token, але це вже початок.
+
+## Підсумок { #recap }
+
+Отже, лише за 3 або 4 додаткові рядки ви вже маєте примітивну форму безпеки.
diff --git a/docs/uk/docs/tutorial/security/get-current-user.md b/docs/uk/docs/tutorial/security/get-current-user.md
new file mode 100644
index 0000000000..b1fe5d852d
--- /dev/null
+++ b/docs/uk/docs/tutorial/security/get-current-user.md
@@ -0,0 +1,105 @@
+# Отримання поточного користувача { #get-current-user }
+
+У попередньому розділі система безпеки (яка базується на системі ін’єкції залежностей) передавала *функції операції шляху* `token` як `str`:
+
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+
+Але це все ще не надто корисно.
+
+Зробімо так, щоб вона повертала нам поточного користувача.
+
+## Створення моделі користувача { #create-a-user-model }
+
+Спочатку створімо модель користувача Pydantic.
+
+Так само, як ми використовуємо Pydantic для оголошення тіл, ми можемо використовувати його будь-де:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
+
+## Створення залежності `get_current_user` { #create-a-get-current-user-dependency }
+
+Створімо залежність `get_current_user`.
+
+Пам’ятаєте, що залежності можуть мати підзалежності?
+
+`get_current_user` матиме залежність із тим самим `oauth2_scheme`, який ми створили раніше.
+
+Так само, як ми робили раніше безпосередньо в *операції шляху*, наша нова залежність `get_current_user` отримуватиме `token` як `str` із підзалежності `oauth2_scheme`:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
+
+## Отримання користувача { #get-the-user }
+
+`get_current_user` використає (фейкову) допоміжну функцію, яку ми створили; вона приймає токен як `str` і повертає нашу модель Pydantic `User`:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
+
+## Ін’єкція поточного користувача { #inject-the-current-user }
+
+Тож тепер ми можемо використати той самий `Depends` із нашим `get_current_user` в *операції шляху*:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
+
+Зверніть увагу, що ми оголошуємо тип `current_user` як модель Pydantic `User`.
+
+Це допоможе нам усередині функції завдяки автодоповненню та перевіркам типів.
+
+/// tip | Порада
+
+Можливо, ви пам’ятаєте, що тіла запитів також оголошуються за допомогою моделей Pydantic.
+
+Тут **FastAPI** не заплутається, бо ви використовуєте `Depends`.
+
+///
+
+/// check
+
+Те, як спроєктовано цю систему залежностей, дозволяє мати різні залежності (різні «dependables»), які всі повертають модель `User`.
+
+Ми не обмежені лише однією залежністю, яка може повертати цей тип даних.
+
+///
+
+## Інші моделі { #other-models }
+
+Тепер ви можете отримувати поточного користувача напряму в *функціях операцій шляху* і працювати з механізмами безпеки на рівні **Dependency Injection**, використовуючи `Depends`.
+
+І ви можете використовувати будь-яку модель або дані для вимог безпеки (у цьому випадку — модель Pydantic `User`).
+
+Але ви не обмежені використанням якоїсь конкретної моделі даних, класу чи типу.
+
+Хочете мати `id` та `email` і не мати жодного `username` у вашій моделі? Звісно. Ви можете використати ці самі інструменти.
+
+Хочете мати лише `str`? Або лише `dict`? Або напряму інстанс моделі класу бази даних? Усе працює так само.
+
+Насправді у вас немає користувачів, які входять у ваш застосунок, а є роботи, боти чи інші системи, що мають лише токен доступу? Знову ж, усе працює так само.
+
+Просто використовуйте будь-який тип моделі, будь-який клас, будь-яку базу даних, які потрібні для вашого застосунку. **FastAPI** покриває це системою ін’єкції залежностей.
+
+## Розмір коду { #code-size }
+
+Цей приклад може здатися багатослівним. Майте на увазі, що ми змішуємо безпеку, моделі даних, допоміжні функції та *операції шляху* в одному файлі.
+
+Але ось ключовий момент.
+
+Уся логіка безпеки та ін’єкції залежностей пишеться один раз.
+
+І ви можете зробити її настільки складною, наскільки захочете. І при цьому вона все одно буде написана лише один раз, в одному місці. З усією гнучкістю.
+
+Але ви можете мати тисячі endpoint’ів (*операцій шляху*), що використовують ту саму систему безпеки.
+
+І всі вони (або будь-яка їх частина, яку ви захочете) можуть скористатися повторним використанням цих залежностей або будь-яких інших залежностей, які ви створите.
+
+І всі ці тисячі *операцій шляху* можуть бути такими короткими, як 3 рядки:
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
+
+## Підсумок { #recap }
+
+Тепер ви можете отримувати поточного користувача безпосередньо у вашій *функції операції шляху*.
+
+Ми вже на пів шляху.
+
+Нам лише потрібно додати *операцію шляху*, щоб користувач/клієнт міг насправді надіслати `username` і `password`.
+
+Це буде далі.
diff --git a/docs/uk/docs/tutorial/security/oauth2-jwt.md b/docs/uk/docs/tutorial/security/oauth2-jwt.md
new file mode 100644
index 0000000000..3323e5cfd9
--- /dev/null
+++ b/docs/uk/docs/tutorial/security/oauth2-jwt.md
@@ -0,0 +1,273 @@
+# OAuth2 із паролем (і хешуванням), Bearer з JWT-токенами { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
+
+Тепер, коли в нас є весь security flow, зробімо застосунок справді безпечним, використовуючи токени JWT і безпечне хешування паролів.
+
+Цей код — те, що ви реально можете використати у своєму застосунку, зберігати хеші паролів у вашій базі даних тощо.
+
+Ми почнемо з місця, на якому зупинилися в попередньому розділі, і будемо поступово його розширювати.
+
+## Про JWT { #about-jwt }
+
+JWT означає «JSON Web Tokens».
+
+Це стандарт для кодування JSON-об’єкта в довгий щільний рядок без пробілів. Він виглядає так:
+
+```
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
+```
+
+Він не зашифрований, тож будь-хто може відновити інформацію з його вмісту.
+
+Але він підписаний. Тож коли ви отримуєте токен, який ви ж і видали, ви можете перевірити, що це справді ваш токен.
+
+Так ви можете створити токен зі строком дії, скажімо, 1 тиждень. А потім, коли користувач повертається наступного дня з токеном, ви знаєте, що він усе ще залогінений у вашій системі.
+
+Після тижня токен протермінується, і користувач не буде авторизований — доведеться знову увійти, щоб отримати новий токен. І якщо користувач (або третя сторона) спробує змінити токен, щоб змінити термін дії, ви зможете це виявити, бо підписи не збігатимуться.
+
+Якщо ви хочете погратися з JWT-токенами й подивитися, як вони працюють, перегляньте https://jwt.io.
+
+## Встановлення `PyJWT` { #install-pyjwt }
+
+Нам потрібно встановити `PyJWT`, щоб генерувати й перевіряти JWT-токени в Python.
+
+Переконайтеся, що ви створили [віртуальне середовище](../../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили `pyjwt`:
+
+
+
+Авторизуйте застосунок так само, як і раніше.
+
+Використовуючи облікові дані:
+
+Ім’я користувача: `johndoe`
+Пароль: `secret`
+
+/// check | Перевірка
+
+Зверніть увагу, що в коді ніде немає відкритого пароля "`secret`" — у нас є лише його хешована версія.
+
+///
+
+
+
+Викличте endpoint `/users/me/`, ви отримаєте відповідь:
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false
+}
+```
+
+
+
+Якщо ви відкриєте інструменти розробника, ви зможете побачити, що надіслані дані містять лише токен; пароль надсилається лише в першому запиті, щоб автентифікувати користувача й отримати access token, але не надсилається після цього:
+
+
+
+/// note | Примітка
+
+Зверніть увагу на заголовок `Authorization`, зі значенням, яке починається з `Bearer `.
+
+///
+
+## Розширене використання зі `scopes` { #advanced-usage-with-scopes }
+
+OAuth2 має поняття «scopes».
+
+Ви можете використати їх, щоб додати до JWT-токена конкретний набір дозволів.
+
+Потім ви можете надати цей токен користувачу напряму або третій стороні, щоб взаємодіяти з вашим API з певним набором обмежень.
+
+Пізніше ви дізнаєтеся, як їх використовувати та як вони інтегруються у **FastAPI**, у **Розширеному посібнику користувача**.
+
+## Підсумок { #recap }
+
+На основі того, що ви побачили до цього моменту, ви можете налаштувати безпечний застосунок **FastAPI**, використовуючи стандарти на кшталт OAuth2 і JWT.
+
+Майже в будь-якому framework робота з безпекою досить швидко стає складною темою.
+
+Багато пакетів, що значно її спрощують, змушені робити багато компромісів щодо моделі даних, бази даних і доступних можливостей. А деякі пакети, що надмірно спрощують речі, насправді мають приховані вразливості.
+
+---
+
+**FastAPI** не йде на компроміси з жодною базою даних, моделлю даних чи інструментом.
+
+Він дає вам повну гнучкість, щоб обрати те, що найкраще підходить вашому проєкту.
+
+І ви можете напряму використовувати багато добре підтримуваних і широко застосовуваних пакетів, як-от `pwdlib` і `PyJWT`, бо **FastAPI** не потребує жодних складних механізмів для інтеграції зовнішніх пакетів.
+
+Водночас він надає вам інструменти, щоб максимально спростити процес без втрати гнучкості, надійності чи безпеки.
+
+І ви можете використовувати та реалізовувати безпечні стандартні протоколи, як-от OAuth2, відносно простим способом.
+
+У **Розширеному посібнику користувача** ви можете дізнатися більше про те, як використовувати OAuth2 «scopes» для більш тонко налаштованої системи дозволів, дотримуючись цих самих стандартів. OAuth2 зі scopes — це механізм, який використовують багато великих провайдерів автентифікації, як-от Facebook, Google, GitHub, Microsoft, X (Twitter) тощо, щоб авторизувати сторонні застосунки для взаємодії з їхніми API від імені користувачів.
diff --git a/docs/uk/docs/tutorial/security/simple-oauth2.md b/docs/uk/docs/tutorial/security/simple-oauth2.md
new file mode 100644
index 0000000000..c6e07216cb
--- /dev/null
+++ b/docs/uk/docs/tutorial/security/simple-oauth2.md
@@ -0,0 +1,289 @@
+# Простий OAuth2 з Password і Bearer { #simple-oauth2-with-password-and-bearer }
+
+Тепер продовжимо з попереднього розділу й додамо відсутні частини, щоб отримати повний потік безпеки.
+
+## Отримайте `username` і `password` { #get-the-username-and-password }
+
+Ми використаємо утиліти безпеки **FastAPI**, щоб отримати `username` і `password`.
+
+OAuth2 визначає, що під час використання «password flow» (який ми використовуємо) клієнт/користувач має надіслати поля `username` і `password` як form data.
+
+І специфікація каже, що поля мають називатися саме так. Тож `user-name` або `email` не спрацюють.
+
+Але не хвилюйтеся — у frontend ви можете показувати це кінцевим користувачам як завгодно.
+
+І ваші моделі бази даних можуть використовувати будь-які інші назви, які вам потрібні.
+
+Але для *операції шляху* входу (login) нам потрібно використовувати ці назви, щоб бути сумісними зі специфікацією (і мати змогу, наприклад, використовувати інтегровану систему документації API).
+
+Специфікація також вказує, що `username` і `password` мають надсилатися як form data (тобто без JSON).
+
+### `scope` { #scope }
+
+Специфікація також каже, що клієнт може надіслати ще одне поле форми «`scope`».
+
+Назва поля форми — `scope` (в однині), але фактично це довгий рядок зі «scopes», розділеними пробілами.
+
+Кожен «scope» — це просто рядок (без пробілів).
+
+Зазвичай їх використовують, щоб оголошувати конкретні дозволи безпеки, наприклад:
+
+* `users:read` або `users:write` — поширені приклади.
+* `instagram_basic` використовується Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` використовується Google.
+
+/// info | Інформація
+
+В OAuth2 «scope» — це просто рядок, що оголошує конкретний потрібний дозвіл.
+
+Не має значення, чи містить він інші символи на кшталт `:` або чи є він URL.
+
+Ці деталі залежать від реалізації.
+
+Для OAuth2 це просто рядки.
+
+///
+
+## Код для отримання `username` і `password` { #code-to-get-the-username-and-password }
+
+Тепер використаємо утиліти, які надає **FastAPI**, щоб це обробити.
+
+### `OAuth2PasswordRequestForm` { #oauth2passwordrequestform }
+
+Спочатку імпортуйте `OAuth2PasswordRequestForm` і використайте його як залежність через `Depends` в *операції шляху* для `/token`:
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[4,78] *}
+
+`OAuth2PasswordRequestForm` — це клас-залежність, який оголошує form body з:
+
+* `username`.
+* `password`.
+* Необов’язковим полем `scope` як великим рядком, складеним із рядків, розділених пробілами.
+* Необов’язковим `grant_type`.
+
+/// tip | Порада
+
+Специфікація OAuth2 фактично *вимагає* поле `grant_type` із фіксованим значенням `password`, але `OAuth2PasswordRequestForm` цього не примушує.
+
+Якщо вам потрібно це примусово перевіряти, використайте `OAuth2PasswordRequestFormStrict` замість `OAuth2PasswordRequestForm`.
+
+///
+
+* Необов’язковим `client_id` (у нашому прикладі він не потрібен).
+* Необов’язковим `client_secret` (у нашому прикладі він не потрібен).
+
+/// info | Інформація
+
+`OAuth2PasswordRequestForm` — не спеціальний клас **FastAPI** на кшталт `OAuth2PasswordBearer`.
+
+`OAuth2PasswordBearer` дає **FastAPI** знати, що це схема безпеки. Тому її саме так додають до OpenAPI.
+
+А `OAuth2PasswordRequestForm` — це просто клас-залежність, який ви могли б написати самі, або могли б оголосити параметри `Form` напряму.
+
+Але оскільки це поширений випадок використання, **FastAPI** надає його напряму, щоб спростити роботу.
+
+///
+
+### Використайте дані форми { #use-the-form-data }
+
+/// tip | Порада
+
+Екземпляр класу-залежності `OAuth2PasswordRequestForm` не матиме атрибута `scope` з довгим рядком, розділеним пробілами; натомість він матиме атрибут `scopes` з фактичним списком рядків для кожного надісланого scope.
+
+Ми не використовуємо `scopes` у цьому прикладі, але ця функціональність доступна, якщо вам вона знадобиться.
+
+///
+
+Тепер отримайте дані користувача з (фейкової) бази даних, використовуючи `username` з поля форми.
+
+Якщо такого користувача немає, повертаємо помилку «Incorrect username or password».
+
+Для помилки ми використовуємо виняток `HTTPException`:
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[3,79:81] *}
+
+### Перевірте пароль { #check-the-password }
+
+На цьому етапі ми маємо дані користувача з нашої бази даних, але ще не перевірили пароль.
+
+Спочатку помістимо ці дані в Pydantic-модель `UserInDB`.
+
+Ніколи не зберігайте паролі у відкритому вигляді, тож ми використаємо (фейкову) систему хешування паролів.
+
+Якщо паролі не збігаються, повертаємо ту саму помилку.
+
+#### Хешування паролів { #password-hashing }
+
+«Hashing» означає: перетворення певного вмісту (у цьому випадку — пароля) на послідовність байтів (просто рядок), яка виглядає як безглуздий набір символів.
+
+Щоразу, коли ви передаєте рівно той самий вміст (рівно той самий пароль), ви отримуєте рівно той самий «набір символів».
+
+Але ви не можете перетворити цей «набір символів» назад у пароль.
+
+##### Навіщо використовувати хешування паролів { #why-use-password-hashing }
+
+Якщо вашу базу даних вкрадуть, злодій не матиме відкритих паролів ваших користувачів, лише хеші.
+
+Тож злодій не зможе спробувати використати ті самі паролі в іншій системі (оскільки багато користувачів всюди використовують один і той самий пароль, це було б небезпечно).
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[82:85] *}
+
+#### Про `**user_dict` { #about-user-dict }
+
+`UserInDB(**user_dict)` означає:
+
+*Передайте ключі та значення з `user_dict` напряму як іменовані аргументи, еквівалентно:*
+
+```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"],
+)
+```
+
+/// info | Інформація
+
+Щоб отримати повніше пояснення `**user_dict`, поверніться до [документації про **Додаткові моделі**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
+
+///
+
+## Поверніть токен { #return-the-token }
+
+Відповідь endpoint `token` має бути JSON-об’єктом.
+
+Вона має містити `token_type`. У нашому випадку, оскільки ми використовуємо токени «Bearer», тип токена має бути `bearer`.
+
+Також вона має містити `access_token` — рядок, що містить наш токен доступу.
+
+Для цього простого прикладу ми просто зробимо все повністю небезпечно і повернемо той самий `username` як токен.
+
+/// tip | Порада
+
+У наступному розділі ви побачите справді безпечну реалізацію з хешуванням паролів і токенами JWT.
+
+Але зараз зосередьмося на конкретних деталях, які нам потрібні.
+
+///
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[87] *}
+
+/// tip | Порада
+
+За специфікацією, ви повинні повертати JSON з `access_token` і `token_type`, як у цьому прикладі.
+
+Це те, що ви маєте зробити самостійно у своєму коді, і переконатися, що використовуєте саме ці ключі JSON.
+
+Це майже єдине, що вам потрібно пам’ятати й зробити правильно самостійно, щоб відповідати специфікаціям.
+
+Усе інше **FastAPI** обробляє за вас.
+
+///
+
+## Оновіть залежності { #update-the-dependencies }
+
+Тепер ми оновимо наші залежності.
+
+Ми хочемо отримувати `current_user` *лише* якщо цей користувач активний.
+
+Тож ми створюємо додаткову залежність `get_current_active_user`, яка, своєю чергою, використовує `get_current_user` як залежність.
+
+Обидві ці залежності просто повернуть HTTP-помилку, якщо користувача не існує або якщо він неактивний.
+
+Тож у нашому endpoint ми отримаємо користувача, лише якщо користувач існує, був коректно автентифікований і є активним:
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
+
+/// info | Інформація
+
+Додатковий заголовок `WWW-Authenticate` зі значенням `Bearer`, який ми тут повертаємо, також є частиною специфікації.
+
+Будь-який HTTP-код (помилки) 401 «UNAUTHORIZED» також має повертати заголовок `WWW-Authenticate`.
+
+У випадку bearer-токенів (наш випадок) значення цього заголовка має бути `Bearer`.
+
+Насправді ви можете пропустити цей додатковий заголовок, і все одно все працюватиме.
+
+Але тут його наведено, щоб відповідати специфікаціям.
+
+Також можуть існувати інструменти, які очікують і використовують його (зараз або в майбутньому), і це може бути корисно вам або вашим користувачам зараз або в майбутньому.
+
+У цьому й користь стандартів...
+
+///
+
+## Подивіться, як це працює { #see-it-in-action }
+
+Відкрийте інтерактивну документацію: http://127.0.0.1:8000/docs.
+
+### Автентифікуйтеся { #authenticate }
+
+Натисніть кнопку «Authorize».
+
+Використайте облікові дані:
+
+Користувач: `johndoe`
+
+Пароль: `secret`
+
+
+
+Після автентифікації в системі ви побачите це так:
+
+
+
+### Отримайте дані свого користувача { #get-your-own-user-data }
+
+Тепер використайте операцію `GET` зі шляхом `/users/me`.
+
+Ви отримаєте дані вашого користувача, наприклад:
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false,
+ "hashed_password": "fakehashedsecret"
+}
+```
+
+
+
+Якщо ви натиснете на іконку замка й вийдете (logout), а потім спробуєте ту саму операцію знову, ви отримаєте HTTP 401 помилку:
+
+```JSON
+{
+ "detail": "Not authenticated"
+}
+```
+
+### Неактивний користувач { #inactive-user }
+
+Тепер спробуйте з неактивним користувачем, автентифікуйтеся з:
+
+Користувач: `alice`
+
+Пароль: `secret2`
+
+І спробуйте використати операцію `GET` зі шляхом `/users/me`.
+
+Ви отримаєте помилку «Inactive user», наприклад:
+
+```JSON
+{
+ "detail": "Inactive user"
+}
+```
+
+## Підсумок { #recap }
+
+Тепер у вас є інструменти, щоб реалізувати повну систему безпеки на основі `username` і `password` для вашого API.
+
+Використовуючи ці інструменти, ви можете зробити систему безпеки сумісною з будь-якою базою даних і будь-якою моделлю користувачів або даних.
+
+Єдина відсутня деталь — вона ще не є по-справжньому «безпечною».
+
+У наступному розділі ви побачите, як використовувати безпечну бібліотеку хешування паролів і токени JWT.
diff --git a/docs/uk/docs/tutorial/sql-databases.md b/docs/uk/docs/tutorial/sql-databases.md
new file mode 100644
index 0000000000..ee353815dc
--- /dev/null
+++ b/docs/uk/docs/tutorial/sql-databases.md
@@ -0,0 +1,357 @@
+# SQL (реляційні) бази даних { #sql-relational-databases }
+
+**FastAPI** не вимагає від вас використання SQL (реляційної) бази даних. Але ви можете використовувати **будь-яку базу даних**, яку забажаєте.
+
+Тут ми розглянемо приклад із використанням SQLModel.
+
+**SQLModel** побудований поверх SQLAlchemy та Pydantic. Його створив той самий автор **FastAPI**, щоб він ідеально підходив для застосунків FastAPI, яким потрібно використовувати **SQL бази даних**.
+
+/// tip | Порада
+
+Ви можете використовувати будь-яку іншу бібліотеку для SQL або NoSQL баз даних (у деяких випадках їх називають "ORMs"), FastAPI не змушує вас використовувати щось конкретне. 😎
+
+///
+
+Оскільки SQLModel базується на SQLAlchemy, ви можете легко використовувати **будь-яку базу даних, яку підтримує** SQLAlchemy (а отже, і SQLModel), наприклад:
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server тощо.
+
+У цьому прикладі ми використаємо **SQLite**, бо вона використовує один файл і має вбудовану підтримку в Python. Тож ви можете скопіювати цей приклад і запустити його як є.
+
+Пізніше, для продакшн-застосунку, вам, імовірно, захочеться використовувати сервер бази даних, наприклад **PostgreSQL**.
+
+/// tip | Порада
+
+Існує офіційний генератор проєкту з **FastAPI** та **PostgreSQL**, який включає frontend і більше інструментів: https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+Це дуже простий і короткий туторіал. Якщо ви хочете дізнатися про бази даних загалом, про SQL або про більш просунуті можливості, перейдіть до документації SQLModel.
+
+## Встановлення `SQLModel` { #install-sqlmodel }
+
+Спершу переконайтеся, що ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановіть `sqlmodel`:
+
+
+
+