Функция Python, совместимая с синхронным и асинхронным клиентомPython

Программы на Python
Ответить Пред. темаСлед. тема
Гость
 Функция Python, совместимая с синхронным и асинхронным клиентом

Сообщение Гость »


Я разрабатываю библиотеку, которая должна поддерживать синхронизацию и асинхронность пользователей, сводя при этом к минимуму дублирование кода внутри библиотеки. Идеальным вариантом была бы реализация асинхронной библиотеки (поскольку библиотека выполняет удаленные вызовы API) и добавление поддержки синхронизации с помощью оболочки или что-то в этом роде. Рассмотрим следующую функцию как часть библиотеки.

Код: Выделить всё

# Library code

async def internal_function():
"""Internal part of my library doing HTTP call"""
pass
My idea was to provide a wrapper that detects if the users of the library use async or not.

Код: Выделить всё

# Library code

def api_call():
"""Public api of my library"""
if asyncio.get_event_loop().is_running():
# Async caller
return internal_function()  # This returns a coroutine, so the caller needs to await it

# Sync caller, so we need to run the coroutine in a blocking way
return asyncio.run(internal_function())
At first, this seemed to be the solution. With this I can support
  • users that call the function from an async function,
  • users that call the function from a notebook (that's also async), and
  • users that call the function from a plain python script (here it falls back to the blocking

    Код: Выделить всё

    asyncio.run
    ).
However, there are cases when the function is called from within an event loop, but the direct caller is a sync function.

Код: Выделить всё

# Code from users of the library

async def entrypoint():
"""This entrypoint is called in an event loop, e.g. within fastlib"""
return legacy_sync_code()  # Call to sync function

def legacy_sync_code():
"""Legacy code that does not support async"""
# Call to library code from sync function,
# expect value not coroutine, could not use await
api_response = api_call()
return api_response.json()  # Needs to be value, not coroutine
In the last line, the call of fails.

Код: Выделить всё

api_call()
wrongly inferrs that the caller can await the response, and returns the coroutine.
In order to support these kind of users, I would need to
  • identify if the direct calling function is sync and expects a value instead of a corouting,
  • have a way to await the result of

    Код: Выделить всё

    internal_function()
    in a blocking way. Using

    Код: Выделить всё

    asyncio.run
    does only work in plain python scripts and fails if the code was called form an event loop higher up in the stack trace.
The first point could be mitigated if my library provided two functions, e.g.,

Код: Выделить всё

api_call_async()
and

Код: Выделить всё

api_call_sync()
.
I hope I make my point clear enough. I don't see way this should be fundamentally impossible, however, I can accept if the design of Python does not allow me to support sync and async users in a completely transparent way.


Источник: https://stackoverflow.com/questions/781 ... ync-client
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • LangChain + локальная модель, совместимая с LLAMA
    Anonymous » » в форуме Python
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • Матрица в виде сетки, совместимая с d3.js и эффектами перехода строк
    Anonymous » » в форуме CSS
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Boost::asio-совместимая ожидаемая переменная условия
    Anonymous » » в форуме C++
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • Интеграция, совместимая с Openssl 3.0.8, в iOS
    Anonymous » » в форуме IOS
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Интеграция OpenSSL 3.0.8, совместимая с FIPS, в iOS
    Anonymous » » в форуме IOS
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»