If a third-party library is not compatible with async/await
then obviously you can’t use it easily. There are two cases:
-
Let’s say that the function in the library is asynchronous and it gives you a callback, e.g.
def fn(..., clb): ...
So you can do:
def on_result(...): ... fn(..., on_result)
In that case you can wrap such functions into the asyncio protocol like this:
from asyncio import Future def wrapper(...): future = Future() def my_clb(...): future.set_result(xyz) fn(..., my_clb) return future
(use
future.set_exception(exc)
on exception)Then you can simply call that wrapper in some
async
function withawait
:value = await wrapper(...)
Note that
await
works with anyFuture
object. You don’t have to declarewrapper
asasync
. -
If the function in the library is synchronous then you can run it in a separate thread (probably you would use some thread pool for that). The whole code may look like this:
import asyncio import time from concurrent.futures import ThreadPoolExecutor # Initialize 10 threads THREAD_POOL = ThreadPoolExecutor(10) def synchronous_handler(param1, ...): # Do something synchronous time.sleep(2) return "foo" # Somewhere else async def main(): loop = asyncio.get_event_loop() futures = [ loop.run_in_executor(THREAD_POOL, synchronous_handler, param1, ...), loop.run_in_executor(THREAD_POOL, synchronous_handler, param1, ...), loop.run_in_executor(THREAD_POOL, synchronous_handler, param1, ...), ] await asyncio.wait(futures) for future in futures: print(future.result()) with THREAD_POOL: loop = asyncio.get_event_loop() loop.run_until_complete(main())
If you can’t use threads for whatever reason then using such a library simply makes entire asynchronous code pointless.
Note however that using synchronous library with async is probably a bad idea. You won’t get much and yet you complicate the code a lot.