Skip to content

asyncify

asyncify ⚓︎

Asyncify

Functions⚓︎

asyncify.aiorun_anyio(awaitable_or_func: Union[Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]], *args: object, backend: str = 'asyncio', backend_options: Optional[Dict[str, Any]] = None) -> T_Retval ⚓︎

Run an async function or awaitable using anyio

Parameters:

Name Type Description Default
awaitable_or_func Union[Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]]

Function or awaitable to run

required
*args object

args to pass to the function

()
backend str

Backend to use for running the function

'asyncio'
backend_options Optional[Dict[str, Any]]

Options to pass to the backend

None

Returns:

Name Type Description
T_Retval T_Retval

Return value of the function

Source code in libs/asyncify/asyncify/core.py
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
def aiorun_anyio(
    awaitable_or_func: Union[
        Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]
    ],
    *args: object,
    backend: str = "asyncio",
    backend_options: Optional[Dict[str, Any]] = None,
) -> T_Retval:
    """Run an async function or awaitable using anyio

    Args:
        awaitable_or_func: Function or awaitable to run
        *args: args to pass to the function
        backend: Backend to use for running the function
        backend_options: Options to pass to the backend

    Returns:
        T_Retval: Return value of the function

    """
    if is_coro(awaitable_or_func):
        if args:
            raise ValueError("args must be empty when calling a coroutine")

        def _aw() -> Coroutine[Any, Any, T_Retval]:
            return cast(Coroutine[Any, Any, T_Retval], awaitable_or_func)

        return anyio_run(_aw, backend=backend, backend_options=backend_options)
    return anyio_run(
        cast(Callable[..., Coroutine[Any, Any, T_Retval]], awaitable_or_func),
        *args,
        backend=backend,
        backend_options=backend_options,
    )

asyncify.aiterable(it: Union[Iterable[T], AsyncIterable[T]]) -> AsyncIterator[T] ⚓︎

Convert any-iterable to an async iterator

Examples:

>>> from os import remove
>>> from asyncio import run
>>> plain_jane_list = list(range(10))
>>> async def consume_aiterable(it):
...     stuff = []
...     async for el in aiterable(it):
...         stuff.append(el)
...     return stuff
>>> run(consume_aiterable(plain_jane_list))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> async def async_gen():
...     for b in range(10):
...        yield b
>>> run(consume_aiterable(async_gen()))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> class AsyncIterable:
...     def __aiter__(self):
...         return async_gen()
>>> run(consume_aiterable(AsyncIterable()))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Source code in libs/asyncify/asyncify/core.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def aiterable(it: Union[Iterable[T], AsyncIterable[T]]) -> AsyncIterator[T]:
    """Convert any-iterable to an async iterator

    Examples:
        >>> from os import remove
        >>> from asyncio import run
        >>> plain_jane_list = list(range(10))
        >>> async def consume_aiterable(it):
        ...     stuff = []
        ...     async for el in aiterable(it):
        ...         stuff.append(el)
        ...     return stuff
        >>> run(consume_aiterable(plain_jane_list))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> async def async_gen():
        ...     for b in range(10):
        ...        yield b
        >>> run(consume_aiterable(async_gen()))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> class AsyncIterable:
        ...     def __aiter__(self):
        ...         return async_gen()
        >>> run(consume_aiterable(AsyncIterable()))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    """
    if isinstance(it, AsyncIterator):
        return it

    if isinstance(it, AsyncIterable):
        return it.__aiter__()

    async def gen() -> AsyncIterator[T]:
        for item in it:
            yield item

    return gen()

asyncify.asyncify(funk: Callable[P, T], *, loop: Optional[AbstractEventLoop] = None, executor: Optional[Any] = None) -> Callable[P, Awaitable[T]] ⚓︎

Makes a sync function async

Parameters:

Name Type Description Default
funk Callable[P, T]

Function to make into an async coroutine

required
loop Optional[AbstractEventLoop]

Event loop in which to run/execute

None
executor Optional[Any]

Executor to with which to execute

None

Returns:

Type Description
Callable[P, Awaitable[T]]

An asynchronous function

Examples:

>>> from asyncify import asyncify
>>> def add(a, b):
...     return a + b
>>> add(1, 5)
6
>>> @asyncify
... def add_async(a, b):
...     return a + b
>>> from asyncio import run
>>> run(add_async(1, 5))
6
Source code in libs/asyncify/asyncify/core.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def asyncify(
    funk: Callable[P, T],
    *,
    loop: Optional[AbstractEventLoop] = None,
    executor: Optional[Any] = None,
) -> Callable[P, Awaitable[T]]:
    """Makes a sync function async

    Args:
        funk: Function to make into an async coroutine
        loop: Event loop in which to run/execute
        executor: Executor to with which to execute

    Returns:
        An asynchronous function

    Examples:
        >>> from asyncify import asyncify
        >>> def add(a, b):
        ...     return a + b
        >>> add(1, 5)
        6
        >>> @asyncify
        ... def add_async(a, b):
        ...     return a + b
        >>> from asyncio import run
        >>> run(add_async(1, 5))
        6

    """
    _loop = loop
    _executor = executor

    @wraps(funk)
    async def _async_funk(
        *args: P.args,
        **kwargs: P.kwargs,
    ) -> T:
        """Async wrapper function

        Args:
            *args: args to pass
            loop: Event loop in which to run/execute
            executor: Executor to with which to execute
            **kwargs: keyword arguments to be passed to the wrapped function

        Returns:
            An asynchronous coroutine

        """
        loop = _loop if _loop else get_event_loop()
        pfunc: Callable[[], T] = partial(funk, *args, **kwargs)
        return await loop.run_in_executor(_executor, pfunc)

    return cast(Callable[P, Awaitable[T]], _async_funk)

asyncify.await_or_return(obj: Union[Awaitable[T], T]) -> T async ⚓︎

Return the result of an awaitable or return the object

Examples:

>>> from asyncify import await_or_return, run
>>> def add(a, b): return a + b
>>> run(await_or_return(add(1, 4)))
5
>>> async def add_(a, b): return a + b
>>> run(await_or_return(add_(1, 4)))
5
Source code in libs/asyncify/asyncify/core.py
267
268
269
270
271
272
273
274
275
276
277
278
279
280
async def await_or_return(obj: Union[Awaitable[T], T]) -> T:
    """Return the result of an awaitable or return the object

    Examples:
        >>> from asyncify import await_or_return, run
        >>> def add(a, b): return a + b
        >>> run(await_or_return(add(1, 4)))
        5
        >>> async def add_(a, b): return a + b
        >>> run(await_or_return(add_(1, 4)))
        5

    """
    return cast(T, await obj if isawaitable(obj) else obj)

asyncify.is_async(obj: Any) -> bool ⚓︎

Return True if function/object is async/awaitable

Parameters:

Name Type Description Default
obj Any

Object (probably a function) that could be async

required

Returns:

Name Type Description
bool bool

True if the object is async/awaitable; False otherwise

Examples:

>>> from asyncify import is_async
>>> def add(a, b): return a + b
>>> is_async(add)
False
>>> async def add_(a, b): return a + b
>>> is_async(add_)
True
Source code in libs/asyncify/asyncify/core.py
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
def is_async(obj: Any) -> bool:
    """Return True if function/object is async/awaitable

    Args:
        obj: Object (probably a function) that could be async

    Returns:
        bool: True if the object is async/awaitable; False otherwise

    Examples:
        >>> from asyncify import is_async
        >>> def add(a, b): return a + b
        >>> is_async(add)
        False
        >>> async def add_(a, b): return a + b
        >>> is_async(add_)
        True

    """
    return asyncio.iscoroutinefunction(obj) or asyncio.iscoroutine(obj)

asyncify.run(aw: Coroutine[Any, Any, T], *, debug: Optional[bool] = None, **kwargs: Any) -> T ⚓︎

Run an async/awaitable function (Polyfill asyncio.run)

Emulate asyncio.run() for snakes below python 3.7; asyncio.run was added in python3.7.

Parameters:

Name Type Description Default
aw Awaitable[T]

Async/awaitable function to run

required
debug Optional[bool]

If True run event loop in debug mode

None
**kwargs Any

keyword arguments to be passed to the wrapped function

{}

Returns:

Name Type Description
T T

Return the result of running the async function

Examples:

>>> async def add(a, b):
...     return a + b
...
>>> from asyncify.core import run
>>> run(add(1, 4))
5
Source code in libs/asyncify/asyncify/core.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
def run(
    aw: Coroutine[Any, Any, T], *, debug: Optional[bool] = None, **kwargs: Any
) -> T:
    """Run an async/awaitable function (Polyfill asyncio.run)

    Emulate `asyncio.run()` for snakes below python 3.7; `asyncio.run` was
    added in python3.7.

    Args:
        aw (Awaitable[T]): Async/awaitable function to run
        debug (Optional[bool]): If True run event loop in debug mode
        **kwargs: keyword arguments to be passed to the wrapped function

    Returns:
        T: Return the result of running the async function

    Examples:
        >>> async def add(a, b):
        ...     return a + b
        ...
        >>> from asyncify.core import run
        >>> run(add(1, 4))
        5

    """
    # If python is 3.6
    if not hasattr(asyncio, "run"):  # pragma: no cover
        warnings.warn(
            "asyncify no longer supports python3.6...",
            DeprecationWarning,
            stacklevel=2,
        )
        return _run(aw, debug=debug)
    return asyncio_run(aw, debug=debug)

Modules⚓︎

asyncify.__about__ ⚓︎

Package metadata/info

asyncify.__main__ ⚓︎

pkg entry ~ python -m asyncify

Functions⚓︎
asyncify.__main__.main() -> None ⚓︎

Print package metadata

Source code in libs/asyncify/asyncify/__main__.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def main() -> None:
    """Print package metadata"""
    import json

    sys.stdout.write(
        json.dumps(
            {
                "package": __title__,
                "version": __version__,
                "pkgroot": __pkgroot__,
            },
            indent=2,
        )
    )

asyncify.aios ⚓︎

aios = asyncio + os

Functions⚓︎

asyncify.core ⚓︎

Asyncify core

Functions⚓︎
asyncify.core.aiorun_anyio(awaitable_or_func: Union[Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]], *args: object, backend: str = 'asyncio', backend_options: Optional[Dict[str, Any]] = None) -> T_Retval ⚓︎

Run an async function or awaitable using anyio

Parameters:

Name Type Description Default
awaitable_or_func Union[Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]]

Function or awaitable to run

required
*args object

args to pass to the function

()
backend str

Backend to use for running the function

'asyncio'
backend_options Optional[Dict[str, Any]]

Options to pass to the backend

None

Returns:

Name Type Description
T_Retval T_Retval

Return value of the function

Source code in libs/asyncify/asyncify/core.py
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
def aiorun_anyio(
    awaitable_or_func: Union[
        Awaitable[T_Retval], Callable[..., Coroutine[Any, Any, T_Retval]]
    ],
    *args: object,
    backend: str = "asyncio",
    backend_options: Optional[Dict[str, Any]] = None,
) -> T_Retval:
    """Run an async function or awaitable using anyio

    Args:
        awaitable_or_func: Function or awaitable to run
        *args: args to pass to the function
        backend: Backend to use for running the function
        backend_options: Options to pass to the backend

    Returns:
        T_Retval: Return value of the function

    """
    if is_coro(awaitable_or_func):
        if args:
            raise ValueError("args must be empty when calling a coroutine")

        def _aw() -> Coroutine[Any, Any, T_Retval]:
            return cast(Coroutine[Any, Any, T_Retval], awaitable_or_func)

        return anyio_run(_aw, backend=backend, backend_options=backend_options)
    return anyio_run(
        cast(Callable[..., Coroutine[Any, Any, T_Retval]], awaitable_or_func),
        *args,
        backend=backend,
        backend_options=backend_options,
    )
asyncify.core.aiterable(it: Union[Iterable[T], AsyncIterable[T]]) -> AsyncIterator[T] ⚓︎

Convert any-iterable to an async iterator

Examples:

>>> from os import remove
>>> from asyncio import run
>>> plain_jane_list = list(range(10))
>>> async def consume_aiterable(it):
...     stuff = []
...     async for el in aiterable(it):
...         stuff.append(el)
...     return stuff
>>> run(consume_aiterable(plain_jane_list))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> async def async_gen():
...     for b in range(10):
...        yield b
>>> run(consume_aiterable(async_gen()))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> class AsyncIterable:
...     def __aiter__(self):
...         return async_gen()
>>> run(consume_aiterable(AsyncIterable()))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Source code in libs/asyncify/asyncify/core.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def aiterable(it: Union[Iterable[T], AsyncIterable[T]]) -> AsyncIterator[T]:
    """Convert any-iterable to an async iterator

    Examples:
        >>> from os import remove
        >>> from asyncio import run
        >>> plain_jane_list = list(range(10))
        >>> async def consume_aiterable(it):
        ...     stuff = []
        ...     async for el in aiterable(it):
        ...         stuff.append(el)
        ...     return stuff
        >>> run(consume_aiterable(plain_jane_list))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> async def async_gen():
        ...     for b in range(10):
        ...        yield b
        >>> run(consume_aiterable(async_gen()))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> class AsyncIterable:
        ...     def __aiter__(self):
        ...         return async_gen()
        >>> run(consume_aiterable(AsyncIterable()))
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    """
    if isinstance(it, AsyncIterator):
        return it

    if isinstance(it, AsyncIterable):
        return it.__aiter__()

    async def gen() -> AsyncIterator[T]:
        for item in it:
            yield item

    return gen()
asyncify.core.asyncify(funk: Callable[P, T], *, loop: Optional[AbstractEventLoop] = None, executor: Optional[Any] = None) -> Callable[P, Awaitable[T]] ⚓︎

Makes a sync function async

Parameters:

Name Type Description Default
funk Callable[P, T]

Function to make into an async coroutine

required
loop Optional[AbstractEventLoop]

Event loop in which to run/execute

None
executor Optional[Any]

Executor to with which to execute

None

Returns:

Type Description
Callable[P, Awaitable[T]]

An asynchronous function

Examples:

>>> from asyncify import asyncify
>>> def add(a, b):
...     return a + b
>>> add(1, 5)
6
>>> @asyncify
... def add_async(a, b):
...     return a + b
>>> from asyncio import run
>>> run(add_async(1, 5))
6
Source code in libs/asyncify/asyncify/core.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def asyncify(
    funk: Callable[P, T],
    *,
    loop: Optional[AbstractEventLoop] = None,
    executor: Optional[Any] = None,
) -> Callable[P, Awaitable[T]]:
    """Makes a sync function async

    Args:
        funk: Function to make into an async coroutine
        loop: Event loop in which to run/execute
        executor: Executor to with which to execute

    Returns:
        An asynchronous function

    Examples:
        >>> from asyncify import asyncify
        >>> def add(a, b):
        ...     return a + b
        >>> add(1, 5)
        6
        >>> @asyncify
        ... def add_async(a, b):
        ...     return a + b
        >>> from asyncio import run
        >>> run(add_async(1, 5))
        6

    """
    _loop = loop
    _executor = executor

    @wraps(funk)
    async def _async_funk(
        *args: P.args,
        **kwargs: P.kwargs,
    ) -> T:
        """Async wrapper function

        Args:
            *args: args to pass
            loop: Event loop in which to run/execute
            executor: Executor to with which to execute
            **kwargs: keyword arguments to be passed to the wrapped function

        Returns:
            An asynchronous coroutine

        """
        loop = _loop if _loop else get_event_loop()
        pfunc: Callable[[], T] = partial(funk, *args, **kwargs)
        return await loop.run_in_executor(_executor, pfunc)

    return cast(Callable[P, Awaitable[T]], _async_funk)
asyncify.core.await_or_return(obj: Union[Awaitable[T], T]) -> T async ⚓︎

Return the result of an awaitable or return the object

Examples:

>>> from asyncify import await_or_return, run
>>> def add(a, b): return a + b
>>> run(await_or_return(add(1, 4)))
5
>>> async def add_(a, b): return a + b
>>> run(await_or_return(add_(1, 4)))
5
Source code in libs/asyncify/asyncify/core.py
267
268
269
270
271
272
273
274
275
276
277
278
279
280
async def await_or_return(obj: Union[Awaitable[T], T]) -> T:
    """Return the result of an awaitable or return the object

    Examples:
        >>> from asyncify import await_or_return, run
        >>> def add(a, b): return a + b
        >>> run(await_or_return(add(1, 4)))
        5
        >>> async def add_(a, b): return a + b
        >>> run(await_or_return(add_(1, 4)))
        5

    """
    return cast(T, await obj if isawaitable(obj) else obj)
asyncify.core.is_async(obj: Any) -> bool ⚓︎

Return True if function/object is async/awaitable

Parameters:

Name Type Description Default
obj Any

Object (probably a function) that could be async

required

Returns:

Name Type Description
bool bool

True if the object is async/awaitable; False otherwise

Examples:

>>> from asyncify import is_async
>>> def add(a, b): return a + b
>>> is_async(add)
False
>>> async def add_(a, b): return a + b
>>> is_async(add_)
True
Source code in libs/asyncify/asyncify/core.py
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
def is_async(obj: Any) -> bool:
    """Return True if function/object is async/awaitable

    Args:
        obj: Object (probably a function) that could be async

    Returns:
        bool: True if the object is async/awaitable; False otherwise

    Examples:
        >>> from asyncify import is_async
        >>> def add(a, b): return a + b
        >>> is_async(add)
        False
        >>> async def add_(a, b): return a + b
        >>> is_async(add_)
        True

    """
    return asyncio.iscoroutinefunction(obj) or asyncio.iscoroutine(obj)
asyncify.core.run(aw: Coroutine[Any, Any, T], *, debug: Optional[bool] = None, **kwargs: Any) -> T ⚓︎

Run an async/awaitable function (Polyfill asyncio.run)

Emulate asyncio.run() for snakes below python 3.7; asyncio.run was added in python3.7.

Parameters:

Name Type Description Default
aw Awaitable[T]

Async/awaitable function to run

required
debug Optional[bool]

If True run event loop in debug mode

None
**kwargs Any

keyword arguments to be passed to the wrapped function

{}

Returns:

Name Type Description
T T

Return the result of running the async function

Examples:

>>> async def add(a, b):
...     return a + b
...
>>> from asyncify.core import run
>>> run(add(1, 4))
5
Source code in libs/asyncify/asyncify/core.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
def run(
    aw: Coroutine[Any, Any, T], *, debug: Optional[bool] = None, **kwargs: Any
) -> T:
    """Run an async/awaitable function (Polyfill asyncio.run)

    Emulate `asyncio.run()` for snakes below python 3.7; `asyncio.run` was
    added in python3.7.

    Args:
        aw (Awaitable[T]): Async/awaitable function to run
        debug (Optional[bool]): If True run event loop in debug mode
        **kwargs: keyword arguments to be passed to the wrapped function

    Returns:
        T: Return the result of running the async function

    Examples:
        >>> async def add(a, b):
        ...     return a + b
        ...
        >>> from asyncify.core import run
        >>> run(add(1, 4))
        5

    """
    # If python is 3.6
    if not hasattr(asyncio, "run"):  # pragma: no cover
        warnings.warn(
            "asyncify no longer supports python3.6...",
            DeprecationWarning,
            stacklevel=2,
        )
        return _run(aw, debug=debug)
    return asyncio_run(aw, debug=debug)