import asyncio
import functools


def aio_run(func):
    """
    Decorate an async function to run as a normal blocking function.

    The async function will be executed in the currently running event
    loop (or automatically create one if none exists).

    Example:

    .. code-block::
        async def coroutine(timeout):
            await asyncio.sleep(timeout)
            return True

        @aio_run
        async def runner(*args, **kwargs):
            return await coroutine(*args, **kwargs)

        # Call coroutine in a blocking manner
        result = runner(timeout=1.0)
        print(result)
    """
    def _wrapper(*args, **kwargs):
        loop = asyncio.get_event_loop()
        return loop.run_until_complete(func(*args, **kwargs))
    return functools.update_wrapper(_wrapper, func)