API Reference

Functions

@asyncify.asyncify_func

This can be used as a decorator.

Make a synchronous function into an asynchronous function by running it in a separate thread.

Example

import asyncify
import requests

@asyncify.asyncify_func
def get(url):
    return requests.get(url).text

# `get` is no longer a blocking function
# it is now a coroutine function

async def main():
    text = await get('https://python.org')

# this is very useful to turn a blocking library into an async library
get = asyncify.asyncify_func(requests.get)

Note

This function uses the default loop executor. Change it with loop.set_default_executor.

Raises:

TypeError – The object passed in was not a function.


@asyncify.syncify_func

This can be used as a decorator.

Make an asynchronous function a synchronous function.

Example

import asyncio
import asyncify

@asyncify.syncify_func
async def coroutine_func():
    await asyncio.sleep(5)
    print('Done')

coroutine_func()  # can be directly called

Note

This is equivalent to the following:

loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine_func())

Warning

There must be a running event loop to call it.

Raises:

TypeError – The object passed was not a coroutine function.


class asyncify.taskify_func(func)

This can be used as a decorator.

Create an asyncio task whenever you call the function!

New in version 2.0.

Example

import asyncio
import asyncify

@asyncify.taskify_func
async def sleep_then_print():
    await asyncio.sleep(5)
    print('Done sleeping!')

async def main():
    task = sleep_then_print():
    print(task) #  <class '_asyncio.Task'>

    # you can even use this as a normal coroutine function
    await sleep_then_print()

Warning

There must be a running event loop to call it.

Raises:

TypeError – The object passed was not a coroutine function.

@default_done_callback

This can be used as a decorator.

Add a callback to be added to the tasks done callbacks with add_done_callback.

remove_default_done_callback(name)

Remove a done callback that would be added to the task.

Parameters:

name (str) – The name of the callback.


Classes

@asyncify.asyncify_class

This can be used as a decorator. Turn a classes methods into async functions. This uses asyncify.asyncify_func().

Example

import asyncify
import requests

@asyncify.asyncify_class
@asyncify.class_include('request', 'get')
class RequestsClient:
    def __init__(self):  # ignored by asyncify
        self.session = requests.Session()

    def request(self, method, url):  # now a coroutine function
        return self.session.request(method, url)

    def get(self, url):
        return self.session.get(url)  # also a coroutine function

client = RequestsClient()

async def main():
    await client.request('GET', 'https://python.org')
    await client.get(...)
Raises:
  • TypeError – The object passed was not a class or both asyncify and asyncify_ignore were passed.

  • ValueErrorclass_include() and class_exclude() were both used.


@asyncify.class_include

This can be used as a decorator.

Select certain methods to be asyncified. All other methods will be ignored.

Parameters:
  • method_names (str) – The methods to asyncify.

  • note:: (..) – This decorator is meant to be used directly on the class.


@asyncify.class_exclude

This can be used as a decorator.

Select certain methods to not be asyncified. All other methods will be asyncified.

Parameters:

method_names (str) – The methods to not asyncify.

Note

This decorator is meant to be used directly on the class.


@asyncify.ignore

This can be used as a decorator.

Ignore a function in a class when using asyncify.asyncify_class().

Deprecated since version 2.1: Use class_exclude() instead.


Iterables

class asyncify.AsyncIterable(iterable, *, before=None, after=None)

Asynchronously iterate through an iterable while calling an async callback before and/or after each iteration.

Changed in version 2.0: Changed from function async_iter to class AsyncIterable

Parameters:
  • iterable (Iterable) – The iterable to iterator over.

  • before (Optional[async_function]) – An optional asynchronous callable for before the iteration.

  • after (Optional[async_function]) – An optional asynchronous callable for after the iteration.

Note

before and after must not take any parameters.

Warning

before will be called once more than after due to not knowing when to stop iterating until after before is called.

Example

import asyncio
import functools
import asyncify

async def main():
    sleep = functools.partial(asyncio.sleep, 1)

    async for number in asyncify.AsyncIterable([1, 2, 3], before=sleep):
        print(f'{number} seconds have passed.')
Raises:

TypeError – The object passed was not an iterable.

async flatten()

Return a list from the result of iterating through the iterable. This still calls before and after.

Return type:

List

property iterator

The current object that is being used for iteration.

Return type:

Optional[Iterator]


Events

class asyncify.EventsEventLoopPolicy(*args, **kwargs)

Call a functions whenever certain things happen in asyncio! This is done using the event loop policy.

Example

import asyncio
import asyncify

policy = asyncify.EventsEventLoopPolicy()

@policy.event
def new_event_loop():
    print('New event loop being created.')

asyncio.set_event_loop_policy(policy)

async def main():
    ...

asyncio.run(main())  # prints 'New event loop being created.'
# asyncio.run creates an event loop with `new_event_loop`

Warning

asyncio.get_event_loop won’t call its event if there is a running and set event loop.

New in version 1.1.

@event

This can be used as a decorator.

Register a function to be called when an event loop policy method is called. The name of the functions should match the event loop policy method. The valid names are get_event_loop, set_event_loop, new_event_loop, get_child_watcher, and set_child_watcher.

Example

@policy.event
def new_event_loop():
    print('New event loop being created.')

Note

Using it multiple times on the same method will overwrite the old one.

Raises:
  • TypeErrorfunc is not a callable.

  • RuntimeError – The name either is invalid.

classmethod change_base_policy(policy_cls)

The actual things the event loop policy does are based on your platform. The default base loop policy is asyncio.DefaultLoopPolicy but can be changed.

Parameters:

policy_cls (Type[asyncio.AbstractEventLoopPolicy]) – This class must inherit from asyncio.AbstractEventLoopPolicy.

This example uses uvloop.

Example

import asyncio
import asyncify
import uvloop

asyncify.EventsEventLoopPolicy.change_base_policy(uvloop.EventLoopPolicy)

policy = asyncify.EventsEventLoopPolicy()

@policy.event
def new_event_loop():
    ...

loop = asyncio.new_event_loop()
print(loop)  # <uvloop.Loop running=False closed=False debug=False>
Raises:

TypeErrorpolicy_cls does not inherit from asyncio.AbstractEventLoopPolicy.

remove_event(name)

Remove an event from the callbacks that would be called.

Parameters:

name (class:str) – The name of the event.

Raises:

RuntimeErrorname is not a registered event.


Sleep

async asyncify.sleep_until(until)

Sleep until a certain time.

New in version 1.3.

Parameters:

until (datetime.datetime) – The time to sleep until.

Raises:

TypeErroruntil is not datetime.datetime.


async asyncify.today_sleep_until(hours=None, minutes=None, seconds=None)

Sleep until a certain time. The difference between this and sleep_until() is that this only sleeps within the current day.

New in version 1.3.

Parameters:
  • hours (Optional[int]) – The hours in the time.

  • minutes (Optional[int]) – The minutes in the time.

  • seconds (Optional[int]) – The seconds in the time.

Raises:

TypeError – No arguments were provided.

Example

import asyncify

async def main():
    await asyncify.today_sleep_until(hours=9, minutes=30)  # sleeps until 9:30 AM

Note

24 hour time is also supported.


Hybrid

class asyncify.HybridFunction(name, sync_callback, async_callback)

Do multiple things depending on whether it was awaited or not! Credit to a user Andy in the python discord server for the regex.

Changed in version 2.0: Changed from function hybrid_function to class HybridFunction

Parameters:
  • name (str) – The name of the new function. This must be the same as the function name to work.

  • sync_callback (Callable[..., Any]) – The callable to call if it is not awaited.

  • async_callback (Callable[..., Coroutine]) – The callable to call if it is awaited.

Example

import asyncify
import discord  # discord.py example

class Client(discord.Client):
    get_or_fetch_user = asyncify.HybridFunction(
                        'get_or_fetch_user',
                         discord.Client.get_user,
                         discord.Client.fetch_user
    )

client = Client()

client.get_or_fetch_user(739510612652195850)  # sync cache lookup
await client.get_or_fetch_user(739510612652195850)  # async api call

Warning

Make the to name the function uniquely. Functions with the same name could be called unexpectedly.


Threads

class asyncify.ThreadCoroutineExecutor(wait=False)

Run coroutines in separate threads easily!

New in version 2.0.

Parameters:

wait (bool) – Whether to wait for all tasks to finish before exiting context manager. Defaults to False.

Example

import asyncify
from aioconsole import aexec

async def main():
    async with asyncify.ThreadCoroutineExecutor(wait=True) as thread:
        while True:
            code = input('Type code here: ')
            # if code is 'import time; time.sleep(5); print('Done') it will block the event loop
            # the solution is to run it in a separate thread
            thread.execute(aexec(code))
close()

Close the event loop and the thread will join the main thread.

Warning

If this is called manually, all tasks will be cancelled regardless of if wait is True. The async with context manager is meant to wait for the tasks.

execute(coro)

Execute a coroutine within the thread.

Parameters:

coro (Coroutine) – The coroutine to execute. It must be a coroutine.

Return type:

asyncio.Future

is_running()

Whether the event loop is running in the thread.

Return type:

bool

start()

Start the thread and its event loop.

Note

It is recommended to use async with instead.