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.
ValueError –
class_include()
andclass_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`
Note
asyncify.EventsEventLoopPolicy
inherits from asyncio.DefaultEventLoopPolicy unless changed withasyncify.EventsEventLoopPolicy.change_base_policy()
.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
, andset_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:
TypeError – func 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:
TypeError – policy_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:
RuntimeError – name 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:
TypeError – until 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 toFalse
.
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
isTrue
. Theasync 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.