Как создать синхронную версию async API

#python #asynchronous

#python #асинхронный

Вопрос:

Я разрабатываю API, который я хотел бы сделать асинхронным. С другой стороны, я все равно хотел бы сохранить простую в использовании синхронную версию. Есть ли простой способ добиться этого?

Я представляю себе что-то вроде декоратора, который автоматически генерирует блокирующие оболочки для моих async def методов.

Ответ №1:

Можно создать декоратор, который просто создает цикл событий каждый раз, когда вы хотите запустить асинхронную функцию, но это добавляет много накладных расходов и путаницы.

Другой распространенной практикой является создание клиента, который может принимать транспорт, таким образом, вы можете просто выбрать синхронизацию транспорта или асинхронность, например, этот проект https://github.com/aio-libs/aioelasticsearch , который принимает синхронизацию elasticsearch pkg, но добавляет асинхронный транспорт, который вы можете использовать с ним.

Или официальное решение elasticsearch для использования async с их pkg https://elasticsearch-py.readthedocs.io/en/master/async.html

В любом случае, если вы спросите меня, я думаю, что лучше придерживаться одной вещи: если ваш проект выигрывает от асинхронности, просто сохраните клиент асинхронным.

Ответ №2:

Для запуска асинхронной функции требуется цикл событий, который контролирует выполнение.

Просто рассмотрите каждую асинхронную функцию, которую вы хотите преобразовать, как отдельную программу. То, о чем вы просите, — это запустить асинхронную программу.

 # async version:
await asyncfunc(arg1, arg2, ...)

# sync version:
asyncio.run(asyncfunc(arg1, arg2, ...))
  

Написание такого декоратора должно быть простым.

Конечно, накладные расходы велики.