"
As join() always returns None..."
join() вообще никогда не возвращает ничего кроме None.
Лучше сообщить потоку, куда он должен поместить результат.
Например, так
def thread_body(arg, target):
result = "foo" + arg
target.append(result)
def call_thread(arg):
target = []
th = threading.Thread(target=thread_body, args=(arg, target))
th.start()
th.join()
return target[0]
Но этот код синхронный. У тебя, насколько я вижу, асинхронная программа, и th.join() её заблокирует.
Может иметь смысл либо использовать
run_in_executor(), либо переделать thread_body() на асинхронный код (если это возможно).
Экзекутор сам создаст за тебя поток, к слову. Пример по ссылке.
Чтобы получить объект loop, в котором работает твоя async-функция, используй
asyncio.get_running_loop().