FastAPI — это современная, быстрая (высокопроизводительная) веб-инфраструктура для создания API-интерфейсов с Python 3.7+ на основе стандартных подсказок типа Python. FastAPI очень популярен благодаря поддержке асинхронности. И поскольку асинхронность в Python — это гораздо более новая концепция, в производственных средах могут возникнуть некоторые проблемы при работе с часто используемыми API.

При вызове вызовов блокировки синхронизации в асинхронных представлениях основной поток замораживается и снижается RPS (запрос в секунду) и параллелизм. Для этого вы можете использовать неасинхронные представления только с ключевым словом def func() или, если очень важно использовать асинхронные представления, скажем, вам нужно также вызвать асинхронный вызов в вашем представлении. . В этот раз вы можете использовать run_in_threadpool FastAPI, который в свою очередь использует AnyIO .to_thread.run_sync. Что он делает, так это создает новый поток или использует один из потоков и выполняет там вызов синхронизации, а затем возвращает ответ из этого потока, и из-за этого вы не блокируете основной поток. Давайте проведем несколько тестов.

Наш код выглядит так:

@app.get("/")
async def read_root():
    logging.warning('Started')
    time.sleep(1)
    logging.warning('Finished')
    return {"Hello": "World"}

Как видите, он выполняет только 1 RPS и обрабатывает второй запрос после завершения первого. Давайте не будем тестировать пример run_in_threadpool.

from fastapi.concurrency import run_in_threadpool

@app.get("/")
async def read_root():
    logging.warning('Started')
    await run_in_threadpool(time.sleep,1)
    logging.warning('Finished')
    return {"Hello": "World"}

Да, мы получили то, что хотели. Теперь все запросы обрабатываются практически одновременно с высокой степенью параллелизма.

Не забудьте подписаться, чтобы получать уведомления о новых статьях