diff --git a/docs/uk/docs/advanced/json-base64-bytes.md b/docs/uk/docs/advanced/json-base64-bytes.md new file mode 100644 index 0000000000..2cb6461ec7 --- /dev/null +++ b/docs/uk/docs/advanced/json-base64-bytes.md @@ -0,0 +1,63 @@ +# JSON з байтами як Base64 { #json-with-bytes-as-base64 } + +Якщо ваш застосунок має отримувати і надсилати дані JSON, але потрібно включати туди двійкові дані, ви можете кодувати їх як base64. + +## Base64 проти файлів { #base64-vs-files } + +Насамперед розгляньте, чи можете ви використати [Файли запиту](../tutorial/request-files.md) для завантаження двійкових даних і [Користувацька відповідь - FileResponse](./custom-response.md#fileresponse--fileresponse-) для надсилання двійкових даних замість кодування їх у JSON. + +JSON може містити лише строки, закодовані в UTF-8, тому він не може містити «сирі» байти. + +Base64 може кодувати двійкові дані у строках, але для цього потрібно більше символів, ніж у початкових двійкових даних, тож зазвичай це менш ефективно, ніж звичайні файли. + +Використовуйте base64 лише якщо справді потрібно включати двійкові дані в JSON і ви не можете використати файли для цього. + +## Pydantic `bytes` { #pydantic-bytes } + +Ви можете оголосити модель Pydantic з полями `bytes`, а потім використати `val_json_bytes` у конфігурації моделі, щоб вказати їй використовувати base64 для перевірки вхідних даних JSON; як частина цієї перевірки, вона декодує строку base64 у байти. + +{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *} + +Якщо ви перевірите `/docs`, там буде показано, що поле `data` очікує байти, закодовані в base64: + +
+ +
+ +Ви можете надіслати запит так: + +```json +{ + "description": "Some data", + "data": "aGVsbG8=" +} +``` + +/// tip | Порада + +`aGVsbG8=` - це кодування base64 для `hello`. + +/// + +Після цього Pydantic декодує строку base64 і надасть вам початкові байти в полі моделі `data`. + +Ви отримаєте відповідь приблизно таку: + +```json +{ + "description": "Some data", + "content": "hello" +} +``` + +## Pydantic `bytes` для вихідних даних { #pydantic-bytes-for-output-data } + +Ви також можете використовувати поля `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] *} + +## Pydantic `bytes` для вхідних і вихідних даних { #pydantic-bytes-for-input-and-output-data } + +І, звісно, ви можете використовувати ту саму модель, налаштовану на 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] *} diff --git a/docs/uk/docs/advanced/stream-data.md b/docs/uk/docs/advanced/stream-data.md new file mode 100644 index 0000000000..4f12132e06 --- /dev/null +++ b/docs/uk/docs/advanced/stream-data.md @@ -0,0 +1,117 @@ +# Потокова передача даних { #stream-data } + +Якщо ви хочете передавати потоком дані, які можна структурувати як JSON, див. [Потокова передача JSON Lines](../tutorial/stream-json-lines.md). + +Але якщо ви хочете передавати потоком чисті бінарні дані або строки, ось як це зробити. + +/// info | Інформація + +Додано у FastAPI 0.134.0. + +/// + +## Варіанти використання { #use-cases } + +Це можна використовувати, якщо ви хочете передавати потоком чисті строки, наприклад безпосередньо з виводу сервісу AI LLM. + +Також це можна використати для потокової передачі великих бінарних файлів, коли ви надсилаєте кожний фрагмент даних під час читання, без потреби завантажувати все в пам'ять одразу. + +Так само можна стрімити відео чи аудіо; їх навіть можна генерувати під час обробки та надсилання. + +## `StreamingResponse` з `yield` { #a-streamingresponse-with-yield } + +Якщо ви оголосите `response_class=StreamingResponse` у вашій функції операції шляху, ви можете використовувати `yield`, щоб послідовно надсилати кожний фрагмент даних. + +{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *} + +FastAPI передаватиме кожний фрагмент даних до `StreamingResponse` як є; він не намагатиметься перетворити його на JSON чи щось подібне. + +### Не-async функції операції шляху { #non-async-path-operation-functions } + +Можна також використовувати звичайні функції `def` (без `async`) і так само застосовувати `yield`. + +{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *} + +### Без анотації { #no-annotation } + +Для потокової передачі бінарних даних немає потреби оголошувати анотацію типу, що повертається. + +Оскільки FastAPI не намагатиметься перетворювати дані на JSON за допомогою Pydantic чи серіалізувати їх іншим чином, у цьому випадку анотація типу потрібна лише для вашого редактора та інструментів; FastAPI її не використовуватиме. + +{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *} + +Це також означає, що з `StreamingResponse` у вас є свобода і відповідальність формувати та кодувати байти даних саме так, як їх потрібно надіслати, незалежно від анотацій типів. 🤓 + +### Потік байтів { #stream-bytes } + +Один з основних сценаріїв - передавати потоком `bytes` замість строк; це, звісно, підтримується. + +{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *} + +## Користувацький `PNGStreamingResponse` { #a-custom-pngstreamingresponse } + +У наведених вище прикладах байти даних передавалися потоком, але у відповіді не було заголовка `Content-Type`, тому клієнт не знав, який тип даних він отримує. + +Можна створити власний підклас `StreamingResponse`, який встановлює заголовок `Content-Type` відповідно до типу даних, що ви стрімите. + +Наприклад, можна створити `PNGStreamingResponse`, який встановлює заголовок `Content-Type` у `image/png` за допомогою атрибута `media_type`: + +{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *} + +Потім ви можете використати цей новий клас у `response_class=PNGStreamingResponse` у вашій функції операції шляху: + +{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *} + +### Симулювати файл { #simulate-a-file } + +У цьому прикладі ми імітуємо файл за допомогою `io.BytesIO` - це об'єкт на кшталт файлу, який існує лише в пам'яті, але надає той самий інтерфейс. + +Наприклад, ми можемо ітеруватися по ньому, щоб зчитати вміст, так само як і з файлом. + +{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *} + +/// note | Технічні деталі + +Інші дві змінні, `image_base64` та `binary_image`, - це зображення, закодоване в Base64, яке потім перетворюється на байти, щоб передати його в `io.BytesIO`. + +Лише для того, щоб усе містилося в одному файлі для цього прикладу, і ви могли скопіювати його та запустити як є. 🥚 + +/// + +Використовуючи блок `with`, ми гарантуємо, що об'єкт, подібний до файлу, буде закрито після завершення генераторної функції (функції з `yield`). Тобто після завершення надсилання відповіді. + +У цьому конкретному прикладі це не так важливо, адже це фальшивий файл у пам'яті (з `io.BytesIO`), але для справжнього файлу важливо переконатися, що файл закрито після завершення роботи з ним. + +### Файли та async { #files-and-async } + +У більшості випадків об'єкти, подібні до файлів, за замовчуванням несумісні з `async` та `await`. + +Наприклад, у них немає `await file.read()` або `async for chunk in file`. + +І часто їх читання є блокувальною операцією (що може блокувати цикл подій), адже дані зчитуються з диска або мережі. + +/// info | Інформація + +Наведений вище приклад - виняток, адже об'єкт `io.BytesIO` вже в пам'яті, тож читання нічого не блокує. + +Але в багатьох випадках читання файлу або схожого на файл об'єкта блокує виконання. + +/// + +Щоб уникнути блокування циклу подій, просто оголосіть функцію операції шляху зі звичайним `def` замість `async def`. Тоді FastAPI виконуватиме її в працівнику пулу потоків, щоб не блокувати головний цикл. + +{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *} + +/// tip | Порада + +Якщо вам потрібно викликати блокувальний код усередині async-функції або async-функцію зсередини блокувальної функції, ви можете скористатися [Asyncer](https://asyncer.tiangolo.com) - спорідненою бібліотекою до FastAPI. + +/// + +### `yield from` { #yield-from } + +Коли ви ітеруєтеся по чомусь, наприклад по об'єкту, подібному до файлу, і робите `yield` для кожного елемента, можна також використати `yield from`, щоб віддавати кожен елемент напряму і пропустити цикл `for`. + +Це не специфічно для FastAPI, це просто Python, але корисний трюк. 😎 + +{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *} diff --git a/docs/uk/docs/advanced/strict-content-type.md b/docs/uk/docs/advanced/strict-content-type.md new file mode 100644 index 0000000000..a244ec9018 --- /dev/null +++ b/docs/uk/docs/advanced/strict-content-type.md @@ -0,0 +1,88 @@ +# Сувора перевірка Content-Type { #strict-content-type-checking } + +За замовчуванням **FastAPI** використовує сувору перевірку заголовка `Content-Type` для тіл запитів JSON, це означає, що запити JSON мають включати дійсний заголовок `Content-Type` (наприклад, `application/json`), щоб тіло було розібране як JSON. + +## Ризик CSRF { #csrf-risk } + +Ця поведінка за замовчуванням забезпечує захист від класу атак **Cross-Site Request Forgery (CSRF)** у дуже конкретному сценарії. + +Ці атаки використовують той факт, що браузери дозволяють скриптам надсилати запити без виконання перевірки CORS preflight, коли вони: + +* не мають заголовка `Content-Type` (наприклад, використовуючи `fetch()` з тілом типу `Blob`) +* і не надсилають жодних облікових даних автентифікації. + +Такий тип атаки головним чином актуальний, коли: + +* застосунок працює локально (наприклад, на `localhost`) або у внутрішній мережі +* і в застосунку немає жодної автентифікації, очікується, що будь-який запит з тієї ж мережі є надійним. + +## Приклад атаки { #example-attack } + +Уявіть, що ви створюєте спосіб запускати локального AI-агента. + +Він надає API за адресою + +``` +http://localhost:8000/v1/agents/multivac +``` + +Є також фронтенд за адресою + +``` +http://localhost:8000 +``` + +/// tip | Порада + +Зауважте, що обидва мають один і той самий хост. + +/// + +Використовуючи фронтенд, ви можете змушувати AI-агента виконувати дії від вашого імені. + +Оскільки він працює локально, а не у відкритому інтернеті, ви вирішуєте не налаштовувати жодної автентифікації, просто покладаючись на доступ до локальної мережі. + +Один із ваших користувачів може встановити його і запустити локально. + +Потім він може відкрити шкідливий вебсайт, напр. щось на кшталт + +``` +https://evilhackers.example.com +``` + +І цей шкідливий вебсайт надсилає запити, використовуючи `fetch()` з тілом типу `Blob`, до локального API за адресою + +``` +http://localhost:8000/v1/agents/multivac +``` + +Хоча хости шкідливого вебсайту та локального застосунку різні, браузер не запустить CORS preflight-запит, тому що: + +* Застосунок працює без будь-якої автентифікації, немає потреби надсилати облікові дані. +* Браузер вважає, що він не надсилає JSON (через відсутній заголовок `Content-Type`). + +Тоді шкідливий вебсайт може змусити локального AI-агента надсилати злі повідомлення колишньому босу користувача... або щось гірше. 😅 + +## Відкритий інтернет { #open-internet } + +Якщо ваш застосунок у відкритому інтернеті, ви не стали б «довіряти мережі» і дозволяти кому завгодно надсилати привілейовані запити без автентифікації. + +Зловмисники можуть просто запустити скрипт, щоб надсилати запити до вашого API, без будь-якої участі браузера, тож ви, ймовірно, вже захищаєте будь-які привілейовані ендпоїнти. + +У такому разі ця атака/ризик до вас не застосовується. + +Цей ризик і атака головним чином актуальні, коли застосунок працює в локальній мережі і це єдиний передбачуваний захист. + +## Дозволення запитів без Content-Type { #allowing-requests-without-content-type } + +Якщо вам потрібно підтримувати клієнтів, які не надсилають заголовок `Content-Type`, ви можете вимкнути сувору перевірку, встановивши `strict_content_type=False`: + +{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *} + +З цим налаштуванням запити без заголовка `Content-Type` матимуть тіло, розібране як JSON, що відповідає поведінці старіших версій FastAPI. + +/// info | Інформація + +Цю поведінку і конфігурацію додано у FastAPI 0.132.0. + +/// diff --git a/docs/uk/docs/editor-support.md b/docs/uk/docs/editor-support.md new file mode 100644 index 0000000000..f0edf62972 --- /dev/null +++ b/docs/uk/docs/editor-support.md @@ -0,0 +1,23 @@ +# Підтримка редакторів { #editor-support } + +Офіційне [FastAPI Extension](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) покращує ваш робочий процес розробки FastAPI завдяки виявленню й навігації по *операціях шляху*, а також розгортанню у FastAPI Cloud і потоковому передаванню журналів у реальному часі. + +Докладніше про розширення дивіться у README в [репозиторії GitHub](https://github.com/fastapi/fastapi-vscode). + +## Налаштування та встановлення { #setup-and-installation } + +**FastAPI Extension** доступне для [VS Code](https://code.visualstudio.com/) і [Cursor](https://www.cursor.com/). Його можна встановити безпосередньо з панелі Extensions у кожному редакторі, знайшовши «FastAPI» і вибравши розширення від **FastAPI Labs**. Розширення також працює у браузерних редакторах, таких як [vscode.dev](https://vscode.dev) і [github.dev](https://github.dev). + +### Виявлення застосунку { #application-discovery } + +Типово розширення автоматично виявляє застосунки FastAPI у вашому робочому просторі, скануючи файли, які створюють екземпляр `FastAPI()`. Якщо автовиявлення не працює для структури вашого проєкту, ви можете вказати точку входу через `[tool.fastapi]` у `pyproject.toml` або налаштування VS Code `fastapi.entryPoint`, використовуючи нотацію модуля (наприклад, `myapp.main:app`). + +## Можливості { #features } + +- **Провідник операцій шляху** - Бічне деревоподібне представлення всіх *операцій шляху* у вашому застосунку. Натисніть, щоб перейти до будь-якого визначення маршруту або маршрутизатора. +- **Пошук маршрутів** - Пошук за шляхом, методом або назвою за допомогою Ctrl + Shift + E (на macOS: Cmd + Shift + E). +- **Навігація CodeLens** - Клікабельні посилання над викликами тестового клієнта (наприклад, `client.get('/items')`), які переходять до відповідної *операції шляху* для швидкої навігації між тестами та реалізацією. +- **Розгортання у FastAPI Cloud** - Розгортання вашого застосунку у [FastAPI Cloud](https://fastapicloud.com/) в один клік. +- **Потокове передавання журналів застосунку** - Потокове передавання журналів у реальному часі з вашого застосунку, розгорнутого у FastAPI Cloud, з фільтруванням за рівнем і пошуком по тексту. + +Щоб ознайомитися з можливостями розширення, відкрийте Палітру команд (Ctrl + Shift + P або на macOS: Cmd + Shift + P), виберіть «Welcome: Open walkthrough...», а потім «Get started with FastAPI». diff --git a/docs/uk/docs/tutorial/server-sent-events.md b/docs/uk/docs/tutorial/server-sent-events.md new file mode 100644 index 0000000000..8234085cfa --- /dev/null +++ b/docs/uk/docs/tutorial/server-sent-events.md @@ -0,0 +1,120 @@ +# Події, надіслані сервером (SSE) { #server-sent-events-sse } + +Ви можете транслювати дані клієнту за допомогою **Server-Sent Events** (SSE). + +Це подібно до [Потік JSON Lines](stream-json-lines.md), але використовує формат `text/event-stream`, який нативно підтримується браузерами через [API `EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource). + +/// info | Інформація + +Додано у FastAPI 0.135.0. + +/// + +## Що таке Server-Sent Events { #what-are-server-sent-events } + +SSE - це стандарт для трансляції даних із сервера до клієнта по HTTP. + +Кожна подія - це невеликий текстовий блок із «полями» на кшталт `data`, `event`, `id` та `retry`, розділений порожніми рядками. + +Виглядає так: + +``` +data: {"name": "Portal Gun", "price": 999.99} + +data: {"name": "Plumbus", "price": 32.99} + +``` + +SSE часто використовують для стрімінгу чатів ШІ, живих сповіщень, логів і спостережуваності, а також інших випадків, коли сервер надсилає оновлення клієнту. + +/// tip | Порада + +Якщо ви хочете транслювати бінарні дані, наприклад відео чи аудіо, перегляньте просунутий посібник: [Потік даних](../advanced/stream-data.md). + +/// + +## Стрімінг SSE у FastAPI { #stream-sse-with-fastapi } + +Щоб транслювати SSE з FastAPI, використовуйте `yield` у вашій *функції операції шляху* і встановіть `response_class=EventSourceResponse`. + +Імпортуйте `EventSourceResponse` з `fastapi.sse`: + +{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[4,22] *} + +Кожен елемент, повернений через `yield`, кодується як JSON і надсилається в полі `data:` події SSE. + +Якщо ви оголосите тип повернення як `AsyncIterable[Item]`, FastAPI використає його, щоб **перевіряти**, **документувати** і **серіалізувати** дані за допомогою Pydantic. + +{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[10:12,23] *} + +/// tip | Порада + +Оскільки Pydantic серіалізує це на боці **Rust**, ви отримаєте значно вищу **продуктивність**, ніж якби не оголошували тип повернення. + +/// + +### Не-async *функції операцій шляху* { #non-async-path-operation-functions } + +Ви також можете використовувати звичайні функції `def` (без `async`) і використовувати `yield` так само. + +FastAPI подбає про коректне виконання, щоб воно не блокувало цикл подій. + +Оскільки в цьому випадку функція не async, коректним типом повернення буде `Iterable[Item]`: + +{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[28:31] hl[29] *} + +### Без типу повернення { #no-return-type } + +Можна також опустити тип повернення. FastAPI використає [`jsonable_encoder`](./encoder.md), щоб конвертувати дані і надіслати їх. + +{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[34:37] hl[35] *} + +## `ServerSentEvent` { #serversentevent } + +Якщо вам потрібно встановити поля SSE, такі як `event`, `id`, `retry` або `comment`, ви можете повертати через `yield` об'єкти `ServerSentEvent` замість звичайних даних. + +Імпортуйте `ServerSentEvent` з `fastapi.sse`: + +{* ../../docs_src/server_sent_events/tutorial002_py310.py hl[4,26] *} + +Поле `data` завжди кодується як JSON. Ви можете передати будь-яке значення, яке можна серіалізувати в JSON, включно з моделями Pydantic. + +## Сирі дані { #raw-data } + +Якщо потрібно надіслати дані **без** кодування в JSON, використовуйте `raw_data` замість `data`. + +Це корисно для надсилання попередньо відформатованого тексту, рядків логів або спеціальних значень «значення-сторож», як-от `[DONE]`. + +{* ../../docs_src/server_sent_events/tutorial003_py310.py hl[17] *} + +/// note | Примітка + +`data` і `raw_data` взаємовиключні. У кожному `ServerSentEvent` ви можете встановити лише одне з них. + +/// + +## Відновлення з `Last-Event-ID` { #resuming-with-last-event-id } + +Коли браузер перепідключається після розриву з'єднання, він надсилає останній отриманий `id` у заголовку `Last-Event-ID`. + +Ви можете прочитати його як параметр заголовка і використати, щоб відновити потік із місця, де клієнт зупинився: + +{* ../../docs_src/server_sent_events/tutorial004_py310.py hl[25,27,31] *} + +## SSE з POST { #sse-with-post } + +SSE працює з **будь-яким HTTP-методом**, не лише з `GET`. + +Це корисно для протоколів на кшталт [MCP](https://modelcontextprotocol.io), які транслюють SSE через `POST`: + +{* ../../docs_src/server_sent_events/tutorial005_py310.py hl[14] *} + +## Технічні деталі { #technical-details } + +FastAPI реалізує деякі найкращі практики SSE «з коробки». + +- Надсилати **коментар «keep alive» `ping`** кожні 15 секунд, коли не було жодного повідомлення, щоб запобігти закриттю з'єднання деякими проксі, як рекомендовано у [Специфікації HTML: Події, надіслані сервером](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes). +- Встановити заголовок `Cache-Control: no-cache`, щоб **запобігти кешуванню** потоку. +- Встановити спеціальний заголовок `X-Accel-Buffering: no`, щоб **запобігти буферизації** у деяких проксі, наприклад Nginx. + +Вам не потрібно нічого з цим робити, воно працює «з коробки». 🤓 diff --git a/docs/uk/docs/tutorial/stream-json-lines.md b/docs/uk/docs/tutorial/stream-json-lines.md new file mode 100644 index 0000000000..f7be4a1b24 --- /dev/null +++ b/docs/uk/docs/tutorial/stream-json-lines.md @@ -0,0 +1,111 @@ +# Стрімінг JSON Lines { #stream-json-lines } + +У вас може бути послідовність даних, яку ви хочете надсилати у **«потоці»**, це можна зробити за допомогою **JSON Lines**. + +/// info | Інформація + +Додано в FastAPI 0.134.0. + +/// + +## Що таке потік { #what-is-a-stream } + +«**Стрімінг**» даних означає, що ваш застосунок почне надсилати елементи даних клієнту, не чекаючи, доки буде готова вся послідовність елементів. + +Тобто він надішле перший елемент, клієнт його отримає і почне обробляти, а ви в цей час уже можете створювати наступний елемент. + +```mermaid +sequenceDiagram + participant App + participant Client + + App->>App: Produce Item 1 + App->>Client: Send Item 1 + App->>App: Produce Item 2 + Client->>Client: Process Item 1 + App->>Client: Send Item 2 + App->>App: Produce Item 3 + Client->>Client: Process Item 2 + App->>Client: Send Item 3 + Client->>Client: Process Item 3 + Note over App: Keeps producing... + Note over Client: Keeps consuming... +``` + +Це може бути навіть нескінченний потік, у якому ви постійно надсилаєте дані. + +## JSON Lines { #json-lines } + +У таких випадках часто надсилають «**JSON Lines**» - формат, у якому ви надсилаєте по одному об’єкту JSON на рядок. + +Відповідь матиме тип вмісту `application/jsonl` (замість `application/json`), а тіло буде приблизно таким: + +```json +{"name": "Plumbus", "description": "A multi-purpose household device."} +{"name": "Portal Gun", "description": "A portal opening device."} +{"name": "Meeseeks Box", "description": "A box that summons a Meeseeks."} +``` + +Це дуже схоже на масив JSON (еквівалент списку Python), але замість того, щоб бути загорнутим у `[]` і мати `,` між елементами, тут є **по одному об’єкту JSON на рядок**, вони розділені символом нового рядка. + +/// info | Інформація + +Важливо те, що ваш застосунок зможе по черзі створювати кожен рядок, поки клієнт споживає попередні рядки. + +/// + +/// note | Технічні деталі + +Оскільки кожен об’єкт JSON буде розділено новим рядком, він не може містити буквальні символи нового рядка у своєму вмісті, але може містити екрановані нові рядки (`\n`), що є частиною стандарту JSON. + +Зазвичай про це не треба турбуватися, усе робиться автоматично, читайте далі. 🤓 + +/// + +## Випадки використання { #use-cases } + +Ви можете використовувати це, щоб стрімити дані зі служби **AI LLM**, із **логів** чи **телеметрії**, або з інших типів даних, які можна структурувати як елементи **JSON**. + +/// tip | Порада + +Якщо ви хочете стрімити бінарні дані, наприклад відео чи аудіо, перегляньте просунутий посібник: [Потокова передача даних](../advanced/stream-data.md). + +/// + +## Стрімінг JSON Lines з FastAPI { #stream-json-lines-with-fastapi } + +Щоб стрімити JSON Lines з FastAPI, замість використання `return` у вашій *функції операції шляху* використовуйте `yield`, щоб по черзі створювати кожен елемент. + +{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[24] *} + +Якщо кожен елемент JSON, який ви хочете надіслати у відповідь, має тип `Item` (модель Pydantic) і це async-функція, ви можете оголосити тип повернення як `AsyncIterable[Item]`: + +{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[9:11,22] *} + +Якщо ви оголосите тип повернення, FastAPI використає його, щоб **перевіряти** дані, **документувати** їх в OpenAPI, **фільтрувати** їх і **серіалізувати** за допомогою Pydantic. + +/// tip | Порада + +Оскільки Pydantic серіалізуватиме це на боці **Rust**, ви отримаєте значно вищу **продуктивність**, ніж якби не оголошували тип повернення. + +/// + +### Не-async *функції операцій шляху* { #non-async-path-operation-functions } + +Ви також можете використовувати звичайні функції `def` (без `async`) і використовувати `yield` так само. + +FastAPI подбає про коректне виконання, щоб це не блокувало цикл подій. + +Оскільки в цьому випадку функція не є async, правильним типом повернення буде `Iterable[Item]`: + +{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[27:30] hl[28] *} + +### Без типу повернення { #no-return-type } + +Ви також можете опустити тип повернення. Тоді FastAPI використає [`jsonable_encoder`](./encoder.md), щоб перетворити дані на щось, що можна серіалізувати в JSON, і потім надішле їх як JSON Lines. + +{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[33:36] hl[34] *} + +## Події, надіслані сервером (SSE) { #server-sent-events-sse } + +FastAPI також має повноцінну підтримку Server-Sent Events (SSE), які досить схожі, але мають кілька додаткових деталей. Ви можете дізнатися про них у наступному розділі: [Події, надіслані сервером (SSE)](server-sent-events.md). 🤓