import asyncio


def from_coroutine(cls, coroutine, scheduler=None, loop=None):
    """
    Generate observable from an asynchronous coroutine.

    :param coroutine: Coroutine to wrap as observable.
    :param scheduler: (Optional) scheduler to determine the event loop.
    :param loop: (Optional) Event loop. Has higher precedence than scheduler.
    """

    # Get the current event loop.
    if loop is None:
        loop = asyncio.get_event_loop()
    elif scheduler is not None:
        loop = scheduler.loop

    task = loop.create_task(coroutine)
    return cls.from_future(task)