Spaces:
Running
Running
File size: 1,051 Bytes
8e48995 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | """
Utilities for safely running async callables from synchronous code.
"""
import asyncio
from concurrent.futures import ThreadPoolExecutor
from typing import Any, Awaitable, Callable, TypeVar
T = TypeVar("T")
def _run_coroutine(async_fn: Callable[..., Awaitable[T]], *args: Any, **kwargs: Any) -> T:
"""Run an async callable in a fresh event loop."""
return asyncio.run(async_fn(*args, **kwargs))
def run_async_from_sync(
async_fn: Callable[..., Awaitable[T]],
*args: Any,
**kwargs: Any,
) -> T:
"""
Execute an async callable from sync code.
If no loop is running in the current thread, run directly with ``asyncio.run``.
If a loop is already running, execute in a dedicated worker thread with its own loop.
"""
try:
asyncio.get_running_loop()
except RuntimeError:
return _run_coroutine(async_fn, *args, **kwargs)
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(_run_coroutine, async_fn, *args, **kwargs)
return future.result()
|