Skip to main content

...

Project description

Test status PyPI - Downloads

Liburing

Liburing is Python + Cython wrapper around C Liburing, which is a helper to setup and tear-down io_uring instances.

  • Fast & scalable asynchronous I/O (storage, networking, …) interface.

  • io_uring reduces number of syscalls overhead & context switches, thus improving speed.

Good(old) documentation Lord of the io_uring

Check out Shakti. It uses liburing and provides an easy to use Python async await Interface.

Requires

  • Linux 6.1+ (6.7+ recommended)

  • Python 3.8+

Includes (battery)

  • C liburing 2.5+

Install, update & uninstall (Alpha)

Use pip to install, upgrade & uninstall Python wrapper:

python3 -m pip install liburing             # install

python3 -m pip install --upgrade liburing   # upgrade

python3 -m pip uninstall liburing           # uninstall

Install directly from GitHub:

python3 -m pip install --upgrade git+https://github.com/YoSTEALTH/Liburing

To find out all the class, functions and definitions:

import liburing

print(dir(liburing))  # to see all the importable names (this will not load all the modules)
help(liburing)        # to see all the help docs (this will load all the modules.)

Find out which io_uring operations is supported by the kernel:

# example/probe.py
import liburing

probe = liburing.probe()
print(probe)

Simple File Example

# example/open_write_read_close.py
from liburing import O_CREAT, O_RDWR, AT_FDCWD, iovec, io_uring, io_uring_get_sqe, \
                     io_uring_prep_openat, io_uring_prep_write, io_uring_prep_read, \
                     io_uring_prep_close, io_uring_submit, io_uring_wait_cqe, \
                     io_uring_cqe_seen, io_uring_cqe, io_uring_queue_init, \
                     io_uring_queue_exit, trap_error


def open(ring, cqes, path, flags, mode=0o660, dir_fd=AT_FDCWD):
    _path = path if isinstance(path, bytes) else str(path).encode()
    # if `path` is relative and `dir_fd` is `AT_FDCWD`, then `path` is relative
    # to current working directory. Also `_path` must be in bytes

    sqe = io_uring_get_sqe(ring)  # sqe(submission queue entry)
    io_uring_prep_openat(sqe, dir_fd, _path, flags, mode)
    return _submit_and_wait(ring, cqes)  # returns fd


def write(ring, cqes, fd, data, offset=0):
    iov = iovec(data)  # or iovec([bytearray(data)])
    sqe = io_uring_get_sqe(ring)
    io_uring_prep_write(sqe, fd, iov.iov_base, iov.iov_len, offset)
    return _submit_and_wait(ring, cqes)  # returns length(s) of bytes written


def read(ring, cqes, fd, length, offset=0):
    iov = iovec(bytearray(length))  # or [bytearray(length)]
    sqe = io_uring_get_sqe(ring)
    io_uring_prep_read(sqe, fd, iov.iov_base, iov.iov_len, offset)
    _submit_and_wait(ring, cqes)  # get actual length of file read.
    return iov.iov_base


def close(ring, cqes, fd):
    sqe = io_uring_get_sqe(ring)
    io_uring_prep_close(sqe, fd)
    _submit_and_wait(ring, cqes)  # no error means success!


def _submit_and_wait(ring, cqes):
    io_uring_submit(ring)  # submit entry
    io_uring_wait_cqe(ring, cqes)  # wait for entry to finish
    result = trap_error(cqes.res)  # auto raise appropriate exception if failed
    # note `cqe.res` returns results, if ``< 0`` its an error, if ``>= 0`` its the value

    # done with current entry so clear it from completion queue.
    io_uring_cqe_seen(ring, cqes)
    return result  # type: int


def main():
    ring = io_uring()
    cqes = io_uring_cqe()
    try:
        io_uring_queue_init(8, ring, 0)

        fd = open(ring, cqes, '/tmp/liburing-test-file.txt', O_CREAT | O_RDWR)
        print('fd:', fd)

        length = write(ring, cqes, fd, b'hello world')
        print('wrote:', length)

        content = read(ring, cqes, fd, length)
        print('read:', content)

        close(ring, cqes, fd)
        print('closed.')
    finally:
        io_uring_queue_exit(ring)


if __name__ == '__main__':
    main()

Note

  • Try not to use from liburing import * this will load all the modules at once, unless that’s what you want!

Cython Note

  • You can cimport liburing directly into your project if you are planning on compiling your project as well.

  • There is also src/liburing/lib directory with raw .pxd header files.

  • All raw C wrapped function, enum, struct, defines starts with __, not including anything that’s ctypedef. This is to prevent naming confusion between whats C and Cython side.

  • liburing must be included in both build-system.requires and project.dependencies in pyproject.toml to compile and use properly.

  • Check out Shakti to see how to include liburing using cython.

TODO

  • Stable Release (currently still in alpha)

  • Linux 6.1 Backwards compatibility.

License

Free, Public Domain (CC0). Read more

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

liburing-2024.4.22.tar.gz (117.1 kB view details)

Uploaded Source

File details

Details for the file liburing-2024.4.22.tar.gz.

File metadata

  • Download URL: liburing-2024.4.22.tar.gz
  • Upload date:
  • Size: 117.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for liburing-2024.4.22.tar.gz
Algorithm Hash digest
SHA256 8bf1d233b38c6c6e8524e3a46e50241c0aebd268e6537b2cb9df6d6605a0f5da
MD5 20ad5f083ea98e56611873e4ad5661ba
BLAKE2b-256 9b592cd6d1f96976695dc6252293fc53f3b582706968e73c9c7853e95502760c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page