PyAwaitable is the only library to support writing and calling asynchronous Python functions from pure C code (with the exception of manually implementing an awaitable class from scratch, which is essentially what PyAwaitable does).
It was originally designed to be directly part of CPython--you can read the scrapped PEP about it. Since this library only uses the public ABI, it's better fit outside of CPython, as a library.
Add it to your project's build process:
# pyproject.toml example with setuptools
[build-system]
requires = ["setuptools", "pyawaitable"]
build-backend = "setuptools.build_meta"
Include it in your extension:
from setuptools import setup, Extension
import pyawaitable
if __name__ == "__main__":
setup(
...,
ext_modules=[Extension(..., include_dirs=[pyawaitable.include()])]
)
#include <pyawaitable.h>
/* Usage from Python: await my_async_function(coro()) */
static PyObject *
my_async_function(PyObject *self, PyObject *coro) {
/* Make our awaitable object */
PyObject *awaitable = PyAwaitable_New();
/* Mark the coroutine for being awaited */
PyAwaitable_AddAwait(awaitable, coro, NULL, NULL);
/* Return the awaitable object to yield to the event loop */
return awaitable;
}
pyawaitable
is distributed under the terms of the MIT license.