https://github.com/zerointensity/pyawaitable
Call asynchronous code from an extension module.
https://github.com/zerointensity/pyawaitable
abi async async-functions asynchronous asynchronous-functions c c-api c-coroutines coroutines cpython-api extension extension-module python
Last synced: about 2 months ago
JSON representation
Call asynchronous code from an extension module.
- Host: GitHub
- URL: https://github.com/zerointensity/pyawaitable
- Owner: ZeroIntensity
- License: mit
- Created: 2024-04-16T13:56:10.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-03-23T13:44:59.000Z (about 2 months ago)
- Last Synced: 2025-03-28T16:45:18.696Z (about 2 months ago)
- Topics: abi, async, async-functions, asynchronous, asynchronous-functions, c, c-api, c-coroutines, coroutines, cpython-api, extension, extension-module, python
- Language: C
- Homepage: https://awaitable.zintensity.dev
- Size: 3.11 MB
- Stars: 42
- Watchers: 3
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# PyAwaitable
## Call asynchronous code from an extension module
[](https://github.com/ZeroIntensity/pyawaitable/actions/workflows/build.yml)
- [Docs](https://pyawaitable.zintensity.dev)
- [Source](https://github.com/ZeroIntensity/pyawaitable)
- [PyPI](https://pypi.org/project/pyawaitable)## What is it?
PyAwaitable is the _only_ library to support defining and calling asynchronous Python functions from pure C code.
It was originally designed to be directly part of CPython; you can read the [scrapped PEP](https://gist.github.com/ZeroIntensity/8d32e94b243529c7e1c27349e972d926) about it. But, since this library only uses the public ABI, it's better fit outside of CPython, as a library.
## Installation
Add it to your project's build process:
```toml
# pyproject.toml example with setuptools
[build-system]
requires = ["setuptools", "pyawaitable"]
build-backend = "setuptools.build_meta"
```Include it in your extension:
```py
from setuptools import setup, Extension
import pyawaitableif __name__ == "__main__":
setup(
...,
ext_modules=[Extension(..., include_dirs=[pyawaitable.include()])]
)
```## Example
```c
/*
Equivalent to the following Python function:async def async_function(coro: collections.abc.Awaitable) -> None:
await coro*/
static PyObject *
async_function(PyObject *self, PyObject *coro)
{
// Create our transport between the C world and the asynchronous world.
PyObject *awaitable = PyAwaitable_New();
if (awaitable == NULL) {
return NULL;
}// Mark our Python coroutine, *coro*, for being executed by the event loop.
if (PyAwaitable_AddAwait(awaitable, coro, NULL, NULL) < 0) {
Py_DECREF(awaitable);
return NULL;
}// Return our transport, allowing *coro* to be eventually executed.
return awaitable;
}
```## Copyright
`pyawaitable` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.