This release is a pre-release and may not be stable for production use.
pyaio: asynchronous file I/O for Python on Linux
pyaio gives asyncio programs file reads, writes and fsyncs that don't block the event loop, backed by io_uring. It also still ships the original callback API on glibc POSIX AIO.
Warning: learning project, alpha quality. pyaio is a small, readable example of integrating io_uring with asyncio. It has not been audited, targets current kernels only, and its API may change.
Warning: io_uring has a long record of kernel security vulnerabilities. Many container runtimes and hardened systems disable it, and it can hide I/O from syscall-based security monitoring. Read SECURITY.md before enabling it on a machine you share or care about.
How it works, with diagrams: docs/architecture.md.
Requirements
- Linux 6.1 or newer with io_uring allowed, CPython 3.10+
- Building from source also needs the liburing headers (2.2 or newer:
liburing-devon Debian/Ubuntu 24.04+,liburing-develon Fedora,liburingon Arch).
Where pyaio does not run: there is no fallback. Creating a UringIO
raises OSError (with the reason) when io_uring is unavailable, which is
common in:
- containers using Docker's default seccomp profile, and most sandboxes;
- systems with
kernel.io_uring_disabledset (hardened or shared hosts); - kernels older than 6.1.
If your code has to run in those places, use a thread pool
(loop.run_in_executor with os.pread) or a library with fallbacks.
Install
pip install --pre pyaio # release candidates need --pre
Wheels for x86_64 and aarch64 bundle liburing, so nothing else is needed.
To build from source instead, install the liburing headers first
(tools/install-liburing.sh builds the
pinned version) and run pip install ..
Quick start
import asyncio
import os
from pyaio.uring import UringIO
async def main():
fd = os.open('/tmp/pyaio.txt', os.O_RDWR | os.O_CREAT, 0o644)
async with UringIO() as io:
await io.write_all(fd, b'hello io_uring', 0)
await io.fsync(fd)
data = await io.read(fd, 0, 5) # bytearray(b'hello')
chunks = await asyncio.gather( # one syscall for all four
*[io.read(fd, off, 4) for off in range(0, 16, 4)])
os.close(fd)
asyncio.run(main())
API
UringIO(entries=256, max_inflight=None) must be created inside a running
event loop and used from that loop's thread:
| Method | Result |
|---|---|
await io.read(fd, offset, nbytes) |
bytearray; shorter than nbytes at end of file, empty past it |
await io.write(fd, data, offset) |
bytes written, which can be short like os.pwrite |
await io.write_all(fd, data, offset) |
len(data); retries short writes |
await io.fsync(fd, datasync=False) |
0 |
await io.aclose(timeout=None) |
cancels outstanding work without blocking the loop |
io.close(timeout=None) |
the same, blocking the calling thread |
io.inflight, io.queued, io.closed |
introspection |
offset=-1means "current file position". Concurrent requests that use it run in no guaranteed order.- Errors raise the matching
OSErrorsubclass (FileNotFoundError,IsADirectoryError,BrokenPipeError, ...). - Cancelling the awaiting task cancels the kernel request. Pipes and sockets stop immediately; reads and writes on regular files the kernel has already started usually finish anyway, and their result is discarded.
- Backpressure: at most
max_inflightrequests (default2 * entries) are handed to the kernel at once. The rest wait in a queue without allocating buffers. - Close timeouts: if requests are still running when the timeout expires,
pyaio abandons them. Their futures fail with
ECANCELED, their buffers are leaked rather than freed (freeing memory the kernel may still write to would corrupt memory), and aResourceWarningis emitted. - Don't use a
UringIOin a child process afterfork(); create a new one there.
Limitations
- Only
read,writeandfsync. Noopen/stat/close, vectored I/O, registered buffers orO_DIRECTaligned buffers. - Kernel cancellation cannot interrupt disk I/O already in progress, so a close on a hung network filesystem waits until its timeout.
- The C extension relies on the GIL. On free-threaded Python builds the GIL is re-enabled when pyaio is imported.
- CI covers Python 3.10 to 3.14 on Linux 6.8 and 6.17 (GitHub's Ubuntu runners) with liburing 2.15.
Legacy POSIX AIO API (deprecated)
Deprecated since 0.5, removed in 0.6.
pyaio.aio_read,aio_writeandaio_initemit aDeprecationWarning. Move topyaio.uring.UringIO:aio_read(fd, offset, n, callback)becomesawait io.read(fd, offset, n)andaio_write(fd, buf, offset, callback)becomesawait io.write(fd, buf, offset). Errors raiseOSErrorinstead of arriving as anerrnoargument.
The original callback API uses glibc's POSIX AIO, which runs blocking I/O on a user-space thread pool (see the comparison). It is loaded only when first used.
import os
import time
import pyaio
def on_read(buf, rcode, errno):
if rcode > 0:
print('read', bytes(buf))
elif rcode == 0:
print('EOF')
else:
print('error', errno)
def on_write(rcode, errno):
print('wrote', rcode) if rcode >= 0 else print('error', errno)
fd = os.open('/tmp/pyaio.txt', os.O_RDWR)
pyaio.aio_read(fd, 0, 20, on_read) # fd, offset, length, callback
pyaio.aio_write(fd, b'data', 30, on_write) # fd, buffer, offset, callback
time.sleep(0.1) # callbacks run on the main thread while it executes Python
Wait for callbacks before queuing many more requests in a tight loop, or
pyaio may stall when glibc's AIO queue is full. Tune the pool with
pyaio.aio_init(max_threads, max_queue_size, max_thread_idle_seconds). pyaio
uses 5 * cores threads and 4 * threads queue entries when that is more
than glibc's default of 20 threads and 64 entries. An exception raised in a
callback is reported through sys.unraisablehook.
Development
python -m venv .venv && . .venv/bin/activate
pip install -e . pytest # builds the C extensions in place
python -m pytest
See CHANGELOG.md for release notes and RELEASING.md for the release process.
License
BSD-3-Clause. See LICENSE.
Metadata
Release files for pyaio 0.5.0rc2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyaio-0.5.0rc2.tar.gz | 35.5 kB | With provenance | Details for pyaio-0.5.0rc2.tar.gz |
Built distributions (wheels)
Total release size: 865.0 kB
Release files / pyaio-0.5.0rc2.tar.gz
| Download URL | pyaio-0.5.0rc2.tar.gz |
|---|---|
| Size | 35.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8dd5057681a395386aece374d6bfdcebf5738731ebb5cfdf288b8eb621b9f9d9
|
|
BLAKE2b-256 checksum How to use checksums |
a6c4c8f04f1163750c7cf76aa5fc9b575db45c2bfa0ef49a28924110ededc7c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyaio-0.5.0rc2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 80.9 kB |
| Tags | CPython 3.14 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
306c9a6a66f273e659300dcafc5e6d7c6e8ce0efc2a5940f026cfd27bc3324bd
|
|
BLAKE2b-256 checksum How to use checksums |
756932d20e5fd58d567342094ee0ac6ae32fd0ca580ce1ad1176778735c65e0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyaio-0.5.0rc2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 86.2 kB |
| Tags | CPython 3.14 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
3a6b13ced17b21639f8032b91dede12895ca2bab4990efa1fb3baaca34f89fe0
|
|
BLAKE2b-256 checksum How to use checksums |
0e382880c6b84a11c93897e8f6f775cc8bcd96582fe15bda651352a244629b1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyaio-0.5.0rc2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 81.0 kB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
cd5e94349c282c886ba8a606bcdf6fee4a7a8914e237b2d7c4e24294d1b441b1
|
|
BLAKE2b-256 checksum How to use checksums |
bdf732238d1ac4812f2eea7f679f70f70ccf03e5083bff687a90e4373579a17e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyaio-0.5.0rc2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 86.2 kB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
16d6ca8114fb3b99b9bffdba893b521200124bb65c1d30c20d5b6b2df1cabf72
|
|
BLAKE2b-256 checksum How to use checksums |
5e126612eebbbb1f47fb7f73c8c521685a102d380494fbe05e80cf6722d3e059
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyaio-0.5.0rc2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 80.9 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
a9a051a4bc4bd258c6a2b87c64fa2895f64c64c45eba85792200396f73ae957f
|
|
BLAKE2b-256 checksum How to use checksums |
14b21d5c967a248b98b46513c68453e2816d67e839e6598dc9392d0e32a36e3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyaio-0.5.0rc2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 86.1 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
e32ea74aba74d4a499a67a3724841e058ad7200c8b28e7a5f57588c6fab23571
|
|
BLAKE2b-256 checksum How to use checksums |
748d0c20f016225a2c9b7d5f62b2fd5764a4f1f3b0e6c61d89666cc831b1e87f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyaio-0.5.0rc2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 79.9 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
d98db6cfe3d12b7677a6078fc76fb15ccf1b11286b45d223ddeadb3c2e62fa3e
|
|
BLAKE2b-256 checksum How to use checksums |
3cb3abc5604c915c839c87c9dbb7d26b9749339c335b140d55af1698ba37cd8f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyaio-0.5.0rc2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 85.5 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
145fc0ee161e385d6f022095b63179c5a23c39582a18052bcc327d1a58a5fca2
|
|
BLAKE2b-256 checksum How to use checksums |
76322eaad6f76cc463eeb9e765f154cfde3dccf25c2c668678a0d7d5155ccf4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyaio-0.5.0rc2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 78.6 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
3b92e072546f366604a8f3448f2d8f96bd4edd28585a30e0b2e5c7326bdc1374
|
|
BLAKE2b-256 checksum How to use checksums |
f3fced47af95c74ca5deba54c5871949e9c4718f5ead8aa5e4f32c986d1c7443
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pyaio-0.5.0rc2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyaio-0.5.0rc2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 84.2 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
62a1d675f038df166a3311cb10023be1063ec0320e18f5d95306bb2ad84f5f8d
|
|
BLAKE2b-256 checksum How to use checksums |
ea07ff3387aba50fc6ec3ec4cdf752499b155c3eceeec5c3f36db013a3f51c47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logSecurity for pyaio 0.5.0rc2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 11 files in this release have been uploaded with provenance metadata.
Attestation for pyaio-0.5.0rc2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.