В предишни статии разгледахме как да създаваме цялостни уеб приложения с Django и RESTful APIs с FastAPI. Днес ще се гмурнем по-дълбоко в концепциите на асинхронното програмиране и как те се използват във FastAPI, за да постигнем забележителна производителност и мащабируемост. Ще обясним какво представлява ASGI и как FastAPI използва нейните възможности за пълноценно асинхронно обслужване на заявки. Нека да започваме!

Какво е ASGI?

ASGI (Asynchronous Server Gateway Interface) е спецификация, която дефинира стандартен интерфейс между асинхронни уеб сървъри, фреймуърци и приложения в Python екосистемата. Тя е еволюция на по-ранната WSGI (Web Server Gateway Interface) спецификация, която се фокусира върху синхронното обработване на заявките.

Основната идея зад ASGI е да позволи на уеб сървърите да обслужват множество заявки едновременно, без да блокират изпълнението на приложението. Това се постига чрез използване на асинхронни функции и корутини, които могат да бъдат прекъснати и възобновени, докато чакат за входно-изходни операции като достъп до мрежата или базата данни.

ASGI дефинира три ключови компонента:

  1. Server: Отговорен за приемане на входящи заявки от клиентите и препредаване към приложението.
  2. Protocol: Дефинира формата на съобщенията, разменяни между сървъра и приложението (например HTTP, WebSocket).
  3. Application: Асинхронна Python функция или обект, която обработва заявките и връща отговори.

Когато заявка пристигне на сървъра, тя се опакова в ASGI съобщение и се препраща към приложението. Приложението обработва съобщението асинхронно, извършва необходимите операции и връща отговор обратно към сървъра, който го препраща към клиента.

ASGI сървъри и фреймуърци

Въпреки че ASGI е само спецификация, съществуват множество конкретни имплементации на ASGI сървъри и уеб фреймуърци, които я използват. Някои популярни примери включват:

  • Uvicorn: Високопроизводителен ASGI сървър, базиран на uvloop и httptools.
  • Hypercorn: ASGI сървър, насочен към максимална съвместимост и стабилност.
  • Daphne: Първият ASGI сървър, първоначално разработен за Django Channels.
  • Starlette: Лек и бърз ASGI фреймуърк, върху който е изграден FastAPI.
  • Quart: ASGI уеб микрофреймуърк с API, подобен на Flask.

Тези инструменти работят заедно, за да осигурят пълноценна асинхронна обработка на заявките, от мрежовия слой до приложението. Те позволяват на Python разработчиците да изграждат мащабируеми и отзивчиви приложения, използвайки съвременни асинхронни концепции.

FastAPI и ASGI

FastAPI е модерен, бърз (високопроизводителен) Python уеб фреймуърк за изграждане на APIs с Python 3.6+ въз основа на стандартни Python type hints. Той е изграден директно върху Starlette и напълно използва неговата ASGI основа.

Ето как FastAPI използва силата на ASGI за ефективна обработка на заявките:

  • Асинхронни route функции: В FastAPI можем да дефинираме route функции като async def, което ги прави асинхронни. Това означава, че те могат да използват await за чакане на други асинхронни операции (напр. достъп до база данни) без да блокират изпълнението на сървъра.

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    item = await get_item_from_db(item_id)
    return item
  • Асинхронни dependancies: FastAPI въвежда концепцията за dependancies – функции, които се инжектират като параметри в route функциите и могат да извършват общи задачи като проверка на автентикацията, обработка на база данни и др. Тези dependancies също могат да бъдат асинхронни:

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = await decode_access_token(token)
    return user

@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user
  • Асинхронни контекстни мениджъри: FastAPI приложенията могат да използват асинхронни контекстни мениджъри за управление на ресурси като връзки към бази данни. Това гарантира, че ресурсите се придобиват и освобождават правилно при всяка заявка:

from fastapi import FastAPI
from databases import Database

app = FastAPI()
database = Database("sqlite:///db.sqlite3")

@app.on_event("startup")
async def startup():
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

@app.get("/users")
async def read_users():
    query = "SELECT * FROM users"
    results = await database.fetch_all(query)
    return results

Чрез използването на тези асинхронни техники на всички нива – от route функциите до dependancies и управлението на ресурси – FastAPI приложенията могат напълно да използват потенциала на ASGI за едновременна обработка на голям брой заявки без блокиране или закъснения.

Предимства на асинхронно програмиране с ASGI и FastAPI

Изграждането на асинхронни уеб приложения с ASGI и FastAPI носи много предимства по отношение на производителността, мащабируемостта и ефективността на ресурсите:

      1. Увеличена конкурентност: Асинхронните сървъри като Uvicorn могат да обработват хиляди едновременни заявки дори само с един CPU процес. Това позволява ефективно използване на системните ресурси и намалява режийните разходи от управление на множество нишки или процеси.
      2. Намалено забавяне: Чрез избягване на блокиращи операции, асинхронните приложения могат да обслужват заявките с минимално закъснение дори при голям брой едновременни клиенти. Това води до по-добра UX и отзивчивост на приложението.
      3. Подобрена мащабируемост: ASGI приложенията могат лесно да се мащабират хоризонтално чрез разпределяне на натоварването между множество процеси или машини. Асинхронната архитектура позволява ефективно използване на ресурсите и минимизира претоварването на всеки отделен възел.
      4. Съвместимост с други асинхронни библиотеки: FastAPI и Starlette са изградени върху стандартни Python асинхронни примитиви като async/await и могат лесно да се интегрират с други асинхронни библиотеки от екосистемата като aiohttp, asyncpg, и т.н. Това позволява изграждането на цялостни асинхронни приложения от край до край.

Разбира се, асинхронното програмиране не е универсално решение и не е подходящо за всеки сценарий. То добавя допълнителна сложност и има определени предизвикателства като управление на състоянието и дебъгване. Но за много видове уеб приложения, особено тези с голям брой заявки IO, ползите от производителността могат да бъдат огромни.

Заключение

В тази статия изследвахме ролята на ASGI в развитието на асинхронен уеб стек в Python и как FastAPI използва тези възможности за изграждане на високопроизводителни и мащабируеми приложения. Видяхме как асинхронните техники на всички нива на приложението могат да доведат до значителни ползи за производителността и UX.

ASGI и инструменти като FastAPI са важна стъпка напред за Python уеб екосистемата, позволявайки на разработчиците да използват пълния потенциал на асинхронните концепции, без неудобствата на ниско-нивово програмиране. С мощта и простотата на тези инструменти, изграждането на модерни, мащабируеми уеб приложения с Python е по-лесно от всякога.

И така, ако търсите върхова производителност и мащабируемост за вашето следващо уеб приложение, помислете за използване на FastAPI и силата на ASGI. Възможностите са вълнуващи и екосистемата непрекъснато се развива.

Last Update: май 3, 2024