How do I pass an async function to a thread target in Python?
Question:
I have the following code:
async some_callback(args):
await some_function()
and I need to give it to a Thread as a target:
_thread = threading.Thread(target=some_callback, args=("some text"))
_thread.start()
The error that I get is "some_callback
is never awaited".
Any ideas how can I solve this problem?
Answers:
You can do it by adding function between to execute async:
async def some_callback(args):
await some_function()
def between_callback(args):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(some_callback(args))
loop.close()
_thread = threading.Thread(target=between_callback, args=("some text"))
_thread.start()
As of Python 3.7, you can use asyncio.run()
which is a bit more straightforward than loop.run_until_complete()
:
_thread = threading.Thread(target=asyncio.run, args=(some_callback("some text"),))
_thread.start()
Didn’t quite work for me, if you are trying to let it run next to your code (example: discord wait for emote reaction aswell as add emotes), you could try to use:
asyncio.get_event_loop().create_task(FUNKTION(ARGUMENT))
Just wrap your async function with this method and run the thread. _target is name of function in string and **args all your args. in addition to Norbeck solution
def middleware_callback(**args,_target):
_proc = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
_proc.run_until_complete(getattr(sys.modules[__name__], _target)(**args)
_proc.close()
After Python 3.7, you can use asyncio.run()
import asyncio
import threading
async def some_callback(args):
await some_function()
def wrap_async_func(args):
asyncio.run(some_callback(args))
_thread = threading.Thread(target=wrap_async_func, args=("some text"))
_thread.start()
I have the following code:
async some_callback(args):
await some_function()
and I need to give it to a Thread as a target:
_thread = threading.Thread(target=some_callback, args=("some text"))
_thread.start()
The error that I get is "some_callback
is never awaited".
Any ideas how can I solve this problem?
You can do it by adding function between to execute async:
async def some_callback(args):
await some_function()
def between_callback(args):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(some_callback(args))
loop.close()
_thread = threading.Thread(target=between_callback, args=("some text"))
_thread.start()
As of Python 3.7, you can use asyncio.run()
which is a bit more straightforward than loop.run_until_complete()
:
_thread = threading.Thread(target=asyncio.run, args=(some_callback("some text"),))
_thread.start()
Didn’t quite work for me, if you are trying to let it run next to your code (example: discord wait for emote reaction aswell as add emotes), you could try to use:
asyncio.get_event_loop().create_task(FUNKTION(ARGUMENT))
Just wrap your async function with this method and run the thread. _target is name of function in string and **args all your args. in addition to Norbeck solution
def middleware_callback(**args,_target):
_proc = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
_proc.run_until_complete(getattr(sys.modules[__name__], _target)(**args)
_proc.close()
After Python 3.7, you can use asyncio.run()
import asyncio
import threading
async def some_callback(args):
await some_function()
def wrap_async_func(args):
asyncio.run(some_callback(args))
_thread = threading.Thread(target=wrap_async_func, args=("some text"))
_thread.start()