Metadata-Version: 2.4
Name: blazio
Version: 0.1.0
Summary: A drop-in asyncio event loop for CPython, backed by zio.ev
Author-email: Lukas Lalinsky <lalinsky@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/lalinsky/blazio
Project-URL: Repository, https://github.com/lalinsky/blazio
Keywords: asyncio,event-loop,io_uring,zio,uvloop
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# blazio

A drop-in [asyncio] event loop for CPython, backed by **[zio.ev]** — the
completion-based event loop from [zio] (io_uring on Linux, kqueue and IOCP
elsewhere). Like [uvloop], but on zio.ev instead of libuv, and with real
asynchronous file I/O.

```python
import asyncio
import blazio

async def main():
    reader, writer = await asyncio.open_connection("example.com", 80)
    writer.write(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
    await writer.drain()
    print(await reader.read())
    writer.close()

asyncio.run(main(), loop_factory=blazio.new_event_loop)
```

That `loop_factory` argument is the only change; the rest of your program is
standard `asyncio`.

## Async files

`blazio.open()` is an `aiofiles`-compatible API over zio.ev's file completions —
real asynchronous file I/O, not a thread pool.

```python
async with blazio.open("access.log") as f:
    async for line in f:
        ...
```

Seekable files also support positional `pread`/`pwrite`.

## Performance

About 1.15x uvloop on transport-based HTTP. Measured on one Linux machine
(io_uring, CPython 3.12, `ReleaseFast`): 20 s `wrk` runs after a 30 s settle,
100 connections. `benchmarks/` reproduces them.

Both drive the Transport/Protocol layer, which is what real servers (uvicorn,
aiohttp, asyncio streams) run on. The low-level `loop.sock_*` API is a separate
path that the three loops optimize very differently, so it is not benchmarked
here.

`benchmarks/mini_http_server.py` — a minimal `Protocol` writing a fixed 1 KB
response, with no framework in the path, so this is close to raw loop overhead:

| loop    |    req/s | p50    | p90    |
|---------|---------:|-------:|-------:|
| asyncio |  101,428 | 0.91ms | 1.03ms |
| uvloop  |  127,036 | 0.74ms | 0.81ms |
| blazio  |  144,781 | 0.64ms | 0.88ms |

`benchmarks/uvicorn_server.py` — the same response through uvicorn. Most of each
request is now framework Python that every loop pays equally, so all three drop
sharply while the ratio between them holds:

| loop    |   req/s | p50    | p90    |
|---------|--------:|-------:|-------:|
| asyncio |  23,501 | 4.02ms | 4.27ms |
| uvloop  |  41,596 | 2.29ms | 2.35ms |
| blazio  |  48,274 | 1.74ms | 2.53ms |

## Install

```bash
pip install git+https://github.com/lalinsky/blazio
```

Requires CPython 3.12 or newer and [Zig] 0.16 on `PATH`.

From a checkout, with the tests:

```bash
pip install .
python -m pytest tests/
```

## License

MIT. See [LICENSE](LICENSE).

[asyncio]: https://docs.python.org/3/library/asyncio.html
[zio]: https://github.com/lalinsky/zio
[zio.ev]: https://github.com/lalinsky/zio/tree/main/src/ev
[uvloop]: https://github.com/MagicStack/uvloop
[Zig]: https://ziglang.org/
