Created
March 29, 2022 07:07
-
-
Save tiagocoutinho/2dbd4fcf63c72cf57e99b9269b5e2ad2 to your computer and use it in GitHub Desktop.
Python sync to async
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
import inspect | |
import functools | |
def async_(fn): | |
""" | |
Wrap the given function into a coroutine function. | |
If the function returns a coroutine, that coroutine is awaited and its | |
value will be the return value. Otherwise the initial return value will | |
be the return value. | |
""" | |
if inspect.iscoroutinefunction(fn): | |
return fn | |
@functools.wraps(fn) | |
async def wrapper(*args, **kwargs): | |
result = fn(*args, **kwargs) | |
if inspect.iscoroutine(result): | |
result = await result | |
return result | |
return wrapper | |
def async_concurrent(fn): | |
""" | |
Ensure function is converted into coroutine function. | |
Coroutine functions are left untouched. | |
Regular functions are executed in the default asyncio thread pool. | |
It won't work for regular functions that return a coroutine since that coroutine will be | |
created in another thread (and therefore another event loop) and cannot be await by the | |
calling thread. | |
""" | |
if inspect.iscoroutinefunction(fn): | |
return fn | |
@functools.wraps(fn) | |
async def wrapper(*args, **kwargs): | |
return await asyncio.to_thread(fn, *args, **kwargs) | |
return wrapper |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment