Асинхронний словник FastAPI і Python для розробників серверів
Операції шляху FastAPI, моделі Pydantic, async/await в Python, введення залежностей і словник API Python.
FastAPI став одним з найпопулярніших фреймворків Python в бекенд-колох — і не без причини. Цей інструмент швидкий, інтуїтивно зрозумілий і автоматично створює документацію. Але коли ви приєднаєтеся до команди, яка використовує його, або коли ви читаєте його проблеми GitHub і обговорення, ви зіткнетеся з щільним кластером спеціалізованих термінів. Знання цих слів не лише допоможе вам з більшою впевненістю читати документацію, але й допоможе вам ставити кращі запитання під час перегляду коду, писати ясніші повідомлення про перенесення і триматися на своїй позиції під час технічних інтерв’ ю.
У цьому підручнику ви дізнаєтесь про основні слова FastAPI і асинхронного Python, з якими ви зіткнетеся як розробник сервера, а також дізнаєтеся про приклади реальних розмов, взятих з повсякденного інженерного життя.
Основні концепції FastAPI
** Операція шляху ** — поєднання методу HTTP (GET, POST, PUT, DELETE тощо) і шаблону URL, який FastAPI реєструє як обробник. Слово « операція » походить зі специфікації OpenAPI, отже, ви побачите, що воно використовується як у документації з платформи, так і у розмовах щодо розробки API.
«Ми потребуємо операції шляху, яка приймає POST до
/users/і повертає новостворений об’єкт користувача»
«Існує три операції шляху на цьому маршрутизаторі — одна для переліку, одна для отримання за ID, і одна для видалення.»
** Декоратор шляху ** — декоратор Python ( @app.get(...), @router.post(...) тощо), розташований над функцією, щоб зареєструвати її як обробник операцій з шляхом. Декоратор повідомляє FastAPI, на який метод HTTP і шлях відповідає функція.
Не забувайте додавати декоратор маршруту над вашою функцією, інакше FastAPI не підбере його
«Я пересунув декоратор маршруту з головного додатка на виділений маршрутизатор, щоб ми могли під’єднати його з префіксом.»
** Параметр шляху ** — сегмент змінної, вбудований безпосередньо у шлях URL, оголошений у квадратних дужках: /items/{item_id}. FastAPI витягує значення і автоматично передає його до функції.
«Параметр шляху
{user_id}повинен точно відповідати аргументу функції, або FastAPI не введе його»
«Ми перейшли від параметра запиту до параметра шляху, тому що REST-конвенції очікують ідентифікатор ресурсу в самому URL.»
** Parameter Query ** — пара ключ- значення, додана до URL після ?, наприклад /items?skip=0&limit=10. Аргументи функції, які не є параметрами шляху і не оголошено у тілі запиту, розглядаються як параметри запиту у FastAPI.
«Додати параметр запиту
limitз типовим значенням 20, щоб кінцева точка не повертала всю таблицю»
«Фронт-енд передає фільтр як параметр запиту, але ми повинні перевірити його на стороні сервера з допомогою моделі Pydantic.»
** Речепті тіло ** — дані, надіслані у тілі HTTP- запиту, зазвичай у вигляді JSON. У FastAPI ви можете оголосити тіла запитів за допомогою анотації параметра функції за допомогою типу моделі Pydantic.
«Тело запиту повинно включати
password— обгорнути їх в Pydantic модель і type-hint параметр»
Наш мобільний клієнт відсилає тіло запиту як
application/json, тому не потрібно жодних змін на стороні FastAPI
Підтримка і підтримка моделей
Pydantic model — клас Python, який успадковує з pydantic.BaseModel і визначає форму і типи даних. FastAPI використовує моделі Pydantic для тіл запитів, моделей відповідей і керування параметрами. Pydantic автоматично перевіряє дані і повідомляє про явні помилки, якщо вхідні дані не відповідають схемі.
«Визначити Pydantic модель для вхідного вантажу, щоб ми отримали примус типу і перевірку безкоштовно.»
«Пюдантична модель для відповіді витягує геш пароля перед тим, як дані залишають сервер — це поведінка, яку ми хочемо»
** Перевірка полів ** — обмеження, застосовані до окремих полів у моделі Pydantic за допомогою Field(...), наприклад, мінімальна довжина, максимальне значення або шаблон регулярного виразу. Pydantic піднімає ValidationError, якщо дані порушують ці обмеження.
Додати перевірку поля до поля
username— без пробілів, між 3 і 30 символами
“Полевая проверка зафиксировала отрицательную цену до того, как она попала в базу данных. Саме тому ми використовуємо Pydantic»
** Модель відповіді ** — модель Pydantic, передана до декоратора маршруту за допомогою response_model=..., яка повідомляє FastAPI, у яку форму буде серіалізовано відповідь. Цей параметр фільтрує поля, які не оголошено у моделі, запобігаючи випадковому витоку даних.
«Встановити
response_model=UserPublicна цій кінцевій точці, щоб внутрішні поля, такі якhashed_password, ніколи не поверталися»
«Ми маємо окрему модель відповіді для адміністраторів, яка включає поля аудиту, які звичайна модель оминула»
Введення залежностей і середнє програмне забезпечення
** Введення залежностей ( Depends() ) ** — механізм у FastAPI, який надає вам змогу оголошувати спільну логіку (сеанси бази даних, перевірки автентифікації, завантаження налаштувань) як функції і автоматично вводити їх до обробників операцій шляху. Ви передаєте залежність до типового значення параметра за допомогою Depends(get_db).
“Замість того, щоб відкривати сеанс бази даних в кожному обробнику, витягніть його в залежність і введіть його з
Depends(get_db).”
«Автентифікаційна перевірка є залежністю, що може використовуватися повторно — просто додайте
current_user: User = Depends(get_current_user)до будь-якої кінцевої точки, яка її потребує»
** Міжпрограмне забезпечення ** — шар коду, який виконується перед і/ або після кожного запиту у програмі, незалежно від того, яка операція шляху обробляє його. Поширені способи використання включають ведення журналу, заголовки CORS, обмеження швидкості і відстеження запитів.
«Ми додали CORS middleware, щоб дозволити фронт-енд походження — без нього, браузер блокував кожен запит preflight.»
“Програма для розрахунку часу записує, скільки часу займає кожен запит. Це допомогло нам виявити, що одна кінцева точка була постійно повільною»
** Lifespan event ** — код, який виконується при запуску або закритті програми, оголошений за допомогою контекстного менеджера lifespan (або старих гачків on_event). Типовим використанням є з’ єднання з базою даних під час запуску і розірвання з’ єднань під час вимкнення.
«Пересунути ініціалізацію бази даних з’єднання в подію lifespan, щоб вона була готова до прибуття першого запиту»
«Подія lifespan на вимкненні закриває з’єднання Redis чисто — без неї ми бачили попередження в журналах виробництва»
Асинхронний Python і стек ASGI
** async def / await ** — ключові слова Python, які визначають і викликають співпрограми, що дозволяють неблокуючий вхід/вихід. У FastAPI ви можете визначити операції шляху з async def для обробки багатьох одночасних запитів на одному потоці без блокування роботи, пов’ язаної з вводом/ виведенням, наприклад, запитів на базу даних або викликів HTTP.
«Визначте обробник з
async defіawaitвикликом бази даних — блокування його синхронним драйвером перемагає мету»
«Ми змінили обробник завантаження файлів на
async defі поліпшення пропускної здатності під навантаженням було відразу помітно»
asyncio — стандартна бібліотека Python для написання одночасного коду за допомогою синтаксису async/await. FastAPI виконується на основі asyncio, отже розуміння концепції циклу подій допомагає під час зневадження перевиконання часу очікування або несподіваної поведінки блокування.
«Проблема була синхронним викликом
sleep()всередині функціїasync def— він блокував петлю подій asyncio для кожного іншого запиту»
«Перевірте asyncio docs на скасування завдання; ми повинні обробляти це граціозно у фоновому робітнику.»
** ASGI (Asynchronous Server Gateway Interface) ** — специфікація, яка визначає, як асинхронна веб- платформа Python взаємодіє з веб- сервером. ASGI є асинхронним наступником WSGI. FastAPI є фреймворком ASGI.
Оскільки це ASGI-сумісний, ви можете запустити FastAPI за будь-яким ASGI сервером — Uvicorn є найпоширенішим вибором
«Старе середнє програмне забезпечення WSGI, яке ви знайшли, не працюватиме тут; ми на ASGI, тому нам потрібен ASGI-сумісний замінник»
** Uvicorn / Gunicorn ** — Uvicorn — це легкий, високопродуктивний сервер ASGI, який використовується для запуску FastAPI у розробці і виробництві. Gunicorn — це менеджер процесів WSGI, який може керувати декількома робочими процесами Uvicorn у виробництві для кращого використання процесора.
Запустити
uvicorn main:app --reloadпід час розробки —--reloadфлаг перезапускає сервер при зміні файлу
«У виробництві ми використовуємо Gunicorn з класом робітників Uvicorn, тому ми отримуємо декілька процесів по всіх ядрах процесора»
** Автоматичное створення OpenAPI ** — FastAPI читає ваші операції з шляхами, моделі Pydantic і підказки типів і автоматично створює схему OpenAPI (раніше Swagger) на /openapi.json, разом з інтерактивною документацією на /docs і /redoc.
Одним з найбільших пунктів продажу є OpenAPI авто-генерування — команда фронт-енду може досліджувати API через
/docsбез читання вихідного коду
«Перевірка вірності опису маршруту в графі «Перевірка вірності маршруту» в OpenAPI» (англ.)
** Фонові завдання ** — робота, яку FastAPI відкладає до того часу, коли відповідь буде надіслано клієнту, за допомогою параметра BackgroundTasks. Корисно для надсилання електронних листів, запису журналів перевірки або запуску webhooks без змушування користувача чекати.
«Надіслання електронної пошти з підтвердженням є фоновим завданням — ми вводимо
BackgroundTasksі додаємо функцію send, тому API відповідає миттєво»
«Фонові завдання мають той же процес, що і основна програма, тому уникайте будь-чого, що вимагає багато процесорного часу; використовуйте правильну чергу завдань для важкої роботи»
** Автентифікація JWT у FastAPI** — звичайний шаблон, де клієнт надсилає JSON Web Token у заголовку Authorization: Bearer <token>, а залежність FastAPI декодує і перевіряє його, повертаючи поточного користувача. Бібліотека python-jose зазвичай використовується для кодування і декодування.
Залежність автентифікації JWT піднімає
HTTPException(401), якщо термін дії токена закінчився або підпис є недійсним
«Ми зберігаємо ідентифікатор користувача в JWT payload і шукаємо повний об’єкт користувача всередині залежності — зберігає токен малим»
Як використовувати ці терміни в розмові
Під час обговорення розробки інтерфейсу API з колегами, ви можете сказати:
«Я визначив модель відповіді, яка омиває внутрішні поля — в поєднанні з перевіркою поля на тілі запиту, кінцева точка безпечна на обох кінцях»
У коментарі перегляду коду:
“Ця логіка дублюється в трьох обробниках. Витягніть його як залежність і введіть його з
Depends()— це також зробить тестування блоків набагато простішим»
При поясненні швидкодії нетехнічним користувачам:
Оскільки API використовує ASGI і асинхронні def-обробники, він може обробляти тисячі одночасних з’єднань без підключення додаткових потоків або процесів
Таблиця швидких посилань
| Term | One-line definition |
|---|---|
| Path operation | HTTP method + URL pattern registered as a handler |
| Route decorator | Python decorator (@app.get) that registers a function as a handler |
| Pydantic model | Class that defines and validates the shape of data |
| Response model | Pydantic model that controls what fields are serialised in the response |
| Depends() | FastAPI’s dependency injection mechanism |
| Middleware | Code that runs before/after every request application-wide |
| Lifespan event | Startup/shutdown hooks for initialising or releasing resources |
| async def / await | Python keywords for writing non-blocking coroutines |
| ASGI | Async interface between Python web frameworks and servers |
| Background tasks | Work deferred until after the HTTP response is sent |
Вправляйтеся у використанні цих термінів у описах ваших запитів на звантаження і оновленнях. Чим більш природно вони прийдуть до вас у письмовій формі, тим більш впевнено вони з’ являться в усній розмові - чи це технічне інтерв’ ю, сесія парного програмування, або перегляд коду з новою командою.