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()

Answered By: norbeq

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()
Answered By: mckbrd

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))
Answered By: InternetNutzer

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()
Answered By: Awais khan

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()
Answered By: eric xu
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.