import functools import asyncio from concurrent.futures import ThreadPoolExecutor def to_async(func): """Turns a sync function to async function using event loop""" @functools.wraps(func) async def run(*args, loop=None, executor=None, **kwargs): if loop is None: loop = asyncio.get_event_loop() pfunc = functools.partial(func, *args, **kwargs) return await loop.run_in_executor(executor, pfunc) return run def to_async_thread(fn): """Turns a sync function to async function using threads""" pool = ThreadPoolExecutor() @functools.wraps(fn) def wrapper(*args, **kwargs): future = pool.submit(fn, *args, **kwargs) return asyncio.wrap_future(future) # make it awaitable return wrapper def to_sync(fn): """Turns an async function to sync function""" @functools.wraps(fn) def wrapper(*args, **kwargs): res = fn(*args, **kwargs) if asyncio.iscoroutine(res): return asyncio.get_event_loop().run_until_complete(res) return res return wrapper