Browse Source

🌐 Update translations for uk (update-outdated) (#15900)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <[email protected]>
pull/15909/head
Sebastián Ramírez 21 hours ago
committed by GitHub
parent
commit
509ac59f5c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      docs/uk/docs/_llm-test.md
  2. 1
      docs/uk/docs/advanced/additional-status-codes.md
  3. 28
      docs/uk/docs/advanced/advanced-dependencies.md
  4. 1
      docs/uk/docs/advanced/dataclasses.md
  5. 46
      docs/uk/docs/advanced/events.md
  6. 16
      docs/uk/docs/advanced/generate-clients.md
  7. 8
      docs/uk/docs/advanced/json-base64-bytes.md
  8. 58
      docs/uk/docs/advanced/openapi-callbacks.md
  9. 1
      docs/uk/docs/advanced/response-change-status-code.md
  10. 2
      docs/uk/docs/advanced/response-cookies.md
  11. 2
      docs/uk/docs/advanced/response-headers.md
  12. 10
      docs/uk/docs/advanced/security/oauth2-scopes.md
  13. 8
      docs/uk/docs/advanced/settings.md
  14. 18
      docs/uk/docs/advanced/stream-data.md
  15. 1
      docs/uk/docs/advanced/wsgi.md
  16. 32
      docs/uk/docs/alternatives.md
  17. 46
      docs/uk/docs/async.md
  18. 2
      docs/uk/docs/deployment/cloud.md
  19. 28
      docs/uk/docs/deployment/concepts.md
  20. 178
      docs/uk/docs/deployment/docker.md
  21. 20
      docs/uk/docs/deployment/https.md
  22. 10
      docs/uk/docs/deployment/manually.md
  23. 1
      docs/uk/docs/editor-support.md
  24. 32
      docs/uk/docs/environment-variables.md
  25. 42
      docs/uk/docs/features.md
  26. 2
      docs/uk/docs/help-fastapi.md
  27. 2
      docs/uk/docs/how-to/configure-swagger-ui.md
  28. 8
      docs/uk/docs/how-to/custom-request-and-route.md
  29. 24
      docs/uk/docs/how-to/graphql.md
  30. 22
      docs/uk/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
  31. 13
      docs/uk/docs/how-to/separate-openapi-schemas.md
  32. 52
      docs/uk/docs/index.md
  33. 1
      docs/uk/docs/project-generation.md
  34. 42
      docs/uk/docs/python-types.md
  35. 38
      docs/uk/docs/tutorial/bigger-applications.md
  36. 60
      docs/uk/docs/tutorial/body-nested-models.md
  37. 2
      docs/uk/docs/tutorial/body.md
  38. 1
      docs/uk/docs/tutorial/debugging.md
  39. 5
      docs/uk/docs/tutorial/dependencies/dependencies-with-yield.md
  40. 8
      docs/uk/docs/tutorial/extra-data-types.md
  41. 8
      docs/uk/docs/tutorial/extra-models.md
  42. 24
      docs/uk/docs/tutorial/first-steps.md
  43. 2
      docs/uk/docs/tutorial/handling-errors.md
  44. 4
      docs/uk/docs/tutorial/index.md
  45. 2
      docs/uk/docs/tutorial/metadata.md
  46. 14
      docs/uk/docs/tutorial/path-operation-configuration.md
  47. 103
      docs/uk/docs/tutorial/query-params-str-validations.md
  48. 40
      docs/uk/docs/tutorial/query-params.md
  49. 18
      docs/uk/docs/tutorial/request-files.md
  50. 2
      docs/uk/docs/tutorial/request-forms.md
  51. 1
      docs/uk/docs/tutorial/response-status-code.md
  52. 6
      docs/uk/docs/tutorial/schema-extra-example.md
  53. 22
      docs/uk/docs/tutorial/security/first-steps.md
  54. 26
      docs/uk/docs/tutorial/security/get-current-user.md
  55. 4
      docs/uk/docs/tutorial/security/oauth2-jwt.md
  56. 28
      docs/uk/docs/tutorial/security/simple-oauth2.md
  57. 6
      docs/uk/docs/tutorial/sql-databases.md
  58. 24
      docs/uk/docs/tutorial/static-files.md
  59. 16
      docs/uk/docs/tutorial/testing.md
  60. 108
      docs/uk/docs/virtual-environments.md

4
docs/uk/docs/_llm-test.md

@ -203,9 +203,9 @@ works(foo="bar") # Це працює 🎉
//// tab | Інформація //// tab | Інформація
Атрибути "title" елементів "abbr" перекладаються за певними інструкціями. Атрибути «title» елементів «abbr» перекладаються за певними інструкціями.
Переклади можуть додавати власні елементи "abbr", які LLM не повинен прибирати. Наприклад, щоб пояснити англійські слова. Переклади можуть додавати власні елементи «abbr», які LLM не повинен прибирати. Наприклад, щоб пояснити англійські слова.
Див. розділ `### HTML abbr elements` в загальній підсказці в `scripts/translate.py`. Див. розділ `### HTML abbr elements` в загальній підсказці в `scripts/translate.py`.

1
docs/uk/docs/advanced/additional-status-codes.md

@ -1,5 +1,6 @@
# Додаткові коди статусу { #additional-status-codes } # Додаткові коди статусу { #additional-status-codes }
За замовчуванням **FastAPI** повертатиме відповіді за допомогою `JSONResponse`, поміщаючи вміст, який ви повертаєте з вашої *операції шляху*, у цей `JSONResponse`. За замовчуванням **FastAPI** повертатиме відповіді за допомогою `JSONResponse`, поміщаючи вміст, який ви повертаєте з вашої *операції шляху*, у цей `JSONResponse`.
Він використовуватиме код статусу за замовчуванням або той, який ви встановите у своїй *операції шляху*. Він використовуватиме код статусу за замовчуванням або той, який ви встановите у своїй *операції шляху*.

28
docs/uk/docs/advanced/advanced-dependencies.md

@ -10,11 +10,11 @@
Але ми хочемо мати змогу параметризувати цей фіксований вміст. Але ми хочемо мати змогу параметризувати цей фіксований вміст.
## Екземпляр «callable» { #a-callable-instance } ## Викликаємий екземпляр { #a-callable-instance }
У Python є спосіб зробити екземпляр класу «callable». У Python є спосіб зробити екземпляр класу викликаємим.
Не сам клас (який уже є «callable»), а екземпляр цього класу. Не сам клас (який уже є викликаємим), а екземпляр цього класу.
Щоб це зробити, оголошуємо метод `__call__`: Щоб це зробити, оголошуємо метод `__call__`:
@ -36,7 +36,7 @@
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *} {* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
Таким чином ми «параметризуємо» нашу залежність, яка тепер містить «bar» як атрибут `checker.fixed_content`. Таким чином ми «параметризуємо» нашу залежність, яка тепер містить `"bar"` як атрибут `checker.fixed_content`.
## Використовувати екземпляр як залежність { #use-the-instance-as-a-dependency } ## Використовувати екземпляр як залежність { #use-the-instance-as-a-dependency }
@ -52,7 +52,7 @@ checker(q="somequery")
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *} {* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip /// tip | Порада
Усе це може здаватися надуманим. І поки що може бути не дуже зрозуміло, навіщо це корисно. Усе це може здаватися надуманим. І поки що може бути не дуже зрозуміло, навіщо це корисно.
@ -66,7 +66,7 @@ checker(q="somequery")
## Залежності з `yield`, `HTTPException`, `except` та фоновими задачами { #dependencies-with-yield-httpexception-except-and-background-tasks } ## Залежності з `yield`, `HTTPException`, `except` та фоновими задачами { #dependencies-with-yield-httpexception-except-and-background-tasks }
/// warning /// warning | Попередження
Найімовірніше, вам не знадобляться ці технічні деталі. Найімовірніше, вам не знадобляться ці технічні деталі.
@ -78,7 +78,7 @@ checker(q="somequery")
### Залежності з `yield` і `scope` { #dependencies-with-yield-and-scope } ### Залежності з `yield` і `scope` { #dependencies-with-yield-and-scope }
У версії 0.121.0 **FastAPI** додано підтримку `Depends(scope="function")` для залежностей з `yield`. У версії 0.121.0 FastAPI додано підтримку `Depends(scope="function")` для залежностей з `yield`.
З `Depends(scope="function")` завершальний код після `yield` виконується одразу після завершення *функції операції шляху*, до того як відповідь буде надіслана клієнту. З `Depends(scope="function")` завершальний код після `yield` виконується одразу після завершення *функції операції шляху*, до того як відповідь буде надіслана клієнту.
@ -88,7 +88,7 @@ checker(q="somequery")
### Залежності з `yield` і `StreamingResponse`, технічні деталі { #dependencies-with-yield-and-streamingresponse-technical-details } ### Залежності з `yield` і `StreamingResponse`, технічні деталі { #dependencies-with-yield-and-streamingresponse-technical-details }
До **FastAPI** 0.118.0, якщо ви використовували залежність із `yield`, завершальний код виконувався після повернення з *функції операції шляху*, але безпосередньо перед відправленням відповіді. До FastAPI 0.118.0, якщо ви використовували залежність із `yield`, завершальний код виконувався після повернення з *функції операції шляху*, але безпосередньо перед відправленням відповіді.
Метою було уникнути утримання ресурсів довше, ніж потрібно, очікуючи, поки відповідь пройде мережею. Метою було уникнути утримання ресурсів довше, ніж потрібно, очікуючи, поки відповідь пройде мережею.
@ -98,7 +98,7 @@ checker(q="somequery")
Цю поведінку змінено у 0.118.0: завершальний код після `yield` знову виконується після відправлення відповіді. Цю поведінку змінено у 0.118.0: завершальний код після `yield` знову виконується після відправлення відповіді.
/// note /// note | Примітка
Як побачите нижче, це дуже схоже на поведінку до версії 0.106.0, але з кількома покращеннями та виправленнями помилок у крайових випадках. Як побачите нижче, це дуже схоже на поведінку до версії 0.106.0, але з кількома покращеннями та виправленнями помилок у крайових випадках.
@ -138,19 +138,19 @@ checker(q="somequery")
### Залежності з `yield` і `except`, технічні деталі { #dependencies-with-yield-and-except-technical-details } ### Залежності з `yield` і `except`, технічні деталі { #dependencies-with-yield-and-except-technical-details }
До **FastAPI** 0.110.0, якщо ви використовували залежність із `yield`, перехоплювали виняток через `except` у цій залежності і не піднімали його знову, виняток автоматично піднімався/пересилався до будь-яких обробників винятків або внутрішнього обробника помилок сервера. До FastAPI 0.110.0, якщо ви використовували залежність із `yield`, перехоплювали виняток через `except` у цій залежності і не піднімали його знову, виняток автоматично піднімався/пересилався до будь-яких обробників винятків або внутрішнього обробника помилок сервера.
Це змінено у версії 0.110.0, щоб усунути неконтрольоване споживання пам'яті від пересланих винятків без обробника (внутрішні помилки сервера) та зробити поведінку узгодженою зі звичайним Python-кодом. Це змінено у версії 0.110.0, щоб усунути неконтрольоване споживання пам'яті від пересланих винятків без обробника (внутрішні помилки сервера) та зробити поведінку узгодженою зі звичайним Python-кодом.
### Фонові задачі та залежності з `yield`, технічні деталі { #background-tasks-and-dependencies-with-yield-technical-details } ### Фонові задачі та залежності з `yield`, технічні деталі { #background-tasks-and-dependencies-with-yield-technical-details }
До **FastAPI** 0.106.0 піднімати винятки після `yield` було неможливо: завершальний код у залежностях з `yield` виконувався після надсилання відповіді, тож [обробники винятків](../tutorial/handling-errors.md#install-custom-exception-handlers) уже відпрацювали б. До FastAPI 0.106.0 піднімати винятки після `yield` було неможливо: завершальний код у залежностях з `yield` виконувався після надсилання відповіді, тож [обробники винятків](../tutorial/handling-errors.md#install-custom-exception-handlers) уже відпрацювали б.
Так було спроєктовано головно для того, щоб дозволити використовувати ті самі об'єкти, «віддані» залежностями через `yield`, усередині фонових задач, оскільки завершальний код виконувався після завершення фонових задач. Так було спроєктовано головно для того, щоб дозволити використовувати ті самі об'єкти, «віддані» залежностями через `yield`, усередині фонових задач, оскільки завершальний код виконувався після завершення фонових задач.
У **FastAPI** 0.106.0 це змінено, щоб не утримувати ресурси під час очікування, поки відповідь піде мережею. У FastAPI 0.106.0 це змінено, щоб не утримувати ресурси під час очікування, поки відповідь піде мережею.
/// tip /// tip | Порада
Крім того, фонова задача зазвичай є незалежним набором логіки, який слід обробляти окремо, з власними ресурсами (наприклад, власним з'єднанням з базою даних). Крім того, фонова задача зазвичай є незалежним набором логіки, який слід обробляти окремо, з власними ресурсами (наприклад, власним з'єднанням з базою даних).
@ -160,4 +160,4 @@ checker(q="somequery")
Якщо ви раніше покладалися на цю поведінку, тепер слід створювати ресурси для фонових задач усередині самої фонової задачі та використовувати всередині лише дані, що не залежать від ресурсів залежностей із `yield`. Якщо ви раніше покладалися на цю поведінку, тепер слід створювати ресурси для фонових задач усередині самої фонової задачі та використовувати всередині лише дані, що не залежать від ресурсів залежностей із `yield`.
Наприклад, замість використання тієї самої сесії бази даних ви створюватимете нову сесію в самій фоновій задачі та отримуватимете об'єкти з бази даних, використовуючи Цю нову сесію. І далі, замість передавання об'єкта з бази даних як параметра у функцію фонової задачі, ви передасте ідентифікатор цього об'єкта, а потім отримаєте об'єкт знову всередині функції фонової задачі. Наприклад, замість використання тієї самої сесії бази даних ви створюватимете нову сесію в самій фоновій задачі та отримуватимете об'єкти з бази даних, використовуючи цю нову сесію. І далі, замість передавання об'єкта з бази даних як параметра у функцію фонової задачі, ви передасте ідентифікатор цього об'єкта, а потім отримаєте об'єкт знову всередині функції фонової задачі.

1
docs/uk/docs/advanced/dataclasses.md

@ -1,5 +1,6 @@
# Використання dataclasses { #using-dataclasses } # Використання dataclasses { #using-dataclasses }
FastAPI побудовано поверх **Pydantic**, і я показував вам, як використовувати моделі Pydantic для оголошення запитів і відповідей. FastAPI побудовано поверх **Pydantic**, і я показував вам, як використовувати моделі Pydantic для оголошення запитів і відповідей.
Але FastAPI також підтримує використання [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) таким самим чином: Але FastAPI також підтримує використання [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) таким самим чином:

46
docs/uk/docs/advanced/events.md

@ -1,30 +1,30 @@
# Події тривалості життя { #lifespan-events } # Події тривалості життя { #lifespan-events }
Ви можете визначити логіку (код), яку слід виконати перед тим, як застосунок запуститься. Це означає, що цей код буде виконано один раз, перед тим як застосунок почне отримувати запити. Ви можете визначити логіку (код), яку слід виконати перед тим, як застосунок **запуститься**. Це означає, що цей код буде виконано **один раз**, **перед** тим як застосунок **почне отримувати запити**.
Так само ви можете визначити логіку (код), яку слід виконати під час вимкнення застосунку. У цьому випадку код буде виконано один раз, після обробки можливо багатьох запитів. Так само ви можете визначити логіку (код), яку слід виконати під час **вимкнення** застосунку. У цьому випадку код буде виконано **один раз**, після обробки можливо **багатьох запитів**.
Оскільки цей код виконується перед тим, як застосунок почне приймати запити, і одразу після того, як він завершить їх обробку, він охоплює всю тривалість життя застосунку (слово «lifespan» буде важливим за мить 😉). Оскільки цей код виконується перед тим, як застосунок **почне** приймати запити, і одразу після того, як він **завершить** їх обробку, він охоплює всю **тривалість життя** застосунку (слово «lifespan» буде важливим за мить 😉).
Це дуже корисно для налаштування ресурсів, які потрібні для всього застосунку, які спільні між запитами, та/або які потрібно потім прибрати. Наприклад, пул з’єднань з базою даних або завантаження спільної моделі машинного навчання. Це дуже корисно для налаштування **ресурсів**, які потрібні для всього застосунку, які **спільні** між запитами, та/або які потрібно потім **прибрати**. Наприклад, пул з’єднань з базою даних або завантаження спільної моделі машинного навчання.
## Випадок використання { #use-case } ## Випадок використання { #use-case }
Почнемо з прикладу випадку використання, а потім подивимось, як це вирішити. Почнемо з прикладу **випадку використання**, а потім подивимось, як це вирішити.
Уявімо, що у вас є моделі машинного навчання, якими ви хочете обробляти запити. 🤖 Уявімо, що у вас є **моделі машинного навчання**, якими ви хочете обробляти запити. 🤖
Ті самі моделі спільні між запитами, тобто це не окрема модель на запит чи на користувача. Ті самі моделі спільні між запитами, тобто це не окрема модель на запит чи на користувача.
Уявімо, що завантаження моделі може займати чимало часу, бо треба читати багато даних з диска. Тож ви не хочете робити це для кожного запиту. Уявімо, що завантаження моделі може **займати чимало часу**, бо треба читати багато **даних з диска**. Тож ви не хочете робити це для кожного запиту.
Ви могли б завантажити її на верхньому рівні модуля/файлу, але це означало б, що модель завантажиться навіть якщо ви просто запускаєте простий автоматизований тест - тоді тест буде повільним, бо йому доведеться чекати завантаження моделі перед виконанням незалежної частини коду. Ви могли б завантажити її на верхньому рівні модуля/файлу, але це означало б, що модель **завантажиться** навіть якщо ви просто запускаєте простий автоматизований тест - тоді тест буде **повільним**, бо йому доведеться чекати завантаження моделі перед виконанням незалежної частини коду.
Ось це ми й вирішимо: завантажимо модель перед обробкою запитів, але лише безпосередньо перед тим, як застосунок почне отримувати запити, а не під час завантаження коду. Ось це ми й вирішимо: завантажимо модель перед обробкою запитів, але лише безпосередньо перед тим, як застосунок почне отримувати запити, а не під час завантаження коду.
## Тривалість життя { #lifespan } ## Тривалість життя { #lifespan }
Ви можете визначити цю логіку запуску і вимкнення за допомогою параметра `lifespan` застосунку `FastAPI` та «менеджера контексту» (зараз покажу, що це). Ви можете визначити цю логіку *запуску* і *вимкнення* за допомогою параметра `lifespan` застосунку `FastAPI` та «менеджера контексту» (зараз покажу, що це).
Почнемо з прикладу, а потім розберемо детально. Почнемо з прикладу, а потім розберемо детально.
@ -32,13 +32,13 @@
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *} {* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
Тут ми імітуємо дорогу операцію запуску із завантаженням моделі, поміщаючи (фальшиву) функцію моделі у словник з моделями машинного навчання перед `yield`. Цей код буде виконано перед тим, як застосунок почне приймати запити, під час запуску. Тут ми імітуємо дорогу операцію *запуску* із завантаженням моделі, поміщаючи (фальшиву) функцію моделі у словник з моделями машинного навчання перед `yield`. Цей код буде виконано **перед** тим, як застосунок **почне приймати запити**, під час *запуску*.
А одразу після `yield` ми розвантажуємо модель. Цей код буде виконано після того, як застосунок завершить обробку запитів, безпосередньо перед вимкненням. Це, наприклад, може звільнити ресурси на кшталт пам’яті або GPU. А одразу після `yield` ми розвантажуємо модель. Цей код буде виконано **після** того, як застосунок **завершить обробку запитів**, безпосередньо перед *вимкненням*. Це, наприклад, може звільнити ресурси на кшталт пам’яті або GPU.
/// tip | Порада /// tip | Порада
Подія `shutdown` відбувається, коли ви зупиняєте застосунок. Подія `shutdown` відбувається, коли ви **зупиняєте** застосунок.
Можливо, вам треба запустити нову версію, або ви просто втомилися її запускати. 🤷 Можливо, вам треба запустити нову версію, або ви просто втомилися її запускати. 🤷
@ -50,26 +50,26 @@
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *} {* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
Перша частина функції до `yield` буде виконана перед запуском застосунку. Перша частина функції до `yield` буде виконана **перед** запуском застосунку.
А частина після `yield` буде виконана після завершення роботи застосунку. А частина після `yield` буде виконана **після** завершення роботи застосунку.
### Асинхронний менеджер контексту { #async-context-manager } ### Асинхронний менеджер контексту { #async-context-manager }
Якщо придивитися, функція задекорована за допомогою `@asynccontextmanager`. Якщо придивитися, функція задекорована за допомогою `@asynccontextmanager`.
Це перетворює функцію на так званий «асинхронний менеджер контексту». Це перетворює функцію на так званий «**асинхронний менеджер контексту**».
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *} {* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
Менеджер контексту в Python - це те, що можна використовувати в операторі `with`, наприклад, `open()` можна використовувати як менеджер контексту: **Менеджер контексту** в Python - це те, що можна використовувати в операторі `with`, наприклад, `open()` можна використовувати як менеджер контексту:
```Python ```Python
with open("file.txt") as file: with open("file.txt") as file:
file.read() file.read()
``` ```
У новіших версіях Python також є асинхронний менеджер контексту. Його використовують з `async with`: У новіших версіях Python також є **асинхронний менеджер контексту**. Його використовують з `async with`:
```Python ```Python
async with lifespan(app): async with lifespan(app):
@ -80,7 +80,7 @@ async with lifespan(app):
У нашому прикладі коду вище ми не використовуємо його напряму, а передаємо його до FastAPI, щоб він його використав. У нашому прикладі коду вище ми не використовуємо його напряму, а передаємо його до FastAPI, щоб він його використав.
Параметр `lifespan` застосунку `FastAPI` приймає асинхронний менеджер контексту, тож ми можемо передати йому наш новий асинхронний менеджер контексту `lifespan`. Параметр `lifespan` застосунку `FastAPI` приймає **асинхронний менеджер контексту**, тож ми можемо передати йому наш новий асинхронний менеджер контексту `lifespan`.
{* ../../docs_src/events/tutorial003_py310.py hl[22] *} {* ../../docs_src/events/tutorial003_py310.py hl[22] *}
@ -88,13 +88,13 @@ async with lifespan(app):
/// warning | Попередження /// warning | Попередження
Рекомендований спосіб обробляти запуск і вимкнення - використовувати параметр `lifespan` застосунку `FastAPI`, як описано вище. Якщо ви надаєте параметр `lifespan`, обробники подій `startup` і `shutdown` більше не будуть викликані. Або все через `lifespan`, або все через події - не обидва одночасно. Рекомендований спосіб обробляти *запуск* і *вимкнення* - використовувати параметр `lifespan` застосунку `FastAPI`, як описано вище. Якщо ви надаєте параметр `lifespan`, обробники подій `startup` і `shutdown` більше не будуть викликані. Або все через `lifespan`, або все через події - не обидва одночасно.
Можете, ймовірно, пропустити цю частину. Можете, ймовірно, пропустити цю частину.
/// ///
Є альтернативний спосіб визначити логіку, яку слід виконати під час запуску і під час вимкнення. Є альтернативний спосіб визначити логіку, яку слід виконати під час *запуску* і під час *вимкнення*.
Ви можете визначити обробники подій (функції), які потрібно виконати перед запуском застосунку або коли застосунок вимикається. Ви можете визначити обробники подій (функції), які потрібно виконати перед запуском застосунку або коли застосунок вимикається.
@ -130,7 +130,7 @@ async with lifespan(app):
Зауважте, що в цьому випадку ми використовуємо стандартну Python-функцію `open()`, яка працює з файлом. Зауважте, що в цьому випадку ми використовуємо стандартну Python-функцію `open()`, яка працює з файлом.
Тобто вона включає I/O (input/output), де потрібно «чекати», поки дані буде записано на диск. Тобто вона включає I/O (введення/виведення), де потрібно «чекати», поки дані буде записано на диск.
Але `open()` не використовує `async` і `await`. Але `open()` не використовує `async` і `await`.
@ -140,7 +140,7 @@ async with lifespan(app):
### Разом `startup` і `shutdown` { #startup-and-shutdown-together } ### Разом `startup` і `shutdown` { #startup-and-shutdown-together }
Велика ймовірність, що логіка для вашого запуску і вимкнення пов’язана: ви можете хотіти щось запустити, а потім завершити, отримати ресурс, а потім звільнити його тощо. Велика ймовірність, що логіка для вашого *запуску* і *вимкнення* пов’язана: ви можете хотіти щось запустити, а потім завершити, отримати ресурс, а потім звільнити його тощо.
Робити це в окремих функціях, які не діляться логікою чи змінними, складніше - доведеться зберігати значення у глобальних змінних або вдаватися до подібних трюків. Робити це в окремих функціях, які не діляться логікою чи змінними, складніше - доведеться зберігати значення у глобальних змінних або вдаватися до подібних трюків.
@ -154,7 +154,7 @@ async with lifespan(app):
/// note | Примітка /// note | Примітка
Ви можете прочитати більше про обробники `lifespan` у [документації Starlette про Lifespan](https://www.starlette.dev/lifespan/). Ви можете прочитати більше про обробники `lifespan` Starlette у [документації Starlette про Lifespan](https://www.starlette.dev/lifespan/).
Зокрема, як працювати зі станом тривалості життя, який можна використовувати в інших ділянках вашого коду. Зокрема, як працювати зі станом тривалості життя, який можна використовувати в інших ділянках вашого коду.

16
docs/uk/docs/advanced/generate-clients.md

@ -10,7 +10,7 @@
Універсальним варіантом є [OpenAPI Generator](https://openapi-generator.tech/), який підтримує **багато мов програмування** та може генерувати SDK з вашої специфікації OpenAPI. Універсальним варіантом є [OpenAPI Generator](https://openapi-generator.tech/), який підтримує **багато мов програмування** та може генерувати SDK з вашої специфікації OpenAPI.
Для **клієнтів TypeScript** [Hey API](https://heyapi.dev/) спеціалізоване рішення, що надає оптимізований досвід для екосистеми TypeScript. Для **клієнтів TypeScript** [Hey API](https://heyapi.dev/) - спеціалізоване рішення, що надає оптимізований досвід для екосистеми TypeScript.
Більше генераторів SDK ви можете знайти на [OpenAPI.Tools](https://openapi.tools/#sdk). Більше генераторів SDK ви можете знайти на [OpenAPI.Tools](https://openapi.tools/#sdk).
@ -20,20 +20,6 @@ FastAPI автоматично генерує специфікації **OpenAPI
/// ///
## Генератори SDK від спонсорів FastAPI { #sdk-generators-from-fastapi-sponsors }
У цьому розділі представлено рішення від компаній, що спонсорують FastAPI: вони мають **венчурну підтримку** та **корпоративну підтримку**. Ці продукти надають **додаткові можливості** та **інтеграції** поверх високоякісно згенерованих SDK.
Завдяки ✨ [**спонсорству FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ ці компанії допомагають підтримувати фреймворк та його **екосистему** здоровими та **сталими**.
Їхня підтримка також демонструє сильну відданість **спільноті** FastAPI (вам), показуючи, що їм важливо не лише надавати **відмінний сервіс**, а й підтримувати **міцний і процвітаючий фреймворк**, FastAPI. 🙇
Наприклад, ви можете спробувати:
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
Деякі з цих рішень також можуть бути з відкритим кодом або мати безкоштовні тарифи, тож ви можете спробувати їх без фінансових зобов'язань. Інші комерційні генератори SDK також доступні й їх можна знайти онлайн. 🤓
## Створити TypeScript SDK { #create-a-typescript-sdk } ## Створити TypeScript SDK { #create-a-typescript-sdk }
Почнімо з простого застосунку FastAPI: Почнімо з простого застосунку FastAPI:

8
docs/uk/docs/advanced/json-base64-bytes.md

@ -4,7 +4,7 @@
## Base64 проти файлів { #base64-vs-files } ## Base64 проти файлів { #base64-vs-files }
Насамперед розгляньте, чи можете ви використати [Файли запиту](../tutorial/request-files.md) для завантаження двійкових даних і [Користувацька відповідь - FileResponse](./custom-response.md#fileresponse--fileresponse-) для надсилання двійкових даних замість кодування їх у JSON. Насамперед розгляньте, чи можете ви використати [Файли запиту](../tutorial/request-files.md) для завантаження двійкових даних і [Користувацька відповідь - FileResponse](./custom-response.md#fileresponse) для надсилання двійкових даних замість кодування їх у JSON.
JSON може містити лише строки, закодовані в UTF-8, тому він не може містити «сирі» байти. JSON може містити лише строки, закодовані в UTF-8, тому він не може містити «сирі» байти.
@ -14,7 +14,7 @@ Base64 може кодувати двійкові дані у строках, а
## Pydantic `bytes` { #pydantic-bytes } ## Pydantic `bytes` { #pydantic-bytes }
Ви можете оголосити модель Pydantic з полями `bytes`, а потім використати `val_json_bytes` у конфігурації моделі, щоб вказати їй використовувати base64 для перевірки вхідних даних JSON; як частина цієї перевірки, вона декодує строку base64 у байти. Ви можете оголосити модель Pydantic з полями `bytes`, а потім використати `val_json_bytes` у конфігурації моделі, щоб вказати їй використовувати base64 для *перевірки* вхідних даних JSON; як частина цієї перевірки, вона декодує строку base64 у байти.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *} {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
@ -52,12 +52,12 @@ Base64 може кодувати двійкові дані у строках, а
## Pydantic `bytes` для вихідних даних { #pydantic-bytes-for-output-data } ## Pydantic `bytes` для вихідних даних { #pydantic-bytes-for-output-data }
Ви також можете використовувати поля `bytes` з `ser_json_bytes` у конфігурації моделі для вихідних даних, і Pydantic серіалізує байти як base64 під час формування відповіді JSON. Ви також можете використовувати поля `bytes` з `ser_json_bytes` у конфігурації моделі для вихідних даних, і Pydantic *серіалізує* байти як base64 під час формування відповіді JSON.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *} {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
## Pydantic `bytes` для вхідних і вихідних даних { #pydantic-bytes-for-input-and-output-data } ## Pydantic `bytes` для вхідних і вихідних даних { #pydantic-bytes-for-input-and-output-data }
І, звісно, ви можете використовувати ту саму модель, налаштовану на base64, щоб обробляти і вхідні дані (перевіряти) з `val_json_bytes`, і вихідні дані (серіалізувати) з `ser_json_bytes` під час отримання та надсилання даних JSON. І, звісно, ви можете використовувати ту саму модель, налаштовану на base64, щоб обробляти і вхідні дані (*перевіряти*) з `val_json_bytes`, і вихідні дані (*серіалізувати*) з `ser_json_bytes` під час отримання та надсилання даних JSON.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *} {* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}

58
docs/uk/docs/advanced/openapi-callbacks.md

@ -1,10 +1,10 @@
# Зворотні виклики OpenAPI { #openapi-callbacks } # Зворотні виклики OpenAPI { #openapi-callbacks }
Ви можете створити API з операцією шляху, яка ініціюватиме запит до зовнішнього API, створеного кимось іншим (ймовірно тим самим розробником, який буде використовувати ваш API). Ви можете створити API з *операцією шляху*, яка ініціюватиме запит до *зовнішнього API*, створеного кимось іншим (ймовірно тим самим розробником, який буде *використовувати* ваш API).
Процес, що відбувається, коли ваш застосунок API викликає зовнішній API, називається «зворотний виклик». Тому що програмне забезпечення, написане зовнішнім розробником, надсилає запит до вашого API, а потім ваш API виконує зворотний виклик, надсилаючи запит до зовнішнього API (його, ймовірно, також створив той самий розробник). Процес, що відбувається, коли ваш застосунок API викликає *зовнішній API*, називається «зворотний виклик». Тому що програмне забезпечення, написане зовнішнім розробником, надсилає запит до вашого API, а потім ваш API *виконує зворотний виклик*, надсилаючи запит до *зовнішнього API* (його, ймовірно, також створив той самий розробник).
У такому випадку вам може знадобитися задокументувати, яким має бути той зовнішній API: які операції шляху він має мати, яке тіло очікувати, яку відповідь повертати тощо. У такому випадку вам може знадобитися задокументувати, яким має бути той *зовнішній API*: яку *операцію шляху* він має мати, яке тіло очікувати, яку відповідь повертати тощо.
## Застосунок зі зворотними викликами { #an-app-with-callbacks } ## Застосунок зі зворотними викликами { #an-app-with-callbacks }
@ -21,13 +21,13 @@
- Надсилати рахунок деякому клієнту зовнішнього розробника. - Надсилати рахунок деякому клієнту зовнішнього розробника.
- Отримувати оплату. - Отримувати оплату.
- Надсилати сповіщення назад користувачу API (зовнішньому розробнику). - Надсилати сповіщення назад користувачу API (зовнішньому розробнику).
- Це буде зроблено шляхом надсилання POST-запиту (з вашого API) до деякого зовнішнього API, наданого тим зовнішнім розробником (це і є «зворотний виклик»). - Це буде зроблено шляхом надсилання POST-запиту (з *вашого API*) до деякого *зовнішнього API*, наданого тим зовнішнім розробником (це і є «зворотний виклик»).
## Звичайний застосунок FastAPI { #the-normal-fastapi-app } ## Звичайний застосунок **FastAPI** { #the-normal-fastapi-app }
Спочатку подивімося, як виглядав би звичайний застосунок API до додавання зворотного виклику. Спочатку подивімося, як виглядав би звичайний застосунок API до додавання зворотного виклику.
Він матиме операцію шляху, яка отримуватиме тіло `Invoice`, і параметр запиту `callback_url`, що міститиме URL для зворотного виклику. Він матиме *операцію шляху*, яка отримуватиме тіло `Invoice`, і параметр запиту `callback_url`, що міститиме URL для зворотного виклику.
Ця частина цілком звична, більшість коду вам, ймовірно, уже знайома: Ця частина цілком звична, більшість коду вам, ймовірно, уже знайома:
@ -39,7 +39,7 @@
/// ///
Єдина нова річ - це `callbacks=invoices_callback_router.routes` як аргумент декоратора операції шляху. Далі розглянемо, що це таке. Єдина нова річ - це `callbacks=invoices_callback_router.routes` як аргумент *декоратора операції шляху*. Далі розглянемо, що це таке.
## Документування зворотного виклику { #documenting-the-callback } ## Документування зворотного виклику { #documenting-the-callback }
@ -54,11 +54,11 @@ callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True}) httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
``` ```
Але, можливо, найважливіша частина зворотного виклику - переконатися, що користувач вашого API (зовнішній розробник) правильно реалізує зовнішній API відповідно до даних, які ваш API надсилатиме в тілі запиту зворотного виклику тощо. Але, можливо, найважливіша частина зворотного виклику - переконатися, що користувач вашого API (зовнішній розробник) правильно реалізує *зовнішній API* відповідно до даних, які *ваш API* надсилатиме в тілі запиту зворотного виклику тощо.
Тому далі ми додамо код, щоб задокументувати, яким має бути цей зовнішній API, щоб приймати зворотний виклик від вашого API. Тому далі ми додамо код, щоб задокументувати, яким має бути цей *зовнішній API*, щоб приймати зворотний виклик від *вашого API*.
Ця документація з'явиться в Swagger UI за адресою `/docs` у вашому API і дасть змогу зовнішнім розробникам зрозуміти, як створити зовнішній API. Ця документація з'явиться в Swagger UI за адресою `/docs` у вашому API і дасть змогу зовнішнім розробникам зрозуміти, як створити *зовнішній API*.
У цьому прикладі сам зворотний виклик не реалізовано (це може бути лише один рядок коду), лише частину з документацією. У цьому прикладі сам зворотний виклик не реалізовано (це може бути лише один рядок коду), лише частину з документацією.
@ -72,47 +72,47 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
## Напишіть код документації для зворотного виклику { #write-the-callback-documentation-code } ## Напишіть код документації для зворотного виклику { #write-the-callback-documentation-code }
Цей код не виконуватиметься у вашому застосунку, він потрібен лише, щоб задокументувати, яким має бути зовнішній API. Цей код не виконуватиметься у вашому застосунку, він потрібен лише, щоб *задокументувати*, яким має бути *зовнішній API*.
Але ви вже знаєте, як легко створювати автоматичну документацію для API за допомогою FastAPI. Але ви вже знаєте, як легко створювати автоматичну документацію для API за допомогою **FastAPI**.
Тож ми скористаємося цими знаннями, щоб задокументувати, яким має бути зовнішній API... створивши операції шляху, які має реалізувати зовнішній API (ті, які викликатиме ваш API). Тож ми скористаємося цими знаннями, щоб задокументувати, яким має бути *зовнішній API*... створивши *операції шляху*, які має реалізувати зовнішній API (ті, які викликатиме ваш API).
/// tip | Порада /// tip | Порада
Пишучи код для документування зворотного виклику, корисно уявити, що ви - той *зовнішній розробник*. І що ви зараз реалізуєте *зовнішній API*, а не *ваш API*. Пишучи код для документування зворотного виклику, корисно уявити, що ви - той *зовнішній розробник*. І що ви зараз реалізуєте *зовнішній API*, а не *ваш API*.
Тимчасово прийнявши цю точку зору ( *зовнішнього розробника* ), вам буде очевидніше, куди помістити параметри, яку Pydantic-модель використати для тіла, для відповіді тощо для того *зовнішнього API*. Тимчасово прийнявши цю точку зору (*зовнішнього розробника*), вам буде очевидніше, куди помістити параметри, яку Pydantic-модель використати для тіла, для відповіді тощо для того *зовнішнього API*.
/// ///
### Створіть callback `APIRouter` { #create-a-callback-apirouter } ### Створіть `APIRouter` зворотного виклику { #create-a-callback-apirouter }
Спочатку створіть новий `APIRouter`, який міститиме один або кілька зворотних викликів. Спочатку створіть новий `APIRouter`, який міститиме один або кілька зворотних викликів.
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *} {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Створіть операцію шляху зворотного виклику { #create-the-callback-path-operation } ### Створіть *операцію шляху* зворотного виклику { #create-the-callback-path-operation }
Щоб створити операцію шляху зворотного виклику, використайте той самий `APIRouter`, який ви створили вище. Щоб створити *операцію шляху* зворотного виклику, використайте той самий `APIRouter`, який ви створили вище.
Вона має виглядати як звичайна операція шляху FastAPI: Вона має виглядати як звичайна *операція шляху* FastAPI:
- Ймовірно має містити оголошення тіла, яке вона приймає, напр. `body: InvoiceEvent`. - Ймовірно має містити оголошення тіла, яке вона приймає, наприклад `body: InvoiceEvent`.
- І також може містити оголошення відповіді, яку вона повертає, напр. `response_model=InvoiceEventReceived`. - І також може містити оголошення відповіді, яку вона повертає, наприклад `response_model=InvoiceEventReceived`.
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *} {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
Є 2 основні відмінності від звичайної операції шляху: Є 2 основні відмінності від звичайної *операції шляху*:
- Їй не потрібен реальний код, адже ваш застосунок ніколи не викликатиме цей код. Вона використовується лише для документування зовнішнього API. Тому функція може просто містити `pass`. - Їй не потрібен реальний код, адже ваш застосунок ніколи не викликатиме цей код. Вона використовується лише для документування *зовнішнього API*. Тому функція може просто містити `pass`.
- Шлях може містити [вираз OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (див. нижче), де можна використовувати змінні з параметрами та частини оригінального запиту, надісланого до вашого API. - *Шлях* може містити [вираз OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (див. нижче), де можна використовувати змінні з параметрами та частини оригінального запиту, надісланого до *вашого API*.
### Вираз шляху зворотного виклику { #the-callback-path-expression } ### Вираз шляху зворотного виклику { #the-callback-path-expression }
Шлях зворотного виклику може містити [вираз OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression), який включає частини оригінального запиту, надісланого до вашого API. *Шлях* зворотного виклику може містити [вираз OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression), який включає частини оригінального запиту, надісланого до *вашого API*.
У цьому випадку це строка: У цьому випадку це `str`:
```Python ```Python
"{$callback_url}/invoices/{$request.body.id}" "{$callback_url}/invoices/{$request.body.id}"
@ -134,7 +134,7 @@ https://yourapi.com/invoices/?callback_url=https://www.external.org/events
} }
``` ```
тоді *ваш API* опрацює рахунок і згодом надішле запит зворотного виклику на `callback_url` ( *зовнішній API* ): тоді *ваш API* опрацює рахунок і згодом надішле запит зворотного виклику на `callback_url` (*зовнішній API*):
``` ```
https://www.external.org/events/invoices/2expen51ve https://www.external.org/events/invoices/2expen51ve
@ -165,9 +165,9 @@ https://www.external.org/events/invoices/2expen51ve
### Додайте маршрутизатор зворотного виклику { #add-the-callback-router } ### Додайте маршрутизатор зворотного виклику { #add-the-callback-router }
На цьому етапі ви маєте потрібні операції шляху зворотного виклику (ті, які має реалізувати *зовнішній розробник* у *зовнішньому API*) у створеному вище маршрутизаторі зворотного виклику. На цьому етапі ви маєте потрібні *операції шляху зворотного виклику* (ті, які має реалізувати *зовнішній розробник* у *зовнішньому API*) у створеному вище маршрутизаторі зворотного виклику.
Тепер використайте параметр `callbacks` у декораторі операції шляху вашого API, щоб передати атрибут `.routes` з цього маршрутизатора зворотного виклику: Тепер використайте параметр `callbacks` у *декораторі операції шляху вашого API*, щоб передати атрибут `.routes` з цього маршрутизатора зворотного виклику:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *} {* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
@ -181,6 +181,6 @@ https://www.external.org/events/invoices/2expen51ve
Тепер ви можете запустити застосунок і перейти за адресою [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). Тепер ви можете запустити застосунок і перейти за адресою [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Ви побачите вашу документацію з розділом «Callbacks» для вашої операції шляху, який показує, як має виглядати зовнішній API: Ви побачите вашу документацію з розділом «Callbacks» для вашої *операції шляху*, який показує, як має виглядати *зовнішній API*:
<img src="/img/tutorial/openapi-callbacks/image01.png"> <img src="/img/tutorial/openapi-callbacks/image01.png">

1
docs/uk/docs/advanced/response-change-status-code.md

@ -1,5 +1,6 @@
# Відповідь - зміна коду статусу { #response-change-status-code } # Відповідь - зміна коду статусу { #response-change-status-code }
Ймовірно, ви вже читали, що можна встановити типовий [код статусу відповіді](../tutorial/response-status-code.md). Ймовірно, ви вже читали, що можна встановити типовий [код статусу відповіді](../tutorial/response-status-code.md).
Але інколи потрібно повернути інший код статусу, ніж типовий. Але інколи потрібно повернути інший код статусу, ніж типовий.

2
docs/uk/docs/advanced/response-cookies.md

@ -26,7 +26,7 @@
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *} {* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip /// tip | Порада
Майте на увазі, що якщо ви повертаєте відповідь безпосередньо замість використання параметра `Response`, FastAPI поверне її напряму. Майте на увазі, що якщо ви повертаєте відповідь безпосередньо замість використання параметра `Response`, FastAPI поверне її напряму.

2
docs/uk/docs/advanced/response-headers.md

@ -38,4 +38,4 @@
Майте на увазі, що власні пропрієтарні заголовки можна додавати [за допомогою префікса `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers). Майте на увазі, що власні пропрієтарні заголовки можна додавати [за допомогою префікса `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
Але якщо у вас є власні заголовки, які клієнт у браузері має бачити, вам потрібно додати їх у вашу конфігурацію CORS (докладніше в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), використовуючи параметр `expose_headers`, задокументований у [документації Starlette щодо CORS](https://www.starlette.dev/middleware/#corsmiddleware). Але якщо у вас є власні заголовки, які клієнт у браузері має бачити, вам потрібно додати їх у вашу конфігурацію CORS (докладніше в [CORS (спільне використання ресурсів між різними джерелами)](../tutorial/cors.md)), використовуючи параметр `expose_headers`, задокументований у [документації Starlette щодо CORS](https://www.starlette.dev/middleware/#corsmiddleware).

10
docs/uk/docs/advanced/security/oauth2-scopes.md

@ -76,7 +76,7 @@ OAuth2 зі scopes - це механізм, який використовуют
Оскільки тепер ми оголошуємо ці scopes, вони з’являться в документації API, коли ви увійдете/авторизуєтеся. Оскільки тепер ми оголошуємо ці scopes, вони з’являться в документації API, коли ви увійдете/авторизуєтеся.
І ви зможете обрати, які scopes надати доступ: `me` і `items`. І ви зможете обрати, яким scopes надати доступ: `me` і `items`.
Це той самий механізм, який використовується, коли ви надаєте дозволи під час входу через Facebook, Google, GitHub тощо: Це той самий механізм, який використовується, коли ви надаєте дозволи під час входу через Facebook, Google, GitHub тощо:
@ -132,7 +132,7 @@ OAuth2 зі scopes - це механізм, який використовуют
Але використовуючи `Security` замість `Depends`, **FastAPI** знатиме, що можна оголошувати scopes безпеки, використовувати їх внутрішньо та документувати API через OpenAPI. Але використовуючи `Security` замість `Depends`, **FastAPI** знатиме, що можна оголошувати scopes безпеки, використовувати їх внутрішньо та документувати API через OpenAPI.
Коли ви імпортуєте `Query`, `Path`, `Depends`, `Security` та інші з `fastapi`, це насправді функції, що повертають спеціальні класи. Але коли ви імпортуєте `Query`, `Path`, `Depends`, `Security` та інші з `fastapi`, це насправді функції, що повертають спеціальні класи.
/// ///
@ -152,7 +152,7 @@ OAuth2 зі scopes - це механізм, який використовуют
{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *} {* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
## Використовуйте scopes { #use-the-scopes } ## Використовуйте `scopes` { #use-the-scopes }
Параметр `security_scopes` матиме тип `SecurityScopes`. Параметр `security_scopes` матиме тип `SecurityScopes`.
@ -194,9 +194,9 @@ OAuth2 зі scopes - це механізм, який використовуют
Ще раз розгляньмо дерево залежностей і scopes. Ще раз розгляньмо дерево залежностей і scopes.
Оскільки залежність `get_current_active_user` має підзалежність `get_current_user`, scope «me», оголошений у `get_current_active_user`, буде включений до списку потрібних scopes у `security_scopes.scopes`, переданого до `get_current_user`. Оскільки залежність `get_current_active_user` має підзалежність `get_current_user`, scope `"me"`, оголошений у `get_current_active_user`, буде включений до списку потрібних scopes у `security_scopes.scopes`, переданого до `get_current_user`.
Сама операція шляху також оголошує scope «items», отже він також буде у списку `security_scopes.scopes`, переданому до `get_current_user`. Сама операція шляху також оголошує scope `"items"`, отже він також буде у списку `security_scopes.scopes`, переданому до `get_current_user`.
Ось як виглядає ієрархія залежностей і scopes: Ось як виглядає ієрархія залежностей і scopes:

8
docs/uk/docs/advanced/settings.md

@ -100,7 +100,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
## Налаштування в іншому модулі { #settings-in-another-module } ## Налаштування в іншому модулі { #settings-in-another-module }
Ви можете розмістити ці налаштування в іншому модулі, як ви бачили в [Більші застосунки - кілька файлів](../tutorial/bigger-applications.md). Ви можете розмістити ці налаштування в іншому файлі модуля, як ви бачили в [Більші застосунки - кілька файлів](../tutorial/bigger-applications.md).
Наприклад, у вас може бути файл `config.py` з: Наприклад, у вас може бути файл `config.py` з:
@ -297,6 +297,6 @@ participant execute as Execute function
Ви можете використовувати Pydantic Settings для обробки налаштувань або конфігурацій вашого застосунку, з усією потужністю моделей Pydantic. Ви можете використовувати Pydantic Settings для обробки налаштувань або конфігурацій вашого застосунку, з усією потужністю моделей Pydantic.
- Використовуючи залежність, ви можете спростити тестування. * Використовуючи залежність, ви можете спростити тестування.
- Ви можете використовувати з ним файли `.env`. * Ви можете використовувати з ним файли `.env`.
- Використання `@lru_cache` дає змогу уникнути повторного читання файла dotenv для кожного запиту, водночас дозволяючи переписувати його під час тестування. * Використання `@lru_cache` дає змогу уникнути повторного читання файла dotenv для кожного запиту, водночас дозволяючи переписувати його під час тестування.

18
docs/uk/docs/advanced/stream-data.md

@ -2,7 +2,7 @@
Якщо ви хочете передавати потоком дані, які можна структурувати як JSON, див. [Потокова передача JSON Lines](../tutorial/stream-json-lines.md). Якщо ви хочете передавати потоком дані, які можна структурувати як JSON, див. [Потокова передача JSON Lines](../tutorial/stream-json-lines.md).
Але якщо ви хочете передавати потоком чисті бінарні дані або строки, ось як це зробити. Але якщо ви хочете передавати потоком **чисті бінарні дані** або строки, ось як це зробити.
/// note | Примітка /// note | Примітка
@ -12,21 +12,21 @@
## Варіанти використання { #use-cases } ## Варіанти використання { #use-cases }
Це можна використовувати, якщо ви хочете передавати потоком чисті строки, наприклад безпосередньо з виводу сервісу AI LLM. Це можна використовувати, якщо ви хочете передавати потоком чисті строки, наприклад безпосередньо з виводу сервісу **AI LLM**.
Також це можна використати для потокової передачі великих бінарних файлів, коли ви надсилаєте кожний фрагмент даних під час читання, без потреби завантажувати все в пам'ять одразу. Також це можна використати для потокової передачі **великих бінарних файлів**, коли ви надсилаєте кожний фрагмент даних під час читання, без потреби завантажувати все в пам'ять одразу.
Так само можна стрімити відео чи аудіо; їх навіть можна генерувати під час обробки та надсилання. Так само можна стрімити **відео** чи **аудіо**; їх навіть можна генерувати під час обробки та надсилання.
## `StreamingResponse` з `yield` { #a-streamingresponse-with-yield } ## `StreamingResponse` з `yield` { #a-streamingresponse-with-yield }
Якщо ви оголосите `response_class=StreamingResponse` у вашій функції операції шляху, ви можете використовувати `yield`, щоб послідовно надсилати кожний фрагмент даних. Якщо ви оголосите `response_class=StreamingResponse` у вашій *функції операції шляху*, ви можете використовувати `yield`, щоб послідовно надсилати кожний фрагмент даних.
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *} {* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
FastAPI передаватиме кожний фрагмент даних до `StreamingResponse` як є; він не намагатиметься перетворити його на JSON чи щось подібне. FastAPI передаватиме кожний фрагмент даних до `StreamingResponse` як є; він не намагатиметься перетворити його на JSON чи щось подібне.
### Не-async функції операції шляху { #non-async-path-operation-functions } ### Не-async *функції операції шляху* { #non-async-path-operation-functions }
Можна також використовувати звичайні функції `def` (без `async`) і так само застосовувати `yield`. Можна також використовувати звичайні функції `def` (без `async`) і так само застосовувати `yield`.
@ -40,7 +40,7 @@ FastAPI передаватиме кожний фрагмент даних до `
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *} {* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
Це також означає, що з `StreamingResponse` у вас є свобода і відповідальність формувати та кодувати байти даних саме так, як їх потрібно надіслати, незалежно від анотацій типів. 🤓 Це також означає, що з `StreamingResponse` у вас є **свобода** і **відповідальність** формувати та кодувати байти даних саме так, як їх потрібно надіслати, незалежно від анотацій типів. 🤓
### Потік байтів { #stream-bytes } ### Потік байтів { #stream-bytes }
@ -58,7 +58,7 @@ FastAPI передаватиме кожний фрагмент даних до `
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *} {* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
Потім ви можете використати цей новий клас у `response_class=PNGStreamingResponse` у вашій функції операції шляху: Потім ви можете використати цей новий клас у `response_class=PNGStreamingResponse` у вашій *функції операції шляху*:
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *} {* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
@ -98,7 +98,7 @@ FastAPI передаватиме кожний фрагмент даних до `
/// ///
Щоб уникнути блокування циклу подій, просто оголосіть функцію операції шляху зі звичайним `def` замість `async def`. Тоді FastAPI виконуватиме її в працівнику пулу потоків, щоб не блокувати головний цикл. Щоб уникнути блокування циклу подій, просто оголосіть *функцію операції шляху* зі звичайним `def` замість `async def`. Тоді FastAPI виконуватиме її в працівнику пулу потоків, щоб не блокувати головний цикл.
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *} {* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}

1
docs/uk/docs/advanced/wsgi.md

@ -1,5 +1,6 @@
# Підключення WSGI - Flask, Django та інші { #including-wsgi-flask-django-others } # Підключення WSGI - Flask, Django та інші { #including-wsgi-flask-django-others }
Ви можете монтувати застосунки WSGI, як ви бачили в [Підзастосунки - монтування](sub-applications.md), [За представником](behind-a-proxy.md). Ви можете монтувати застосунки WSGI, як ви бачили в [Підзастосунки - монтування](sub-applications.md), [За представником](behind-a-proxy.md).
Для цього ви можете використати `WSGIMiddleware` і обгорнути ним ваш застосунок WSGI, наприклад Flask, Django тощо. Для цього ви можете використати `WSGIMiddleware` і обгорнути ним ваш застосунок WSGI, наприклад Flask, Django тощо.

32
docs/uk/docs/alternatives.md

@ -44,11 +44,11 @@ Django REST Framework створив Том Крісті. Той самий тв
### [Flask](https://flask.palletsprojects.com) { #flask } ### [Flask](https://flask.palletsprojects.com) { #flask }
Flask це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django. Flask - це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django.
Ця простота та гнучкість дозволяють використовувати бази даних NoSQL як основну систему зберігання даних. Ця простота та гнучкість дозволяють використовувати бази даних NoSQL як основну систему зберігання даних.
Оскільки він дуже простий, він порівняно легкий та інтуїтивний для освоєння, хоча в деяких моментах документація стає дещо технічною. Оскільки він дуже простий, він порівняно інтуїтивний для освоєння, хоча в деяких моментах документація стає дещо технічною.
Він також зазвичай використовується для інших програм, яким не обов’язково потрібна база даних, керування користувачами або будь-яка з багатьох функцій, які є попередньо вбудованими в Django. Хоча багато з цих функцій можна додати за допомогою плагінів. Він також зазвичай використовується для інших програм, яким не обов’язково потрібна база даних, керування користувачами або будь-яка з багатьох функцій, які є попередньо вбудованими в Django. Хоча багато з цих функцій можна додати за допомогою плагінів.
@ -72,7 +72,7 @@ Flask — це «мікрофреймворк», він не включає ін
Але все ж FastAPI черпав натхнення з Requests. Але все ж FastAPI черпав натхнення з Requests.
**Requests** це бібліотека для *взаємодії* з API (як клієнт), а **FastAPI** це бібліотека для *створення* API (як сервер). **Requests** - це бібліотека для *взаємодії* з API (як клієнт), а **FastAPI** - це бібліотека для *створення* API (як сервер).
Вони більш-менш знаходяться на протилежних кінцях, доповнюючи одна одну. Вони більш-менш знаходяться на протилежних кінцях, доповнюючи одна одну.
@ -88,7 +88,7 @@ Requests мають дуже простий та інтуїтивно зрозу
response = requests.get("http://example.com/some/url") response = requests.get("http://example.com/some/url")
``` ```
Відповідна операція шляху API FastAPI може виглядати так: Відповідна *операція шляху* API FastAPI може виглядати так:
```Python hl_lines="1" ```Python hl_lines="1"
@app.get("/some/url") @app.get("/some/url")
@ -124,7 +124,7 @@ def read_url():
Інтегрувати інструменти інтерфейсу на основі стандартів: Інтегрувати інструменти інтерфейсу на основі стандартів:
* [Інтерфейс Swagger](https://github.com/swagger-api/swagger-ui) * [Swagger UI](https://github.com/swagger-api/swagger-ui)
* [ReDoc](https://github.com/Rebilly/ReDoc) * [ReDoc](https://github.com/Rebilly/ReDoc)
Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**). Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**).
@ -157,7 +157,7 @@ Marshmallow створено для забезпечення цих функці
Іншою важливою функцією, необхідною для API, є <dfn title="читання та перетворення на дані Python">аналіз</dfn> даних із вхідних запитів. Іншою важливою функцією, необхідною для API, є <dfn title="читання та перетворення на дані Python">аналіз</dfn> даних із вхідних запитів.
Webargs це інструмент, створений, щоб забезпечити це поверх кількох фреймворків, включаючи Flask. Webargs - це інструмент, створений, щоб забезпечити це поверх кількох фреймворків, включаючи Flask.
Він використовує Marshmallow в основі для перевірки даних. І створений тими ж розробниками. Він використовує Marshmallow в основі для перевірки даних. І створений тими ж розробниками.
@ -239,7 +239,7 @@ Flask-apispec був створений тими ж розробниками Mar
### [NestJS](https://nestjs.com/) (та [Angular](https://angular.io/)) { #nestjs-and-angular } ### [NestJS](https://nestjs.com/) (та [Angular](https://angular.io/)) { #nestjs-and-angular }
Це навіть не Python, NestJS це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular. Це навіть не Python, NestJS - це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular.
Це досягає чогось подібного до того, що можна зробити з Flask-apispec. Це досягає чогось подібного до того, що можна зробити з Flask-apispec.
@ -281,7 +281,7 @@ Flask-apispec був створений тими ж розробниками Mar
### [Falcon](https://falconframework.org/) { #falcon } ### [Falcon](https://falconframework.org/) { #falcon }
Falcon ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug. Falcon - ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug.
Він розроблений таким чином, щоб мати функції, які отримують два параметри, один «запит» і один «відповідь». Потім ви «читаєте» частини запиту та «записуєте» частини у відповідь. Через такий дизайн неможливо оголосити параметри запиту та тіла за допомогою стандартних підказок типу Python як параметри функції. Він розроблений таким чином, щоб мати функції, які отримують два параметри, один «запит» і один «відповідь». Потім ви «читаєте» частини запиту та «записуєте» частини у відповідь. Через такий дизайн неможливо оголосити параметри запиту та тіла за допомогою стандартних підказок типу Python як параметри функції.
@ -351,7 +351,7 @@ Hug надихнув **FastAPI** оголосити параметр `response`
/// ///
### [APIStar](https://github.com/encode/apistar) (<= 0,5) { #apistar-0-5 } ### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 }
Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн. Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн.
@ -373,7 +373,7 @@ Hug надихнув **FastAPI** оголосити параметр `response`
Це вже не був веб-фреймворк API, оскільки творцю потрібно було зосередитися на Starlette. Це вже не був веб-фреймворк API, оскільки творцю потрібно було зосередитися на Starlette.
Тепер APIStar це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк. Тепер APIStar - це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк.
/// note | Примітка /// note | Примітка
@ -403,7 +403,7 @@ APIStar створив Том Крісті. Той самий хлопець, я
### [Pydantic](https://docs.pydantic.dev/) { #pydantic } ### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
Pydantic це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою Схеми JSON) на основі підказок типу Python. Pydantic - це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою Схеми JSON) на основі підказок типу Python.
Це робить його надзвичайно інтуїтивним. Це робить його надзвичайно інтуїтивним.
@ -419,7 +419,7 @@ Pydantic — це бібліотека для визначення переві
### [Starlette](https://www.starlette.dev/) { #starlette } ### [Starlette](https://www.starlette.dev/) { #starlette }
Starlette це легкий фреймворк/набір інструментів <dfn title="Новий стандарт для створення асинхронних вебзастосунків на Python">ASGI</dfn>, який ідеально підходить для створення високопродуктивних asyncio сервісів. Starlette - це легкий фреймворк/набір інструментів <dfn title="Новий стандарт для створення асинхронних вебзастосунків на Python">ASGI</dfn>, який ідеально підходить для створення високопродуктивних asyncio сервісів.
Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти. Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти.
@ -433,7 +433,7 @@ Starlette — це легкий фреймворк/набір інструмен
* CORS, GZip, статичні файли, потокові відповіді. * CORS, GZip, статичні файли, потокові відповіді.
* Підтримку сеансів і кукі. * Підтримку сеансів і кукі.
* 100% покриття тестом. * 100% покриття тестом.
* 100% анотовану кодову базу. * 100% анотовану типами кодову базу.
* Кілька жорстких залежностей. * Кілька жорстких залежностей.
Starlette наразі є найшвидшим фреймворком Python із перевірених. Перевершує лише Uvicorn, який є не фреймворком, а сервером. Starlette наразі є найшвидшим фреймворком Python із перевірених. Перевершує лише Uvicorn, який є не фреймворком, а сервером.
@ -446,7 +446,7 @@ Starlette надає всі основні функції веб-мікрофр
/// note | Технічні деталі /// note | Технічні деталі
ASGI це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього. ASGI - це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього.
Тим не менш, він уже використовується як «стандарт» кількома інструментами. Це значно покращує сумісність, оскільки ви можете переключити Uvicorn на будь-який інший сервер ASGI (наприклад, Daphne або Hypercorn), або ви можете додати інструменти, сумісні з ASGI, як-от `python-socketio`. Тим не менш, він уже використовується як «стандарт» кількома інструментами. Це значно покращує сумісність, оскільки ви можете переключити Uvicorn на будь-який інший сервер ASGI (наприклад, Daphne або Hypercorn), або ви можете додати інструменти, сумісні з ASGI, як-от `python-socketio`.
@ -464,9 +464,9 @@ ASGI — це новий «стандарт», який розробляєтьс
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn } ### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
Uvicorn це блискавичний сервер ASGI, побудований на uvloop і httptools. Uvicorn - це блискавичний сервер ASGI, побудований на uvloop і httptools.
Це не веб-фреймворк, а сервер. Наприклад, він не надає інструментів для маршрутизації. Це те, що фреймворк на кшталт Starlette (або **FastAPI**) забезпечить поверх нього. Це не веб-фреймворк, а сервер. Наприклад, він не надає інструментів для маршрутизації за шляхами. Це те, що фреймворк на кшталт Starlette (або **FastAPI**) забезпечить поверх нього.
Це рекомендований сервер для Starlette і **FastAPI**. Це рекомендований сервер для Starlette і **FastAPI**.

46
docs/uk/docs/async.md

@ -1,6 +1,6 @@
# Рівночасність і async / await { #concurrency-and-async-await } # Рівночасність і async / await { #concurrency-and-async-await }
Деталі щодо синтаксису `async def` для функцій операції шляху і деякі відомості про асинхронний код, рівночасність і паралелізм. Деталі щодо синтаксису `async def` для *функцій операції шляху* і деякі відомості про асинхронний код, рівночасність і паралелізм.
## Поспішаєте? { #in-a-hurry } ## Поспішаєте? { #in-a-hurry }
@ -12,7 +12,7 @@
results = await some_library() results = await some_library()
``` ```
Тоді оголошуйте ваші функції операції шляху з `async def`, наприклад: Тоді оголошуйте ваші *функції операції шляху* з `async def`, наприклад:
```Python hl_lines="2" ```Python hl_lines="2"
@app.get('/') @app.get('/')
@ -29,7 +29,7 @@ async def read_results():
--- ---
Якщо ви використовуєте сторонню бібліотеку, яка взаємодіє з чимось (база даних, API, файлова система тощо) і не підтримує використання `await` (наразі це стосується більшості бібліотек баз даних), тоді оголошуйте ваші функції операції шляху як зазвичай, просто з `def`, наприклад: Якщо ви використовуєте сторонню бібліотеку, яка взаємодіє з чимось (база даних, API, файлова система тощо) і не підтримує використання `await` (наразі це стосується більшості бібліотек баз даних), тоді оголошуйте ваші *функції операції шляху* як зазвичай, просто з `def`, наприклад:
```Python hl_lines="2" ```Python hl_lines="2"
@app.get('/') @app.get('/')
@ -48,7 +48,7 @@ def results():
--- ---
Примітка: ви можете змішувати `def` і `async def` у ваших функціях операції шляху скільки завгодно і визначати кожну з них найкращим для вас способом. FastAPI зробить з ними все правильно. **Примітка**: ви можете змішувати `def` і `async def` у ваших *функціях операції шляху* скільки завгодно і визначати кожну з них найкращим для вас способом. FastAPI зробить з ними все правильно.
У будь-якому з наведених випадків FastAPI все одно працюватиме асинхронно і буде надзвичайно швидким. У будь-якому з наведених випадків FastAPI все одно працюватиме асинхронно і буде надзвичайно швидким.
@ -56,17 +56,17 @@ def results():
## Технічні деталі { #technical-details } ## Технічні деталі { #technical-details }
Сучасні версії Python мають підтримку «асинхронного коду» за допомогою так званих «співпрограм» з синтаксисом **`async` і `await`**. Сучасні версії Python мають підтримку **«асинхронного коду»** за допомогою так званих **«співпрограм»** з синтаксисом **`async` і `await`**.
Розгляньмо цю фразу по частинах у секціях нижче: Розгляньмо цю фразу по частинах у секціях нижче:
- Асинхронний код - **Асинхронний код**
- `async` і `await` - **`async` і `await`**
- Співпрограми - **Співпрограми**
## Асинхронний код { #asynchronous-code } ## Асинхронний код { #asynchronous-code }
Асинхронний код означає, що мова 💬 має спосіб сказати комп’ютеру/програмі 🤖, що в певний момент у коді він 🤖 має почекати, поки «щось інше» завершиться десь ще. Скажімо, це «щось інше» називається «slow-file» 📝. Асинхронний код означає, що мова 💬 має спосіб сказати комп’ютеру/програмі 🤖, що в певний момент у коді він 🤖 має почекати, поки *«щось інше»* завершиться десь ще. Скажімо, це *«щось інше»* називається «slow-file» 📝.
Отже, в цей час комп’ютер може піти і зробити іншу роботу, доки «slow-file» 📝 завершується. Отже, в цей час комп’ютер може піти і зробити іншу роботу, доки «slow-file» 📝 завершується.
@ -97,9 +97,9 @@ def results():
Ідею **асинхронного** коду, описану вище, інколи також називають **«рівночасністю»**. Вона відрізняється від **«паралелізму»**. Ідею **асинхронного** коду, описану вище, інколи також називають **«рівночасністю»**. Вона відрізняється від **«паралелізму»**.
І рівночасність, і паралелізм стосуються «різних речей, що відбуваються більш-менш одночасно». **Рівночасність** і **паралелізм** стосуються «різних речей, що відбуваються більш-менш одночасно».
Але деталі між рівночасністю і паралелізмом досить різні. Але деталі між *рівночасністю* і *паралелізмом* досить різні.
Щоб побачити різницю, уявімо таку історію про бургери: Щоб побачити різницю, уявімо таку історію про бургери:
@ -257,7 +257,7 @@ def results():
Ні! Це не мораль історії. Ні! Це не мораль історії.
Рівночасність відрізняється від паралелізму. І вона краща у конкретних сценаріях, що містять багато очікування. Через це зазвичай вона значно краща за паралелізм для розробки вебзастосунків. Але не для всього. Рівночасність відрізняється від паралелізму. І вона краща у **конкретних** сценаріях, що містять багато очікування. Через це зазвичай вона значно краща за паралелізм для розробки вебзастосунків. Але не для всього.
Щоб урівноважити це, уявімо коротку історію: Щоб урівноважити це, уявімо коротку історію:
@ -273,15 +273,15 @@ def results():
Завершення займе той самий час із «чергами» чи без (рівночасність), і ви виконаєте той самий обсяг роботи. Завершення займе той самий час із «чергами» чи без (рівночасність), і ви виконаєте той самий обсяг роботи.
Але в цьому випадку, якби ви могли привести 8 колишніх касирів/кухарів/тепер прибиральників, і кожен з них (разом із вами) взяв би свою зону будинку для прибирання, ви могли б виконати всю роботу паралельно — з додатковою допомогою — і завершити значно швидше. Але в цьому випадку, якби ви могли привести 8 колишніх касирів/кухарів/тепер прибиральників, і кожен з них (разом із вами) взяв би свою зону будинку для прибирання, ви могли б виконати всю роботу **паралельно** - з додатковою допомогою - і завершити значно швидше.
У цьому сценарії кожен з прибиральників (включно з вами) був би процесором, що виконує свою частину роботи. У цьому сценарії кожен з прибиральників (включно з вами) був би процесором, що виконує свою частину роботи.
І оскільки більшість часу виконання займає реальна робота (а не очікування), а роботу на комп’ютері виконує <abbr title="Central Processing Unit - Центральний процесор">CPU</abbr>, ці проблеми називають «CPU bound». І оскільки більшість часу виконання займає реальна робота (а не очікування), а роботу на комп’ютері виконує <abbr title="Central Processing Unit - Центральний процесор">CPU</abbr>, ці проблеми називають **«CPU bound»**.
--- ---
Поширені приклади «CPU bound» операцій - це речі, що потребують складної математичної обробки. Поширені приклади **CPU bound** операцій - це речі, що потребують складної математичної обробки.
Наприклад: Наприклад:
@ -294,7 +294,7 @@ def results():
З **FastAPI** ви можете скористатися рівночасністю, що дуже поширена у веброзробці (та ж головна принада NodeJS). З **FastAPI** ви можете скористатися рівночасністю, що дуже поширена у веброзробці (та ж головна принада NodeJS).
Але ви також можете використати переваги паралелізму і багатопроцесорності (наявність кількох процесів, що працюють паралельно) для навантажень «CPU bound», як у системах машинного навчання. Але ви також можете використати переваги паралелізму і багатопроцесорності (наявність кількох процесів, що працюють паралельно) для навантажень **«CPU bound»**, як у системах машинного навчання.
Це, плюс простий факт, що Python є основною мовою для **Data Science**, машинного навчання і особливо глибокого навчання, робить FastAPI дуже вдалим вибором для веб API та застосунків Data Science / машинного навчання (серед багатьох інших). Це, плюс простий факт, що Python є основною мовою для **Data Science**, машинного навчання і особливо глибокого навчання, робить FastAPI дуже вдалим вибором для веб API та застосунків Data Science / машинного навчання (серед багатьох інших).
@ -340,7 +340,7 @@ burgers = get_burgers(2)
--- ---
Отже, якщо ви використовуєте бібліотеку, яку можна викликати з `await`, вам потрібно створити функцію операції шляху, що її використовує, з `async def`, як тут: Отже, якщо ви використовуєте бібліотеку, яку можна викликати з `await`, вам потрібно створити *функцію операції шляху*, що її використовує, з `async def`, як тут:
```Python hl_lines="2-3" ```Python hl_lines="2-3"
@app.get('/burgers') @app.get('/burgers')
@ -357,7 +357,7 @@ async def read_burgers():
Тож як же викликати першу `async`-функцію - курка чи яйце? Тож як же викликати першу `async`-функцію - курка чи яйце?
Якщо ви працюєте з **FastAPI**, вам не потрібно про це турбуватися, адже цією «першою» функцією буде ваша функція операції шляху, і FastAPI знатиме, як учинити правильно. Якщо ви працюєте з **FastAPI**, вам не потрібно про це турбуватися, адже цією «першою» функцією буде ваша *функція операції шляху*, і FastAPI знатиме, як учинити правильно.
Але якщо ви хочете використовувати `async` / `await` без FastAPI, ви також можете це зробити. Але якщо ви хочете використовувати `async` / `await` без FastAPI, ви також можете це зробити.
@ -395,7 +395,7 @@ Starlette (і **FastAPI**) базуються на [AnyIO](https://anyio.readthe
Погляньмо на ту саму фразу ще раз: Погляньмо на ту саму фразу ще раз:
> Сучасні версії Python мають підтримку «асинхронного коду» за допомогою так званих «співпрограм», з синтаксисом **`async` і `await`**. > Сучасні версії Python мають підтримку **«асинхронного коду»** за допомогою так званих **«співпрограм»**, з синтаксисом **`async` і `await`**.
Тепер це має більше сенсу. ✨ Тепер це має більше сенсу. ✨
@ -415,11 +415,11 @@ Starlette (і **FastAPI**) базуються на [AnyIO](https://anyio.readthe
### Функції операції шляху { #path-operation-functions } ### Функції операції шляху { #path-operation-functions }
Коли ви оголошуєте функцію операції шляху зі звичайним `def` замість `async def`, вона виконується у зовнішньому пулі потоків (threadpool), який потім «очікується», замість прямого виклику (оскільки прямий виклик блокував би сервер). Коли ви оголошуєте *функцію операції шляху* зі звичайним `def` замість `async def`, вона виконується у зовнішньому пулі потоків (threadpool), який потім «очікується», замість прямого виклику (оскільки прямий виклик блокував би сервер).
Якщо ви прийшли з іншого async-фреймворку, який не працює так, як описано вище, і звикли визначати тривіальні, лише обчислювальні функції операції шляху зі звичайним `def` заради крихітного виграшу у продуктивності (близько 100 наносекунд), зверніть увагу, що у **FastAPI** ефект буде протилежним. У таких випадках краще використовувати `async def`, якщо тільки ваші функції операції шляху не використовують код, що виконує блокуюче <abbr title="Input/Output - Ввід/Вивід: читання або запис на диск, мережеві комунікації.">I/O</abbr>. Якщо ви прийшли з іншого async-фреймворку, який не працює так, як описано вище, і звикли визначати тривіальні, лише обчислювальні *функції операції шляху* зі звичайним `def` заради крихітного виграшу у продуктивності (близько 100 наносекунд), зверніть увагу, що у **FastAPI** ефект буде протилежним. У таких випадках краще використовувати `async def`, якщо тільки ваші *функції операції шляху* не використовують код, що виконує блокуюче <abbr title="Input/Output - Ввід/Вивід: читання або запис на диск, мережеві комунікації.">I/O</abbr>.
Втім, у будь-якій ситуації є велика ймовірність, що **FastAPI** [все одно буде швидшим](index.md#performance) (або принаймні порівнянним) за ваш попередній фреймворк. Втім, в обох ситуаціях є велика ймовірність, що **FastAPI** [все одно буде швидшим](index.md#performance) (або принаймні порівнянним) за ваш попередній фреймворк.
### Залежності { #dependencies } ### Залежності { #dependencies }
@ -433,7 +433,7 @@ Starlette (і **FastAPI**) базуються на [AnyIO](https://anyio.readthe
Будь-яка інша допоміжна функція, яку ви викликаєте безпосередньо, може бути створена зі звичайним `def` або `async def`, і FastAPI не впливатиме на спосіб її виклику. Будь-яка інша допоміжна функція, яку ви викликаєте безпосередньо, може бути створена зі звичайним `def` або `async def`, і FastAPI не впливатиме на спосіб її виклику.
Це відрізняється від функцій, які FastAPI викликає за вас: функції операції шляху і залежності. Це відрізняється від функцій, які FastAPI викликає за вас: *функції операції шляху* і залежності.
Якщо ваша допоміжна функція є звичайною функцією з `def`, її буде викликано безпосередньо (як ви написали у своєму коді), не в пулі потоків; якщо функція створена з `async def`, тоді вам слід використовувати `await` при її виклику у вашому коді. Якщо ваша допоміжна функція є звичайною функцією з `def`, її буде викликано безпосередньо (як ви написали у своєму коді), не в пулі потоків; якщо функція створена з `async def`, тоді вам слід використовувати `await` при її виклику у вашому коді.

2
docs/uk/docs/deployment/cloud.md

@ -16,7 +16,7 @@ FastAPI Cloud є основним спонсором і джерелом фін
## Хмарні постачальники - спонсори { #cloud-providers-sponsors } ## Хмарні постачальники - спонсори { #cloud-providers-sponsors }
Деякі інші хмарні постачальники ✨ [**спонсорують FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ також. 🙇 Деякі інші хмарні постачальники ✨ [**спонсорують FastAPI**](https://github.com/sponsors/tiangolo) ✨ також. 🙇
Можливо, ви захочете розглянути їх, щоб дотримуватися їхніх інструкцій і спробувати їхні сервіси: Можливо, ви захочете розглянути їх, щоб дотримуватися їхніх інструкцій і спробувати їхні сервіси:

28
docs/uk/docs/deployment/concepts.md

@ -5,11 +5,11 @@
Деякі важливі концепції: Деякі важливі концепції:
- Безпека - HTTPS - Безпека - HTTPS
- Запуск під час старту - Запуск під час запуску
- Перезапуски - Перезапуски
- Реплікація (кількість запущених процесів) - Реплікація (кількість запущених процесів)
- Пам'ять - Пам'ять
- Попередні кроки перед стартом - Попередні кроки перед запуском
Подивимось, як вони впливають на **розгортання**. Подивимось, як вони впливають на **розгортання**.
@ -88,7 +88,7 @@
Тепер, коли ми знаємо різницю між термінами **процес** і **програма**, продовжимо говорити про розгортання. Тепер, коли ми знаємо різницю між термінами **процес** і **програма**, продовжимо говорити про розгортання.
## Запуск під час старту { #running-on-startup } ## Запуск під час запуску { #running-on-startup }
У більшості випадків, коли ви створюєте веб-API, ви хочете, щоб він **працював постійно**, без перерв, щоб клієнти завжди мали до нього доступ. Звісно, якщо немає особливих причин запускати його лише в певних ситуаціях. Але зазвичай ви хочете, щоб він постійно працював і був **доступний**. У більшості випадків, коли ви створюєте веб-API, ви хочете, щоб він **працював постійно**, без перерв, щоб клієнти завжди мали до нього доступ. Звісно, якщо немає особливих причин запускати його лише в певних ситуаціях. Але зазвичай ви хочете, щоб він постійно працював і був **доступний**.
@ -102,15 +102,15 @@
І якщо сервер буде перезавантажено (наприклад, після оновлень або міграцій у хмарного провайдера), ви, ймовірно, **не помітите цього**. І через це ви навіть не знатимете, що треба вручну перезапустити процес. У результаті ваш API просто залишиться «мертвим». 😱 І якщо сервер буде перезавантажено (наприклад, після оновлень або міграцій у хмарного провайдера), ви, ймовірно, **не помітите цього**. І через це ви навіть не знатимете, що треба вручну перезапустити процес. У результаті ваш API просто залишиться «мертвим». 😱
### Автоматичний запуск під час старту { #run-automatically-on-startup } ### Автоматичний запуск під час запуску { #run-automatically-on-startup }
Загалом ви, напевно, захочете, щоб серверна програма (наприклад, Uvicorn) запускалася автоматично під час старту сервера і без будь-якого **людського втручання**, щоб завжди був запущений процес із вашим API (наприклад, Uvicorn із вашим FastAPI-застосунком). Загалом ви, напевно, захочете, щоб серверна програма (наприклад, Uvicorn) запускалася автоматично під час запуску сервера і без будь-якого **людського втручання**, щоб завжди був запущений процес із вашим API (наприклад, Uvicorn із вашим FastAPI-застосунком).
### Окрема програма { #separate-program } ### Окрема програма { #separate-program }
Щоб цього досягти, зазвичай використовують **окрему програму**, яка гарантує запуск вашого застосунку під час старту. І в багатьох випадках вона також забезпечує запуск інших компонентів або застосунків, наприклад бази даних. Щоб цього досягти, зазвичай використовують **окрему програму**, яка гарантує запуск вашого застосунку під час запуску. І в багатьох випадках вона також забезпечує запуск інших компонентів або застосунків, наприклад бази даних.
### Приклади інструментів для запуску під час старту { #example-tools-to-run-at-startup } ### Приклади інструментів для запуску під час запуску { #example-tools-to-run-at-startup }
Приклади інструментів, які можуть це робити: Приклади інструментів, які можуть це робити:
@ -127,7 +127,7 @@
## Перезапуски { #restarts } ## Перезапуски { #restarts }
Подібно до забезпечення запуску застосунку під час старту системи, ви, ймовірно, також захочете гарантувати його **перезапуск** після збоїв. Подібно до забезпечення запуску застосунку під час запуску системи, ви, ймовірно, також захочете гарантувати його **перезапуск** після збоїв.
### Ми помиляємося { #we-make-mistakes } ### Ми помиляємося { #we-make-mistakes }
@ -163,7 +163,7 @@
### Приклади інструментів для автоматичного перезапуску { #example-tools-to-restart-automatically } ### Приклади інструментів для автоматичного перезапуску { #example-tools-to-restart-automatically }
У більшості випадків той самий інструмент, який використовується для **запуску програми під час старту**, також використовується для автоматичних **перезапусків**. У більшості випадків той самий інструмент, який використовується для **запуску програми під час запуску**, також використовується для автоматичних **перезапусків**.
Наприклад, це можуть забезпечувати: Наприклад, це можуть забезпечувати:
@ -192,7 +192,7 @@
Пам'ятаєте з документації [Про HTTPS](https.md), що на сервері лише один процес може слухати певну комбінацію порту та IP-адреси? Пам'ятаєте з документації [Про HTTPS](https.md), що на сервері лише один процес може слухати певну комбінацію порту та IP-адреси?
Это досі так. Це досі так.
Отже, щоб мати **кілька процесів** одночасно, має бути **єдиний процес, який слухає порт**, і який далі якимось чином передає комунікацію кожному процесу-працівнику. Отже, щоб мати **кілька процесів** одночасно, має бути **єдиний процес, який слухає порт**, і який далі якимось чином передає комунікацію кожному процесу-працівнику.
@ -247,9 +247,9 @@
/// ///
## Попередні кроки перед стартом { #previous-steps-before-starting } ## Попередні кроки перед запуском { #previous-steps-before-starting }
Є багато випадків, коли потрібно виконати деякі кроки **перед стартом** вашого застосунку. Є багато випадків, коли потрібно виконати деякі кроки **перед запуском** вашого застосунку.
Наприклад, ви можете захотіти запустити **міграції бази даних**. Наприклад, ви можете захотіти запустити **міграції бази даних**.
@ -310,11 +310,11 @@
Тут ви прочитали про основні концепції, які, ймовірно, потрібно тримати в голові, вирішуючи, як розгортати ваш застосунок: Тут ви прочитали про основні концепції, які, ймовірно, потрібно тримати в голові, вирішуючи, як розгортати ваш застосунок:
- Безпека - HTTPS - Безпека - HTTPS
- Запуск під час старту - Запуск під час запуску
- Перезапуски - Перезапуски
- Реплікація (кількість запущених процесів) - Реплікація (кількість запущених процесів)
- Пам'ять - Пам'ять
- Попередні кроки перед стартом - Попередні кроки перед запуском
Розуміння цих ідей і того, як їх застосовувати, має дати вам інтуїцію, необхідну для прийняття рішень під час конфігурування і тонкого налаштування ваших розгортань. 🤓 Розуміння цих ідей і того, як їх застосовувати, має дати вам інтуїцію, необхідну для прийняття рішень під час конфігурування і тонкого налаштування ваших розгортань. 🤓

178
docs/uk/docs/deployment/docker.md

@ -1,8 +1,8 @@
# FastAPI у контейнерах - Docker { #fastapi-in-containers-docker } # FastAPI у контейнерах - Docker { #fastapi-in-containers-docker }
Під час розгортання застосунків FastAPI поширений підхід - збирати образи контейнерів Linux. Зазвичай це робиться за допомогою [Docker](https://www.docker.com/). Потім ви можете розгорнути цей образ контейнера кількома різними способами. Під час розгортання застосунків FastAPI поширений підхід - збирати **образи контейнерів Linux**. Зазвичай це робиться за допомогою [**Docker**](https://www.docker.com/). Потім ви можете розгорнути цей образ контейнера кількома різними способами.
Використання контейнерів Linux має кілька переваг, зокрема безпека, відтворюваність, простота та інші. Використання контейнерів Linux має кілька переваг, зокрема **безпека**, **відтворюваність**, **простота** та інші.
/// tip | Порада /// tip | Порада
@ -34,33 +34,33 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
## Що таке контейнер { #what-is-a-container } ## Що таке контейнер { #what-is-a-container }
Контейнери (переважно контейнери Linux) - це дуже легкий спосіб упакувати застосунки з усіма їхніми залежностями та потрібними файлами, ізолювавши їх від інших контейнерів (інших застосунків або компонентів) у тій самій системі. Контейнери (переважно контейнери Linux) - це дуже **легкий** спосіб упакувати застосунки з усіма їхніми залежностями та потрібними файлами, ізолювавши їх від інших контейнерів (інших застосунків або компонентів) у тій самій системі.
Контейнери Linux працюють, використовуючи той самий ядро Linux, що й хост (машина, віртуальна машина, хмарний сервер тощо). Це означає, що вони дуже легкі (у порівнянні з повними віртуальними машинами, які емулюють цілу операційну систему). Контейнери Linux працюють, використовуючи те саме ядро Linux, що й хост (машина, віртуальна машина, хмарний сервер тощо). Це означає, що вони дуже легкі (у порівнянні з повними віртуальними машинами, які емулюють цілу операційну систему).
Таким чином контейнери споживають мало ресурсів, приблизно як безпосередньо запущені процеси (віртуальна машина споживала б значно більше). Таким чином контейнери споживають **мало ресурсів**, приблизно як безпосередньо запущені процеси (віртуальна машина споживала б значно більше).
У контейнерів також є власні ізольовані процеси виконання (зазвичай лише один процес), файлові системи та мережі, що спрощує розгортання, безпеку, розробку тощо. У контейнерів також є власні **ізольовані** процеси виконання (зазвичай лише один процес), файлові системи та мережі, що спрощує розгортання, безпеку, розробку тощо.
## Що таке образ контейнера { #what-is-a-container-image } ## Що таке образ контейнера { #what-is-a-container-image }
Контейнер запускається з образу контейнера. **Контейнер** запускається з **образу контейнера**.
Образ контейнера - це статична версія всіх файлів, змінних оточення та типова команда/програма, яка має бути присутня в контейнері. Тут «статична» означає, що образ контейнера не запущений, він не виконується, це лише упаковані файли та метадані. Образ контейнера - це **статична** версія всіх файлів, змінних оточення та типова команда/програма, яка має бути присутня в контейнері. Тут **«статична»** означає, що **образ** контейнера не запущений, він не виконується, це лише упаковані файли та метадані.
На противагу «образу контейнера», що є збереженим статичним вмістом, «контейнер» зазвичай означає запущений екземпляр, те, що виконується. На противагу «**образу контейнера**», що є збереженим статичним вмістом, «**контейнер**» зазвичай означає запущений екземпляр, те, що **виконується**.
Коли контейнер запущено (запущений з образу контейнера), він може створювати або змінювати файли, змінні оточення тощо. Ці зміни існуватимуть лише в цьому контейнері, але не збережуться в базовому образі контейнера (не будуть записані на диск). Коли **контейнер** запущено (запущений з **образу контейнера**), він може створювати або змінювати файли, змінні оточення тощо. Ці зміни існуватимуть лише в цьому контейнері, але не збережуться в базовому образі контейнера (не будуть записані на диск).
Образ контейнера можна порівняти з файлом і вмістом програми, наприклад `python` і файлом `main.py`. Образ контейнера можна порівняти з файлом і вмістом **програми**, наприклад `python` і файлом `main.py`.
А сам контейнер (на відміну від образу) - це фактично запущений екземпляр образу, порівнянний із процесом. Насправді контейнер працює лише тоді, коли в ньому працює процес (і зазвичай це один процес). Контейнер зупиняється, коли в ньому не працює жоден процес. А сам **контейнер** (на відміну від **образу контейнера**) - це фактично запущений екземпляр образу, порівнянний із **процесом**. Насправді контейнер працює лише тоді, коли в ньому **працює процес** (і зазвичай це один процес). Контейнер зупиняється, коли в ньому не працює жоден процес.
## Образи контейнерів { #container-images } ## Образи контейнерів { #container-images }
Docker був одним з основних інструментів для створення та керування образами контейнерів і контейнерами. Docker був одним з основних інструментів для створення та керування **образами контейнерів** і **контейнерами**.
Існує публічний [Docker Hub](https://hub.docker.com/) з готовими офіційними образами для багатьох інструментів, середовищ, баз даних і застосунків. Існує публічний [Docker Hub](https://hub.docker.com/) з готовими **офіційними образами контейнерів** для багатьох інструментів, середовищ, баз даних і застосунків.
Наприклад, є офіційний [образ Python](https://hub.docker.com/_/python). Наприклад, є офіційний [образ Python](https://hub.docker.com/_/python).
@ -71,43 +71,43 @@ Docker був одним з основних інструментів для с
* [MongoDB](https://hub.docker.com/_/mongo) * [MongoDB](https://hub.docker.com/_/mongo)
* [Redis](https://hub.docker.com/_/redis) тощо. * [Redis](https://hub.docker.com/_/redis) тощо.
Використовуючи готовий образ контейнера, дуже легко поєднувати та використовувати різні інструменти. Наприклад, щоб випробувати нову базу даних. У більшості випадків ви можете використати офіційні образи та просто налаштувати їх змінними оточення. Використовуючи готовий образ контейнера, дуже легко **поєднувати** та використовувати різні інструменти. Наприклад, щоб випробувати нову базу даних. У більшості випадків ви можете використати **офіційні образи** та просто налаштувати їх змінними оточення.
Таким чином, у багатьох випадках ви зможете навчитися працювати з контейнерами і Docker та повторно використати ці знання з багатьма різними інструментами і компонентами. Таким чином, у багатьох випадках ви зможете навчитися працювати з контейнерами і Docker та повторно використати ці знання з багатьма різними інструментами і компонентами.
Тобто ви запускатимете кілька контейнерів з різними речами, як-от базу даних, застосунок на Python, вебсервер із фронтендом на React, і з’єднаєте їх через внутрішню мережу. Тобто ви запускатимете **кілька контейнерів** з різними речами, як-от базу даних, застосунок на Python, вебсервер із фронтендом на React, і з’єднаєте їх через внутрішню мережу.
Усі системи керування контейнерами (як Docker чи Kubernetes) мають ці мережеві можливості вбудовано. Усі системи керування контейнерами (як Docker чи Kubernetes) мають ці мережеві можливості вбудовано.
## Контейнери і процеси { #containers-and-processes } ## Контейнери і процеси { #containers-and-processes }
Образ контейнера зазвичай містить у своїх метаданих типову програму або команду, яку слід виконати під час запуску контейнера, і параметри для цієї програми. Дуже схоже на те, що ви б виконали в командному рядку. **Образ контейнера** зазвичай містить у своїх метаданих типову програму або команду, яку слід виконати під час запуску **контейнера**, і параметри для цієї програми. Дуже схоже на те, що ви б виконали в командному рядку.
Коли контейнер запускається, він виконає цю команду/програму (хоча ви можете перевизначити її і запустити іншу команду/програму). Коли **контейнер** запускається, він виконає цю команду/програму (хоча ви можете перевизначити її і запустити іншу команду/програму).
Контейнер працює доти, доки працює головний процес (команда або програма). Контейнер працює доти, доки працює **головний процес** (команда або програма).
Зазвичай контейнер має один процес, але також можливо запускати підпроцеси з головного процесу, і таким чином у вас може бути кілька процесів у тому самому контейнері. Зазвичай контейнер має **один процес**, але також можливо запускати підпроцеси з головного процесу, і таким чином у вас може бути **кілька процесів** у тому самому контейнері.
Але неможливо мати запущений контейнер без принаймні одного запущеного процесу. Якщо головний процес зупиняється, контейнер зупиняється. Але неможливо мати запущений контейнер без **принаймні одного запущеного процесу**. Якщо головний процес зупиняється, контейнер зупиняється.
## Зібрати Docker-образ для FastAPI { #build-a-docker-image-for-fastapi } ## Зібрати Docker-образ для FastAPI { #build-a-docker-image-for-fastapi }
Гаразд, зберімо щось зараз! 🚀 Гаразд, зберімо щось зараз! 🚀
Я покажу вам, як зібрати образ Docker для FastAPI з нуля на основі офіційного образу Python. Я покажу вам, як зібрати **образ Docker** для FastAPI **з нуля** на основі **офіційного образу Python**.
Це те, що ви захочете робити у більшості випадків, наприклад: Це те, що ви захочете робити у **більшості випадків**, наприклад:
* Використання Kubernetes або подібних інструментів * Використання **Kubernetes** або подібних інструментів
* Під час запуску на Raspberry Pi * Під час запуску на **Raspberry Pi**
* Використання хмарного сервісу, який запустить для вас образ контейнера тощо * Використання хмарного сервісу, який запустить для вас образ контейнера тощо
### Вимоги до пакетів { #package-requirements } ### Вимоги до пакетів { #package-requirements }
Зазвичай ви маєте вимоги до пакетів для вашого застосунку в окремому файлі. Зазвичай ви маєте **вимоги до пакетів** для вашого застосунку в окремому файлі.
Це залежить переважно від інструменту, який ви використовуєте для встановлення цих вимог. Це залежить переважно від інструменту, який ви використовуєте для **встановлення** цих вимог.
Найпоширеніший спосіб - мати файл `requirements.txt` з назвами пакетів і їхніми версіями, по одному на рядок. Найпоширеніший спосіб - мати файл `requirements.txt` з назвами пакетів і їхніми версіями, по одному на рядок.
@ -192,9 +192,9 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
3. Скопіюйте файл з вимогами в директорію `/code`. 3. Скопіюйте файл з вимогами в директорію `/code`.
Спочатку скопіюйте лише файл з вимогами, а не решту коду. Спочатку скопіюйте **лише** файл з вимогами, а не решту коду.
Оскільки цей файл змінюється нечасто, Docker виявить це і використає кеш для цього кроку, що також увімкне кеш і для наступного кроку. Оскільки цей файл **змінюється нечасто**, Docker виявить це і використає **кеш** для цього кроку, що також увімкне кеш і для наступного кроку.
4. Встановіть залежності пакетів із файлу вимог. 4. Встановіть залежності пакетів із файлу вимог.
@ -208,21 +208,21 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
Опція `--upgrade` каже `pip` оновити пакети, якщо вони вже встановлені. Опція `--upgrade` каже `pip` оновити пакети, якщо вони вже встановлені.
Оскільки попередній крок копіювання файлу може бути виявлений кешем Docker, цей крок також використовуватиме кеш Docker, коли це можливо. Оскільки попередній крок копіювання файлу може бути виявлений **кешем Docker**, цей крок також **використовуватиме кеш Docker**, коли це можливо.
Використання кешу на цьому кроці збереже вам багато часу під час повторних збірок образу в розробці, замість того щоб завжди завантажувати і встановлювати всі залежності. Використання кешу на цьому кроці **збереже** вам багато **часу** під час повторних збірок образу в розробці, замість того щоб **завантажувати і встановлювати** всі залежності **щоразу**.
5. Скопіюйте директорію `./app` у директорію `/code`. 5. Скопіюйте директорію `./app` у директорію `/code`.
Оскільки тут увесь код, який змінюється найчастіше, кеш Docker не буде легко використаний для цього або будь-яких наступних кроків. Оскільки тут увесь код, який **змінюється найчастіше**, **кеш** Docker не буде легко використаний для цього або будь-яких **наступних кроків**.
Тому важливо розмістити це ближче до кінця `Dockerfile`, щоб оптимізувати час збірки образу контейнера. Тому важливо розмістити це **ближче до кінця** `Dockerfile`, щоб оптимізувати час збірки образу контейнера.
6. Встановіть команду для використання `fastapi run`, яка всередині використовує Uvicorn. 6. Встановіть **команду** для використання `fastapi run`, яка всередині використовує Uvicorn.
`CMD` приймає список строк, кожна з яких - це те, що ви б набирали в командному рядку, розділене пробілами. `CMD` приймає список строк, кожна з яких - це те, що ви б набирали в командному рядку, розділене пробілами.
Ця команда буде виконана з поточної робочої директорії, тієї самої `/code`, яку ви вказали вище через `WORKDIR /code`. Ця команда буде виконана з **поточної робочої директорії**, тієї самої `/code`, яку ви вказали вище через `WORKDIR /code`.
/// tip | Порада /// tip | Порада
@ -232,7 +232,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
/// warning | Попередження /// warning | Попередження
Обов’язково завжди використовуйте exec form інструкції `CMD`, як пояснено нижче. Обов’язково **завжди** використовуйте **exec form** інструкції `CMD`, як пояснено нижче.
/// ///
@ -240,21 +240,21 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
Інструкцію Docker [`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) можна записати у двох формах: Інструкцію Docker [`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) можна записати у двох формах:
✅ Exec form: **Exec** form:
```Dockerfile ```Dockerfile
# ✅ Робіть так # ✅ Робіть так
CMD ["fastapi", "run", "app/main.py", "--port", "80"] CMD ["fastapi", "run", "app/main.py", "--port", "80"]
``` ```
⛔️ Shell form: ⛔️ **Shell** form:
```Dockerfile ```Dockerfile
# ⛔️ Не робіть так # ⛔️ Не робіть так
CMD fastapi run app/main.py --port 80 CMD fastapi run app/main.py --port 80
``` ```
Обов’язково завжди використовуйте exec form, щоб FastAPI міг коректно завершувати роботу та щоб були викликані [події тривалості життя](../advanced/events.md). Обов’язково завжди використовуйте **exec** form, щоб FastAPI міг коректно завершувати роботу та щоб були викликані [події тривалості життя](../advanced/events.md).
Докладніше про це можна прочитати в [документації Docker про shell та exec form](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form). Докладніше про це можна прочитати в [документації Docker про shell та exec form](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form).
@ -283,31 +283,31 @@ CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
#### Кеш Docker { #docker-cache } #### Кеш Docker { #docker-cache }
У цьому `Dockerfile` є важливий трюк: спочатку ми копіюємо лише файл із залежностями, а не решту коду. Ось чому. У цьому `Dockerfile` є важливий трюк: спочатку ми копіюємо лише **файл із залежностями**, а не решту коду. Ось чому.
```Dockerfile ```Dockerfile
COPY ./requirements.txt /code/requirements.txt COPY ./requirements.txt /code/requirements.txt
``` ```
Docker та інші інструменти збирають ці образи контейнерів інкрементально, додаючи один шар поверх іншого, починаючи з верхньої частини `Dockerfile` і додаючи будь-які файли, створені кожною інструкцією в `Dockerfile`. Docker та інші інструменти **збирають** ці образи контейнерів **інкрементально**, додаючи **один шар поверх іншого**, починаючи з верхньої частини `Dockerfile` і додаючи будь-які файли, створені кожною інструкцією в `Dockerfile`.
Docker та подібні інструменти також використовують внутрішній кеш під час збірки образу. Якщо файл не змінювався з моменту останньої збірки, тоді він повторно використає той самий шар, створений востанє, замість копіювання файлу знову та створення нового шару з нуля. Docker та подібні інструменти також використовують **внутрішній кеш** під час збірки образу. Якщо файл не змінювався з моменту останньої збірки, тоді він **повторно використає той самий шар**, створений востаннє, замість копіювання файлу знову та створення нового шару з нуля.
Просте уникнення копіювання файлів не обов’язково суттєво покращує ситуацію, але оскільки для цього кроку використано кеш, він може використати кеш і для наступного кроку. Наприклад, він може використати кеш для інструкції, яка встановлює залежності: Просте уникнення копіювання файлів не обов’язково суттєво покращує ситуацію, але оскільки для цього кроку використано кеш, він може **використати кеш і для наступного кроку**. Наприклад, він може використати кеш для інструкції, яка встановлює залежності:
```Dockerfile ```Dockerfile
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
``` ```
Файл із вимогами до пакетів змінюватиметься нечасто. Отже, копіюючи лише цей файл, Docker зможе використати кеш для цього кроку. Файл із вимогами до пакетів **змінюватиметься нечасто**. Отже, копіюючи лише цей файл, Docker зможе **використати кеш** для цього кроку.
А потім Docker зможе використати кеш і для наступного кроку, який завантажує та встановлює ці залежності. І саме тут ми заощаджуємо багато часу. ✨ ...і уникаємо нудного очікування. 😪😆 А потім Docker зможе **використати кеш і для наступного кроку**, який завантажує та встановлює ці залежності. І саме тут ми **заощаджуємо багато часу**. ✨ ...і уникаємо нудного очікування. 😪😆
Завантаження і встановлення залежностей пакетів може займати хвилини, але використання кешу займе максимум секунди. Завантаження і встановлення залежностей пакетів **може займати хвилини**, але використання **кешу** займе **максимум секунди**.
І оскільки ви збиратимете образ контейнера знову і знову під час розробки, щоб перевіряти, що зміни у вашому коді працюють, це заощадить багато накопиченого часу. І оскільки ви збиратимете образ контейнера знову і знову під час розробки, щоб перевіряти, що зміни у вашому коді працюють, це заощадить багато накопиченого часу.
Потім, ближче до кінця `Dockerfile`, ми копіюємо весь код. Оскільки це те, що змінюється найчастіше, ми розміщуємо це ближче до кінця, адже майже завжди все після цього кроку не зможе використати кеш. Потім, ближче до кінця `Dockerfile`, ми копіюємо весь код. Оскільки це те, що **змінюється найчастіше**, ми розміщуємо це ближче до кінця, адже майже завжди все після цього кроку не зможе використати кеш.
```Dockerfile ```Dockerfile
COPY ./app /code/app COPY ./app /code/app
@ -415,11 +415,11 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
Поговорімо знову про деякі з тих самих [Концепцій розгортання](concepts.md) у термінах контейнерів. Поговорімо знову про деякі з тих самих [Концепцій розгортання](concepts.md) у термінах контейнерів.
Контейнери - це переважно інструмент для спрощення процесу збирання та розгортання застосунку, але вони не нав’язують конкретний підхід до обробки цих концепцій розгортання, і існує кілька можливих стратегій. Контейнери - це переважно інструмент для спрощення процесу **збирання та розгортання** застосунку, але вони не нав’язують конкретний підхід до обробки цих **концепцій розгортання**, і існує кілька можливих стратегій.
Гарна новина полягає в тому, що для кожної стратегії є спосіб покрити всі концепції розгортання. 🎉 **Гарна новина** полягає в тому, що для кожної стратегії є спосіб покрити всі концепції розгортання. 🎉
Розгляньмо ці концепції розгортання в контексті контейнерів: Розгляньмо ці **концепції розгортання** в контексті контейнерів:
* HTTPS * HTTPS
* Автозапуск * Автозапуск
@ -430,9 +430,9 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
## HTTPS { #https } ## HTTPS { #https }
Якщо зосередитись лише на образі контейнера для застосунку FastAPI (а згодом на запущеному контейнері), HTTPS зазвичай обробляється зовнішнім іншим інструментом. Якщо зосередитись лише на **образі контейнера** для застосунку FastAPI (а згодом на запущеному **контейнері**), HTTPS зазвичай обробляється **зовнішнім** іншим інструментом.
Це може бути інший контейнер, наприклад з [Traefik](https://traefik.io/), що обробляє HTTPS і автоматичне отримання сертифікатів. Це може бути інший контейнер, наприклад з [Traefik](https://traefik.io/), що обробляє **HTTPS** і **автоматичне** отримання **сертифікатів**.
/// tip | Порада /// tip | Порада
@ -444,57 +444,57 @@ Traefik має інтеграції з Docker, Kubernetes та іншими, т
## Автозапуск і перезапуски { #running-on-startup-and-restarts } ## Автозапуск і перезапуски { #running-on-startup-and-restarts }
Зазвичай інший інструмент відповідає за запуск і виконання вашого контейнера. Зазвичай інший інструмент відповідає за **запуск і виконання** вашого контейнера.
Це може бути безпосередньо Docker, Docker Compose, Kubernetes, хмарний сервіс тощо. Це може бути безпосередньо **Docker**, **Docker Compose**, **Kubernetes**, **хмарний сервіс** тощо.
У більшості (або всіх) випадків є проста опція, щоб увімкнути запуск контейнера при старті системи та перезапуски у разі збоїв. Наприклад, у Docker це опція командного рядка `--restart`. У більшості (або всіх) випадків є проста опція, щоб увімкнути запуск контейнера при старті системи та перезапуски у разі збоїв. Наприклад, у Docker це опція командного рядка `--restart`.
Без використання контейнерів змусити застосунки запускатися при старті системи та з перезапусками може бути клопітно і складно. Але під час роботи з контейнерами у більшості випадків ця функціональність вбудована за замовчуванням. ✨ Без використання контейнерів змусити застосунки запускатися при старті системи та з перезапусками може бути клопітно і складно. Але під час **роботи з контейнерами** у більшості випадків ця функціональність вбудована за замовчуванням. ✨
## Реплікація - кількість процесів { #replication-number-of-processes } ## Реплікація - кількість процесів { #replication-number-of-processes }
Якщо у вас є <dfn title="Група машин, налаштованих бути з'єднаними та працювати разом певним чином.">кластер</dfn> машин із Kubernetes, Docker Swarm Mode, Nomad або іншою подібною складною системою для керування розподіленими контейнерами на кількох машинах, тоді ви, ймовірно, захочете обробляти реплікацію на рівні кластера замість використання менеджера процесів (як-от Uvicorn з працівниками) у кожному контейнері. Якщо у вас є <dfn title="Група машин, налаштованих бути зєднаними та працювати разом певним чином.">кластер</dfn> машин із **Kubernetes**, Docker Swarm Mode, Nomad або іншою подібною складною системою для керування розподіленими контейнерами на кількох машинах, тоді ви, ймовірно, захочете **обробляти реплікацію** на **рівні кластера** замість використання **менеджера процесів** (як-от Uvicorn з працівниками) у кожному контейнері.
Одна з таких розподілених систем керування контейнерами, як-от Kubernetes, зазвичай має інтегровані способи обробляти реплікацію контейнерів, підтримуючи водночас балансування навантаження для вхідних запитів. Усе це - на рівні кластера. Одна з таких розподілених систем керування контейнерами, як-от Kubernetes, зазвичай має інтегровані способи обробляти **реплікацію контейнерів**, підтримуючи водночас **балансування навантаження** для вхідних запитів. Усе це - на **рівні кластера**.
У таких випадках ви, ймовірно, захочете зібрати Docker-образ з нуля, як [пояснено вище](#dockerfile), встановивши ваші залежності і запустивши один процес Uvicorn замість використання кількох працівників Uvicorn. У таких випадках ви, ймовірно, захочете зібрати **Docker-образ з нуля**, як [пояснено вище](#dockerfile), встановивши ваші залежності і запустивши **один процес Uvicorn** замість використання кількох працівників Uvicorn.
### Балансувальник навантаження { #load-balancer } ### Балансувальник навантаження { #load-balancer }
При використанні контейнерів зазвичай є якийсь компонент, що слухає на головному порту. Це може бути інший контейнер, який також є представником з термінацією TLS для обробки HTTPS, або подібний інструмент. При використанні контейнерів зазвичай є якийсь компонент, що **слухає на головному порту**. Це може бути інший контейнер, який також є **представником з термінацією TLS** для обробки **HTTPS**, або подібний інструмент.
Оскільки цей компонент приймає навантаження запитів і розподіляє його між працівниками (сподіваємось) збалансовано, його також часто називають балансувальником навантаження. Оскільки цей компонент приймає **навантаження** запитів і розподіляє його між працівниками (сподіваємось) **збалансовано**, його також часто називають **балансувальником навантаження**.
/// tip | Порада /// tip | Порада
Той самий компонент представника з термінацією TLS, що використовується для HTTPS, швидше за все, також буде балансувальником навантаження. Той самий компонент **представника з термінацією TLS**, що використовується для HTTPS, швидше за все, також буде **балансувальником навантаження**.
/// ///
І під час роботи з контейнерами та сама система, яку ви використовуєте для їх запуску і керування ними, вже матиме внутрішні інструменти для передавання мережевої комунікації (наприклад, HTTP-запитів) від цього балансувальника навантаження (який також може бути представником з термінацією TLS) до контейнерів із вашим застосунком. І під час роботи з контейнерами та сама система, яку ви використовуєте для їх запуску і керування ними, вже матиме внутрішні інструменти для передавання **мережевої комунікації** (наприклад, HTTP-запитів) від цього **балансувальника навантаження** (який також може бути **представником з термінацією TLS**) до контейнерів із вашим застосунком.
### Один балансувальник навантаження - кілька контейнерів-працівників { #one-load-balancer-multiple-worker-containers } ### Один балансувальник навантаження - кілька контейнерів-працівників { #one-load-balancer-multiple-worker-containers }
Під час роботи з Kubernetes або подібними розподіленими системами керування контейнерами використання їхніх внутрішніх мережевих механізмів дозволяє єдиному балансувальнику навантаження, що слухає на головному порту, передавати комунікацію (запити) до кількох контейнерів, у яких запущено ваш застосунок. Під час роботи з **Kubernetes** або подібними розподіленими системами керування контейнерами використання їхніх внутрішніх мережевих механізмів дозволяє єдиному **балансувальнику навантаження**, що слухає на головному **порту**, передавати комунікацію (запити) до кількох **контейнерів**, у яких запущено ваш застосунок.
Кожен з цих контейнерів із вашим застосунком зазвичай має лише один процес (наприклад, процес Uvicorn, що запускає ваш застосунок FastAPI). Усі вони будуть ідентичними контейнерами, які запускають те саме, але кожен зі своїм процесом, пам’яттю тощо. Таким чином ви використаєте переваги паралелізму на різних ядрах процесора або навіть на різних машинах. Кожен з цих контейнерів із вашим застосунком зазвичай має **лише один процес** (наприклад, процес Uvicorn, що запускає ваш застосунок FastAPI). Усі вони будуть **ідентичними контейнерами**, які запускають те саме, але кожен зі своїм процесом, пам’яттю тощо. Таким чином ви використаєте переваги **паралелізації** на **різних ядрах** процесора або навіть на **різних машинах**.
А розподілена система контейнерів із балансувальником навантаження розподілятиме запити між кожним із контейнерів із вашим застосунком по черзі. Тож кожен запит може оброблятися одним із кількох реплікованих контейнерів, що запускають ваш застосунок. А розподілена система контейнерів із **балансувальником навантаження** **розподілятиме запити** між кожним із контейнерів із вашим застосунком **по черзі**. Тож кожен запит може оброблятися одним із кількох **реплікованих контейнерів**, що запускають ваш застосунок.
І зазвичай цей балансувальник навантаження зможе обробляти запити, які йдуть до інших застосунків у вашому кластері (наприклад, до іншого домену або під іншим префіксом шляху URL), і передаватиме комунікацію до відповідних контейнерів для того іншого застосунку, що працює у вашому кластері. І зазвичай цей **балансувальник навантаження** зможе обробляти запити, які йдуть до *інших* застосунків у вашому кластері (наприклад, до іншого домену або під іншим префіксом шляху URL), і передаватиме комунікацію до відповідних контейнерів для *того іншого* застосунку, що працює у вашому кластері.
### Один процес на контейнер { #one-process-per-container } ### Один процес на контейнер { #one-process-per-container }
У такому сценарії ви, ймовірно, захочете мати один (Uvicorn) процес на контейнер, адже ви вже обробляєте реплікацію на рівні кластера. У такому сценарії ви, ймовірно, захочете мати **один (Uvicorn) процес на контейнер**, адже ви вже обробляєте реплікацію на рівні кластера.
Тобто в цьому випадку ви не захочете мати кількох працівників у контейнері, наприклад через опцію командного рядка `--workers`. Ви захочете мати лише один процес Uvicorn на контейнер (але, ймовірно, кілька контейнерів). Тобто в цьому випадку ви **не захочете** мати кількох працівників у контейнері, наприклад через опцію командного рядка `--workers`. Ви захочете мати лише **один процес Uvicorn** на контейнер (але, ймовірно, кілька контейнерів).
Наявність іншого менеджера процесів всередині контейнера (як це було б із кількома працівниками) лише додасть зайвої складності, яку, найімовірніше, ви вже вирішуєте на рівні кластера. Наявність іншого менеджера процесів всередині контейнера (як це було б із кількома працівниками) лише додасть **зайвої складності**, яку, найімовірніше, ви вже вирішуєте на рівні кластера.
### Контейнери з кількоми процесами та особливі випадки { #containers-with-multiple-processes-and-special-cases } ### Контейнери з кількома процесами та особливі випадки { #containers-with-multiple-processes-and-special-cases }
Звісно, є особливі випадки, коли ви можете захотіти мати контейнер із кількома процесами-працівниками Uvicorn всередині. Звісно, є **особливі випадки**, коли ви можете захотіти мати **контейнер** із кількома **процесами-працівниками Uvicorn** всередині.
У таких випадках ви можете використати опцію командного рядка `--workers`, щоб задати кількість працівників, яких потрібно запустити: У таких випадках ви можете використати опцію командного рядка `--workers`, щоб задати кількість працівників, яких потрібно запустити:
@ -519,17 +519,17 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
#### Простий застосунок { #a-simple-app } #### Простий застосунок { #a-simple-app }
Ви можете захотіти менеджер процесів у контейнері, якщо ваш застосунок достатньо простий, щоб запускати його на одному сервері, а не на кластері. Ви можете захотіти менеджер процесів у контейнері, якщо ваш застосунок **достатньо простий**, щоб запускати його на **одному сервері**, а не на кластері.
#### Docker Compose { #docker-compose } #### Docker Compose { #docker-compose }
Ви можете розгортати на одному сервері (не в кластері) за допомогою Docker Compose, тож у вас не буде простого способу керувати реплікацією контейнерів (у Docker Compose), зберігаючи спільну мережу та балансування навантаження. Ви можете розгортати на **одному сервері** (не в кластері) за допомогою **Docker Compose**, тож у вас не буде простого способу керувати реплікацією контейнерів (у Docker Compose), зберігаючи спільну мережу та **балансування навантаження**.
Тоді ви можете захотіти мати один контейнер із менеджером процесів, що запускає кілька процесів-працівників всередині. Тоді ви можете захотіти мати **один контейнер** із **менеджером процесів**, що запускає **кілька процесів-працівників** всередині.
--- ---
Головна думка: це не правила, викарбувані в камені, яких потрібно сліпо дотримуватися. Ви можете використати ці ідеї, щоб оцінити власний кейс і вирішити, який підхід найкращий для вашої системи, розглядаючи, як керувати такими концепціями: Головна думка: **жодне** з цього не є **правилами, викарбуваними в камені**, яких потрібно сліпо дотримуватися. Ви можете використати ці ідеї, щоб **оцінити власний кейс** і вирішити, який підхід найкращий для вашої системи, розглядаючи, як керувати такими концепціями:
* Безпека - HTTPS * Безпека - HTTPS
* Автозапуск * Автозапуск
@ -540,13 +540,13 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
## Пам’ять { #memory } ## Пам’ять { #memory }
Якщо ви запускаєте один процес на контейнер, ви матимете більш-менш чітко визначений, стабільний і обмежений обсяг пам’яті, що споживається кожним із цих контейнерів (їх може бути більше одного, якщо вони репліковані). Якщо ви запускаєте **один процес на контейнер**, ви матимете більш-менш чітко визначений, стабільний і обмежений обсяг пам’яті, що споживається кожним із цих контейнерів (їх може бути більше одного, якщо вони репліковані).
Потім ви можете встановити ті самі ліміти та вимоги до пам’яті у ваших конфігураціях для системи керування контейнерами (наприклад, у Kubernetes). Таким чином вона зможе реплікувати контейнери на доступних машинах, враховуючи обсяг пам’яті, потрібний їм, і обсяг доступної пам’яті на машинах у кластері. Потім ви можете встановити ті самі ліміти та вимоги до пам’яті у ваших конфігураціях для системи керування контейнерами (наприклад, у **Kubernetes**). Таким чином вона зможе **реплікувати контейнери** на **доступних машинах**, враховуючи обсяг пам’яті, потрібний їм, і обсяг доступної пам’яті на машинах у кластері.
Якщо ваш застосунок простий, імовірно, це не буде проблемою, і вам може не знадобитися задавати жорсткі ліміти пам’яті. Але якщо ви використовуєте багато пам’яті (наприклад, із моделями машинного навчання), вам слід перевірити, скільки пам’яті ви споживаєте, і відкоригувати кількість контейнерів, що запускаються на кожній машині (і, можливо, додати більше машин у ваш кластер). Якщо ваш застосунок **простий**, імовірно, це **не буде проблемою**, і вам може не знадобитися задавати жорсткі ліміти пам’яті. Але якщо ви **використовуєте багато пам’яті** (наприклад, із моделями **машинного навчання**), вам слід перевірити, скільки пам’яті ви споживаєте, і відкоригувати **кількість контейнерів**, що запускаються на **кожній машині** (і, можливо, додати більше машин у ваш кластер).
Якщо ви запускаєте кілька процесів на контейнер, вам потрібно переконатися, що кількість запущених процесів не споживає більше пам’яті, ніж доступно. Якщо ви запускаєте **кілька процесів на контейнер**, вам потрібно переконатися, що кількість запущених процесів не **споживає більше пам’яті**, ніж доступно.
## Попередні кроки перед запуском і контейнери { #previous-steps-before-starting-and-containers } ## Попередні кроки перед запуском і контейнери { #previous-steps-before-starting-and-containers }
@ -554,7 +554,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
### Кілька контейнерів { #multiple-containers } ### Кілька контейнерів { #multiple-containers }
Якщо у вас кілька контейнерів, імовірно кожен запускає один процес (наприклад, у кластері Kubernetes), тоді ви, ймовірно, захочете мати окремий контейнер, який виконає попередні кроки в одному контейнері, запустивши один процес, перед запуском реплікованих контейнерів-працівників. Якщо у вас **кілька контейнерів**, імовірно кожен запускає **один процес** (наприклад, у кластері **Kubernetes**), тоді ви, ймовірно, захочете мати **окремий контейнер**, який виконає **попередні кроки** в одному контейнері, запустивши один процес, **перед** запуском реплікованих контейнерів-працівників.
/// note | Примітка /// note | Примітка
@ -562,19 +562,19 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
/// ///
Якщо у вашому випадку немає проблеми запускати ці попередні кроки кілька разів паралельно (наприклад, якщо ви не виконуєте міграції бази даних, а лише перевіряєте, чи база вже готова), тоді ви також можете просто помістити їх у кожен контейнер безпосередньо перед запуском головного процесу. Якщо у вашому випадку немає проблеми запускати ці попередні кроки **кілька разів паралельно** (наприклад, якщо ви не виконуєте міграції бази даних, а лише перевіряєте, чи база вже готова), тоді ви також можете просто помістити їх у кожен контейнер безпосередньо перед запуском головного процесу.
### Один контейнер { #single-container } ### Один контейнер { #single-container }
Якщо у вас просте налаштування з одним контейнером, який потім запускає кілька процесів-працівників (або теж лише один процес), тоді ви можете виконати ці попередні кроки в тому ж контейнері безпосередньо перед запуском процесу із застосунком. Якщо у вас просте налаштування з **одним контейнером**, який потім запускає кілька **процесів-працівників** (або теж лише один процес), тоді ви можете виконати ці попередні кроки в тому ж контейнері безпосередньо перед запуском процесу із застосунком.
### Базовий образ Docker { #base-docker-image } ### Базовий образ Docker { #base-docker-image }
Колись існував офіційний образ Docker для FastAPI: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker). Але зараз він застарілий. ⛔️ Колись існував офіційний образ Docker для FastAPI: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker). Але зараз він застарілий. ⛔️
Ймовірно, вам не слід використовувати цей базовий образ Docker (або будь-який інший подібний). Ймовірно, вам **не** слід використовувати цей базовий образ Docker (або будь-який інший подібний).
Якщо ви використовуєте Kubernetes (або інші) і вже налаштовуєте реплікацію на рівні кластера з кількома контейнерами. У таких випадках краще зібрати образ з нуля, як описано вище: [Зібрати Docker-образ для FastAPI](#build-a-docker-image-for-fastapi). Якщо ви використовуєте **Kubernetes** (або інші) і вже налаштовуєте **реплікацію** на рівні кластера з кількома **контейнерами**. У таких випадках краще **зібрати образ з нуля**, як описано вище: [Зібрати Docker-образ для FastAPI](#build-a-docker-image-for-fastapi).
А якщо вам потрібно мати кілька працівників, ви можете просто використати опцію командного рядка `--workers`. А якщо вам потрібно мати кілька працівників, ви можете просто використати опцію командного рядка `--workers`.
@ -592,8 +592,8 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
Наприклад: Наприклад:
* З Docker Compose на одному сервері * З **Docker Compose** на одному сервері
* З кластером Kubernetes * З кластером **Kubernetes**
* З кластером Docker Swarm Mode * З кластером Docker Swarm Mode
* З іншим інструментом, як-от Nomad * З іншим інструментом, як-от Nomad
* З хмарним сервісом, який бере ваш образ контейнера і розгортає його * З хмарним сервісом, який бере ваш образ контейнера і розгортає його
@ -604,7 +604,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
## Підсумок { #recap } ## Підсумок { #recap }
Використовуючи системи контейнерів (наприклад, з Docker і Kubernetes), досить просто обробляти всі концепції розгортання: Використовуючи системи контейнерів (наприклад, з **Docker** і **Kubernetes**), досить просто обробляти всі **концепції розгортання**:
* HTTPS * HTTPS
* Автозапуск * Автозапуск
@ -613,6 +613,6 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
* Пам’ять * Пам’ять
* Попередні кроки перед запуском * Попередні кроки перед запуском
У більшості випадків ви, ймовірно, не захочете використовувати будь-який базовий образ, а натомість зібрати образ контейнера з нуля на основі офіційного образу Python для Docker. У більшості випадків ви, ймовірно, не захочете використовувати будь-який базовий образ, а натомість **зібрати образ контейнера з нуля** на основі офіційного образу Python для Docker.
Дотримуючись порядку інструкцій у `Dockerfile` і використовуючи кеш Docker, ви можете мінімізувати час збірки, щоб максимізувати свою продуктивність (і уникнути нудьги). 😎 Дотримуючись **порядку** інструкцій у `Dockerfile` і використовуючи **кеш Docker**, ви можете **мінімізувати час збірки**, щоб максимізувати свою продуктивність (і уникнути нудьги). 😎

20
docs/uk/docs/deployment/https.md

@ -14,8 +14,8 @@
Тепер, з **точки зору розробника**, ось кілька речей, які варто пам'ятати, розмірковуючи про HTTPS: Тепер, з **точки зору розробника**, ось кілька речей, які варто пам'ятати, розмірковуючи про HTTPS:
* Для HTTPS **сервер** має **мати «сертифікати»**, видані **третьою стороною**. * Для HTTPS **сервер** має **мати «сертифікати»**, згенеровані **третьою стороною**.
* Насправді ці сертифікати **«отримуються»** у третьої сторони, а не **«генеруються»**. * Насправді ці сертифікати **«отримуються»** у третьої сторони, а не **«згенеровані»**.
* Сертифікати мають **строк дії**. * Сертифікати мають **строк дії**.
* Їхній строк дії **спливає**. * Їхній строк дії **спливає**.
* І тоді їх потрібно **поновити**, **знову отримавши** у третьої сторони. * І тоді їх потрібно **поновити**, **знову отримавши** у третьої сторони.
@ -190,15 +190,15 @@ TLS Termination Proxy використає узгоджене шифруванн
Увесь цей процес поновлення, паралельно з обслуговуванням застосунку, - одна з головних причин, чому ви можете захотіти мати **окрему систему для обробки HTTPS** за допомогою TLS Termination Proxy замість того, щоб просто використовувати сертифікати TLS безпосередньо з сервером застосунку (наприклад, Uvicorn). Увесь цей процес поновлення, паралельно з обслуговуванням застосунку, - одна з головних причин, чому ви можете захотіти мати **окрему систему для обробки HTTPS** за допомогою TLS Termination Proxy замість того, щоб просто використовувати сертифікати TLS безпосередньо з сервером застосунку (наприклад, Uvicorn).
## Направлені заголовки проксі { #proxy-forwarded-headers } ## Направлені заголовки представника { #proxy-forwarded-headers }
Коли ви використовуєте проксі для обробки HTTPS, ваш **сервер застосунку** (наприклад, Uvicorn через FastAPI CLI) нічого не знає про процес HTTPS, він спілкується звичайним HTTP із **TLS Termination Proxy**. Коли ви використовуєте представника для обробки HTTPS, ваш **сервер застосунку** (наприклад, Uvicorn через FastAPI CLI) нічого не знає про процес HTTPS, він спілкується звичайним HTTP із **TLS Termination Proxy**.
Цей **проксі** зазвичай динамічно встановлює деякі HTTP-заголовки перед передачею запиту **серверу застосунку**, щоб дати йому знати, що запит **направляється** проксі. Цей **представник** зазвичай динамічно встановлює деякі HTTP-заголовки перед передачею запиту **серверу застосунку**, щоб дати йому знати, що запит **направляється** представником.
/// note | Технічні деталі /// note | Технічні деталі
Заголовки проксі: Заголовки представника:
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For) * [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto) * [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
@ -206,11 +206,11 @@ TLS Termination Proxy використає узгоджене шифруванн
/// ///
Втім, оскільки **сервер застосунку** не знає, що він стоїть за довіреним **проксі**, за замовчуванням він не довірятиме цим заголовкам. Втім, оскільки **сервер застосунку** не знає, що він стоїть за довіреним **представником**, за замовчуванням він не довірятиме цим заголовкам.
Але ви можете налаштувати **сервер застосунку**, щоб довіряти направленим заголовкам, надісланим **проксі**. Якщо ви використовуєте FastAPI CLI, ви можете скористатися курсивною *опцією CLI* `--forwarded-allow-ips`, щоб повідомити, з яких IP-адрес слід довіряти цим направленим заголовкам. Але ви можете налаштувати **сервер застосунку**, щоб довіряти *направленим* заголовкам, надісланим **представником**. Якщо ви використовуєте FastAPI CLI, ви можете скористатися *опцією CLI* `--forwarded-allow-ips`, щоб повідомити, з яких IP-адрес слід довіряти цим *направленим* заголовкам.
Наприклад, якщо **сервер застосунку** отримує комунікацію лише від довіреного **проксі**, ви можете встановити `--forwarded-allow-ips="*"`, щоб довіряти всім вхідним IP-адресам, оскільки він отримуватиме запити лише з тієї IP-адреси, яку використовує **проксі**. Наприклад, якщо **сервер застосунку** отримує комунікацію лише від довіреного **представника**, ви можете встановити `--forwarded-allow-ips="*"`, щоб довіряти всім вхідним IP-адресам, оскільки він отримуватиме запити лише з тієї IP-адреси, яку використовує **представник**.
Так застосунок зможе знати свою публічну URL-адресу, чи використовує він HTTPS, домен тощо. Так застосунок зможе знати свою публічну URL-адресу, чи використовує він HTTPS, домен тощо.
@ -218,7 +218,7 @@ TLS Termination Proxy використає узгоджене шифруванн
/// tip | Порада /// tip | Порада
Ви можете дізнатися більше про це в документації [За проксі - Увімкнути направлені заголовки проксі](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers) Ви можете дізнатися більше про це в документації [За представником - Увімкнути направлені заголовки представника](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers)
/// ///

10
docs/uk/docs/deployment/manually.md

@ -40,7 +40,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
Це спрацює в більшості випадків. 😎 Це спрацює в більшості випадків. 😎
Цю команду можна використати, наприклад, щоб запустити ваш застосунок FastAPI у контейнері, на сервері тощо. Цю команду можна використати, наприклад, щоб запустити ваш застосунок **FastAPI** у контейнері, на сервері тощо.
## Сервери ASGI { #asgi-servers } ## Сервери ASGI { #asgi-servers }
@ -61,11 +61,11 @@ FastAPI використовує стандарт для побудови Python
Є невелика деталь щодо назв, яку варто пам'ятати. 💡 Є невелика деталь щодо назв, яку варто пам'ятати. 💡
Слово «сервер» зазвичай означає і віддалений/хмарний комп'ютер (фізична або віртуальна машина), і програму, що працює на цій машині (наприклад, Uvicorn). Слово **«сервер»** зазвичай означає і віддалений/хмарний комп'ютер (фізична або віртуальна машина), і програму, що працює на цій машині (наприклад, Uvicorn).
Майте на увазі, що коли ви бачите слово «сервер» загалом, воно може стосуватися будь-якого з цих двох значень. Майте на увазі, що коли ви бачите слово «сервер» загалом, воно може стосуватися будь-якого з цих двох значень.
Коли йдеться про віддалену машину, її часто називають «сервер», а також «машина», «VM» (віртуальна машина), «вузол». Усе це означає різновиди віддаленої машини, зазвичай з Linux, на якій ви запускаєте програми. Коли йдеться про віддалену машину, її часто називають **«сервер»**, а також **«машина»**, **«VM»** (віртуальна машина), **«вузол»**. Усе це означає різновиди віддаленої машини, зазвичай з Linux, на якій ви запускаєте програми.
## Встановіть серверну програму { #install-the-server-program } ## Встановіть серверну програму { #install-the-server-program }
@ -101,7 +101,7 @@ $ pip install "uvicorn[standard]"
## Запустіть серверну програму { #run-the-server-program } ## Запустіть серверну програму { #run-the-server-program }
Якщо ви встановили ASGI-сервер вручну, зазвичай потрібно передати рядок імпорту в спеціальному форматі, щоб він імпортував ваш застосунок FastAPI: Якщо ви встановили ASGI-сервер вручну, зазвичай потрібно передати строку імпорту в спеціальному форматі, щоб він імпортував ваш застосунок FastAPI:
<div class="termy"> <div class="termy">
@ -142,7 +142,7 @@ Uvicorn та інші сервери підтримують опцію `--reload
## Концепції розгортання { #deployment-concepts } ## Концепції розгортання { #deployment-concepts }
Ці приклади запускають серверну програму (наприклад, Uvicorn), піднімаючи один процес, що слухає всі IP (`0.0.0.0`) на визначеному порту (наприклад, `80`). Ці приклади запускають серверну програму (наприклад, Uvicorn), піднімаючи **один процес**, що слухає всі IP (`0.0.0.0`) на визначеному порту (наприклад, `80`).
Це базова ідея. Але, ймовірно, вам знадобиться подбати ще про таке: Це базова ідея. Але, ймовірно, вам знадобиться подбати ще про таке:

1
docs/uk/docs/editor-support.md

@ -1,5 +1,6 @@
# Підтримка редакторів { #editor-support } # Підтримка редакторів { #editor-support }
Офіційне [FastAPI Extension](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) покращує ваш робочий процес розробки FastAPI завдяки виявленню й навігації по *операціях шляху*, а також розгортанню у FastAPI Cloud і потоковому передаванню журналів у реальному часі. Офіційне [FastAPI Extension](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) покращує ваш робочий процес розробки FastAPI завдяки виявленню й навігації по *операціях шляху*, а також розгортанню у FastAPI Cloud і потоковому передаванню журналів у реальному часі.
Докладніше про розширення дивіться у README в [репозиторії GitHub](https://github.com/fastapi/fastapi-vscode). Докладніше про розширення дивіться у README в [репозиторії GitHub](https://github.com/fastapi/fastapi-vscode).

32
docs/uk/docs/environment-variables.md

@ -6,13 +6,13 @@
/// ///
Змінна оточення (також відома як «env var») - це змінна, що існує поза кодом Python, в операційній системі, і може бути прочитана вашим кодом Python (а також іншими програмами). Змінна оточення (також відома як «**env var**») - це змінна, що існує **поза** кодом Python, в **операційній системі**, і може бути прочитана вашим кодом Python (а також іншими програмами).
Змінні оточення корисні для роботи з налаштуваннями застосунку, як частина встановлення Python тощо. Змінні оточення корисні для роботи з **налаштуваннями** застосунку, як частина **встановлення** Python тощо.
## Створення і використання змінних оточення { #create-and-use-env-vars } ## Створення і використання змінних оточення { #create-and-use-env-vars }
Ви можете створювати і використовувати змінні оточення в оболонці (терміналі) без участі Python: Ви можете **створювати** і використовувати змінні оточення в **оболонці (терміналі)** без участі Python:
//// tab | Linux, macOS, Windows Bash //// tab | Linux, macOS, Windows Bash
@ -52,7 +52,7 @@ Hello Wade Wilson
## Читання змінних оточення в Python { #read-env-vars-in-python } ## Читання змінних оточення в Python { #read-env-vars-in-python }
Ви також можете створити змінні оточення поза Python, у терміналі (або будь-яким іншим способом), а потім зчитати їх у Python. Ви також можете створити змінні оточення **поза** Python, у терміналі (або будь-яким іншим способом), а потім **зчитати їх у Python**.
Наприклад, у вас може бути файл `main.py` з: Наприклад, у вас може бути файл `main.py` з:
@ -127,9 +127,9 @@ Hello Wade Wilson from Python
//// ////
Оскільки змінні оточення можна встановлювати поза кодом, але читати в коді, і їх не потрібно зберігати (фіксувати у `git`) разом з іншими файлами, їх часто використовують для конфігурацій або налаштувань. Оскільки змінні оточення можна встановлювати поза кодом, але читати в коді, і їх не потрібно зберігати (фіксувати у `git`) разом з іншими файлами, їх часто використовують для конфігурацій або **налаштувань**.
Ви також можете створити змінну оточення лише для конкретного запуску програми, вона буде доступна тільки цій програмі і лише на час її виконання. Ви також можете створити змінну оточення лише для **конкретного запуску програми**, вона буде доступна тільки цій програмі і лише на час її виконання.
Щоб зробити це, створіть її безпосередньо перед командою запуску програми, в тому самому рядку: Щоб зробити це, створіть її безпосередньо перед командою запуску програми, в тому самому рядку:
@ -159,15 +159,15 @@ Hello World from Python
## Типи і перевірка { #types-and-validation } ## Типи і перевірка { #types-and-validation }
Ці змінні оточення можуть містити лише текстові строки, оскільки вони зовнішні щодо Python і мають бути сумісними з іншими програмами та рештою системи (і навіть з різними операційними системами, як-от Linux, Windows, macOS). Ці змінні оточення можуть містити лише **текстові строки**, оскільки вони зовнішні щодо Python і мають бути сумісними з іншими програмами та рештою системи (і навіть з різними операційними системами, як-от Linux, Windows, macOS).
Це означає, що будь-яке значення, прочитане в Python зі змінної оточення, буде `str`, а будь-яке перетворення до іншого типу або будь-яка перевірка має виконуватися в коді. Це означає, що **будь-яке значення**, прочитане в Python зі змінної оточення, **буде `str`**, а будь-яке перетворення до іншого типу або будь-яка перевірка має виконуватися в коді.
Ви дізнаєтеся більше про використання змінних оточення для роботи з налаштуваннями застосунку в розділі [Просунутий посібник користувача - Налаштування і змінні оточення](./advanced/settings.md). Ви дізнаєтеся більше про використання змінних оточення для роботи з **налаштуваннями застосунку** в розділі [Просунутий посібник користувача - Налаштування і змінні оточення](./advanced/settings.md).
## Змінна оточення `PATH` { #path-environment-variable } ## Змінна оточення `PATH` { #path-environment-variable }
Є спеціальна змінна оточення `PATH`, яку використовують операційні системи (Linux, macOS, Windows) для пошуку програм для запуску. Є **спеціальна** змінна оточення **`PATH`**, яку використовують операційні системи (Linux, macOS, Windows) для пошуку програм для запуску.
Значення змінної `PATH` - це довга строка, що складається з каталогів, розділених двокрапкою `:` у Linux і macOS та крапкою з комою `;` у Windows. Значення змінної `PATH` - це довга строка, що складається з каталогів, розділених двокрапкою `:` у Linux і macOS та крапкою з комою `;` у Windows.
@ -203,11 +203,11 @@ C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System3
//// ////
Коли ви вводите команду в терміналі, операційна система шукає програму в кожному з тих каталогів, перелічених у змінній оточення `PATH`. Коли ви вводите **команду** в терміналі, операційна система **шукає** програму в **кожному з тих каталогів**, перелічених у змінній оточення `PATH`.
Наприклад, коли ви вводите `python` у терміналі, операційна система шукає програму з назвою `python` у першому каталозі цього списку. Наприклад, коли ви вводите `python` у терміналі, операційна система шукає програму з назвою `python` у **першому каталозі** цього списку.
Якщо знайде, вона використає її. Інакше продовжить пошук в інших каталогах. Якщо знайде, вона **використає її**. Інакше продовжить пошук в **інших каталогах**.
### Встановлення Python і оновлення `PATH` { #installing-python-and-updating-the-path } ### Встановлення Python і оновлення `PATH` { #installing-python-and-updating-the-path }
@ -255,7 +255,7 @@ $ python
//// tab | Linux, macOS //// tab | Linux, macOS
Система знайде програму `python` у `/opt/custompython/bin` і запустить її. Система **знайде** програму `python` у `/opt/custompython/bin` і запустить її.
Це приблизно еквівалентно введенню: Це приблизно еквівалентно введенню:
@ -271,7 +271,7 @@ $ /opt/custompython/bin/python
//// tab | Windows //// tab | Windows
Система знайде програму `python` у `C:\opt\custompython\bin\python` і запустить її. Система **знайде** програму `python` у `C:\opt\custompython\bin\python` і запустить її.
Це приблизно еквівалентно введенню: Це приблизно еквівалентно введенню:
@ -289,7 +289,7 @@ $ C:\opt\custompython\bin\python
## Висновок { #conclusion } ## Висновок { #conclusion }
Тепер ви маєте базове розуміння того, що таке змінні оточення і як їх використовувати в Python. Тепер ви маєте базове розуміння того, що таке **змінні оточення** і як їх використовувати в Python.
Також можна прочитати більше у [Вікіпедії про змінну оточення](https://en.wikipedia.org/wiki/Environment_variable). Також можна прочитати більше у [Вікіпедії про змінну оточення](https://en.wikipedia.org/wiki/Environment_variable).

42
docs/uk/docs/features.md

@ -6,8 +6,8 @@
### На основі відкритих стандартів { #based-on-open-standards } ### На основі відкритих стандартів { #based-on-open-standards }
* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) для створення API, включаючи оголошення <dfn title="також відомі як: кінцеві точки, маршрути">шляхів</dfn> <dfn title="також відомі як методи HTTP, як-от POST, GET, PUT, DELETE">операцій</dfn>, параметрів, тіл запитів, безпеки тощо. * [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) для створення API, включаючи оголошення <dfn title="також відомі як: кінцеві точки, маршрути">шляхових</dfn> <dfn title="також відомі як методи HTTP, як-от POST, GET, PUT, DELETE">операцій</dfn>, параметрів, тіл запитів, безпеки тощо.
* Автоматична документація моделей даних за допомогою [**JSON Schema**](https://json-schema.org/) (оскільки OpenAPI базується саме на JSON Schema). * Автоматична документація моделей даних за допомогою [**Схеми JSON**](https://json-schema.org/) (оскільки OpenAPI базується саме на Схемі JSON).
* Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури. * Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури.
* Це також дає змогу використовувати автоматичну **генерацію клієнтського коду** багатьма мовами. * Це також дає змогу використовувати автоматичну **генерацію клієнтського коду** багатьма мовами.
@ -15,9 +15,9 @@
Інтерактивна документація API та вебінтерфейси для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, 2 з яких включені за замовчуванням. Інтерактивна документація API та вебінтерфейси для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, 2 з яких включені за замовчуванням.
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui) з інтерактивним дослідженням, викликом і тестуванням вашого API прямо з браузера. * [**Swagger UI**](https://github.com/swagger-api/swagger-ui) - з інтерактивним дослідженням, викликом і тестуванням вашого API прямо з браузера.
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) ![взаємодія Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Альтернативна документація API за допомогою [**ReDoc**](https://github.com/Rebilly/ReDoc). * Альтернативна документація API за допомогою [**ReDoc**](https://github.com/Rebilly/ReDoc).
@ -27,7 +27,7 @@
Усе базується на стандартних оголошеннях **типів Python** (завдяки Pydantic). Жодного нового синтаксису для вивчення. Лише стандартний сучасний Python. Усе базується на стандартних оголошеннях **типів Python** (завдяки Pydantic). Жодного нового синтаксису для вивчення. Лише стандартний сучасний Python.
Якщо вам потрібно 2-хвилинне нагадування про те, як використовувати типи Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий підручник: [Типи Python](python-types.md). Якщо вам потрібно 2-хвилинне нагадування про те, як використовувати типи Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий навчальний посібник: [Типи Python](python-types.md).
Ви пишете стандартний Python з типами: Ви пишете стандартний Python з типами:
@ -85,13 +85,13 @@ my_second_user: User = User(**second_user_data)
* у [Visual Studio Code](https://code.visualstudio.com/): * у [Visual Studio Code](https://code.visualstudio.com/):
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) ![підтримка редактора](https://fastapi.tiangolo.com/img/vscode-completion.png)
* у [PyCharm](https://www.jetbrains.com/pycharm/): * у [PyCharm](https://www.jetbrains.com/pycharm/):
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png) ![підтримка редактора](https://fastapi.tiangolo.com/img/pycharm-completion.png)
Ви отримаєте автодоповнення в коді, який раніше могли вважати навіть неможливим. Наприклад, для ключа `price` всередині JSON body (який міг бути вкладеним), що надходить із запиту. Ви отримаєте автодоповнення в коді, який раніше могли вважати навіть неможливим. Наприклад, для ключа `price` всередині тіла JSON (яке могло бути вкладеним), що надходить із запиту.
Більше не доведеться вводити неправильні назви ключів, постійно повертатися до документації або прокручувати вгору-вниз, щоб знайти, чи ви зрештою використали `username` чи `user_name`. Більше не доведеться вводити неправильні назви ключів, постійно повертатися до документації або прокручувати вгору-вниз, щоб знайти, чи ви зрештою використали `username` чи `user_name`.
@ -106,7 +106,7 @@ FastAPI має розумні **налаштування за замовчува
* Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема: * Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема:
* JSON-об'єктів (`dict`). * JSON-об'єктів (`dict`).
* JSON-масивів (`list`) із визначенням типів елементів. * JSON-масивів (`list`) із визначенням типів елементів.
* Полів-рядків (`str`) із визначенням мінімальної та максимальної довжини. * Полів-строк (`str`) із визначенням мінімальної та максимальної довжини.
* Чисел (`int`, `float`) з мінімальними та максимальними значеннями тощо. * Чисел (`int`, `float`) з мінімальними та максимальними значеннями тощо.
* Валідація для більш екзотичних типів, як-от: * Валідація для більш екзотичних типів, як-от:
@ -124,30 +124,30 @@ FastAPI має розумні **налаштування за замовчува
Підтримуються всі схеми безпеки, визначені в OpenAPI, включно з: Підтримуються всі схеми безпеки, визначені в OpenAPI, включно з:
* HTTP Basic. * HTTP Basic.
* **OAuth2** (також із підтримкою **JWT tokens**). Перегляньте підручник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md). * **OAuth2** (також із підтримкою **JWT tokens**). Перегляньте навчальний посібник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md).
* Ключі API в: * Ключі API в:
* Заголовках. * Заголовках.
* Параметрах запиту. * Параметрах запиту.
* Cookies тощо. * Кукі тощо.
А також усі можливості безпеки від Starlette (зокрема **session cookies**). А також усі можливості безпеки від Starlette (зокрема **сесійні кукі**).
Усе це зроблено як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо. Усе це зроблено як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо.
### Впровадження залежностей { #dependency-injection } ### Впровадження залежностей { #dependency-injection }
FastAPI містить надзвичайно просту у використанні, але надзвичайно потужну систему <dfn title='також відоме як «components», «resources», «services», «providers»'><strong>Впровадження залежностей</strong></dfn>. FastAPI містить надзвичайно просту у використанні, але надзвичайно потужну систему <dfn title='також відоме як «компоненти», «ресурси», «сервіси», «провайдери»'><strong>Впровадження залежностей</strong></dfn>.
* Навіть залежності можуть мати власні залежності, утворюючи ієрархію або **«граф» залежностей**. * Навіть залежності можуть мати власні залежності, утворюючи ієрархію або **«граф» залежностей**.
* Усе **автоматично обробляється** фреймворком. * Усе **автоматично обробляється** фреймворком.
* Усі залежності можуть вимагати дані із запитів і **розширювати обмеження операції шляху** та автоматичну документацію. * Усі залежності можуть вимагати дані із запитів і **розширювати обмеження операції шляху** та автоматичну документацію.
* **Автоматична валідація** навіть для *операції шляху*, визначених у залежностях. * **Автоматична валідація** навіть для параметрів *операції шляху*, визначених у залежностях.
* Підтримка складних систем автентифікації користувачів, **підключень до баз даних** тощо. * Підтримка складних систем автентифікації користувачів, **підключень до баз даних** тощо.
* **Жодних компромісів** із базами даних, фронтендами тощо. Але проста інтеграція з усіма ними. * **Жодних компромісів** із базами даних, фронтендами тощо. Але проста інтеграція з усіма ними.
### Необмежені «плагіни» { #unlimited-plug-ins } ### Необмежені «плагіни» { #unlimited-plug-ins }
Інакше кажучи, вони не потрібні імпортуйте та використовуйте код, який вам потрібен. Інакше кажучи, вони не потрібні - імпортуйте та використовуйте код, який вам потрібен.
Будь-яка інтеграція спроєктована так, щоб її було дуже просто використовувати (із залежностями), тож ви можете створити «плагін» для свого застосунку у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*. Будь-яка інтеграція спроєктована так, щоб її було дуже просто використовувати (із залежностями), тож ви можете створити «плагін» для свого застосунку у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*.
@ -163,15 +163,15 @@ FastAPI містить надзвичайно просту у використа
`FastAPI` фактично є підкласом `Starlette`. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само. `FastAPI` фактично є підкласом `Starlette`. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само.
З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI це просто Starlette на стероїдах): З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI - це просто Starlette на стероїдах):
* Разюча продуктивність. Це [один із найшвидших доступних Python-фреймворків, на рівні з **NodeJS** і **Go**](https://github.com/encode/starlette#performance). * Разюча продуктивність. Це [один із найшвидших доступних Python-фреймворків, на рівні з **NodeJS** і **Go**](https://github.com/encode/starlette#performance).
* Підтримка **WebSocket**. * Підтримка **WebSocket**.
* Фонові задачі у процесі. * Фонові задачі у процесі.
* Події запуску та завершення роботи. * Події запуску та вимкнення.
* Клієнт для тестування, побудований на HTTPX. * Клієнт для тестування, побудований на HTTPX.
* Підтримка **CORS**, **GZip**, статичних файлів, потокових відповідей. * Підтримка **CORS**, **GZip**, статичних файлів, потокових відповідей.
* Підтримка **сесій** і **cookie**. * Підтримка **сесій і кукі**.
* 100% покриття тестами. * 100% покриття тестами.
* 100% анотована типами кодова база. * 100% анотована типами кодова база.
@ -183,7 +183,7 @@ FastAPI містить надзвичайно просту у використа
Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте із запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється. Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте із запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється.
Те саме застосовується й у зворотному напрямку у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**. Те саме застосовується й у зворотному напрямку - у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**.
З **FastAPI** ви отримуєте всі можливості **Pydantic** (адже FastAPI базується на Pydantic для обробки всіх даних): З **FastAPI** ви отримуєте всі можливості **Pydantic** (адже FastAPI базується на Pydantic для обробки всіх даних):
@ -193,8 +193,8 @@ FastAPI містить надзвичайно просту у використа
* Легко працює з вашим **<abbr title="Integrated Development Environment - Інтегроване середовище розробки: схоже на код-редактор">IDE</abbr>/<dfn title="Програма, що перевіряє код на помилки">linter</dfn>/мозком**: * Легко працює з вашим **<abbr title="Integrated Development Environment - Інтегроване середовище розробки: схоже на код-редактор">IDE</abbr>/<dfn title="Програма, що перевіряє код на помилки">linter</dfn>/мозком**:
* Оскільки структури даних pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними. * Оскільки структури даних pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними.
* Валідує **складні структури**: * Валідує **складні структури**:
* Використання ієрархічних моделей Pydantic, Python `typing`’s `List` і `Dict` тощо. * Використання ієрархічних моделей Pydantic, `List` і `Dict` з Python `typing` тощо.
* Валідатори дають змогу складні схеми даних чітко й просто визначати, перевіряти й документувати як JSON Schema. * Валідатори дають змогу складні схеми даних чітко й просто визначати, перевіряти й документувати як Схему JSON.
* Ви можете мати глибоко **вкладені JSON** об'єкти, і всі вони будуть валідовані та анотовані. * Ви можете мати глибоко **вкладені JSON** об'єкти, і всі вони будуть валідовані та анотовані.
* **Розширюваність**: * **Розширюваність**:
* Pydantic дозволяє визначати користувацькі типи даних або ви можете розширити валідацію методами в моделі, позначеними декоратором validator. * Pydantic дозволяє визначати користувацькі типи даних або ви можете розширити валідацію методами в моделі, позначеними декоратором validator.

2
docs/uk/docs/help-fastapi.md

@ -6,7 +6,7 @@
## Підпишіться на розсилку { #subscribe-to-the-newsletter } ## Підпишіться на розсилку { #subscribe-to-the-newsletter }
Ви можете підписатися на (нечасту) розсилку [**FastAPI and friends**](newsletter.md), щоб бути в курсі: Ви можете підписатися на (нечасту) [розсилку **FastAPI and friends**](newsletter.md), щоб бути в курсі:
* Новин про FastAPI та друзів 🚀 * Новин про FastAPI та друзів 🚀
* Посібників 📝 * Посібників 📝

2
docs/uk/docs/how-to/configure-swagger-ui.md

@ -67,4 +67,4 @@ presets: [
Це об’єкти **JavaScript**, а не строки, тому ви не можете передати їх безпосередньо з коду Python. Це об’єкти **JavaScript**, а не строки, тому ви не можете передати їх безпосередньо з коду Python.
Якщо вам потрібно використати такі налаштування лише для JavaScript, скористайтеся одним із методів вище. Повністю перепишіть операцію шляху Swagger UI та вручну напишіть потрібний JavaScript. Якщо вам потрібно використати такі налаштування лише для JavaScript, скористайтеся одним із методів вище. Повністю перепишіть *операцію шляху* Swagger UI та вручну напишіть потрібний JavaScript.

8
docs/uk/docs/how-to/custom-request-and-route.md

@ -18,9 +18,9 @@
Деякі варіанти використання: Деякі варіанти використання:
- Перетворення не-JSON тіл запитів на JSON (наприклад, [`msgpack`](https://msgpack.org/index.html)). * Перетворення не-JSON тіл запитів на JSON (наприклад, [`msgpack`](https://msgpack.org/index.html)).
- Розпакування тіл запитів, стиснених gzip. * Розпакування тіл запитів, стиснених gzip.
- Автоматичне логування всіх тіл запитів. * Автоматичне логування всіх тіл запитів.
## Обробка користувацьких кодувань тіла запиту { #handling-custom-request-body-encodings } ## Обробка користувацьких кодувань тіла запиту { #handling-custom-request-body-encodings }
@ -76,7 +76,7 @@
Після цього вся логіка обробки залишається тією самою. Після цього вся логіка обробки залишається тією самою.
А завдяки змінам у `GzipRequest.body` тіло запиту за потреби буде автоматично розпаковане під час завантаження **FastAPI**. Але завдяки змінам у `GzipRequest.body` тіло запиту за потреби буде автоматично розпаковане, коли **FastAPI** завантажуватиме його.
## Доступ до тіла запиту в обробнику виключень { #accessing-the-request-body-in-an-exception-handler } ## Доступ до тіла запиту в обробнику виключень { #accessing-the-request-body-in-an-exception-handler }

24
docs/uk/docs/how-to/graphql.md

@ -1,22 +1,22 @@
# GraphQL { #graphql } # GraphQL { #graphql }
Оскільки FastAPI базується на стандарті ASGI, дуже просто інтегрувати будь-яку бібліотеку GraphQL, сумісну з ASGI. Оскільки **FastAPI** базується на стандарті **ASGI**, дуже просто інтегрувати будь-яку бібліотеку **GraphQL**, сумісну з ASGI.
Ви можете поєднувати звичайні *операції шляху* FastAPI з GraphQL в одному застосунку. Ви можете поєднувати звичайні *операції шляху* FastAPI з GraphQL в одному застосунку.
/// tip | Порада /// tip | Порада
GraphQL розв’язує деякі дуже специфічні сценарії використання. **GraphQL** розв’язує деякі дуже специфічні сценарії використання.
Порівняно зі звичайними веб-API він має переваги та недоліки. Порівняно зі звичайними **веб-API** він має **переваги** та **недоліки**.
Переконайтеся, що переваги для вашого випадку використання переважають недоліки. 🤓 Переконайтеся, що **переваги** для вашого випадку використання переважають **недоліки**. 🤓
/// ///
## Бібліотеки GraphQL { #graphql-libraries } ## Бібліотеки GraphQL { #graphql-libraries }
Ось деякі бібліотеки GraphQL з підтримкою ASGI. Ви можете використовувати їх із FastAPI: Ось деякі бібліотеки **GraphQL** з підтримкою **ASGI**. Ви можете використовувати їх із **FastAPI**:
* [Strawberry](https://strawberry.rocks/) 🍓 * [Strawberry](https://strawberry.rocks/) 🍓
* З [документацією для FastAPI](https://strawberry.rocks/docs/integrations/fastapi) * З [документацією для FastAPI](https://strawberry.rocks/docs/integrations/fastapi)
@ -29,23 +29,23 @@ GraphQL розв’язує деякі дуже специфічні сцена
## GraphQL зі Strawberry { #graphql-with-strawberry } ## GraphQL зі Strawberry { #graphql-with-strawberry }
Якщо вам потрібен або ви хочете використовувати GraphQL, [Strawberry](https://strawberry.rocks/) - рекомендована бібліотека, адже її дизайн найближчий до дизайну FastAPI; усе базується на анотаціях типів. Якщо вам потрібен або ви хочете використовувати **GraphQL**, [**Strawberry**](https://strawberry.rocks/) - **рекомендована** бібліотека, адже її дизайн найближчий до дизайну **FastAPI**; усе базується на **анотаціях типів**.
Залежно від вашого сценарію використання ви можете надати перевагу іншій бібліотеці, але якби ви запитали мене, я, ймовірно, порадив би спробувати Strawberry. Залежно від вашого сценарію використання ви можете надати перевагу іншій бібліотеці, але якби ви запитали мене, я, ймовірно, порадив би спробувати **Strawberry**.
Ось невеликий приклад того, як інтегрувати Strawberry з FastAPI: Ось невеликий попередній перегляд того, як ви могли б інтегрувати Strawberry з FastAPI:
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *} {* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
Більше про Strawberry ви можете дізнатися в [документації Strawberry](https://strawberry.rocks/). Більше про Strawberry ви можете дізнатися в [документації Strawberry](https://strawberry.rocks/).
І також [документацію про Strawberry з FastAPI](https://strawberry.rocks/docs/integrations/fastapi). І також документацію про [Strawberry з FastAPI](https://strawberry.rocks/docs/integrations/fastapi).
## Застарілий `GraphQLApp` зі Starlette { #older-graphqlapp-from-starlette } ## Застарілий `GraphQLApp` зі Starlette { #older-graphqlapp-from-starlette }
Попередні версії Starlette містили клас `GraphQLApp` для інтеграції з [Graphene](https://graphene-python.org/). Попередні версії Starlette містили клас `GraphQLApp` для інтеграції з [Graphene](https://graphene-python.org/).
Його вилучено з Starlette як застарілий, але якщо у вас є код, що його використовував, ви можете легко мігрувати на [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3), який покриває той самий сценарій використання та має майже ідентичний інтерфейс. Його було оголошено застарілим у Starlette, але якщо у вас є код, що його використовував, ви можете легко **мігрувати** на [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3), який покриває той самий сценарій використання та має **майже ідентичний інтерфейс**.
/// tip | Порада /// tip | Порада
@ -55,6 +55,6 @@ GraphQL розв’язує деякі дуже специфічні сцена
## Дізнайтеся більше { #learn-more } ## Дізнайтеся більше { #learn-more }
Ви можете дізнатися більше про GraphQL в [офіційній документації GraphQL](https://graphql.org/). Ви можете дізнатися більше про **GraphQL** в [офіційній документації GraphQL](https://graphql.org/).
Також ви можете почитати більше про кожну з цих бібліотек за наведеними посиланнями. Також ви можете почитати більше про кожну з цих бібліотек, описаних вище, за наведеними посиланнями.

22
docs/uk/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md

@ -8,9 +8,11 @@ FastAPI версії 0.119.0 запровадив часткову підтри
FastAPI 0.126.0 припинив підтримку Pydantic v1, водночас ще певний час підтримував `pydantic.v1`. FastAPI 0.126.0 припинив підтримку Pydantic v1, водночас ще певний час підтримував `pydantic.v1`.
FastAPI 0.128.0 також припинив підтримку `pydantic.v1`, тому найновіші версії FastAPI вимагають Pydantic v2.
/// warning | Попередження /// warning | Попередження
Команда Pydantic припинила підтримку Pydantic v1 для останніх версій Python, починаючи з Python 3.14. Команда Pydantic припинила підтримку Pydantic v1 для останніх версій Python, починаючи з **Python 3.14**.
Це стосується і `pydantic.v1`, який більше не підтримується в Python 3.14 і новіших. Це стосується і `pydantic.v1`, який більше не підтримується в Python 3.14 і новіших.
@ -18,7 +20,7 @@ FastAPI 0.126.0 припинив підтримку Pydantic v1, водноча
/// ///
Якщо у вас стара програма FastAPI з Pydantic v1, нижче я покажу, як мігрувати на Pydantic v2, а також можливості FastAPI 0.119.0, які допоможуть з поступовою міграцією. Якщо у вас стара програма FastAPI з Pydantic v1, нижче я покажу, як мігрувати на Pydantic v2, а також **можливості FastAPI 0.119.0**, які допоможуть з поступовою міграцією.
## Офіційний посібник { #official-guide } ## Офіційний посібник { #official-guide }
@ -54,6 +56,16 @@ Pydantic v2 містить усе з Pydantic v1 як підмодуль `pydant
### Підтримка FastAPI для Pydantic v1 у v2 { #fastapi-support-for-pydantic-v1-in-v2 } ### Підтримка FastAPI для Pydantic v1 у v2 { #fastapi-support-for-pydantic-v1-in-v2 }
/// warning | Попередження
Цю підтримку FastAPI для моделей `pydantic.v1` було додано у **FastAPI 0.119.0** і видалено у **FastAPI 0.128.0**. Вона була задумана як тимчасова допомога для міграції на Pydantic v2.
У поточних версіях FastAPI використання моделі `pydantic.v1` у вашій програмі спричинить помилку.
Решта цього розділу описує тимчасову підтримку, доступну лише в тих старіших версіях.
///
Починаючи з FastAPI 0.119.0, також є часткова підтримка Pydantic v1 всередині Pydantic v2, щоб спростити перехід на v2. Починаючи з FastAPI 0.119.0, також є часткова підтримка Pydantic v1 всередині Pydantic v2, щоб спростити перехід на v2.
Тож ви можете оновити Pydantic до останньої версії 2 і змінити імпорти на використання підмодуля `pydantic.v1`, і в багатьох випадках усе просто запрацює. Тож ви можете оновити Pydantic до останньої версії 2 і змінити імпорти на використання підмодуля `pydantic.v1`, і в багатьох випадках усе просто запрацює.
@ -122,6 +134,12 @@ graph TB
### Покрокова міграція { #migrate-in-steps } ### Покрокова міграція { #migrate-in-steps }
/// warning | Попередження
Поступова міграція з використанням моделей Pydantic v1 і v2 в одній програмі, описана нижче, працює лише у **FastAPI 0.119.0 до 0.127.x**. Її було видалено у **FastAPI 0.128.0**, найновіші версії вимагають моделей **Pydantic v2**.
///
/// tip | Порада /// tip | Порада
Спершу спробуйте `bump-pydantic`: якщо ваші тести проходять і все працює - ви впоралися однією командою. ✨ Спершу спробуйте `bump-pydantic`: якщо ваші тести проходять і все працює - ви впоралися однією командою. ✨

13
docs/uk/docs/how-to/separate-openapi-schemas.md

@ -2,7 +2,7 @@
Відколи вийшов **Pydantic v2**, згенерований OpenAPI став трохи точнішим і більш **коректним**, ніж раніше. 😎 Відколи вийшов **Pydantic v2**, згенерований OpenAPI став трохи точнішим і більш **коректним**, ніж раніше. 😎
Насправді подекуди буде навіть **дві схеми JSON** в OpenAPI для тієї самої моделі Pydantic: для введення та для виведення - залежно від наявності значень за замовчуванням. Насправді подекуди буде навіть **дві Схеми JSON** в OpenAPI для тієї самої моделі Pydantic: для введення та для виведення - залежно від наявності **значень за замовчуванням**.
Розгляньмо, як це працює, і як це змінити за потреби. Розгляньмо, як це працює, і як це змінити за потреби.
@ -18,7 +18,7 @@
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *} {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
…тоді поле `description` не буде обов'язковим, адже воно має значення за замовчуванням `None`. …тоді поле `description` **не буде обов'язковим**. Адже воно має значення за замовчуванням `None`.
### Модель для введення в документації { #input-model-in-docs } ### Модель для введення в документації { #input-model-in-docs }
@ -34,7 +34,7 @@
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
…тоді, оскільки `description` має значення за замовчуванням, якщо ви нічого не повернете для цього поля, воно все одно матиме це **значення за замовчуванням**. …тоді, оскільки `description` має значення за замовчуванням, якщо ви **нічого не повернете** для цього поля, воно все одно матиме це **значення за замовчуванням**.
### Модель для даних відповіді при виведенні { #model-for-output-response-data } ### Модель для даних відповіді при виведенні { #model-for-output-response-data }
@ -51,12 +51,13 @@
У OpenAPI це описується тим, що поле позначається як **обов'язкове**, адже воно завжди присутнє. У OpenAPI це описується тим, що поле позначається як **обов'язкове**, адже воно завжди присутнє.
Тому Схема JSON для моделі може відрізнятися залежно від того, чи використовується вона для **введення або виведення**: Тому Схема JSON для моделі може відрізнятися залежно від того, чи використовується вона для **введення або виведення**:
- для **введення** `description` не буде обов'язковим
- для **виведення** воно буде **обов'язковим** (і можливо `None`, або в термінах JSON - `null`) * для **введення** `description` **не буде обов'язковим**
* для **виведення** воно буде **обов'язковим** (і можливо `None`, або в термінах JSON - `null`)
### Модель для виведення в документації { #model-for-output-in-docs } ### Модель для виведення в документації { #model-for-output-in-docs }
У документації ви також можете перевірити модель для виведення: **і** `name`, і `description` позначені як **обов'язкові** червоною зірочкою: У документації ви також можете перевірити модель для виведення: **і** `name`, і `description` позначені як **обов'язкові** **червоною зірочкою**:
<div class="screenshot"> <div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image03.png"> <img src="/img/tutorial/separate-openapi-schemas/image03.png">

52
docs/uk/docs/index.md

@ -49,7 +49,7 @@ FastAPI - це сучасний, швидкий (високопродуктив
* **Простий**: спроєктований так, щоб бути простим у використанні та вивченні. Менше часу на читання документації. * **Простий**: спроєктований так, щоб бути простим у використанні та вивченні. Менше часу на читання документації.
* **Короткий**: мінімізує дублювання коду. Кілька можливостей з кожного оголошення параметра. Менше помилок. * **Короткий**: мінімізує дублювання коду. Кілька можливостей з кожного оголошення параметра. Менше помилок.
* **Надійний**: ви отримуєте код, готовий до продакшну. З автоматичною інтерактивною документацією. * **Надійний**: ви отримуєте код, готовий до продакшну. З автоматичною інтерактивною документацією.
* **Заснований на стандартах**: базується на (і повністю сумісний з) відкритими стандартами для API: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (раніше відомий як Swagger) та [JSON Schema](https://json-schema.org/). * **Заснований на стандартах**: базується на (і повністю сумісний з) відкритими стандартами для API: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (раніше відомий як Swagger) та [Схема JSON](https://json-schema.org/).
<small>* оцінка на основі тестів, проведених внутрішньою командою розробників, що створює продакшн-застосунки.</small> <small>* оцінка на основі тестів, проведених внутрішньою командою розробників, що створює продакшн-застосунки.</small>
@ -105,47 +105,47 @@ FastAPI - це сучасний, швидкий (високопродуктив
</div> </div>
<div class="fastapi-opinions__panel" id="fo-panel-microsoft" role="tabpanel" aria-labelledby="fo-tab-microsoft" tabindex="0"> <div class="fastapi-opinions__panel" id="fo-panel-microsoft" role="tabpanel" aria-labelledby="fo-tab-microsoft" tabindex="0">
<blockquote class="fastapi-opinions__quote">«Я дуже часто використовую <strong>FastAPI</strong> останнім часом. Я насправді планую використовувати його для всіх <strong>ML-сервісів моєї команди в Microsoft</strong>. Деякі з них інтегруються до основного продукту <strong>Windows</strong> і деякі з продуктів <strong>Office</strong>».</blockquote> <blockquote class="fastapi-opinions__quote">«Я дуже часто використовую <strong>FastAPI</strong> останнім часом. Я насправді планую використовувати його для всіх <strong>ML-сервісів моєї команди в Microsoft</strong>. Деякі з них інтегруються до основного продукту <strong>Windows</strong> і деяких продуктів <strong>Office</strong>».</blockquote>
<div class="fastapi-opinions__attr"> Kabir Khan, <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26">(ref)</a></div> <div class="fastapi-opinions__attr">- Kabir Khan, <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26">(джерело)</a></div>
</div> </div>
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden> <div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">«Ми прийняли бібліотеку <strong>FastAPI</strong>, щоб запустити сервер <strong>REST</strong>, до якого можна надсилати запити для отримання <strong>прогнозів</strong>». <em>[для Ludwig]</em></blockquote> <blockquote class="fastapi-opinions__quote">«Ми прийняли бібліотеку <strong>FastAPI</strong>, щоб запустити сервер <strong>REST</strong>, до якого можна надсилати запити для отримання <strong>прогнозів</strong>». <em>[для Ludwig]</em></blockquote>
<div class="fastapi-opinions__attr"> Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(ref)</a></div> <div class="fastapi-opinions__attr">- Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(джерело)</a></div>
</div> </div>
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden> <div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">«<strong>Netflix</strong> із задоволенням оголошує про випуск з відкритим кодом нашого фреймворку оркестрації <strong>керування кризами</strong>: <strong>Dispatch</strong><em>[побудовано з FastAPI]</em></blockquote> <blockquote class="fastapi-opinions__quote">«<strong>Netflix</strong> із задоволенням оголошує про випуск з відкритим кодом нашого фреймворку оркестрації <strong>керування кризами</strong>: <strong>Dispatch</strong><em>[побудовано з FastAPI]</em></blockquote>
<div class="fastapi-opinions__attr"> Kevin Glisson, Marc Vilanova, Forest Monsen, <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072">(ref)</a></div> <div class="fastapi-opinions__attr">- Kevin Glisson, Marc Vilanova, Forest Monsen, <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072">(джерело)</a></div>
</div> </div>
<div class="fastapi-opinions__panel" id="fo-panel-cisco" role="tabpanel" aria-labelledby="fo-tab-cisco" tabindex="0" hidden> <div class="fastapi-opinions__panel" id="fo-panel-cisco" role="tabpanel" aria-labelledby="fo-tab-cisco" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">«Якщо хтось хоче створювати продакшн-API на Python, я дуже рекомендую <strong>FastAPI</strong>. Він <strong>чудово спроєктований</strong>, <strong>простий у використанні</strong> і <strong>дуже масштабований</strong> він став <strong>ключовим компонентом</strong> у нашій стратегії розробки з пріоритетом API».</blockquote> <blockquote class="fastapi-opinions__quote">«Якщо хтось хоче створювати продакшн-API на Python, я дуже рекомендую <strong>FastAPI</strong>. Він <strong>чудово спроєктований</strong>, <strong>простий у використанні</strong> і <strong>дуже масштабований</strong> - він став <strong>ключовим компонентом</strong> у нашій стратегії розробки з пріоритетом API».</blockquote>
<div class="fastapi-opinions__attr"> Deon Pillsbury, <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/">(ref)</a></div> <div class="fastapi-opinions__attr">- Deon Pillsbury, <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/">(джерело)</a></div>
</div> </div>
</div> </div>
<!-- /only-mkdocs --> <!-- /only-mkdocs -->
<div class="only-github" markdown="1"> <div class="only-github" markdown="1">
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" "_[...] Я дуже часто використовую **FastAPI** останнім часом. [...] Я насправді планую використовувати його для всіх **ML-сервісів моєї команди в Microsoft**. Деякі з них інтегруються до основного продукту **Windows** і деяких продуктів **Office**._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div> <div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(джерело)</small></a></div>
--- ---
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" "_Ми прийняли бібліотеку **FastAPI**, щоб запустити сервер **REST**, до якого можна надсилати запити для отримання **прогнозів**. [для Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div> <div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(джерело)</small></a></div>
--- ---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" "_**Netflix** із задоволенням оголошує про випуск з відкритим кодом нашого фреймворку оркестрації **керування кризами**: **Dispatch**! [побудовано з **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div> <div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(джерело)</small></a></div>
--- ---
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._" "_Якщо хтось хоче створювати продакшн-API на Python, я дуже рекомендую **FastAPI**. Він **чудово спроєктований**, **простий у використанні** і **дуже масштабований**, він став **ключовим компонентом** у нашій стратегії розробки з пріоритетом API і забезпечує багато автоматизацій та сервісів, як-от наш Virtual TAC Engineer._"
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div> <div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(джерело)</small></a></div>
--- ---
@ -239,7 +239,7 @@ async def read_item(item_id: int, q: str | None = None):
**Примітка**: **Примітка**:
Якщо ви не знаєте, перегляньте розділ _"In a hurry?"_ про [`async` та `await` у документації](https://fastapi.tiangolo.com/uk/async/#in-a-hurry). Якщо ви не знаєте, перегляньте розділ _«Поспішаєте?»_ про [`async` та `await` у документації](https://fastapi.tiangolo.com/uk/async/#in-a-hurry).
</details> </details>
@ -412,10 +412,10 @@ item: Item
* JSON. * JSON.
* Параметрів шляху. * Параметрів шляху.
* Параметрів запиту. * Параметрів запиту.
* Cookies. * Кукі.
* Headers. * Заголовків.
* Forms. * Форм.
* Files. * Файлів.
* <dfn title="також відоме як: серіалізація, парсинг, маршалінг">Перетворення</dfn> вихідних даних: перетворення з даних і типів Python у мережеві дані (як JSON): * <dfn title="також відоме як: серіалізація, парсинг, маршалінг">Перетворення</dfn> вихідних даних: перетворення з даних і типів Python у мережеві дані (як JSON):
* Перетворення типів Python (`str`, `int`, `float`, `bool`, `list`, тощо). * Перетворення типів Python (`str`, `int`, `float`, `bool`, `list`, тощо).
* Обʼєктів `datetime`. * Обʼєктів `datetime`.
@ -477,10 +477,10 @@ item: Item
**Попередження про спойлер**: навчальний посібник - посібник користувача містить: **Попередження про спойлер**: навчальний посібник - посібник користувача містить:
* Оголошення **параметрів** з інших різних місць, як-от: **headers**, **cookies**, **form fields** та **files**. * Оголошення **параметрів** з інших різних місць, як-от: **заголовки**, **кукі**, **поля форми** та **файли**.
* Як встановлювати **обмеження валідації** як `maximum_length` або `regex`. * Як встановлювати **обмеження валідації** як `maximum_length` або `regex`.
* Дуже потужну і просту у використанні систему **<dfn title="також відоме як: компоненти, ресурси, провайдери, сервіси, інжектовані залежності">Впровадження залежностей</dfn>**. * Дуже потужну і просту у використанні систему **<dfn title="також відоме як: компоненти, ресурси, провайдери, сервіси, інжектовані залежності">Впровадження залежностей</dfn>**.
* Безпеку та автентифікацію, включно з підтримкою **OAuth2** з **JWT tokens** та **HTTP Basic** auth. * Безпеку та автентифікацію, включно з підтримкою **OAuth2** з **токенами JWT** та **базовою автентифікацією HTTP**.
* Досконаліші (але однаково прості) техніки для оголошення **глибоко вкладених моделей JSON** (завдяки Pydantic). * Досконаліші (але однаково прості) техніки для оголошення **глибоко вкладених моделей JSON** (завдяки Pydantic).
* Інтеграцію **GraphQL** з [Strawberry](https://strawberry.rocks) та іншими бібліотеками. * Інтеграцію **GraphQL** з [Strawberry](https://strawberry.rocks) та іншими бібліотеками.
* Багато додаткових можливостей (завдяки Starlette) як-от: * Багато додаткових можливостей (завдяки Starlette) як-от:
@ -518,13 +518,13 @@ CLI автоматично визначить ваш застосунок FastAP
Він спрощує процес **створення**, **розгортання** та **доступу** до API з мінімальними зусиллями. Він спрощує процес **створення**, **розгортання** та **доступу** до API з мінімальними зусиллями.
Він забезпечує той самий **developer experience** створення застосунків на FastAPI під час їх **розгортання** у хмарі. 🎉 Він забезпечує той самий **досвід розробника** створення застосунків на FastAPI під час їх **розгортання** у хмарі. 🎉
FastAPI Cloud - основний спонсор і джерело фінансування open source проєктів *FastAPI and friends*. ✨ FastAPI Cloud - основний спонсор і джерело фінансування проєктів з відкритим кодом *FastAPI and friends*. ✨
#### Розгортання в інших хмарних провайдерів { #deploy-to-other-cloud-providers } #### Розгортання в інших хмарних провайдерів { #deploy-to-other-cloud-providers }
FastAPI - open source проєкт і базується на стандартах. Ви можете розгортати застосунки FastAPI в будь-якому хмарному провайдері, який ви оберете. FastAPI - проєкт з відкритим кодом і базується на стандартах. Ви можете розгортати застосунки FastAPI в будь-якому хмарному провайдері, який ви оберете.
Дотримуйтеся інструкцій вашого хмарного провайдера, щоб розгорнути застосунки FastAPI у нього. 🤓 Дотримуйтеся інструкцій вашого хмарного провайдера, щоб розгорнути застосунки FastAPI у нього. 🤓
@ -532,7 +532,7 @@ FastAPI - open source проєкт і базується на стандарта
Незалежні тести TechEmpower показують застосунки **FastAPI**, які працюють під керуванням Uvicorn, як [одні з найшвидших доступних Python-фреймворків](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), поступаючись лише Starlette та Uvicorn (які внутрішньо використовуються в FastAPI). (*) Незалежні тести TechEmpower показують застосунки **FastAPI**, які працюють під керуванням Uvicorn, як [одні з найшвидших доступних Python-фреймворків](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), поступаючись лише Starlette та Uvicorn (які внутрішньо використовуються в FastAPI). (*)
Щоб дізнатися більше, перегляньте розділ [Benchmarks](https://fastapi.tiangolo.com/uk/benchmarks/). Щоб дізнатися більше, перегляньте розділ [Тести продуктивності](https://fastapi.tiangolo.com/uk/benchmarks/).
## Залежності { #dependencies } ## Залежності { #dependencies }

1
docs/uk/docs/project-generation.md

@ -1,5 +1,6 @@
# Шаблон Full Stack FastAPI { #full-stack-fastapi-template } # Шаблон Full Stack FastAPI { #full-stack-fastapi-template }
Шаблони, хоча зазвичай постачаються з певним налаштуванням, спроєктовані бути гнучкими та налаштовуваними. Це дає змогу змінювати їх і адаптувати до вимог вашого проєкту, що робить їх чудовою відправною точкою. 🏁 Шаблони, хоча зазвичай постачаються з певним налаштуванням, спроєктовані бути гнучкими та налаштовуваними. Це дає змогу змінювати їх і адаптувати до вимог вашого проєкту, що робить їх чудовою відправною точкою. 🏁
Ви можете використати цей шаблон для старту, адже в ньому вже виконано значну частину початкового налаштування, безпеки, роботи з базою даних і деяких кінцевих точок API. Ви можете використати цей шаблон для старту, адже в ньому вже виконано значну частину початкового налаштування, безпеки, роботи з базою даних і деяких кінцевих точок API.

42
docs/uk/docs/python-types.md

@ -2,7 +2,7 @@
Python підтримує додаткові «підказки типів» (також звані «анотаціями типів»). Python підтримує додаткові «підказки типів» (також звані «анотаціями типів»).
Ці **«підказки типів»** або анотації це спеціальний синтаксис, що дозволяє оголошувати <dfn title="наприклад: str, int, float, bool">тип</dfn> змінної. Ці **«підказки типів»** або анотації - це спеціальний синтаксис, що дозволяє оголошувати <dfn title="наприклад: str, int, float, bool">тип</dfn> змінної.
За допомогою оголошення типів для ваших змінних редактори та інструменти можуть надати вам кращу підтримку. За допомогою оголошення типів для ваших змінних редактори та інструменти можуть надати вам кращу підтримку.
@ -50,7 +50,7 @@ John Doe
Це буде `upper`? Чи `uppercase`? `first_uppercase`? `capitalize`? Це буде `upper`? Чи `uppercase`? `first_uppercase`? `capitalize`?
Тоді ви спробуєте давнього друга програміста автозаповнення редактора коду. Тоді ви спробуєте давнього друга програміста - автозаповнення редактора коду.
Ви надрукуєте перший параметр функції, `first_name`, тоді крапку (`.`), а тоді натиснете `Ctrl+Space`, щоб запустити автозаповнення. Ви надрукуєте перший параметр функції, `first_name`, тоді крапку (`.`), а тоді натиснете `Ctrl+Space`, щоб запустити автозаповнення.
@ -147,20 +147,20 @@ def some_function(data: Any):
print(data) print(data)
``` ```
### Generic типи { #generic-types } ### Узагальнені типи { #generic-types }
Деякі типи можуть приймати «параметри типів» у квадратних дужках, щоб визначити їх внутрішні типи. Наприклад, «list строк» буде оголошений як `list[str]`. Деякі типи можуть приймати «параметри типів» у квадратних дужках, щоб визначити їх внутрішні типи. Наприклад, «list строк» буде оголошений як `list[str]`.
Ці типи, які можуть приймати параметри типів, називаються **generic типами** або **generics**. Ці типи, які можуть приймати параметри типів, називаються **узагальненими типами** або **дженериками**.
Ви можете використовувати ті самі вбудовані типи як generics (з квадратними дужками та типами всередині): Ви можете використовувати ті самі вбудовані типи як дженерики (з квадратними дужками та типами всередині):
* `list` * `list`
* `tuple` * `tuple`
* `set` * `set`
* `dict` * `dict`
#### List { #list } #### Список { #list }
Наприклад, давайте визначимо змінну, яка буде `list` із `str`. Наприклад, давайте визначимо змінну, яка буде `list` із `str`.
@ -176,11 +176,11 @@ def some_function(data: Any):
Ці внутрішні типи в квадратних дужках називаються «параметрами типу». Ці внутрішні типи в квадратних дужках називаються «параметрами типу».
У цьому випадку `str` це параметр типу, переданий у `list`. У цьому випадку `str` - це параметр типу, переданий у `list`.
/// ///
Це означає: «змінна `items` це `list`, і кожен з елементів у цьому списку `str`». Це означає: «змінна `items` - це `list`, і кожен з елементів у цьому списку - `str`».
Зробивши це, ваш редактор може надати підтримку навіть під час обробки елементів зі списку: Зробивши це, ваш редактор може надати підтримку навіть під час обробки елементів зі списку:
@ -192,7 +192,7 @@ def some_function(data: Any):
І все ж редактор знає, що це `str`, і надає підтримку для цього. І все ж редактор знає, що це `str`, і надає підтримку для цього.
#### Tuple and Set { #tuple-and-set } #### Кортеж і множина { #tuple-and-set }
Ви повинні зробити те ж саме, щоб оголосити `tuple` і `set`: Ви повинні зробити те ж саме, щоб оголосити `tuple` і `set`:
@ -200,10 +200,10 @@ def some_function(data: Any):
Це означає: Це означає:
* Змінна `items_t` це `tuple` з 3 елементами: `int`, ще `int`, та `str`. * Змінна `items_t` - це `tuple` з 3 елементами: `int`, ще `int`, та `str`.
* Змінна `items_s` це `set`, і кожен його елемент має тип `bytes`. * Змінна `items_s` - це `set`, і кожен його елемент має тип `bytes`.
#### Dict { #dict } #### Словник { #dict }
Щоб оголосити `dict`, вам потрібно передати 2 параметри типу, розділені комами. Щоб оголосити `dict`, вам потрібно передати 2 параметри типу, розділені комами.
@ -215,17 +215,17 @@ def some_function(data: Any):
Це означає: Це означає:
* Змінна `prices` це `dict`: * Змінна `prices` - це `dict`:
* Ключі цього `dict` мають тип `str` (скажімо, назва кожного предмета). * Ключі цього `dict` мають тип `str` (скажімо, назва кожного предмета).
* Значення цього `dict` мають тип `float` (скажімо, ціна кожного предмета). * Значення цього `dict` мають тип `float` (скажімо, ціна кожного предмета).
#### Union { #union } #### Об’єднання { #union }
Ви можете оголосити, що змінна може бути будь-яким із **кількох типів**, наприклад `int` або `str`. Ви можете оголосити, що змінна може бути будь-яким із **кількох типів**, наприклад `int` або `str`.
Щоб визначити це, використовуйте <dfn title='також називають «побітовим оператором "або"», але це значення тут не актуальне'>вертикальну риску (`|`)</dfn>, щоб розділити обидва типи. Щоб визначити це, використовуйте <dfn title='також називають «побітовим оператором "або"», але це значення тут не актуальне'>вертикальну риску (`|`)</dfn>, щоб розділити обидва типи.
Це називається «union», тому що змінна може бути чимось із об’єднання цих двох множин типів. Це називається «об’єднанням», тому що змінна може бути чимось із об’єднання цих двох множин типів.
```Python hl_lines="1" ```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!} {!> ../../docs_src/python_types/tutorial008b_py310.py!}
@ -263,11 +263,11 @@ def some_function(data: Any):
<img src="/img/python-types/image06.png"> <img src="/img/python-types/image06.png">
Зверніть увагу, що це означає: «`one_person` це **екземпляр** класу `Person`». Зверніть увагу, що це означає: «`one_person` - це **екземпляр** класу `Person`».
Це не означає: «`one_person` це **клас** з назвою `Person`». Це не означає: «`one_person` - це **клас** з назвою `Person`».
## Pydantic моделі { #pydantic-models } ## Моделі Pydantic { #pydantic-models }
[Pydantic](https://docs.pydantic.dev/) — це бібліотека Python для валідації даних. [Pydantic](https://docs.pydantic.dev/) — це бібліотека Python для валідації даних.
@ -295,7 +295,7 @@ def some_function(data: Any):
## Підказки типів з анотаціями метаданих { #type-hints-with-metadata-annotations } ## Підказки типів з анотаціями метаданих { #type-hints-with-metadata-annotations }
У Python також є можливість додавати **додаткові <dfn title="Дані про дані, у цьому випадку інформація про тип, наприклад опис.">метадані</dfn>** до цих підказок типів за допомогою `Annotated`. У Python також є можливість додавати **додаткові <dfn title="Дані про дані, у цьому випадку - інформація про тип, наприклад опис.">метадані</dfn>** до цих підказок типів за допомогою `Annotated`.
Ви можете імпортувати `Annotated` з `typing`. Ви можете імпортувати `Annotated` з `typing`.
@ -305,7 +305,7 @@ def some_function(data: Any):
Але ви можете використати це місце в `Annotated`, щоб надати **FastAPI** додаткові метадані про те, як ви хочете, щоб ваш застосунок поводився. Але ви можете використати це місце в `Annotated`, щоб надати **FastAPI** додаткові метадані про те, як ви хочете, щоб ваш застосунок поводився.
Важливо пам’ятати, що **перший *параметр типу***, який ви передаєте в `Annotated`, — це **фактичний тип**. Решта — це лише метадані для інших інструментів. Важливо пам’ятати, що **перший *параметр типу***, який ви передаєте в `Annotated`, - це **фактичний тип**. Решта - це лише метадані для інших інструментів.
Наразі вам просто потрібно знати, що `Annotated` існує і що це стандартний Python. 😎 Наразі вам просто потрібно знати, що `Annotated` існує і що це стандартний Python. 😎
@ -335,7 +335,7 @@ def some_function(data: Any):
* **Перевірки даних**: що надходять від кожного запиту: * **Перевірки даних**: що надходять від кожного запиту:
* Генерування **автоматичних помилок**, що повертаються клієнту, коли дані недійсні. * Генерування **автоматичних помилок**, що повертаються клієнту, коли дані недійсні.
* **Документування** API за допомогою OpenAPI: * **Документування** API за допомогою OpenAPI:
* який потім використовується для автоматичної інтерактивної документації користувальницьких інтерфейсів. * що потім використовується автоматичними інтерактивними користувацькими інтерфейсами документації.
Все це може здатися абстрактним. Не хвилюйтеся. Ви побачите все це в дії в [Навчальний посібник - Посібник користувача](tutorial/index.md). Все це може здатися абстрактним. Не хвилюйтеся. Ви побачите все це в дії в [Навчальний посібник - Посібник користувача](tutorial/index.md).

38
docs/uk/docs/tutorial/bigger-applications.md

@ -17,16 +17,16 @@
``` ```
. .
├── app ├── app
   ├── __init__.py ├── __init__.py
   ├── main.py ├── main.py
   ├── dependencies.py ├── dependencies.py
   └── routers └── routers
   │ ├── __init__.py │ ├── __init__.py
   │ ├── items.py │ ├── items.py
   │ └── users.py │ └── users.py
   └── internal └── internal
   ├── __init__.py ├── __init__.py
   └── admin.py └── admin.py
``` ```
/// tip | Порада /// tip | Порада
@ -382,11 +382,11 @@ from .routers.users import router
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *} {* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// note | Технічні деталі /// note | Примітка
FastAPI зберігає оригінальний `APIRouter` і його `APIRoute` активними після включення router'а до основного застосунку. `users.router` містить `APIRouter` всередині файлу `app/routers/users.py`.
Це означає, що користувацькі підкласи `APIRouter` і `APIRoute` і надалі братимуть участь після включення router'а. А `items.router` містить `APIRouter` всередині файлу `app/routers/items.py`.
/// ///
@ -394,6 +394,14 @@ FastAPI зберігає оригінальний `APIRouter` і його `APIRo
Це включить усі маршрути з цього router'а як частину застосунку. Це включить усі маршрути з цього router'а як частину застосунку.
/// note | Технічні деталі
FastAPI зберігає оригінальний `APIRouter` і його `APIRoute` активними після включення router'а до основного застосунку.
Це означає, що користувацькі підкласи `APIRouter` і `APIRoute` і надалі братимуть участь після включення router'а.
///
/// tip | Порада /// tip | Порада
Вам не потрібно перейматися продуктивністю під час включення router'ів. Вам не потрібно перейматися продуктивністю під час включення router'ів.
@ -445,7 +453,7 @@ FastAPI зберігає оригінальний `APIRouter` і його `APIRo
/// note | Дуже технічні деталі /// note | Дуже технічні деталі
Примітка: це дуже технічна деталь, яку ви, ймовірно, можете просто пропустити. **Примітка**: це дуже технічна деталь, яку ви, ймовірно, можете **просто пропустити**.
--- ---
@ -510,7 +518,7 @@ $ fastapi dev
## Включайте той самий router кілька разів з різними `prefix` { #include-the-same-router-multiple-times-with-different-prefix } ## Включайте той самий router кілька разів з різними `prefix` { #include-the-same-router-multiple-times-with-different-prefix }
Ви також можете використовувати `.include_router()` кілька разів з одним і тим самим router'ом, але з різними префіксами. Ви також можете використовувати `.include_router()` кілька разів з *тим самим* router'ом, але з різними префіксами.
Це може бути корисно, наприклад, щоб публікувати той самий API під різними префіксами, наприклад `/api/v1` і `/api/latest`. Це може бути корисно, наприклад, щоб публікувати той самий API під різними префіксами, наприклад `/api/v1` і `/api/latest`.

60
docs/uk/docs/tutorial/body-nested-models.md

@ -27,17 +27,17 @@ my_list: list[str]
Використовуйте той самий стандартний синтаксис для атрибутів моделей з внутрішніми типами. Використовуйте той самий стандартний синтаксис для атрибутів моделей з внутрішніми типами.
Отже, у нашому прикладі, ми можемо зробити `tags` саме «списком рядків»: Отже, у нашому прикладі, ми можемо зробити `tags` саме «списком строк»:
{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *} {* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
## Типи множин { #set-types } ## Типи множин { #set-types }
Але потім ми подумали, що теги не повинні повторюватися, вони, ймовірно, повинні бути унікальними рядками. Але потім ми подумали, що теги не повинні повторюватися, вони, ймовірно, повинні бути унікальними строками.
І Python має спеціальний тип даних для множин унікальних елементів це `set`. І Python має спеціальний тип даних для множин унікальних елементів - це `set`.
Тому ми можемо оголосити `tags` як множину рядків: Тому ми можемо оголосити `tags` як множину строк:
{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *} {* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
@ -45,7 +45,7 @@ my_list: list[str]
І коли ви будете виводити ці дані, навіть якщо джерело містить дублікати, вони будуть виведені як множина унікальних елементів. І коли ви будете виводити ці дані, навіть якщо джерело містить дублікати, вони будуть виведені як множина унікальних елементів.
І це буде анотовано/документовано відповідно. І це буде анотовано / документовано відповідно.
## Вкладені моделі { #nested-models } ## Вкладені моделі { #nested-models }
@ -69,7 +69,7 @@ my_list: list[str]
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *} {* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
Це означатиме, що **FastAPI** очікуватиме тіло запиту такого вигляду: Це означатиме, що **FastAPI** очікуватиме тіло, подібне до:
```JSON ```JSON
{ {
@ -85,7 +85,7 @@ my_list: list[str]
} }
``` ```
Завдяки такій декларації у **FastAPI** ви отримуєте: Знову ж, лише завдяки такому оголошенню, з **FastAPI** ви отримуєте:
* Підтримку в редакторі (автозавершення тощо), навіть для вкладених моделей * Підтримку в редакторі (автозавершення тощо), навіть для вкладених моделей
* Конвертацію даних * Конвертацію даних
@ -94,23 +94,23 @@ my_list: list[str]
## Спеціальні типи та валідація { #special-types-and-validation } ## Спеціальні типи та валідація { #special-types-and-validation }
Окрім звичайних типів, таких як `str`, `int`, `float`, та ін. ви можете використовувати складніші типи, які наслідують `str`. Окрім звичайних одиничних типів, таких як `str`, `int`, `float`, та ін. ви можете використовувати складніші одиничні типи, які наслідують `str`.
Щоб побачити всі доступні варіанти, ознайомтеся з [Оглядом типів у Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Деякі приклади будуть у наступному розділі. Щоб побачити всі доступні варіанти, ознайомтеся з [Оглядом типів у Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Деякі приклади будуть у наступному розділі.
Наприклад, у моделі `Image` є поле `url`, тому ми можемо оголосити його як `HttpUrl` від Pydantic замість `str`: Наприклад, оскільки в моделі `Image` є поле `url`, ми можемо оголосити його як екземпляр `HttpUrl` від Pydantic замість `str`:
{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *} {* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
Рядок буде перевірено як дійсну URL-адресу і задокументовано в JSON Schema / OpenAPI як URL. Строку буде перевірено як дійсну URL-адресу і задокументовано в Схемі JSON / OpenAPI як таку.
## Атрибути зі списками підмоделей { #attributes-with-lists-of-submodels } ## Атрибути зі списками підмоделей { #attributes-with-lists-of-submodels }
У Pydantic ви можете використовувати моделі як підтипи для `list`, `set` тощо: У Pydantic ви також можете використовувати моделі як підтипи для `list`, `set` тощо:
{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *} {* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
Це означає, що **FastAPI** буде очікувати (конвертувати, валідувати, документувати тощо) JSON тіло запиту у вигляді: Це очікуватиме (конвертуватиме, валідуватиме, документуватиме тощо) тіло JSON у вигляді:
```JSON hl_lines="11" ```JSON hl_lines="11"
{ {
@ -150,61 +150,61 @@ my_list: list[str]
/// note | Примітка /// note | Примітка
Зверніть увагу, що в моделі `Offer` є список `Item`ів, які, своєю чергою, можуть мати необов'язковий список `Image`ів. Зверніть увагу, що `Offer` має список `Item`ів, які, своєю чергою, мають необов'язковий список `Image`ів
/// ///
## Тіла запитів, що складаються зі списків { #bodies-of-pure-lists } ## Тіла запитів, що складаються зі списків { #bodies-of-pure-lists }
Якщо верхній рівень JSON тіла, яке ви очікуєте, є JSON `масивом` (у Python — `list`), ви можете оголосити тип у параметрі функції, як і в моделях Pydantic: Якщо значення верхнього рівня JSON тіла, яке ви очікуєте, є JSON `array` (Python `list`), ви можете оголосити тип у параметрі функції так само, як у моделях Pydantic:
```Python ```Python
images: list[Image] images: list[Image]
``` ```
наприклад: як у:
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *} {* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## Підтримка в редакторі всюди { #editor-support-everywhere } ## Підтримка в редакторі всюди { #editor-support-everywhere }
Ви отримаєте підтримку в редакторі всюди. І ви отримаєте підтримку в редакторі всюди.
Навіть для елементів у списках: Навіть для елементів у списках:
<img src="/img/tutorial/body-nested-models/image01.png"> <img src="/img/tutorial/body-nested-models/image01.png">
Ви не змогли б отримати таку підтримку в редакторі, якби працювали напряму зі `dict`, а не з моделями Pydantic. Ви не змогли б отримати таку підтримку в редакторі, якби працювали напряму зі `dict`, а не з моделями Pydantic.
Але вам не потрібно турбуватися про це: вхідні dict'и автоматично конвертуються, а вихідні дані автоматично перетворюються в JSON. Але вам також не потрібно турбуватися про них: вхідні словники автоматично конвертуються, а вихідні дані автоматично перетворюються в JSON.
## Тіла з довільними `dict` { #bodies-of-arbitrary-dicts } ## Тіла з довільними `dict` { #bodies-of-arbitrary-dicts }
Ви також можете оголосити тіло як `dict` з ключами одного типу та значеннями іншого типу. Ви також можете оголосити тіло як `dict` з ключами одного типу та значеннями іншого типу.
Це корисно, якщо ви не знаєте наперед, які імена полів будуть дійсними (як у випадку з моделями Pydantic). Таким чином, вам не потрібно наперед знати, які імена полів/атрибутів є дійсними (як це було б у випадку з моделями Pydantic).
Це буде корисно, якщо ви хочете приймати ключі, які заздалегідь невідомі. Це буде корисно, якщо ви хочете приймати ключі, які заздалегідь невідомі.
--- ---
Це також зручно, якщо ви хочете мати ключі іншого типу (наприклад, `int`). Інший корисний випадок - коли ви хочете мати ключі іншого типу (наприклад, `int`).
Ось що ми розглянемо далі. Ось що ми розглянемо тут.
У цьому випадку ви можете приймати будь-який `dict`, якщо його ключі — це `int`, а значення — `float`: У цьому випадку ви можете приймати будь-який `dict`, якщо він має ключі `int` зі значеннями `float`:
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *} {* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip | Порада /// tip | Порада
Майте на увазі, що в JSON тілі ключі можуть бути лише рядками (`str`). Майте на увазі, що JSON підтримує лише `str` як ключі.
Але Pydantic автоматично конвертує дані. Але Pydantic має автоматичну конвертацію даних.
Це означає, що навіть якщо клієнти вашого API надсилатимуть ключі у вигляді рядків, якщо вони містять цілі числа, Pydantic конвертує їх і проведе валідацію. Це означає, що навіть якщо клієнти вашого API можуть надсилати лише строки як ключі, якщо ці строки містять цілі числа, Pydantic конвертує їх і проведе валідацію.
Тобто `dict`, який ви отримаєте як `weights`, матиме ключі типу `int` та значення типу `float`. І `dict`, який ви отримаєте як `weights`, фактично матиме ключі типу `int` та значення типу `float`.
/// ///
@ -212,10 +212,10 @@ images: list[Image]
З **FastAPI** ви маєте максимальну гнучкість завдяки моделям Pydantic, зберігаючи при цьому код простим, коротким та елегантним. З **FastAPI** ви маєте максимальну гнучкість завдяки моделям Pydantic, зберігаючи при цьому код простим, коротким та елегантним.
А також отримуєте всі переваги: Але з усіма перевагами:
* Підтримка в редакторі (автодоповнення всюди!) * Підтримка в редакторі (автозавершення всюди!)
* Конвертація даних (парсинг/серіалізація) * Конвертація даних (також відома як парсинг / серіалізація)
* Валідація даних * Валідація даних
* Документація схем * Документація схем
* Автоматичне створення документації * Автоматична документація

2
docs/uk/docs/tutorial/body.md

@ -4,7 +4,7 @@
Тіло **запиту** - це дані, надіслані клієнтом до вашого API. Тіло **відповіді** - це дані, які ваш API надсилає клієнту. Тіло **запиту** - це дані, надіслані клієнтом до вашого API. Тіло **відповіді** - це дані, які ваш API надсилає клієнту.
Ваш API майже завжди має надсилати тіло **відповіді**. Але клієнтам не обов’язково потрібно постійно надсилати тіла **запитів** інколи вони лише запитують шлях, можливо з деякими параметрами запиту, але не надсилають тіло. Ваш API майже завжди має надсилати тіло **відповіді**. Але клієнтам не обов’язково потрібно постійно надсилати тіла **запитів** - інколи вони лише запитують шлях, можливо з деякими параметрами запиту, але не надсилають тіло.
Щоб оголосити тіло **запиту**, ви використовуєте [Pydantic](https://docs.pydantic.dev/) моделі з усією їх потужністю та перевагами. Щоб оголосити тіло **запиту**, ви використовуєте [Pydantic](https://docs.pydantic.dev/) моделі з усією їх потужністю та перевагами.

1
docs/uk/docs/tutorial/debugging.md

@ -1,5 +1,6 @@
# Налагодження { #debugging } # Налагодження { #debugging }
Ви можете під'єднати дебагер у вашому редакторі коду, наприклад, у Visual Studio Code або PyCharm. Ви можете під'єднати дебагер у вашому редакторі коду, наприклад, у Visual Studio Code або PyCharm.
## Виклик `uvicorn` { #call-uvicorn } ## Виклик `uvicorn` { #call-uvicorn }

5
docs/uk/docs/tutorial/dependencies/dependencies-with-yield.md

@ -63,7 +63,7 @@ FastAPI підтримує залежності, які виконують де
Ви можете мати підзалежності та «дерева» підзалежностей будь-якого розміру і форми, і будь-яка або всі з них можуть використовувати `yield`. Ви можете мати підзалежності та «дерева» підзалежностей будь-якого розміру і форми, і будь-яка або всі з них можуть використовувати `yield`.
**FastAPI** гарантує, що «exit code» у кожній залежності з `yield` буде виконано в правильному порядку. **FastAPI** гарантує, що «код виходу» у кожній залежності з `yield` буде виконано в правильному порядку.
Наприклад, `dependency_c` може залежати від `dependency_b`, а `dependency_b` - від `dependency_a`: Наприклад, `dependency_c` може залежати від `dependency_b`, а `dependency_b` - від `dependency_a`:
@ -194,7 +194,7 @@ participant tasks as Background tasks
`Depends()` приймає параметр `scope`, який може бути: `Depends()` приймає параметр `scope`, який може бути:
* `"function"`: запустити залежність перед *функцією операції шляху*, що обробляє запит, завершити залежність після завершення *функції операції шляху*, але **до** того, як відповідь буде відправлена клієнту. Тобто функція залежності буде виконуватися **навколо** *функції операції **шляху***. * `"function"`: запустити залежність перед *функцією операції шляху*, що обробляє запит, завершити залежність після завершення *функції операції шляху*, але **до** того, як відповідь буде відправлена клієнту. Тобто функція залежності буде виконуватися **навколо** ***функції** операції шляху*.
* `"request"`: запустити залежність перед *функцією операції шляху*, що обробляє запит (подібно до `"function"`), але завершити **після** того, як відповідь буде відправлена клієнту. Тобто функція залежності буде виконуватися **навколо** циклу **запиту** та відповіді. * `"request"`: запустити залежність перед *функцією операції шляху*, що обробляє запит (подібно до `"function"`), але завершити **після** того, як відповідь буде відправлена клієнту. Тобто функція залежності буде виконуватися **навколо** циклу **запиту** та відповіді.
Якщо не вказано, і залежність має `yield`, за замовчуванням `scope` дорівнює `"request"`. Якщо не вказано, і залежність має `yield`, за замовчуванням `scope` дорівнює `"request"`.
@ -234,6 +234,7 @@ participant operation as Path Operation
Залежності з `yield` еволюціонували з часом, щоб покрити різні сценарії та виправити деякі проблеми. Залежності з `yield` еволюціонували з часом, щоб покрити різні сценарії та виправити деякі проблеми.
Якщо ви хочете дізнатися, що змінювалося в різних версіях FastAPI, прочитайте про це в просунутому посібнику користувача: [Розширені залежності - Залежності з `yield`, `HTTPException`, `except` і фоновими задачами](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks). Якщо ви хочете дізнатися, що змінювалося в різних версіях FastAPI, прочитайте про це в просунутому посібнику користувача: [Розширені залежності - Залежності з `yield`, `HTTPException`, `except` і фоновими задачами](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Менеджери контексту { #context-managers } ## Менеджери контексту { #context-managers }
### Що таке «Менеджери контексту» { #what-are-context-managers } ### Що таке «Менеджери контексту» { #what-are-context-managers }

8
docs/uk/docs/tutorial/extra-data-types.md

@ -22,7 +22,7 @@
Ось додаткові типи даних для використання: Ось додаткові типи даних для використання:
* `UUID`: * `UUID`:
* Стандартний "Універсальний унікальний ідентифікатор", який часто використовується як ID у багатьох базах даних та системах. * Стандартний «Універсальний унікальний ідентифікатор», який часто використовується як ID у багатьох базах даних та системах.
* У запитах та відповідях буде представлений як `str`. * У запитах та відповідях буде представлений як `str`.
* `datetime.datetime`: * `datetime.datetime`:
* Пайтонівський `datetime.datetime`. * Пайтонівський `datetime.datetime`.
@ -36,16 +36,16 @@
* `datetime.timedelta`: * `datetime.timedelta`:
* Пайтонівський `datetime.timedelta`. * Пайтонівський `datetime.timedelta`.
* У запитах та відповідях буде представлений як `float` загальної кількості секунд. * У запитах та відповідях буде представлений як `float` загальної кількості секунд.
* Pydantic також дозволяє представляти це як "ISO 8601 time diff encoding", [дивіться документацію для отримання додаткової інформації](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers). * Pydantic також дозволяє представляти це як «ISO 8601 time diff encoding», [дивіться документацію для отримання додаткової інформації](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
* `frozenset`: * `frozenset`:
* У запитах і відповідях це буде оброблено так само, як і `set`: * У запитах і відповідях це буде оброблено так само, як і `set`:
* У запитах список буде зчитано, дублікати буде видалено, і його буде перетворено на `set`. * У запитах список буде зчитано, дублікати буде видалено, і його буде перетворено на `set`.
* У відповідях `set` буде перетворено на `list`. * У відповідях `set` буде перетворено на `list`.
* Згенерована схема буде вказувати, що значення `set` є унікальними (з використанням JSON Schema's `uniqueItems`). * Згенерована схема буде вказувати, що значення `set` є унікальними (з використанням `uniqueItems` Схеми JSON).
* `bytes`: * `bytes`:
* Стандартний Пайтонівський `bytes`. * Стандартний Пайтонівський `bytes`.
* У запитах і відповідях це буде оброблено як `str`. * У запитах і відповідях це буде оброблено як `str`.
* Згенерована схема буде вказувати, що це `str` з "форматом" `binary`. * Згенерована схема буде вказувати, що це `str` з «форматом» `binary`.
* `Decimal`: * `Decimal`:
* Стандартний Пайтонівський `Decimal`. * Стандартний Пайтонівський `Decimal`.
* У запитах і відповідях це буде оброблено так само, як і `float`. * У запитах і відповідях це буде оброблено так само, як і `float`.

8
docs/uk/docs/tutorial/extra-models.md

@ -63,7 +63,7 @@ print(user_dict)
#### Розпакування `dict` { #unpacking-a-dict } #### Розпакування `dict` { #unpacking-a-dict }
Якщо взяти `dict`, наприклад `user_dict`, і передати його у функцію (або клас) як `**user_dict`, Python «розпакує» його. Ключі та значення `user_dict` будуть передані безпосередньо як іменовані аргументи. Якщо взяти `dict`, наприклад `user_dict`, і передати його у функцію (або клас) як `**user_dict`, Python «розпакує» його. Ключі та значення `user_dict` будуть передані безпосередньо як аргументи ключ-значення.
Отже, продовжуючи з `user_dict` вище, запис: Отже, продовжуючи з `user_dict` вище, запис:
@ -176,7 +176,7 @@ UserInDB(
У цьому прикладі ми передаємо `Union[PlaneItem, CarItem]` як значення аргументу `response_model`. У цьому прикладі ми передаємо `Union[PlaneItem, CarItem]` як значення аргументу `response_model`.
Оскільки ми передаємо його як значення аргументу, а не в анотації типу, потрібно використовувати `Union` навіть у Python 3.10. Оскільки ми передаємо його як **значення аргументу**, а не розміщуємо в **анотації типу**, потрібно використовувати `Union` навіть у Python 3.10.
Якби це була анотація типу, можна було б використати вертикальну риску, наприклад: Якби це була анотація типу, можна було б використати вертикальну риску, наприклад:
@ -184,7 +184,7 @@ UserInDB(
some_variable: PlaneItem | CarItem some_variable: PlaneItem | CarItem
``` ```
Але якщо записати це як присвоєння `response_model=PlaneItem | CarItem`, отримаємо помилку, тому що Python спробує виконати невалідну операцію між `PlaneItem` і `CarItem`, замість того щоб трактувати це як анотацію типу. Але якщо записати це як присвоєння `response_model=PlaneItem | CarItem`, отримаємо помилку, тому що Python спробує виконати **невалідну операцію** між `PlaneItem` і `CarItem`, замість того щоб трактувати це як анотацію типу.
## Список моделей { #list-of-models } ## Список моделей { #list-of-models }
@ -208,4 +208,4 @@ some_variable: PlaneItem | CarItem
Використовуйте кілька моделей Pydantic і вільно наслідуйте для кожного випадку. Використовуйте кілька моделей Pydantic і вільно наслідуйте для кожного випадку.
Не обов’язково мати одну модель даних на сутність, якщо ця сутність може мати різні «стани». Як у випадку сутності користувача зі станами: з `password`, з `password_hash` і без пароля. Не обов’язково мати одну модель даних на сутність, якщо ця сутність повинна мати різні «стани». «Сутність» **користувач** є прикладом зі станами, що включають `password`, `password_hash` або відсутність пароля.

24
docs/uk/docs/tutorial/first-steps.md

@ -88,13 +88,13 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
#### «Схема» { #schema } #### «Схема» { #schema }
«Схема» це визначення або опис чогось. Це не код, який його реалізує, а просто абстрактний опис. «Схема» - це визначення або опис чогось. Це не код, який його реалізує, а просто абстрактний опис.
#### API «схема» { #api-schema } #### API «схема» { #api-schema }
У цьому випадку, [OpenAPI](https://github.com/OAI/OpenAPI-Specification) є специфікацією, яка визначає, як описати схему вашого API. У цьому випадку, [OpenAPI](https://github.com/OAI/OpenAPI-Specification) є специфікацією, яка визначає, як описати схему вашого API.
Це визначення схеми включає шляхи (paths) вашого API, можливі параметри, які вони приймають, тощо. Це визначення схеми включає шляхи вашого API, можливі параметри, які вони приймають, тощо.
#### «Схема» даних { #data-schema } #### «Схема» даних { #data-schema }
@ -102,13 +102,13 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
У цьому випадку це означає атрибути JSON і типи даних, які вони мають, тощо. У цьому випадку це означає атрибути JSON і типи даних, які вони мають, тощо.
#### OpenAPI і JSON Schema { #openapi-and-json-schema } #### OpenAPI і Схема JSON { #openapi-and-json-schema }
OpenAPI описує схему API для вашого API. І ця схема включає визначення (або «схеми») даних, що надсилаються та отримуються вашим API, за допомогою **JSON Schema**, стандарту для схем даних JSON. OpenAPI описує схему API для вашого API. І ця схема включає визначення (або «схеми») даних, що надсилаються та отримуються вашим API, за допомогою **Схеми JSON**, стандарту для схем даних JSON.
#### Перевірте `openapi.json` { #check-the-openapi-json } #### Перевірте `openapi.json` { #check-the-openapi-json }
Якщо вас цікавить, як виглядає «сирий» OpenAPI schema, FastAPI автоматично генерує JSON (schema) з описами всього вашого API. Якщо вас цікавить, як виглядає «сирa» схема OpenAPI, FastAPI автоматично генерує JSON (схему) з описами всього вашого API.
Ви можете побачити це напряму тут: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json). Ви можете побачити це напряму тут: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json).
@ -137,7 +137,7 @@ OpenAPI описує схему API для вашого API. І ця схема
#### Для чого потрібний OpenAPI { #what-is-openapi-for } #### Для чого потрібний OpenAPI { #what-is-openapi-for }
OpenAPI schema — це те, на чому працюють дві включені системи інтерактивної документації. Схема OpenAPI - це те, на чому працюють дві включені системи інтерактивної документації.
Також існують десятки альтернатив, і всі вони засновані на OpenAPI. Ви можете легко додати будь-яку з цих альтернатив до вашого застосунку, створеного з **FastAPI**. Також існують десятки альтернатив, і всі вони засновані на OpenAPI. Ви можете легко додати будь-яку з цих альтернатив до вашого застосунку, створеного з **FastAPI**.
@ -226,11 +226,11 @@ CLI автоматично визначить ваш застосунок FastAP
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *} {* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI` це клас у Python, який надає всю функціональність для вашого API. `FastAPI` - це клас у Python, який надає всю функціональність для вашого API.
/// note | Технічні деталі /// note | Технічні деталі
`FastAPI` це клас, який успадковується безпосередньо від `Starlette`. `FastAPI` - це клас, який успадковується безпосередньо від `Starlette`.
Ви також можете використовувати всю функціональність [Starlette](https://www.starlette.dev/) у `FastAPI`. Ви також можете використовувати всю функціональність [Starlette](https://www.starlette.dev/) у `FastAPI`.
@ -312,7 +312,7 @@ https://example.com/items/foo
Декоратор `@app.get("/")` повідомляє **FastAPI**, що функція одразу нижче відповідає за обробку запитів, які надходять до: Декоратор `@app.get("/")` повідомляє **FastAPI**, що функція одразу нижче відповідає за обробку запитів, які надходять до:
* шляху `/` * шляху `/`
* використовуючи <dfn title="HTTP метод GET"><code>get</code> операція</dfn> * використовуючи <dfn title="HTTP метод GET">операцію <code>get</code></dfn>
/// note | `@decorator` Інформація /// note | `@decorator` Інформація
@ -389,7 +389,7 @@ https://example.com/items/foo
Також можна повернути моделі Pydantic (про це ви дізнаєтесь пізніше). Також можна повернути моделі Pydantic (про це ви дізнаєтесь пізніше).
Існує багато інших обʼєктів і моделей, які будуть автоматично конвертовані в JSON (зокрема ORM тощо). Спробуйте використати свої улюблені велика ймовірність, що вони вже підтримуються. Існує багато інших обʼєктів і моделей, які будуть автоматично конвертовані в JSON (зокрема ORM тощо). Спробуйте використати свої улюблені - велика ймовірність, що вони вже підтримуються.
### Крок 6: розгорніть його { #step-6-deploy-it } ### Крок 6: розгорніть його { #step-6-deploy-it }
@ -403,11 +403,11 @@ https://example.com/items/foo
Він переносить той самий **досвід розробника** зі створення застосунків на FastAPI на **розгортання** їх у хмарі. 🎉 Він переносить той самий **досвід розробника** зі створення застосунків на FastAPI на **розгортання** їх у хмарі. 🎉
FastAPI Cloud основний спонсор і джерело фінансування для open source проєктів *FastAPI and friends*. ✨ FastAPI Cloud - основний спонсор і джерело фінансування для open source проєктів *FastAPI and friends*. ✨
#### Розгортання в інших хмарних провайдерах { #deploy-to-other-cloud-providers } #### Розгортання в інших хмарних провайдерах { #deploy-to-other-cloud-providers }
FastAPI це open source і базується на стандартах. Ви можете розгортати FastAPI-застосунки у будь-якого хмарного провайдера на ваш вибір. FastAPI - це open source і базується на стандартах. Ви можете розгортати FastAPI-застосунки у будь-якого хмарного провайдера на ваш вибір.
Дотримуйтеся інструкцій вашого хмарного провайдера, щоб розгорнути FastAPI-застосунки з їхньою допомогою. 🤓 Дотримуйтеся інструкцій вашого хмарного провайдера, щоб розгорнути FastAPI-застосунки з їхньою допомогою. 🤓

2
docs/uk/docs/tutorial/handling-errors.md

@ -33,7 +33,7 @@
Оскільки це помилка Python, ви не `return` її, а `raise` її. Оскільки це помилка Python, ви не `return` її, а `raise` її.
Це також означає, що якщо ви перебуваєте всередині допоміжної функції, яку викликаєте всередині своєї *функції операції шляху*, і там згенеруєте `HTTPException` всередині цієї допоміжної функції, то решта коду в *функції операції шляху* не буде виконана. Запит одразу завершиться, і HTTP-помилка з `HTTPException` буде надіслана клієнту. Це також означає, що якщо ви перебваєте всередині допоміжної функції, яку викликаєте всередині своєї *функції операції шляху*, і там згенеруєте `HTTPException` всередині цієї допоміжної функції, то решта коду в *функції операції шляху* не буде виконана. Запит одразу завершиться, і HTTP-помилка з `HTTPException` буде надіслана клієнту.
Перевага генерації виключення замість повернення значення стане більш очевидною в розділі про залежності та безпеку. Перевага генерації виключення замість повернення значення стане більш очевидною в розділі про залежності та безпеку.

4
docs/uk/docs/tutorial/index.md

@ -54,7 +54,7 @@ $ <font color="#4E9A06">fastapi</font> dev
**ДУЖЕ радимо** написати або скопіювати код, відредагувати його та запустити локально. **ДУЖЕ радимо** написати або скопіювати код, відредагувати його та запустити локально.
Використання його у своєму редакторі це те, що дійсно показує вам переваги FastAPI, бачите, як мало коду вам потрібно написати, всі перевірки типів, автозаповнення тощо. Використання його у своєму редакторі - це те, що дійсно показує вам переваги FastAPI, бачите, як мало коду вам потрібно написати, всі перевірки типів, автозаповнення тощо.
--- ---
@ -86,7 +86,7 @@ $ pip install "fastapi[standard]"
/// tip | Порада /// tip | Порада
FastAPI має [офіційне розширення для VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (та Cursor), яке надає багато можливостей, включно з переглядачем операцій шляху, пошуком операцій шляху, навігацією CodeLens у тестах (перехід до визначення з тестів), а також розгортанням і журналами FastAPI Cloud усе безпосередньо з вашого редактора. FastAPI має [офіційне розширення для VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (та Cursor), яке надає багато можливостей, включно з переглядачем операцій шляху, пошуком операцій шляху, навігацією CodeLens у тестах (перехід до визначення з тестів), а також розгортанням і журналами FastAPI Cloud - усе безпосередньо з вашого редактора.
/// ///

2
docs/uk/docs/tutorial/metadata.md

@ -11,7 +11,7 @@
| `title` | `str` | Назва API. | | `title` | `str` | Назва API. |
| `summary` | `str` | Короткий підсумок API. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small> | | `summary` | `str` | Короткий підсумок API. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
| `description` | `str` | Короткий опис API. Може використовувати Markdown. | | `description` | `str` | Короткий опис API. Може використовувати Markdown. |
| `version` | `string` | Версія API. Це версія вашого додатка, а не OpenAPI. Наприклад, `2.5.0`. | | `version` | `str` | Версія API. Це версія вашого додатка, а не OpenAPI. Наприклад, `2.5.0`. |
| `terms_of_service` | `str` | URL до умов використання API. Якщо вказано, має бути у форматі URL. | | `terms_of_service` | `str` | URL до умов використання API. Якщо вказано, має бути у форматі URL. |
| `contact` | `dict` | Інформація для контакту з опублікованим API. Може містити кілька полів. <details><summary><code>contact</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Ідентифікаційне ім'я контактної особи або організації.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL, що вказує на контактну інформацію. <strong>МАЄ</strong> бути у форматі URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Адреса електронної пошти контактної особи або організації. <strong>МАЄ</strong> бути у форматі адреси електронної пошти.</td></tr></tbody></table></details> | | `contact` | `dict` | Інформація для контакту з опублікованим API. Може містити кілька полів. <details><summary><code>contact</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Ідентифікаційне ім'я контактної особи або організації.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL, що вказує на контактну інформацію. <strong>МАЄ</strong> бути у форматі URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Адреса електронної пошти контактної особи або організації. <strong>МАЄ</strong> бути у форматі адреси електронної пошти.</td></tr></tbody></table></details> |
| `license_info` | `dict` | Інформація про ліцензію для опублікованого API. Може містити кілька полів. <details><summary><code>license_info</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБОВ'ЯЗКОВО</strong> (якщо встановлено <code>license_info</code>). Назва ліцензії для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ліцензійний вираз за [SPDX](https://spdx.org/licenses/) для API. Поле <code>identifier</code> взаємовиключне з полем <code>url</code>. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL до ліцензії, яка використовується для API. <strong>МАЄ</strong> бути у форматі URL.</td></tr></tbody></table></details> | | `license_info` | `dict` | Інформація про ліцензію для опублікованого API. Може містити кілька полів. <details><summary><code>license_info</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБОВ'ЯЗКОВО</strong> (якщо встановлено <code>license_info</code>). Назва ліцензії для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ліцензійний вираз за [SPDX](https://spdx.org/licenses/) для API. Поле <code>identifier</code> взаємовиключне з полем <code>url</code>. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL до ліцензії, яка використовується для API. <strong>МАЄ</strong> бути у форматі URL.</td></tr></tbody></table></details> |

14
docs/uk/docs/tutorial/path-operation-configuration.md

@ -12,7 +12,7 @@
Ви можете визначити (HTTP) `status_code`, який буде використано у відповіді вашої «операції шляху». Ви можете визначити (HTTP) `status_code`, який буде використано у відповіді вашої «операції шляху».
Можна передати безпосередньо цілий код, наприклад `404`. Ви можете передати безпосередньо код `int`, наприклад `404`.
Якщо ви не пам'ятаєте призначення числових кодів, скористайтеся скороченими константами в `status`: Якщо ви не пам'ятаєте призначення числових кодів, скористайтеся скороченими константами в `status`:
@ -24,7 +24,7 @@
Ви також можете використати `from starlette import status`. Ви також можете використати `from starlette import status`.
FastAPI надає той самий `starlette.status` як `fastapi.status` для вашої зручності як розробника. Але він походить безпосередньо зі Starlette. **FastAPI** надає той самий `starlette.status` як `fastapi.status` для вашої зручності як розробника. Але він походить безпосередньо зі Starlette.
/// ///
@ -40,11 +40,11 @@ FastAPI надає той самий `starlette.status` як `fastapi.status` д
### Мітки з переліками { #tags-with-enums } ### Мітки з переліками { #tags-with-enums }
У великому застосунку ви можете накопичити багато міток і захочете переконатися, що завжди використовуєте ту саму мітку для пов'язаних «операцій шляху». У великому застосунку ви можете накопичити **багато міток** і захочете переконатися, що завжди використовуєте **ту саму мітку** для пов'язаних «операцій шляху».
У таких випадках має сенс зберігати мітки в `Enum`. У таких випадках має сенс зберігати мітки в `Enum`.
FastAPI підтримує це так само, як і зі звичайними строками: **FastAPI** підтримує це так само, як і зі звичайними строками:
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *} {* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
@ -56,7 +56,7 @@ FastAPI підтримує це так само, як і зі звичайним
## Опис зі строки документації { #description-from-docstring } ## Опис зі строки документації { #description-from-docstring }
Оскільки описи зазвичай довгі та займають кілька рядків, ви можете оголосити опис «операції шляху» у <dfn title="багаторядкова строка як перший вираз усередині функції (не прив'язаний до жодної змінної), використовується для документації">строці документації</dfn> функції, і FastAPI прочитає його звідти. Оскільки описи зазвичай довгі та займають кілька рядків, ви можете оголосити опис «операції шляху» у <dfn title="багаторядкова строка як перший вираз усередині функції (не прив'язаний до жодної змінної), використовується для документації">строці документації</dfn> функції, і **FastAPI** прочитає його звідти.
Ви можете писати [Markdown](https://en.wikipedia.org/wiki/Markdown) у строці документації, його буде інтерпретовано та показано коректно (з урахуванням відступів у строці документації). Ви можете писати [Markdown](https://en.wikipedia.org/wiki/Markdown) у строці документації, його буде інтерпретовано та показано коректно (з урахуванням відступів у строці документації).
@ -82,7 +82,7 @@ FastAPI підтримує це так само, як і зі звичайним
OpenAPI визначає, що кожна «операція шляху» потребує опису відповіді. OpenAPI визначає, що кожна «операція шляху» потребує опису відповіді.
Тому, якщо ви його не надасте, FastAPI автоматично згенерує «Successful response». Тому, якщо ви його не надасте, **FastAPI** автоматично згенерує «Successful response».
/// ///
@ -98,7 +98,7 @@ OpenAPI визначає, що кожна «операція шляху» пот
<img src="/img/tutorial/path-operation-configuration/image04.png"> <img src="/img/tutorial/path-operation-configuration/image04.png">
Подивіться, як виглядають застарілі та незастарілі «операції шляху»: Перевірте, як виглядають застарілі та незастарілі «операції шляху»:
<img src="/img/tutorial/path-operation-configuration/image05.png"> <img src="/img/tutorial/path-operation-configuration/image05.png">

103
docs/uk/docs/tutorial/query-params-str-validations.md

@ -1,4 +1,4 @@
# Query параметри та валідація рядків { #query-parameters-and-string-validations } # Параметри запиту та валідація строк { #query-parameters-and-string-validations }
**FastAPI** дозволяє оголошувати додаткову інформацію та виконувати валідацію для ваших параметрів. **FastAPI** дозволяє оголошувати додаткову інформацію та виконувати валідацію для ваших параметрів.
@ -6,7 +6,7 @@
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *} {* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
Query параметр `q` має тип `str | None`, що означає, що він має тип `str`, але також може бути `None`, і справді, значення за замовчуванням `None`, тож FastAPI знатиме, що він не є обов'язковим. Параметр запиту `q` має тип `str | None`, що означає, що він має тип `str`, але також може бути `None`, і справді, значення за замовчуванням - `None`, тож FastAPI знатиме, що він не є обов'язковим.
/// note | Примітка /// note | Примітка
@ -18,7 +18,7 @@ FastAPI знатиме, що значення `q` не є обов’язков
## Додаткова валідація { #additional-validation } ## Додаткова валідація { #additional-validation }
Ми хочемо, щоб навіть якщо `q` є необов’язковим, коли його передають, його довжина не перевищувала 50 символів. Ми забезпечимо, що навіть якщо `q` є необов’язковим, коли його передають, **його довжина не перевищувала 50 символів**.
### Імпорт `Query` та `Annotated` { #import-query-and-annotated } ### Імпорт `Query` та `Annotated` { #import-query-and-annotated }
@ -45,7 +45,7 @@ FastAPI додав підтримку `Annotated` (і почав рекомен
Зараз саме час використати його разом із FastAPI. 🚀 Зараз саме час використати його разом із FastAPI. 🚀
Раніше ми мали таку анотацію типу: Ми мали таку анотацію типу:
```Python ```Python
q: str | None = None q: str | None = None
@ -57,31 +57,31 @@ q: str | None = None
q: Annotated[str | None] = None q: Annotated[str | None] = None
``` ```
Обидві ці версії означають одне й те саме: `q` це параметр, який може бути `str` або `None`, і за замовчуванням має значення `None`. Обидві ці версії означають одне й те саме: `q` - це параметр, який може бути `str` або `None`, і за замовчуванням має значення `None`.
А тепер переходимо до цікавого! 🎉 А тепер переходимо до цікавого! 🎉
## Додавання `Query` до `Annotated` у параметр `q` { #add-query-to-annotated-in-the-q-parameter } ## Додавання `Query` до `Annotated` у параметр `q` { #add-query-to-annotated-in-the-q-parameter }
Тепер, коли у нас є `Annotated`, де ми можемо додавати додаткову інформацію (у цьому випадку додаткову валідацію), додамо `Query` всередину `Annotated` і встановимо параметр `max_length` у `50`: Тепер, коли у нас є `Annotated`, де ми можемо додавати додаткову інформацію (у цьому випадку - додаткову валідацію), додамо `Query` всередину `Annotated` і встановимо параметр `max_length` у `50`:
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
Зверніть увагу, що значення за замовчуванням усе ще `None`, тому параметр залишається необов'язковим. Зверніть увагу, що значення за замовчуванням усе ще `None`, тому параметр залишається необов'язковим.
Але тепер, додавши `Query(max_length=50)` всередину `Annotated`, ми повідомляємо FastAPI, що хочемо додаткову валідацію для цього значення: ми хочемо, щоб воно мало максимум 50 символів. 😎 Але тепер, додавши `Query(max_length=50)` всередину `Annotated`, ми повідомляємо FastAPI, що хочемо **додаткову валідацію** для цього значення: ми хочемо, щоб воно мало максимум 50 символів. 😎
/// tip | Порада /// tip | Порада
Тут ми використовуємо `Query()`, оскільки це query параметр. Далі ми розглянемо інші варіанти, як-от `Path()`, `Body()`, `Header()` та `Cookie()`, які приймають ті самі аргументи, що й `Query()`. Тут ми використовуємо `Query()`, оскільки це **параметр запиту**. Далі ми розглянемо інші варіанти, як-от `Path()`, `Body()`, `Header()` та `Cookie()`, які приймають ті самі аргументи, що й `Query()`.
/// ///
Тепер FastAPI: Тепер FastAPI:
* Перевірить дані, щоб переконатися, що їхня максимальна довжина 50 символів * **Перевірить** дані, щоб переконатися, що їхня максимальна довжина - 50 символів
* Покажe чітку помилку клієнту, якщо дані недійсні * Покажe **чітку помилку** клієнту, якщо дані недійсні
* Задокументує параметр в OpenAPI-схемі операції шляху (що відобразиться в автоматично згенерованій документації) * **Задокументує** параметр в *операції шляху* схеми OpenAPI (що відобразиться в **автоматичному інтерфейсі документації**)
## Альтернативний (застарілий) метод: `Query` як значення за замовчуванням { #alternative-old-query-as-the-default-value } ## Альтернативний (застарілий) метод: `Query` як значення за замовчуванням { #alternative-old-query-as-the-default-value }
@ -93,7 +93,7 @@ q: Annotated[str | None] = None
/// ///
Раніше ми писали `Query()` як значення за замовчуванням для параметра функції, встановлюючи `max_length` у 50: Раніше ми писали `Query()` як значення за замовчуванням для параметра функції, встановлюючи параметр `max_length` у 50:
{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *} {* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
@ -107,19 +107,20 @@ q: str | None = Query(default=None)
...робить параметр необов’язковим зі значенням за замовчуванням `None`, що еквівалентно: ...робить параметр необов’язковим зі значенням за замовчуванням `None`, що еквівалентно:
```Python ```Python
q: str | None = None q: str | None = None
``` ```
Але у версії з `Query` ми явно вказуємо, що це query параметр. Але у версії з `Query` ми явно вказуємо, що це параметр запиту.
Далі ми можемо передавати `Query` додаткові параметри. У цьому випадку — параметр `max_length`, який застосовується до рядків: Далі ми можемо передавати `Query` додаткові параметри. У цьому випадку - параметр `max_length`, який застосовується до строк:
```Python ```Python
q: str | None = Query(default=None, max_length=50) q: str | None = Query(default=None, max_length=50)
``` ```
Це забезпечить валідацію даних, виведе зрозумілу помилку у разі недійсних даних і задокументує параметр у схемі OpenAPI операції шляху. Це забезпечить валідацію даних, виведе зрозумілу помилку у разі недійсних даних і задокументує параметр у *операції шляху* схеми OpenAPI.
### `Query` як значення за замовчуванням або всередині `Annotated` { #query-as-the-default-value-or-in-annotated } ### `Query` як значення за замовчуванням або всередині `Annotated` { #query-as-the-default-value-or-in-annotated }
@ -149,13 +150,13 @@ q: str = Query(default="rick")
### Переваги використання `Annotated` { #advantages-of-annotated } ### Переваги використання `Annotated` { #advantages-of-annotated }
Використання `Annotated` є рекомендованим замість задання значення за замовчуванням у параметрах функції, оскільки воно краще з кількох причин. 🤓 **Використання `Annotated` є рекомендованим** замість задання значення за замовчуванням у параметрах функції, оскільки воно **краще** з кількох причин. 🤓
Значення за замовчуванням параметра функції є фактичним значенням за замовчуванням, що є більш інтуїтивним у Python загалом. 😌 **Значення за замовчуванням** **параметра функції** є **фактичним значенням за замовчуванням**, що є більш інтуїтивним у Python загалом. 😌
Ви можете викликати ту саму функцію в інших місцях без FastAPI, і вона працюватиме очікувано. Якщо параметр є обов’язковим (без значення за замовчуванням), ваш редактор повідомить про помилку, а Python також видасть помилку, якщо ви виконаєте функцію без передавання цього параметра. Ви можете **викликати** ту саму функцію в **інших місцях** без FastAPI, і вона **працюватиме очікувано**. Якщо параметр є **обов’язковим** (без значення за замовчуванням), ваш **редактор** повідомить про помилку, а **Python** також видасть помилку, якщо ви виконаєте функцію без передавання обов’язкового параметра.
Якщо ви не використовуєте `Annotated`, а використовуєте (старий) стиль значень за замовчуванням, то при виклику цієї функції без FastAPI в інших місцях потрібно пам’ятати передати їй аргументи, щоб вона працювала коректно, інакше значення будуть відрізнятися від очікуваних (наприклад, ви отримаєте `QueryInfo` або щось подібне замість `str`). І ваш редактор не повідомить про помилку, і Python не скаржитиметься під час запуску цієї функції лише коли операції всередині завершаться помилкою. Якщо ви не використовуєте `Annotated`, а використовуєте **(старий) стиль значень за замовчуванням**, то при виклику цієї функції без FastAPI в **інших місцях** потрібно **пам’ятати** передати їй аргументи, щоб вона працювала коректно, інакше значення будуть відрізнятися від очікуваних (наприклад, ви отримаєте `QueryInfo` або щось подібне замість `str`). І ваш редактор не повідомить про помилку, і Python не скаржитиметься під час запуску цієї функції - лише коли операції всередині завершаться помилкою.
Оскільки `Annotated` може містити кілька анотацій метаданих, тепер ви навіть можете використовувати ту саму функцію з іншими інструментами, такими як [Typer](https://typer.tiangolo.com/). 🚀 Оскільки `Annotated` може містити кілька анотацій метаданих, тепер ви навіть можете використовувати ту саму функцію з іншими інструментами, такими як [Typer](https://typer.tiangolo.com/). 🚀
@ -167,7 +168,7 @@ q: str = Query(default="rick")
## Додавання регулярних виразів { #add-regular-expressions } ## Додавання регулярних виразів { #add-regular-expressions }
Ви можете визначити <dfn title="Регулярний вираз, regex або regexp це послідовність символів, яка визначає шаблон для пошуку в рядках.">регулярний вираз</dfn> `pattern`, якому має відповідати параметр: Ви можете визначити <dfn title="Регулярний вираз, regex або regexp - це послідовність символів, яка визначає шаблон для пошуку в строках.">регулярний вираз</dfn> `pattern`, якому має відповідати параметр:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *} {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@ -177,7 +178,7 @@ q: str = Query(default="rick")
* `fixedquery`: точно відповідає значенню `fixedquery`. * `fixedquery`: точно відповідає значенню `fixedquery`.
* `$`: закінчується тут, після `fixedquery` немає жодних символів. * `$`: закінчується тут, після `fixedquery` немає жодних символів.
Якщо ви почуваєтеся розгублено щодо **«regular expression»**, не хвилюйтеся. Це складна тема для багатьох людей. Ви все одно можете робити багато речей без використання регулярних виразів. Якщо ви почуваєтеся розгублено щодо всіх цих ідей **«регулярного виразу»**, не хвилюйтеся. Це складна тема для багатьох людей. Ви все одно можете робити багато речей без потреби в регулярних виразах.
Тепер ви знаєте, що коли вони знадобляться, їх можна застосовувати у **FastAPI**. Тепер ви знаєте, що коли вони знадобляться, їх можна застосовувати у **FastAPI**.
@ -185,19 +186,19 @@ q: str = Query(default="rick")
Ви можете, звісно, використовувати значення за замовчуванням, відмінні від `None`. Ви можете, звісно, використовувати значення за замовчуванням, відмінні від `None`.
Припустімо, що ви хочете оголосити query параметр `q` з `min_length` `3` і значенням за замовчуванням `"fixedquery"`: Припустімо, що ви хочете оголосити параметр запиту `q` з `min_length` `3` і значенням за замовчуванням `"fixedquery"`:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note | Примітка /// note | Примітка
Наявність значення за замовчуванням будь-якого типу, включаючи `None`, робить параметр необов’язковим (not required). Наявність значення за замовчуванням будь-якого типу, включаючи `None`, робить параметр необов’язковим (не обов’язковим).
/// ///
## Обов’язкові параметри { #required-parameters } ## Обов’язкові параметри { #required-parameters }
Якщо нам не потрібно оголошувати додаткові валідації або метадані, ми можемо зробити query параметр `q` обов’язковим, просто не вказуючи значення за замовчуванням, наприклад: Якщо нам не потрібно оголошувати додаткові валідації або метадані, ми можемо зробити параметр запиту `q` обов’язковим, просто не вказуючи значення за замовчуванням, наприклад:
```Python ```Python
q: str q: str
@ -227,11 +228,11 @@ q: Annotated[str | None, Query(min_length=3)] = None
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
## Список query параметрів / кілька значень { #query-parameter-list-multiple-values } ## Список параметрів запиту / кілька значень { #query-parameter-list-multiple-values }
Коли ви явно визначаєте query параметр за допомогою `Query`, ви також можете оголосити, що він має приймати список значень, або, іншими словами, кілька значень. Коли ви явно визначаєте параметр запиту за допомогою `Query`, ви також можете оголосити, що він має приймати список значень, або, іншими словами, кілька значень.
Наприклад, щоб оголосити query параметр `q`, який може з’являтися в URL кілька разів, можна написати: Наприклад, щоб оголосити параметр запиту `q`, який може з’являтися в URL кілька разів, можна написати:
{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
@ -241,7 +242,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
http://localhost:8000/items/?q=foo&q=bar http://localhost:8000/items/?q=foo&q=bar
``` ```
ви отримаєте кілька значень `q` query параметрів (`foo` і `bar`) у вигляді Python `list` у вашій функції операції шляху, у параметрі функції `q`. ви отримаєте кілька значень *параметрів запиту* `q` (`foo` і `bar`) у вигляді Python `list` у вашій *функції операції шляху*, у *параметрі функції* `q`.
Отже, відповідь на цей URL буде: Отже, відповідь на цей URL буде:
@ -256,7 +257,7 @@ http://localhost:8000/items/?q=foo&q=bar
/// tip | Порада /// tip | Порада
Щоб оголосити query параметр з типом `list`, як у наведеному вище прикладі, потрібно явно використовувати `Query`, інакше він буде інтерпретований як тіло запиту. Щоб оголосити параметр запиту з типом `list`, як у наведеному вище прикладі, потрібно явно використовувати `Query`, інакше він буде інтерпретований як тіло запиту.
/// ///
@ -264,7 +265,7 @@ http://localhost:8000/items/?q=foo&q=bar
<img src="/img/tutorial/query-params-str-validations/image02.png"> <img src="/img/tutorial/query-params-str-validations/image02.png">
### Список query параметрів / кілька значень за замовчуванням { #query-parameter-list-multiple-values-with-defaults } ### Список параметрів запиту / кілька значень за замовчуванням { #query-parameter-list-multiple-values-with-defaults }
Ви також можете визначити значення за замовчуванням `list`, якщо жодне значення не було передане: Ви також можете визначити значення за замовчуванням `list`, якщо жодне значення не було передане:
@ -297,7 +298,7 @@ http://localhost:8000/items/
Майте на увазі, що в цьому випадку FastAPI не перевірятиме вміст списку. Майте на увазі, що в цьому випадку FastAPI не перевірятиме вміст списку.
Наприклад, `list[int]` перевірятиме (і документуватиме), що вміст списку цілі числа. Але `list` без уточнення цього не робитиме. Наприклад, `list[int]` перевірятиме (і документуватиме), що вміст списку - цілі числа. Але `list` без уточнення цього не робитиме.
/// ///
@ -305,7 +306,7 @@ http://localhost:8000/items/
Ви можете додати більше інформації про параметр. Ви можете додати більше інформації про параметр.
Ця інформація буде включена у згенерований OpenAPI та використана інтерфейсами документації та зовнішніми інструментами. Ця інформація буде включена у згенерований OpenAPI та використана користувацькими інтерфейсами документації та зовнішніми інструментами.
/// note | Примітка /// note | Примітка
@ -333,9 +334,9 @@ http://localhost:8000/items/
http://127.0.0.1:8000/items/?item-query=foobaritems http://127.0.0.1:8000/items/?item-query=foobaritems
``` ```
Але `item-query` це некоректна назва змінної в Python. Але `item-query` - це некоректна назва змінної в Python.
Найближчий допустимий варіант `item_query`. Найближчий допустимий варіант - `item_query`.
Проте вам потрібно, щоб параметр залишався саме `item-query`... Проте вам потрібно, щоб параметр залишався саме `item-query`...
@ -359,17 +360,17 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
## Виняток параметрів з OpenAPI { #exclude-parameters-from-openapi } ## Виняток параметрів з OpenAPI { #exclude-parameters-from-openapi }
Щоб виключити query параметр зі згенерованої схеми OpenAPI (і, таким чином, з автоматичних систем документації), встановіть параметр `include_in_schema` для `Query` в `False`: Щоб виключити параметр запиту зі згенерованої схеми OpenAPI (і, таким чином, з автоматичних систем документації), встановіть параметр `include_in_schema` для `Query` в `False`:
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *} {* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
## Кастомна валідація { #custom-validation } ## Кастомна валідація { #custom-validation }
Можуть бути випадки, коли вам потрібно провести кастомну валідацію, яку не можна реалізувати за допомогою параметрів, показаних вище. Можуть бути випадки, коли вам потрібно провести **кастомну валідацію**, яку не можна реалізувати за допомогою параметрів, показаних вище.
У таких випадках ви можете використати кастомну функцію-валідатор, яка буде застосована після звичайної валідації (наприклад, після перевірки, що значення є типом `str`). У таких випадках ви можете використати **кастомну функцію-валідатор**, яка буде застосована після звичайної валідації (наприклад, після перевірки, що значення є типом `str`).
Це можна досягти за допомогою [Pydantic's `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) в середині `Annotated`. Це можна досягти за допомогою [Pydantic's `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) всередині `Annotated`.
/// tip | Порада /// tip | Порада
@ -377,7 +378,7 @@ Pydantic також має [`BeforeValidator`](https://docs.pydantic.dev/latest/
/// ///
Наприклад, цей кастомний валідатор перевіряє, чи починається ID елемента з `isbn-` для номера книги <abbr title="International Standard Book Number - Міжнародний стандартний номер книги">ISBN</abbr> або з `imdb-` для ID URL фільму на <abbr title="Internet Movie Database - Інтернетна база даних фільмів: вебсайт з інформацією про фільми">IMDB</abbr>: Наприклад, цей кастомний валідатор перевіряє, чи починається ID предмета з `isbn-` для номера книги <abbr title="International Standard Book Number - Міжнародний стандартний номер книги">ISBN</abbr> або з `imdb-` для ID URL фільму на <abbr title="Internet Movie Database - Інтернетна база даних фільмів: вебсайт з інформацією про фільми">IMDB</abbr>:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *} {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@ -389,39 +390,39 @@ Pydantic також має [`BeforeValidator`](https://docs.pydantic.dev/latest/
/// tip | Порада /// tip | Порада
Якщо вам потрібно виконати будь-яку валідацію, яка вимагає взаємодії з будь-яким зовнішнім компонентом, таким як база даних чи інший API, замість цього слід використовувати FastAPI Dependencies — ви дізнаєтесь про них пізніше. Якщо вам потрібно виконати будь-яку валідацію, яка вимагає взаємодії з будь-яким **зовнішнім компонентом**, таким як база даних чи інший API, замість цього слід використовувати **FastAPI Dependencies** - ви дізнаєтесь про них пізніше.
Ці кастомні валідатори використовуються для речей, які можна перевірити лише з тими самими даними, що надані в запиті. Ці кастомні валідатори використовуються для речей, які можна перевірити **лише** з **тими самими даними**, що надані в запиті.
/// ///
### Зрозумійте цей код { #understand-that-code } ### Зрозумійте цей код { #understand-that-code }
Головний момент — це використання `AfterValidator` з функцією всередині `Annotated`. Можете пропустити цю частину, якщо хочете. 🤸 Головний момент - це використання **`AfterValidator` з функцією всередині `Annotated`**. Можете пропустити цю частину, якщо хочете. 🤸
--- ---
Але якщо вам цікаво розібратися в цьому конкретному прикладі коду і вам ще не набридло, ось кілька додаткових деталей. Але якщо вам цікаво розібратися в цьому конкретному прикладі коду і вам ще не набридло, ось кілька додаткових деталей.
#### Рядок із `value.startswith()` { #string-with-value-startswith } #### Строка з `value.startswith()` { #string-with-value-startswith }
Звернули увагу? Рядок із `value.startswith()` може приймати кортеж, і тоді він перевірятиме кожне значення в кортежі: Звернули увагу? Строка з `value.startswith()` може приймати кортеж, і тоді він перевірятиме кожне значення в кортежі:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *} {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
#### Випадковий елемент { #a-random-item } #### Випадковий предмет { #a-random-item }
За допомогою `data.items()` ми отримуємо <dfn title="Щось, що ми можемо ітерувати циклом for, як-от список, множина тощо.">ітерабельний об'єкт</dfn> із кортежами, що містять ключ і значення для кожного елемента словника. За допомогою `data.items()` ми отримуємо <dfn title="Щось, що ми можемо ітерувати циклом for, як-от список, множина тощо.">ітерабельний об'єкт</dfn> із кортежами, що містять ключ і значення для кожного предмета словника.
Ми перетворюємо цей ітерабельний об'єкт у звичайний `list` за допомогою `list(data.items())`. Ми перетворюємо цей ітерабельний об'єкт у звичайний `list` за допомогою `list(data.items())`.
Потім, використовуючи `random.choice()`, ми можемо отримати випадкове значення зі списку, тобто отримуємо кортеж із `(id, name)`. Це може бути щось на зразок `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`. Потім, використовуючи `random.choice()`, ми можемо отримати **випадкове значення** зі списку, тобто отримуємо кортеж із `(id, name)`. Це може бути щось на зразок `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Далі ми присвоюємо ці два значення кортежу змінним `id` і `name`. Далі ми **присвоюємо ці два значення** кортежу змінним `id` і `name`.
Тож, якщо користувач не вказав ID елемента, він все одно отримає випадкову рекомендацію. Тож, якщо користувач не вказав ID предмета, він все одно отримає випадкову рекомендацію.
...ми робимо все це в одному простому рядку. 🤯 Хіба ви не любите Python? 🐍 ...ми робимо все це в **одному простому рядку**. 🤯 Хіба ви не любите Python? 🐍
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *} {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
@ -436,7 +437,7 @@ Pydantic також має [`BeforeValidator`](https://docs.pydantic.dev/latest/
* `description` * `description`
* `deprecated` * `deprecated`
Валідації, специфічні для рядків: Валідації, специфічні для строк:
* `min_length` * `min_length`
* `max_length` * `max_length`

40
docs/uk/docs/tutorial/query-params.md

@ -1,10 +1,10 @@
# Query параметри { #query-parameters } # Параметри запиту { #query-parameters }
Коли ви оголошуєте інші параметри функції, які не є частиною параметрів шляху, вони автоматично інтерпретуються як параметри «query». Коли ви оголошуєте інші параметри функції, які не є частиною параметрів шляху, вони автоматично інтерпретуються як параметри «запиту».
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *} {* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
Query — це набір пар ключ-значення, що йдуть після символу `?` в URL, розділені символами `&`. Запит - це набір пар ключ-значення, що йдуть після символу `?` в URL, розділені символами `&`.
Наприклад, в URL: Наприклад, в URL:
@ -12,25 +12,25 @@ Query — це набір пар ключ-значення, що йдуть пі
http://127.0.0.1:8000/items/?skip=0&limit=10 http://127.0.0.1:8000/items/?skip=0&limit=10
``` ```
...параметрами query є: ...параметрами запиту є:
* `skip`: зі значенням `0` * `skip`: зі значенням `0`
* `limit`: зі значенням `10` * `limit`: зі значенням `10`
Оскільки вони є частиною URL, вони «природно» є рядками. Оскільки вони є частиною URL, вони «природно» є строками.
Але коли ви оголошуєте їх із типами Python (у наведеному прикладі як `int`), вони перетворюються на цей тип і проходять перевірку відповідності. Але коли ви оголошуєте їх із типами Python (у наведеному прикладі як `int`), вони перетворюються на цей тип і проходять перевірку відповідності.
Увесь той самий процес, який застосовується до параметрів шляху, також застосовується до параметрів query: Увесь той самий процес, який застосовується до параметрів шляху, також застосовується до параметрів запиту:
* Підтримка в редакторі (очевидно) * Підтримка в редакторі (очевидно)
* <dfn title="перетворення рядка, що надходить з HTTP-запиту, у дані Python">«парсинг»</dfn> даних * <dfn title="перетворення строки, що надходить з HTTP-запиту, у дані Python">«парсинг»</dfn> даних
* Валідація даних * Валідація даних
* Автоматична документація * Автоматична документація
## Значення за замовчуванням { #defaults } ## Значення за замовчуванням { #defaults }
Оскільки параметри query не є фіксованою частиною шляху, вони можуть бути необов’язковими та мати значення за замовчуванням. Оскільки параметри запиту не є фіксованою частиною шляху, вони можуть бути необов’язковими та мати значення за замовчуванням.
У наведеному вище прикладі вони мають значення за замовчуванням: `skip=0` і `limit=10`. У наведеному вище прикладі вони мають значення за замовчуванням: `skip=0` і `limit=10`.
@ -59,7 +59,7 @@ http://127.0.0.1:8000/items/?skip=20
## Необов'язкові параметри { #optional-parameters } ## Необов'язкові параметри { #optional-parameters }
Так само ви можете оголосити необов’язкові параметри query, встановивши для них значення за замовчуванням `None`: Так само ви можете оголосити необов’язкові параметри запиту, встановивши для них значення за замовчуванням `None`:
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *} {* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
@ -67,11 +67,11 @@ http://127.0.0.1:8000/items/?skip=20
/// tip | Порада /// tip | Порада
Також зверніть увагу, що **FastAPI** достатньо розумний, щоб визначити, що параметр шляху `item_id` є параметром шляху, а `q` — ні, отже, це параметр query. Також зверніть увагу, що **FastAPI** достатньо розумний, щоб визначити, що параметр шляху `item_id` є параметром шляху, а `q` - ні, отже, це параметр запиту.
/// ///
## Перетворення типу параметра query { #query-parameter-type-conversion } ## Перетворення типу параметра запиту { #query-parameter-type-conversion }
Ви також можете оголошувати параметри типу `bool`, і вони будуть автоматично конвертовані: Ви також можете оголошувати параметри типу `bool`, і вони будуть автоматично конвертовані:
@ -107,12 +107,12 @@ http://127.0.0.1:8000/items/foo?short=on
http://127.0.0.1:8000/items/foo?short=yes http://127.0.0.1:8000/items/foo?short=yes
``` ```
або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` типу `bool`. В іншому випадку `False`. або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` типу `bool`. В іншому випадку - `False`.
## Кілька path і query параметрів { #multiple-path-and-query-parameters } ## Кілька параметрів шляху та запиту { #multiple-path-and-query-parameters }
Ви можете одночасно оголошувати кілька параметрів шляху та параметрів query, **FastAPI** знає, який з них який. Ви можете одночасно оголошувати кілька параметрів шляху та параметрів запиту, **FastAPI** знає, який з них який.
І вам не потрібно оголошувати їх у якомусь конкретному порядку. І вам не потрібно оголошувати їх у якомусь конкретному порядку.
@ -120,17 +120,17 @@ http://127.0.0.1:8000/items/foo?short=yes
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *} {* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
## Обов’язкові параметри query { #required-query-parameters } ## Обов’язкові параметри запиту { #required-query-parameters }
Коли ви оголошуєте значення за замовчуванням для не-path-параметрів (поки що ми бачили лише параметри query), тоді вони не є обов’язковими. Коли ви оголошуєте значення за замовчуванням для параметрів, що не є параметрами шляху (поки що ми бачили лише параметри запиту), тоді вони не є обов’язковими.
Якщо ви не хочете задавати конкретне значення, а просто зробити параметр необов’язковим, задайте `None` як значення за замовчуванням. Якщо ви не хочете задавати конкретне значення, а просто зробити параметр необов’язковим, задайте `None` як значення за замовчуванням.
Але якщо ви хочете зробити параметр query обов’язковим, просто не вказуйте для нього значення за замовчуванням: Але якщо ви хочете зробити параметр запиту обов’язковим, просто не вказуйте для нього значення за замовчуванням:
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *} {* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
Тут параметр query `needy` — обов’язковий параметр query типу `str`. Тут параметр запиту `needy` - обов’язковий параметр запиту типу `str`.
Якщо ви відкриєте у браузері URL-адресу: Якщо ви відкриєте у браузері URL-адресу:
@ -171,11 +171,11 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
} }
``` ```
І звісно, ви можете визначити деякі параметри як обов’язкові, деякі — зі значенням за замовчуванням, а деякі — повністю необов’язкові: І звісно, ви можете визначити деякі параметри як обов’язкові, деякі - зі значенням за замовчуванням, а деякі - повністю необов’язкові:
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *} {* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
У цьому випадку є 3 параметри query: У цьому випадку є 3 параметри запиту:
* `needy`, обов’язковий `str`. * `needy`, обов’язковий `str`.
* `skip`, `int` зі значенням за замовчуванням `0`. * `skip`, `int` зі значенням за замовчуванням `0`.

18
docs/uk/docs/tutorial/request-files.md

@ -12,7 +12,7 @@
$ pip install python-multipart $ pip install python-multipart
``` ```
Це необхідно, оскільки завантажені файли передаються у вигляді «form data». Це необхідно, оскільки завантажені файли передаються як «дані форми».
/// ///
@ -30,7 +30,7 @@ $ pip install python-multipart
/// note | Примітка /// note | Примітка
`File` це клас, який безпосередньо успадковує `Form`. `File` - це клас, який безпосередньо успадковує `Form`.
Але пам’ятайте, що коли ви імпортуєте `Query`, `Path`, `File` та інші з `fastapi`, це насправді функції, які повертають спеціальні класи. Але пам’ятайте, що коли ви імпортуєте `Query`, `Path`, `File` та інші з `fastapi`, це насправді функції, які повертають спеціальні класи.
@ -42,7 +42,7 @@ $ pip install python-multipart
/// ///
Файли будуть завантажені у вигляді «form data». Файли будуть завантажені як «дані форми».
Якщо ви оголосите тип параметра *функції операції шляху* як `bytes`, **FastAPI** прочитає файл за вас, і ви отримаєте його вміст у вигляді `bytes`. Якщо ви оголосите тип параметра *функції операції шляху* як `bytes`, **FastAPI** прочитає файл за вас, і ви отримаєте його вміст у вигляді `bytes`.
@ -70,8 +70,8 @@ $ pip install python-multipart
`UploadFile` має такі атрибути: `UploadFile` має такі атрибути:
* `filename`: Рядок `str` з оригінальною назвою файлу, який був завантажений (наприклад, `myimage.jpg`). * `filename`: Строка `str` з оригінальною назвою файлу, який був завантажений (наприклад, `myimage.jpg`).
* `content_type`: Рядок `str` з типом вмісту (MIME type / media type) (наприклад, `image/jpeg`). * `content_type`: Строка `str` з типом вмісту (MIME type / media type) (наприклад, `image/jpeg`).
* `file`: [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) ([file-like](https://docs.python.org/3/glossary.html#term-file-like-object) об'єкт). Це фактичний файловий об'єкт Python, який ви можете передавати безпосередньо іншим функціям або бібліотекам, що очікують «file-like» об'єкт. * `file`: [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) ([file-like](https://docs.python.org/3/glossary.html#term-file-like-object) об'єкт). Це фактичний файловий об'єкт Python, який ви можете передавати безпосередньо іншим функціям або бібліотекам, що очікують «file-like» об'єкт.
`UploadFile` має такі асинхронні `async` методи. Вони всі викликають відповідні методи файлу під капотом (використовуючи внутрішній `SpooledTemporaryFile`). `UploadFile` має такі асинхронні `async` методи. Вони всі викликають відповідні методи файлу під капотом (використовуючи внутрішній `SpooledTemporaryFile`).
@ -109,7 +109,7 @@ contents = myfile.file.read()
/// ///
## Що таке «Form Data» { #what-is-form-data } ## Що таке «дані форми» { #what-is-form-data }
Спосіб, у який HTML-форми (`<form></form>`) надсилають дані на сервер, зазвичай використовує «спеціальне» кодування для цих даних, відмінне від JSON. Спосіб, у який HTML-форми (`<form></form>`) надсилають дані на сервер, зазвичай використовує «спеціальне» кодування для цих даних, відмінне від JSON.
@ -121,7 +121,7 @@ contents = myfile.file.read()
Але якщо форма містить файли, вона кодується як `multipart/form-data`. Якщо ви використовуєте `File`, **FastAPI** знатиме, що потрібно отримати файли з правильної частини тіла. Але якщо форма містить файли, вона кодується як `multipart/form-data`. Якщо ви використовуєте `File`, **FastAPI** знатиме, що потрібно отримати файли з правильної частини тіла.
Якщо ви хочете дізнатися більше про ці типи кодування та формові поля, ознайомтеся з [<abbr title="Mozilla Developer Network - Мережа Розробників Mozilla">MDN</abbr> web docs для `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST). Якщо ви хочете дізнатися більше про ці типи кодування та поля форми, ознайомтеся з [<abbr title="Mozilla Developer Network - Мережа Розробників Mozilla">MDN</abbr> web docs для `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
/// ///
@ -149,7 +149,7 @@ contents = myfile.file.read()
Можна завантажувати кілька файлів одночасно. Можна завантажувати кілька файлів одночасно.
Вони будуть пов’язані з одним і тим самим «form field», який передається у вигляді «form data». Вони будуть пов’язані з одним і тим самим «полем форми», яке передається як «дані форми».
Щоб це реалізувати, потрібно оголосити список `bytes` або `UploadFile`: Щоб це реалізувати, потрібно оголосити список `bytes` або `UploadFile`:
@ -173,4 +173,4 @@ contents = myfile.file.read()
## Підсумок { #recap } ## Підсумок { #recap }
Використовуйте `File`, `bytes` та `UploadFile`, щоб оголошувати файли для завантаження в запиті, надіслані у вигляді form data. Використовуйте `File`, `bytes` та `UploadFile`, щоб оголошувати файли для завантаження в запиті, надіслані як дані форми.

2
docs/uk/docs/tutorial/request-forms.md

@ -34,7 +34,7 @@ $ pip install python-multipart
/// note | Примітка /// note | Примітка
`Form` це клас, який безпосередньо наслідується від `Body`. `Form` - це клас, який безпосередньо наслідується від `Body`.
/// ///

1
docs/uk/docs/tutorial/response-status-code.md

@ -1,5 +1,6 @@
# Код статусу відповіді { #response-status-code } # Код статусу відповіді { #response-status-code }
Так само, як ви можете вказати модель відповіді, ви також можете оголосити HTTP код статусу, що використовується для відповіді, за допомогою параметра `status_code` в будь-якій з *операцій шляху*: Так само, як ви можете вказати модель відповіді, ви також можете оголосити HTTP код статусу, що використовується для відповіді, за допомогою параметра `status_code` в будь-якій з *операцій шляху*:
* `@app.get()` * `@app.get()`

6
docs/uk/docs/tutorial/schema-extra-example.md

@ -1,4 +1,4 @@
# Декларування прикладів вхідних даних { #declare-request-example-data } # Декларування прикладів даних запиту { #declare-request-example-data }
Ви можете задати приклади даних, які ваш застосунок може отримувати. Ви можете задати приклади даних, які ваш застосунок може отримувати.
@ -42,7 +42,7 @@ OpenAPI 3.1.0 (який використовується починаючи з F
## `examples` у Схемі JSON - OpenAPI { #examples-in-json-schema-openapi } ## `examples` у Схемі JSON - OpenAPI { #examples-in-json-schema-openapi }
При використанні будь-кого з наступного: Під час використання будь-чого з наведеного:
* `Path()` * `Path()`
* `Query()` * `Query()`
@ -109,7 +109,7 @@ OpenAPI 3.1.0 (який використовується починаючи з F
* `value`: це сам приклад, який буде показано, наприклад `dict`. * `value`: це сам приклад, який буде показано, наприклад `dict`.
* `externalValue`: альтернатива `value`, URL-адреса, що вказує на приклад. Проте це може не підтримуватися такою кількістю інструментів, як `value`. * `externalValue`: альтернатива `value`, URL-адреса, що вказує на приклад. Проте це може не підтримуватися такою кількістю інструментів, як `value`.
Використання виглядає так: Ви можете використати це так:
{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *} {* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}

22
docs/uk/docs/tutorial/security/first-steps.md

@ -4,7 +4,7 @@
А **frontend** - на іншому домені або в іншому шляху того ж домену (або у мобільному застосунку). А **frontend** - на іншому домені або в іншому шляху того ж домену (або у мобільному застосунку).
І ви хочете, щоб frontend міг автентифікуватися в backend, використовуючи ім'я користувача та пароль. І ви хочете, щоб frontend міг автентифікуватися в backend, використовуючи **ім'я користувача** та **пароль**.
Ми можемо використати **OAuth2**, щоб збудувати це з **FastAPI**. Ми можемо використати **OAuth2**, щоб збудувати це з **FastAPI**.
@ -40,7 +40,7 @@ $ pip install python-multipart
/// ///
Запустіть приклад: Запустіть приклад за допомогою:
<div class="termy"> <div class="termy">
@ -60,7 +60,7 @@ $ fastapi dev
<img src="/img/tutorial/security/image01.png"> <img src="/img/tutorial/security/image01.png">
/// tip | Кнопка Authorize! /// tip | Кнопка «Authorize»!
У вас уже є нова блискуча кнопка «Authorize». У вас уже є нова блискуча кнопка «Authorize».
@ -78,7 +78,7 @@ $ fastapi dev
/// ///
Звісно, це не frontend для кінцевих користувачів, але це чудовий інструмент для інтерактивної документації всього вашого API. Звісно, це не frontend для кінцевих користувачів, але це чудовий автоматичний інструмент для інтерактивного документування всього вашого API.
Ним може користуватися команда frontend (якою можете бути і ви самі). Ним може користуватися команда frontend (якою можете бути і ви самі).
@ -86,11 +86,11 @@ $ fastapi dev
І ним також можете користуватися ви самі, щоб налагоджувати, перевіряти та тестувати той самий застосунок. І ним також можете користуватися ви самі, щоб налагоджувати, перевіряти та тестувати той самий застосунок.
## Потік паролю { #the-password-flow } ## Потік `password` { #the-password-flow }
Тепер повернімося трохи назад і розберімося, що це все таке. Тепер повернімося трохи назад і розберімося, що це все таке.
`password` «flow» - це один зі способів («flows»), визначених в OAuth2, для обробки безпеки та автентифікації. `password` «потік» - це один зі способів («потоків»), визначених в OAuth2, для обробки безпеки та автентифікації.
OAuth2 був спроєктований так, щоб backend або API могли бути незалежними від сервера, який автентифікує користувача. OAuth2 був спроєктований так, щоб backend або API могли бути незалежними від сервера, який автентифікує користувача.
@ -100,7 +100,7 @@ OAuth2 був спроєктований так, щоб backend або API мо
- Користувач вводить `username` і `password` у frontend і натискає `Enter`. - Користувач вводить `username` і `password` у frontend і натискає `Enter`.
- Frontend (у браузері користувача) надсилає ці `username` і `password` на специфічну URL-адресу нашого API (оголошену як `tokenUrl="token"`). - Frontend (у браузері користувача) надсилає ці `username` і `password` на специфічну URL-адресу нашого API (оголошену як `tokenUrl="token"`).
- API перевіряє ці `username` і `password` та повертає «токен» (ми ще нічого з цього не реалізували). - API перевіряє ці `username` і `password` та відповідає «токеном» (ми ще нічого з цього не реалізували).
- «Токен» - це просто строка з деяким вмістом, який ми можемо пізніше використати, щоб перевірити цього користувача. - «Токен» - це просто строка з деяким вмістом, який ми можемо пізніше використати, щоб перевірити цього користувача.
- Зазвичай токен налаштований на завершення строку дії через певний час. - Зазвичай токен налаштований на завершення строку дії через певний час.
- Тож користувачу доведеться знову увійти пізніше. - Тож користувачу доведеться знову увійти пізніше.
@ -116,11 +116,11 @@ OAuth2 був спроєктований так, щоб backend або API мо
**FastAPI** надає кілька інструментів на різних рівнях абстракції, щоб реалізувати ці функції безпеки. **FastAPI** надає кілька інструментів на різних рівнях абстракції, щоб реалізувати ці функції безпеки.
У цьому прикладі ми використаємо **OAuth2** з потоком **Password**, використовуючи токен **Bearer**. Це робиться за допомогою класу `OAuth2PasswordBearer`. У цьому прикладі ми використаємо **OAuth2** з потоком **Password**, використовуючи **токен носія**. Це робиться за допомогою класу `OAuth2PasswordBearer`.
/// note | Примітка /// note | Примітка
«Bearer»-токен - не єдиний варіант. «Токен носія» - не єдиний варіант.
Але це найкращий для нашого сценарію. Але це найкращий для нашого сценарію.
@ -138,7 +138,7 @@ OAuth2 був спроєктований так, щоб backend або API мо
Тут `tokenUrl="token"` відноситься до відносної URL-адреси `token`, яку ми ще не створили. Оскільки це відносна URL-адреса, вона еквівалентна `./token`. Тут `tokenUrl="token"` відноситься до відносної URL-адреси `token`, яку ми ще не створили. Оскільки це відносна URL-адреса, вона еквівалентна `./token`.
Тому, якщо ваш API розміщений на `https://example.com/`, це буде `https://example.com/token`. А якщо на `https://example.com/api/v1/`, тоді це буде `https://example.com/api/v1/token`. Оскільки ми використовуємо відносну URL-адресу, якщо ваш API розміщений на `https://example.com/`, це буде `https://example.com/token`. А якщо ваш API розміщений на `https://example.com/api/v1/`, тоді це буде `https://example.com/api/v1/token`.
Використання відносної URL-адреси важливе, щоб ваша програма продовжувала працювати навіть у просунутому сценарії, як-от [За представником](../../advanced/behind-a-proxy.md). Використання відносної URL-адреси важливе, щоб ваша програма продовжувала працювати навіть у просунутому сценарії, як-от [За представником](../../advanced/behind-a-proxy.md).
@ -188,7 +188,7 @@ oauth2_scheme(some, parameters)
Вона шукатиме в запиті заголовок `Authorization`, перевірить, чи його значення - це `Bearer ` плюс деякий токен, і поверне токен як `str`. Вона шукатиме в запиті заголовок `Authorization`, перевірить, чи його значення - це `Bearer ` плюс деякий токен, і поверне токен як `str`.
Якщо заголовка `Authorization` немає або значення не містить токена `Bearer `, вона одразу відповість помилкою зі статус-кодом 401 (`UNAUTHORIZED`). Якщо заголовка `Authorization` немає або значення не містить токена `Bearer `, вона одразу відповість помилкою з кодом статусу 401 (`UNAUTHORIZED`).
Вам навіть не потрібно перевіряти, чи існує токен, щоб повернути помилку. Ви можете бути певні: якщо ваша функція виконується, у параметрі токена буде `str`. Вам навіть не потрібно перевіряти, чи існує токен, щоб повернути помилку. Ви можете бути певні: якщо ваша функція виконується, у параметрі токена буде `str`.

26
docs/uk/docs/tutorial/security/get-current-user.md

@ -1,6 +1,6 @@
# Отримати поточного користувача { #get-current-user } # Отримати поточного користувача { #get-current-user }
У попередньому розділі система безпеки (яка базується на системі впровадження залежностей) передавала функції операції шляху `token` як `str`: У попередньому розділі система безпеки (яка базується на системі впровадження залежностей) передавала *функції операції шляху* `token` як `str`:
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *} {* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
@ -14,7 +14,7 @@
Так само, як ми використовуємо Pydantic для оголошення тіл, ми можемо використовувати його будь-де: Так само, як ми використовуємо Pydantic для оголошення тіл, ми можемо використовувати його будь-де:
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *} {* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *}
## Створити залежність `get_current_user` { #create-a-get-current-user-dependency } ## Створити залежність `get_current_user` { #create-a-get-current-user-dependency }
@ -24,19 +24,19 @@
`get_current_user` матиме залежність із тим самим `oauth2_scheme`, який ми створили раніше. `get_current_user` матиме залежність із тим самим `oauth2_scheme`, який ми створили раніше.
Так само, як ми робили раніше безпосередньо в операції шляху, наша нова залежність `get_current_user` отримає `token` як `str` від підзалежності `oauth2_scheme`: Так само, як ми робили раніше безпосередньо в *операції шляху*, наша нова залежність `get_current_user` отримає `token` як `str` від підзалежності `oauth2_scheme`:
{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *} {* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
## Отримати користувача { #get-the-user } ## Отримати користувача { #get-the-user }
`get_current_user` використає (фальшиву) утилітну функцію, яку ми створили, що приймає `token` як `str` і повертає нашу Pydantic-модель `User`: `get_current_user` використає (фальшиву) утилітну функцію, яку ми створили, що приймає токен як `str` і повертає нашу Pydantic-модель `User`:
{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *} {* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
## Впровадити поточного користувача { #inject-the-current-user } ## Впровадити поточного користувача { #inject-the-current-user }
Тепер ми можемо використати той самий `Depends` з нашим `get_current_user` в операції шляху: Тепер ми можемо використати той самий `Depends` з нашим `get_current_user` в *операції шляху*:
{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *} {* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
@ -62,13 +62,13 @@
## Інші моделі { #other-models } ## Інші моделі { #other-models }
Тепер ви можете отримувати поточного користувача безпосередньо у функціях операцій шляху та працювати з механізмами безпеки на рівні **впровадження залежностей**, використовуючи `Depends`. Тепер ви можете отримувати поточного користувача безпосередньо у *функціях операцій шляху* та працювати з механізмами безпеки на рівні **впровадження залежностей**, використовуючи `Depends`.
І ви можете використовувати будь-яку модель або дані для вимог безпеки (у цьому випадку Pydantic-модель `User`). І ви можете використовувати будь-яку модель або дані для вимог безпеки (у цьому випадку Pydantic-модель `User`).
Але ви не обмежені використанням якоїсь конкретної модели даних, класу чи типу. Але ви не обмежені використанням якоїсь конкретної моделі даних, класу чи типу.
Хочете мати id та email і не мати жодного username у вашій моделі? Без проблем. Ви можете використовувати ті самі інструменти. Хочете мати `id` та `email` і не мати жодного `username` у вашій моделі? Без проблем. Ви можете використовувати ті самі інструменти.
Хочете мати просто `str`? Або лише `dict`? Або безпосередньо екземпляр класу моделі бази даних? Усе працює так само. Хочете мати просто `str`? Або лише `dict`? Або безпосередньо екземпляр класу моделі бази даних? Усе працює так само.
@ -78,7 +78,7 @@
## Розмір коду { #code-size } ## Розмір коду { #code-size }
Цей приклад може здаватися багатослівним. Майте на увазі, що ми змішуємо безпеку, моделі даних, утилітні функції та операції шляху в одному файлі. Цей приклад може здаватися багатослівним. Майте на увазі, що ми змішуємо безпеку, моделі даних, утилітні функції та *операції шляху* в одному файлі.
Але ось ключовий момент. Але ось ключовий момент.
@ -86,20 +86,20 @@
І ви можете зробити це настільки складним, наскільки потрібно. І все одно мати це написаним лише один раз, в одному місці. З усією гнучкістю. І ви можете зробити це настільки складним, наскільки потрібно. І все одно мати це написаним лише один раз, в одному місці. З усією гнучкістю.
Зате ви можете мати тисячі кінцевих точок (операцій шляху), що використовують одну й ту саму систему безпеки. Зате ви можете мати тисячі кінцевих точок (*операцій шляху*), що використовують одну й ту саму систему безпеки.
І всі вони (або будь-яка їхня частина, яку ви захочете) можуть скористатися повторним використанням цих залежностей або будь-яких інших, які ви створите. І всі вони (або будь-яка їхня частина, яку ви захочете) можуть скористатися повторним використанням цих залежностей або будь-яких інших, які ви створите.
І всі ці тисячі операцій шляху можуть бути всього у 3 рядки: І всі ці тисячі *операцій шляху* можуть бути всього у 3 рядки:
{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *} {* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
## Підсумок { #recap } ## Підсумок { #recap }
Тепер ви можете отримувати поточного користувача безпосередньо у вашій функції операції шляху. Тепер ви можете отримувати поточного користувача безпосередньо у вашій *функції операції шляху*.
Ми вже на півдорозі. Ми вже на півдорозі.
Потрібно лише додати операцію шляху, щоб користувач/клієнт міг фактично надіслати `username` і `password`. Потрібно лише додати *операцію шляху*, щоб користувач/клієнт міг фактично надіслати `username` і `password`.
Далі саме це. Далі саме це.

4
docs/uk/docs/tutorial/security/oauth2-jwt.md

@ -10,7 +10,7 @@
JWT означає «JSON Web Tokens». JWT означає «JSON Web Tokens».
Це стандарт кодування об'єкта JSON у довгий щільний рядок без пробілів. Він виглядає так: Це стандарт кодування об'єкта JSON у довгу щільну строку без пробілів. Він виглядає так:
``` ```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
@ -168,7 +168,7 @@ $ openssl rand -hex 32
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *} {* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
## Оновіть операцію шляху `/token` { #update-the-token-path-operation } ## Оновіть *операцію шляху* `/token` { #update-the-token-path-operation }
Створіть `timedelta` з часом життя токена. Створіть `timedelta` з часом життя токена.

28
docs/uk/docs/tutorial/security/simple-oauth2.md

@ -28,9 +28,9 @@ OAuth2 визначає, що під час використання «пото
Їх зазвичай використовують для оголошення конкретних прав доступу, наприклад: Їх зазвичай використовують для оголошення конкретних прав доступу, наприклад:
- `users:read` або `users:write` — поширені приклади. * `users:read` або `users:write` — поширені приклади.
- `instagram_basic` використовується Facebook / Instagram. * `instagram_basic` використовується Facebook / Instagram.
- `https://www.googleapis.com/auth/drive` використовується Google. * `https://www.googleapis.com/auth/drive` використовується Google.
/// note | Примітка /// note | Примітка
@ -56,21 +56,21 @@ OAuth2 визначає, що під час використання «пото
`OAuth2PasswordRequestForm` — це клас залежності, що оголошує тіло форми з: `OAuth2PasswordRequestForm` — це клас залежності, що оголошує тіло форми з:
- `username`. * `username`.
- `password`. * `password`.
- Необов'язковим полем `scope` як великою строкою, складеною зі строк, розділених пробілами. * Необов'язковим полем `scope` як великою строкою, складеною зі строк, розділених пробілами.
- Необов'язковим `grant_type`. * Необов'язковим `grant_type`.
/// tip | Порада /// tip | Порада
Специфікація OAuth2 насправді вимагає поле `grant_type` із фіксованим значенням `password`, але `OAuth2PasswordRequestForm` цього не примушує. Специфікація OAuth2 насправді *вимагає* поле `grant_type` із фіксованим значенням `password`, але `OAuth2PasswordRequestForm` цього не примушує.
Якщо вам потрібно це примусити, використовуйте `OAuth2PasswordRequestFormStrict` замість `OAuth2PasswordRequestForm`. Якщо вам потрібно це примусити, використовуйте `OAuth2PasswordRequestFormStrict` замість `OAuth2PasswordRequestForm`.
/// ///
- Необов'язковим `client_id` (для нашого прикладу не потрібно). * Необов'язковим `client_id` (для нашого прикладу не потрібно).
- Необов'язковим `client_secret` (для нашого прикладу не потрібно). * Необов'язковим `client_secret` (для нашого прикладу не потрібно).
/// note | Примітка /// note | Примітка
@ -132,7 +132,7 @@ OAuth2 визначає, що під час використання «пото
`UserInDB(**user_dict)` означає: `UserInDB(**user_dict)` означає:
Передати ключі та значення з `user_dict` безпосередньо як аргументи ключ-значення, еквівалентно до: *Передати ключі та значення з `user_dict` безпосередньо як аргументи ключ-значення, еквівалентно до:*
```Python ```Python
UserInDB( UserInDB(
@ -146,7 +146,7 @@ UserInDB(
/// note | Примітка /// note | Примітка
Для повнішого пояснення `**user_dict` перегляньте [документацію для **Додаткових моделей**](../extra-models.md#about-user-in-dict). Для повнішого пояснення `**user_dict` перегляньте [документацію для **Додаткових моделей**](../extra-models.md#about-user-in-model-dump).
/// ///
@ -186,7 +186,7 @@ UserInDB(
Тепер оновимо наші залежності. Тепер оновимо наші залежності.
Ми хочемо отримати `current_user` лише якщо цей користувач активний. Ми хочемо отримати `current_user` *лише* якщо цей користувач активний.
Тому створимо додаткову залежність `get_current_active_user`, яка своєю чергою використовує як залежність `get_current_user`. Тому створимо додаткову залежність `get_current_active_user`, яка своєю чергою використовує як залежність `get_current_user`.
@ -200,7 +200,7 @@ UserInDB(
Додатковий заголовок `WWW-Authenticate` зі значенням `Bearer`, який ми тут повертаємо, також є частиною специфікації. Додатковий заголовок `WWW-Authenticate` зі значенням `Bearer`, який ми тут повертаємо, також є частиною специфікації.
Будь-який HTTP (помилка) зі статус-кодом 401 «UNAUTHORIZED» також має повертати заголовок `WWW-Authenticate`. Будь-який HTTP (помилка) з кодом статусу 401 «UNAUTHORIZED» також має повертати заголовок `WWW-Authenticate`.
У випадку токенів носія (наш випадок) значенням цього заголовка має бути `Bearer`. У випадку токенів носія (наш випадок) значенням цього заголовка має бути `Bearer`.

6
docs/uk/docs/tutorial/sql-databases.md

@ -1,6 +1,6 @@
# SQL (реляційні) бази даних { #sql-relational-databases } # SQL (реляційні) бази даних { #sql-relational-databases }
**FastAPI** не вимагає від вас використовувати SQL (реляційну) базу даних. Але ви можете скористатися будь-якою базою даних, яку забажаєте. **FastAPI** не вимагає від вас використовувати SQL (реляційну) базу даних. Але ви можете скористатися **будь-якою базою даних**, яку забажаєте.
Тут ми розглянемо приклад з [SQLModel](https://sqlmodel.tiangolo.com/). Тут ми розглянемо приклад з [SQLModel](https://sqlmodel.tiangolo.com/).
@ -8,7 +8,7 @@
/// tip | Порада /// tip | Порада
Ви можете використовувати будь-яку іншу бібліотеку для SQL або NoSQL баз (інколи їх називають <abbr title="Object Relational Mapper - Об'єктно-реляційний відображувач: складний термін для бібліотеки, де деякі класи представляють таблиці SQL, а екземпляри представляють рядки в цих таблицях">"ORMs"</abbr>), FastAPI нічого не нав’язує. 😎 Ви можете використовувати будь-яку іншу бібліотеку для SQL або NoSQL баз (інколи їх називають <abbr title="Object Relational Mapper - Об'єктно-реляційний відображувач: складний термін для бібліотеки, де деякі класи представляють таблиці SQL, а екземпляри представляють рядки в цих таблицях">«ORMs»</abbr>), FastAPI нічого не нав’язує. 😎
/// ///
@ -65,7 +65,7 @@ $ pip install sqlmodel
* `Field(primary_key=True)` каже SQLModel, що `id` - це **первинний ключ** у SQL базі даних (більше про первинні ключі в SQL див. у документації SQLModel). * `Field(primary_key=True)` каже SQLModel, що `id` - це **первинний ключ** у SQL базі даних (більше про первинні ключі в SQL див. у документації SQLModel).
Примітка: Ми використовуємо `int | None` для поля первинного ключа, щоб у Python-коді можна було створити об’єкт без `id` (`id=None`), припускаючи, що база даних згенерує його під час збереження. SQLModel розуміє, що `id` надасть база даних, і визначає стовпець як ненульовий `INTEGER` у схемі бази даних. Докладніше див. [документацію SQLModel про первинні ключі](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id). **Примітка:** Ми використовуємо `int | None` для поля первинного ключа, щоб у Python-коді можна було створити об’єкт без `id` (`id=None`), припускаючи, що база даних згенерує його під час збереження. SQLModel розуміє, що `id` надасть база даних, і визначає стовпець як ненульовий `INTEGER` у схемі бази даних. Докладніше див. [документацію SQLModel про первинні ключі](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id).
* `Field(index=True)` каже SQLModel створити **SQL-індекс** для цього стовпця, що дозволить швидше виконувати пошук у базі даних під час читання даних, відфільтрованих за цим стовпцем. * `Field(index=True)` каже SQLModel створити **SQL-індекс** для цього стовпця, що дозволить швидше виконувати пошук у базі даних під час читання даних, відфільтрованих за цим стовпцем.

24
docs/uk/docs/tutorial/static-files.md

@ -2,10 +2,18 @@
Ви можете автоматично надавати статичні файли з каталогу, використовуючи `StaticFiles`. Ви можете автоматично надавати статичні файли з каталогу, використовуючи `StaticFiles`.
/// tip | Порада
Якщо вам потрібно розмістити фронтенд, натомість використовуйте `app.frontend()`, прочитайте про це у [Frontend](frontend.md).
`app.frontend()` використовує `StaticFiles` всередині, з кількома додатковими перевагами для фронтендів, як-от обробка клієнтської маршрутизації.
///
## Використання `StaticFiles` { #use-staticfiles } ## Використання `StaticFiles` { #use-staticfiles }
* Імпортуйте `StaticFiles`. * Імпортуйте `StaticFiles`.
* «Під'єднати» екземпляр `StaticFiles()` з вказанням необхідного шляху. * «Змонтуйте» екземпляр `StaticFiles()` у певному шляху.
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *} {* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
@ -17,24 +25,24 @@
/// ///
### Що таке «Під'єднання» { #what-is-mounting } ### Що таке «Монтування» { #what-is-mounting }
«Під'єднання» означає додавання повноцінного «незалежного» застосунку за певним шляхом, який потім обробляє всі під шляхи. «Монтування» означає додавання повноцінного «незалежного» застосунку за певним шляхом, який потім відповідає за обробку всіх підшляхів.
Це відрізняється від використання `APIRouter`, оскільки під'єднаний застосунок є повністю незалежним. OpenAPI та документація вашого основного застосунку не будуть знати нічого про ваш під'єднаний застосунок тощо. Це відрізняється від використання `APIRouter`, оскільки змонтований застосунок є повністю незалежним. OpenAPI та документація вашого основного застосунку не включатимуть нічого зі змонтованого застосунку тощо.
Ви можете дізнатися більше про це в [Посібнику для просунутих користувачів](../advanced/index.md). Ви можете дізнатися більше про це в [Просунутому посібнику користувача](../advanced/index.md).
## Деталі { #details } ## Деталі { #details }
Перше `"/static"` вказує на під шлях, за яким буде «під'єднано» цей новий «підзастосунок». Тому будь-який шлях, який починається з `"/static"`, буде оброблятися ним. Перше `"/static"` стосується підшляху, на якому буде «змонтовано» цей «підзастосунок». Тому будь-який шлях, який починається з `"/static"`, буде оброблятися ним.
`directory="static"` визначає назву каталогу, що містить ваші статичні файли. `directory="static"` визначає назву каталогу, що містить ваші статичні файли.
`name="static"` це ім'я, яке можна використовувати всередині **FastAPI**. `name="static"` надає йому ім'я, яке можна використовувати всередині **FastAPI**.
Усі ці параметри можуть бути іншими за "`static`", налаштуйте їх відповідно до потреб і особливостей вашого застосунку. Усі ці параметри можуть бути іншими за "`static`", налаштуйте їх відповідно до потреб і особливостей вашого застосунку.
## Додаткова інформація { #more-info } ## Додаткова інформація { #more-info }
Детальніше про налаштування та можливості можна дізнатися в [документації Starlette про статичні файли](https://www.starlette.dev/staticfiles/). Для отримання додаткової інформації та параметрів перевірте [документацію Starlette про Static Files](https://www.starlette.dev/staticfiles/).

16
docs/uk/docs/tutorial/testing.md

@ -52,7 +52,7 @@ $ pip install httpx
/// tip | Порада /// tip | Порада
Якщо ви хочете викликати `async`-функції у ваших тестах, окрім відправлення запитів до вашого застосунку FastAPI (наприклад, асинхронні функції роботи з базою даних), перегляньте [Async Tests](../advanced/async-tests.md) у розширеному керівництві. Якщо ви хочете викликати `async`-функції у ваших тестах, окрім відправлення запитів до вашого застосунку FastAPI (наприклад, асинхронні функції роботи з базою даних), перегляньте [Асинхронні тести](../advanced/async-tests.md) у просунутому навчальному посібнику.
/// ///
@ -64,7 +64,7 @@ $ pip install httpx
### Файл застосунку **FastAPI** { #fastapi-app-file } ### Файл застосунку **FastAPI** { #fastapi-app-file }
Припустимо, у вас є структура файлів, описана в розділі [Bigger Applications](bigger-applications.md): Припустимо, у вас є структура файлів, описана в розділі [Більші застосунки](bigger-applications.md):
``` ```
. .
@ -130,17 +130,17 @@ $ pip install httpx
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *} {* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
Коли вам потрібно передати клієнту інформацію в запиті, але ви не знаєте, як це зробити, ви можете пошукати (Google), як це зробити в `httpx`, або навіть як це зробити з `requests`, оскільки дизайн HTTPX базується на дизайні Requests. Коли вам потрібно, щоб клієнт передав інформацію в запиті, але ви не знаєте, як це зробити, ви можете пошукати (Google), як це зробити в `httpx`, або навіть як це зробити з `requests`, оскільки дизайн HTTPX базується на дизайні Requests.
Далі ви просто повторюєте ці ж дії у ваших тестах. Далі ви просто повторюєте ці ж дії у ваших тестах.
Наприклад: Наприклад:
* Щоб передати *path* або *query* параметр, додайте його безпосередньо до URL. * Щоб передати параметр *шляху* або *запиту*, додайте його безпосередньо до URL.
* Щоб передати тіло JSON, передайте Python-об'єкт (наприклад, `dict`) у параметр `json`. * Щоб передати тіло JSON, передайте Python-об'єкт (наприклад, `dict`) у параметр `json`.
* Якщо потрібно надіслати *Form Data* замість JSON, використовуйте параметр `data`. * Якщо потрібно надіслати *дані форми* замість JSON, використовуйте параметр `data`.
* Щоб передати заголовки *headers*, використовуйте `dict` у параметрі `headers`. * Щоб передати *заголовки*, використовуйте `dict` у параметрі `headers`.
* Для *cookies* використовуйте `dict` у параметрі `cookies`. * Для *кукі* використовуйте `dict` у параметрі `cookies`.
Докладніше про передачу даних у бекенд (за допомогою `httpx` або `TestClient`) можна знайти в [документації HTTPX](https://www.python-httpx.org). Докладніше про передачу даних у бекенд (за допомогою `httpx` або `TestClient`) можна знайти в [документації HTTPX](https://www.python-httpx.org).
@ -148,7 +148,7 @@ $ pip install httpx
Зверніть увагу, що `TestClient` отримує дані, які можна конвертувати в JSON, а не Pydantic-моделі. Зверніть увагу, що `TestClient` отримує дані, які можна конвертувати в JSON, а не Pydantic-моделі.
Якщо у вас є Pydantic-модель у тесті, і ви хочете передати її дані в застосунок під час тестування, ви можете використати `jsonable_encoder`, описаний у розділі [JSON Compatible Encoder](encoder.md). Якщо у вас є Pydantic-модель у тесті, і ви хочете передати її дані в застосунок під час тестування, ви можете використати `jsonable_encoder`, описаний у розділі [JSON-сумісний кодувальник](encoder.md).
/// ///

108
docs/uk/docs/virtual-environments.md

@ -1,6 +1,6 @@
# Віртуальні середовища { #virtual-environments } # Віртуальні середовища { #virtual-environments }
Коли ви працюєте над проєктами Python, вам, імовірно, слід використовувати віртуальне середовище (або схожий механізм), щоб ізолювати пакети, які ви встановлюєте для кожного проєкту. Коли ви працюєте над проєктами Python, вам, імовірно, слід використовувати **віртуальне середовище** (або схожий механізм), щоб ізолювати пакети, які ви встановлюєте для кожного проєкту.
/// note | Примітка /// note | Примітка
@ -10,19 +10,19 @@
/// tip | Порада /// tip | Порада
Віртуальне середовище відрізняється від змінної оточення. **Віртуальне середовище** відрізняється від **змінної оточення**.
Змінна оточення - це змінна в системі, яку можуть використовувати програми. **Змінна оточення** - це змінна в системі, яку можуть використовувати програми.
Віртуальне середовище - це каталог із файлами в ньому. **Віртуальне середовище** - це каталог із файлами в ньому.
/// ///
/// note | Примітка /// note | Примітка
На цій сторінці ви дізнаєтеся, як використовувати віртуальні середовища і як вони працюють. На цій сторінці ви дізнаєтеся, як використовувати **віртуальні середовища** і як вони працюють.
Якщо ви готові прийняти інструмент, що керує всім за вас (включно з установленням Python), спробуйте [uv](https://github.com/astral-sh/uv). Якщо ви готові прийняти **інструмент, що керує всім** за вас (включно з установленням Python), спробуйте [uv](https://github.com/astral-sh/uv).
/// ///
@ -53,11 +53,11 @@ $ cd awesome-project
## Створіть віртуальне середовище { #create-a-virtual-environment } ## Створіть віртуальне середовище { #create-a-virtual-environment }
Коли ви починаєте працювати над проєктом Python уперше, створіть віртуальне середовище у вашому проєкті **<dfn title="є інші варіанти, це проста настанова">у вашому проєкті</dfn>**. Коли ви починаєте працювати над проєктом Python **уперше**, створіть віртуальне середовище **<dfn title="є інші варіанти, це проста настанова">у вашому проєкті</dfn>**.
/// tip | Порада /// tip | Порада
Це потрібно робити лише один раз на проєкт, не щоразу, коли ви працюєте. Це потрібно робити лише **один раз на проєкт**, не щоразу, коли ви працюєте.
/// ///
@ -120,7 +120,7 @@ $ uv venv
/// tip | Порада /// tip | Порада
Робіть це щоразу, коли ви починаєте нову сесію термінала для роботи над проєктом. Робіть це **щоразу**, коли ви починаєте **нову сесію термінала** для роботи над проєктом.
/// ///
@ -164,9 +164,9 @@ $ source .venv/Scripts/activate
/// tip | Порада /// tip | Порада
Кожного разу, коли ви встановлюєте новий пакет у це середовище, активуйте середовище знову. Кожного разу, коли ви встановлюєте **новий пакет** у це середовище, **активуйте** середовище знову.
Це гарантує, що якщо ви використовуєте програму термінала (<abbr title="command line interface - інтерфейс командного рядка">CLI</abbr>), встановлену цим пакетом, ви використовуєте саме ту з вашого віртуального середовища, а не будь-яку іншу, яка може бути встановлена глобально, імовірно з іншою версією, ніж вам потрібно. Це гарантує, що якщо ви використовуєте **програму термінала (<abbr title="command line interface - інтерфейс командного рядка">CLI</abbr>)**, встановлену цим пакетом, ви використовуєте саме ту з вашого віртуального середовища, а не будь-яку іншу, яка може бути встановлена глобально, імовірно з іншою версією, ніж вам потрібно.
/// ///
@ -176,7 +176,7 @@ $ source .venv/Scripts/activate
/// tip | Порада /// tip | Порада
Це необов'язково, але це гарний спосіб перевірити, що все працює як очікується і ви використовуєте саме те віртуальне середовище, яке планували. Це **необов'язково**, але це гарний спосіб **перевірити**, що все працює як очікується і ви використовуєте саме те віртуальне середовище, яке планували.
/// ///
@ -220,13 +220,13 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
/// ///
Якщо ви використовуєте `pip` для встановлення пакетів (він іде за замовчуванням із Python), вам слід оновити його до найновішої версії. Якщо ви використовуєте `pip` для встановлення пакетів (він іде за замовчуванням із Python), вам слід **оновити** його до найновішої версії.
Багато дивних помилок під час встановлення пакета вирішуються тим, що спочатку оновлюють `pip`. Багато дивних помилок під час встановлення пакета вирішуються тим, що спочатку оновлюють `pip`.
/// tip | Порада /// tip | Порада
Зазвичай це роблять один раз, відразу після створення віртуального середовища. Зазвичай це роблять **один раз**, відразу після створення віртуального середовища.
/// ///
@ -264,7 +264,7 @@ $ python -m ensurepip --upgrade
## Додайте `.gitignore` { #add-gitignore } ## Додайте `.gitignore` { #add-gitignore }
Якщо ви використовуєте Git (варто це робити), додайте файл `.gitignore`, щоб виключити з Git усе у вашому `.venv`. Якщо ви використовуєте **Git** (варто це робити), додайте файл `.gitignore`, щоб виключити з Git усе у вашому `.venv`.
/// tip | Порада /// tip | Порада
@ -274,7 +274,7 @@ $ python -m ensurepip --upgrade
/// tip | Порада /// tip | Порада
Зробіть це один раз, відразу після створення віртуального середовища. Зробіть це **один раз**, відразу після створення віртуального середовища.
/// ///
@ -308,9 +308,9 @@ $ echo "*" > .venv/.gitignore
/// tip | Порада /// tip | Порада
Робіть це один раз під час встановлення або оновлення пакетів, потрібних вашому проєкту. Робіть це **один раз** під час встановлення або оновлення пакетів, потрібних вашому проєкту.
Якщо вам потрібно оновити версію або додати новий пакет, ви зробите це знову. Якщо вам потрібно оновити версію або додати новий пакет, ви **зробите це знову**.
/// ///
@ -421,13 +421,13 @@ Hello World
/// tip | Порада /// tip | Порада
Зазвичай це потрібно робити лише один раз, коли ви створюєте віртуальне середовище. Зазвичай це потрібно робити лише **один раз**, коли ви створюєте віртуальне середовище.
/// ///
## Деактивуйте віртуальне середовище { #deactivate-the-virtual-environment } ## Деактивуйте віртуальне середовище { #deactivate-the-virtual-environment }
Коли ви завершили роботу над проєктом, ви можете деактивувати віртуальне середовище. Коли ви завершили роботу над проєктом, ви можете **деактивувати** віртуальне середовище.
<div class="termy"> <div class="termy">
@ -443,6 +443,8 @@ $ deactivate
Тепер ви готові почати працювати над вашим проєктом. Тепер ви готові почати працювати над вашим проєктом.
/// tip | Порада /// tip | Порада
Хочете зрозуміти, що це все було вище? Хочете зрозуміти, що це все було вище?
@ -455,33 +457,33 @@ $ deactivate
Щоб працювати з FastAPI, вам потрібно встановити [Python](https://www.python.org/). Щоб працювати з FastAPI, вам потрібно встановити [Python](https://www.python.org/).
Після цього вам потрібно буде встановити FastAPI та інші пакети, які ви хочете використовувати. Після цього вам потрібно буде **встановити** FastAPI та інші **пакети**, які ви хочете використовувати.
Для встановлення пакетів зазвичай використовують команду `pip`, що постачається з Python (або схожі альтернативи). Для встановлення пакетів зазвичай використовують команду `pip`, що постачається з Python (або схожі альтернативи).
Однак, якщо ви просто користуватиметеся `pip` напряму, пакети встановлюватимуться у ваше глобальне середовище Python (глобальну інсталяцію Python). Однак, якщо ви просто користуватиметеся `pip` напряму, пакети встановлюватимуться у ваше **глобальне середовище Python** (глобальну інсталяцію Python).
### Проблема { #the-problem } ### Проблема { #the-problem }
То в чому ж проблема встановлення пакетів у глобальне середовище Python? То в чому ж проблема встановлення пакетів у глобальне середовище Python?
З часом ви, вірогідно, писатимете багато різних програм, які залежать від різних пакетів. І деякі з цих ваших проєктів залежатимуть від різних версій одного й того ж пакета. 😱 З часом ви, вірогідно, писатимете багато різних програм, які залежать від **різних пакетів**. І деякі з цих ваших проєктів залежатимуть від **різних версій** одного й того ж пакета. 😱
Наприклад, ви можете створити проєкт із назвою `philosophers-stone`, ця програма залежить від іншого пакета з назвою `harry`, використовуючи версію `1`. Тож вам потрібно встановити `harry`. Наприклад, ви можете створити проєкт із назвою `philosophers-stone`, ця програма залежить від іншого пакета з назвою **`harry`, використовуючи версію `1`**. Тож вам потрібно встановити `harry`.
```mermaid ```mermaid
flowchart LR flowchart LR
stone(philosophers-stone) -->|requires| harry-1[harry v1] stone(philosophers-stone) -->|requires| harry-1[harry v1]
``` ```
Потім, трохи згодом, ви створюєте інший проєкт із назвою `prisoner-of-azkaban`, і цей проєкт також залежить від `harry`, але йому потрібна версія `harry` `3`. Потім, трохи згодом, ви створюєте інший проєкт із назвою `prisoner-of-azkaban`, і цей проєкт також залежить від `harry`, але йому потрібна **версія `harry` `3`**.
```mermaid ```mermaid
flowchart LR flowchart LR
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3] azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
``` ```
Але тепер проблема в тому, що якщо ви встановлюєте пакети глобально (у глобальне середовище), а не у локальне віртуальне середовище, вам доведеться вибирати, яку версію `harry` встановити. Але тепер проблема в тому, що якщо ви встановлюєте пакети глобально (у глобальне середовище), а не у локальне **віртуальне середовище**, вам доведеться вибирати, яку версію `harry` встановити.
Якщо ви хочете запустити `philosophers-stone`, вам спочатку потрібно встановити `harry` версії `1`, наприклад, так: Якщо ви хочете запустити `philosophers-stone`, вам спочатку потрібно встановити `harry` версії `1`, наприклад, так:
@ -517,7 +519,7 @@ $ pip install "harry==3"
У підсумку у вас буде встановлено `harry` версії `3` у глобальному середовищі Python. У підсумку у вас буде встановлено `harry` версії `3` у глобальному середовищі Python.
А якщо ви знову спробуєте запустити `philosophers-stone`, є шанс, що він не працюватиме, тому що йому потрібен `harry` версії `1`. А якщо ви знову спробуєте запустити `philosophers-stone`, є шанс, що він **не працюватиме**, тому що йому потрібен `harry` версії `1`.
```mermaid ```mermaid
flowchart LR flowchart LR
@ -536,13 +538,13 @@ flowchart LR
/// tip | Порада /// tip | Порада
У пакетах Python дуже поширена практика намагатися якнайкраще уникати несумісних змін у нових версіях, але краще підстрахуватися та встановлювати новіші версії свідомо і тоді, коли ви можете запустити тести, щоб перевірити, що все працює коректно. У пакетах Python дуже поширена практика намагатися якнайкраще **уникати несумісних змін** у **нових версіях**, але краще підстрахуватися та встановлювати новіші версії свідомо і тоді, коли ви можете запустити тести, щоб перевірити, що все працює коректно.
/// ///
Тепер уявіть те саме з багатьма іншими пакетами, від яких залежать усі ваші проєкти. Це дуже складно керувати. І ви, імовірно, запускатимете деякі проєкти з деякими несумісними версіями пакетів і не розумітимете, чому щось не працює. Тепер уявіть те саме з **багатьма** іншими **пакетами**, від яких залежать усі ваші **проєкти**. Це дуже складно керувати. І ви, імовірно, запускатимете деякі проєкти з деякими **несумісними версіями** пакетів і не розумітимете, чому щось не працює.
Також, залежно від вашої операційної системи (напр., Linux, Windows, macOS), у ній може бути вже встановлений Python. І в такому разі, імовірно, уже будуть попередньо встановлені деякі пакети з певними версіями, потрібними вашій системі. Якщо ви встановлюєте пакети в глобальне середовище Python, ви можете зламати деякі програми, що постачаються з вашою операційною системою. Також, залежно від вашої операційної системи (напр., Linux, Windows, macOS), у ній може бути вже встановлений Python. І в такому разі, імовірно, уже будуть попередньо встановлені деякі пакети з певними версіями, **потрібними вашій системі**. Якщо ви встановлюєте пакети в глобальне середовище Python, ви можете **зламати** деякі програми, що постачаються з вашою операційною системою.
## Де встановлюються пакети { #where-are-packages-installed } ## Де встановлюються пакети { #where-are-packages-installed }
@ -564,17 +566,17 @@ $ pip install "fastapi[standard]"
Це завантажить стиснений файл з кодом FastAPI, зазвичай із [PyPI](https://pypi.org/project/fastapi/). Це завантажить стиснений файл з кодом FastAPI, зазвичай із [PyPI](https://pypi.org/project/fastapi/).
Також будуть завантажені файли для інших пакетів, від яких залежить FastAPI. Також будуть **завантажені** файли для інших пакетів, від яких залежить FastAPI.
Потім усе це буде розпаковано та покладено в каталог на вашому комп'ютері. Потім усе це буде **розпаковано** та покладено в каталог на вашому комп'ютері.
Типово ці завантажені та розпаковані файли будуть покладені в каталог, що постачається з вашою інсталяцією Python, це глобальне середовище. Типово ці завантажені та розпаковані файли будуть покладені в каталог, що постачається з вашою інсталяцією Python, це **глобальне середовище**.
## Що таке віртуальні середовища { #what-are-virtual-environments } ## Що таке віртуальні середовища { #what-are-virtual-environments }
Рішенням проблеми з наявністю всіх пакетів у глобальному середовищі є використання віртуального середовища для кожного проєкту, над яким ви працюєте. Рішенням проблеми з наявністю всіх пакетів у глобальному середовищі є використання **віртуального середовища для кожного проєкту**, над яким ви працюєте.
Віртуальне середовище - це каталог, дуже схожий на глобальний, у якому ви можете встановлювати пакети для конкретного проєкту. Віртуальне середовище - це **каталог**, дуже схожий на глобальний, у якому ви можете встановлювати пакети для конкретного проєкту.
Таким чином кожен проєкт матиме власне віртуальне середовище (каталог `.venv`) із власними пакетами. Таким чином кожен проєкт матиме власне віртуальне середовище (каталог `.venv`) із власними пакетами.
@ -637,7 +639,7 @@ $ source .venv/Scripts/activate
//// ////
Ця команда створить або змінить деякі [Змінні оточення](environment-variables.md), які будуть доступні для наступних команд. Ця команда створить або змінить деякі [змінні оточення](environment-variables.md), які будуть доступні для наступних команд.
Однією з цих змінних є змінна `PATH`. Однією з цих змінних є змінна `PATH`.
@ -728,7 +730,7 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
//// ////
Важлива деталь: шлях до віртуального середовища буде додано на початок змінної `PATH`. Система знайде його раніше за будь-який інший доступний Python. Таким чином, коли ви запускаєте `python`, використовується саме Python із віртуального середовища, а не будь-який інший `python` (наприклад, з глобального середовища). Важлива деталь: шлях до віртуального середовища буде додано на **початок** змінної `PATH`. Система знайде його **раніше** за будь-який інший доступний Python. Таким чином, коли ви запускаєте `python`, використовується саме Python **із віртуального середовища**, а не будь-який інший `python` (наприклад, з глобального середовища).
Активація віртуального середовища також змінює ще кілька речей, але це одна з найважливіших. Активація віртуального середовища також змінює ще кілька речей, але це одна з найважливіших.
@ -764,11 +766,11 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
//// ////
Це означає, що програма `python`, яка буде використана, знаходиться у віртуальному середовищі. Це означає, що програма `python`, яка буде використана, знаходиться **у віртуальному середовищі**.
На Linux і macOS використовують `which`, а в Windows PowerShell - `Get-Command`. На Linux і macOS використовують `which`, а в Windows PowerShell - `Get-Command`.
Принцип роботи цієї команди в тому, що вона перевіряє змінну оточення `PATH`, проходячи по кожному шляху по порядку, шукаючи програму з назвою `python`. Щойно вона її знайде, вона покаже вам шлях до цієї програми. Принцип роботи цієї команди в тому, що вона перевіряє змінну оточення `PATH`, проходячи по **кожному шляху по порядку**, шукаючи програму з назвою `python`. Щойно вона її знайде, вона **покаже вам шлях** до цієї програми.
Найважливіше, що коли ви викликаєте `python`, це рівно той «`python`», який буде виконаний. Найважливіше, що коли ви викликаєте `python`, це рівно той «`python`», який буде виконаний.
@ -776,9 +778,9 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
/// tip | Порада /// tip | Порада
Легко активувати одне віртуальне середовище, отримати один Python, а потім перейти до іншого проєкту. Легко активувати одне віртуальне середовище, отримати один Python, а потім **перейти до іншого проєкту**.
І другий проєкт не працюватиме, бо ви використовуєте некоректний Python з віртуального середовища іншого проєкту. І другий проєкт **не працюватиме**, бо ви використовуєте **некоректний Python** з віртуального середовища іншого проєкту.
Корисно вміти перевіряти, який саме `python` використовується. 🤓 Корисно вміти перевіряти, який саме `python` використовується. 🤓
@ -786,9 +788,9 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
## Навіщо деактивувати віртуальне середовище { #why-deactivate-a-virtual-environment } ## Навіщо деактивувати віртуальне середовище { #why-deactivate-a-virtual-environment }
Наприклад, ви працюєте над проєктом `philosophers-stone`, активували його віртуальне середовище, встановили пакети та працюєте з цим середовищем. Наприклад, ви працюєте над проєктом `philosophers-stone`, **активували його віртуальне середовище**, встановили пакети та працюєте з цим середовищем.
А потім ви хочете працювати над іншим проєктом `prisoner-of-azkaban`. А потім ви хочете працювати над **іншим проєктом** `prisoner-of-azkaban`.
Ви переходите до цього проєкту: Ви переходите до цього проєкту:
@ -840,23 +842,23 @@ I solemnly swear 🐺
## Альтернативи { #alternatives } ## Альтернативи { #alternatives }
Це простий посібник, щоб ви швидко стартували та зрозуміли, як усе працює «під капотом». Це простий посібник, щоб ви швидко стартували та зрозуміли, як усе працює **«під капотом»**.
Існує багато альтернатив керування віртуальними середовищами, залежностями пакетів (вимогами), проєктами. Існує багато **альтернатив** керування віртуальними середовищами, залежностями пакетів (вимогами), проєктами.
Коли будете готові й захочете використовувати інструмент для керування всім проєктом, залежностями пакетів, віртуальними середовищами тощо, я раджу спробувати [uv](https://github.com/astral-sh/uv). Коли будете готові й захочете використовувати інструмент для **керування всім проєктом**, залежностями пакетів, віртуальними середовищами тощо, я раджу спробувати [uv](https://github.com/astral-sh/uv).
`uv` уміє багато чого, зокрема: `uv` уміє багато чого, зокрема:
* Встановлювати Python для вас, включно з різними версіями * **Встановлювати Python** для вас, включно з різними версіями
* Керувати віртуальним середовищем ваших проєктів * Керувати **віртуальним середовищем** ваших проєктів
* Встановлювати пакети * Встановлювати **пакети**
* Керувати залежностями пакетів і версіями у вашому проєкті * Керувати **залежностями і версіями** пакетів у вашому проєкті
* Гарантувати, що у вас є точний набір пакетів і версій для встановлення, включно з їхніми залежностями, щоб ви були певні, що зможете запустити ваш проєкт у продакшені точно так само, як і на вашому комп'ютері під час розробки - це називається блокуванням * Гарантувати, що у вас є **точний** набір пакетів і версій для встановлення, включно з їхніми залежностями, щоб ви були певні, що зможете запустити ваш проєкт у продакшені точно так само, як і на вашому комп'ютері під час розробки - це називається **блокуванням**
* І багато іншого * І багато іншого
## Висновок { #conclusion } ## Висновок { #conclusion }
Якщо ви все це прочитали й зрозуміли, тепер ви знаєте значно більше про віртуальні середовища, ніж багато розробників. 🤓 Якщо ви все це прочитали й зрозуміли, тепер **ви знаєте значно більше** про віртуальні середовища, ніж багато розробників. 🤓
Знання цих деталей, найімовірніше, стане в пригоді в майбутньому, коли ви налагоджуватимете щось, що виглядає складним, але ви знатимете, як усе працює «під капотом». 😎 Знання цих деталей, найімовірніше, стане в пригоді в майбутньому, коли ви налагоджуватимете щось, що виглядає складним, але ви знатимете, **як усе працює «під капотом»**. 😎

Loading…
Cancel
Save