Pyjo-Reactor-Uvloop
Low level event reactor with uvloop support for Pyjoyment.
Pyjo.Reactor.Uvloop is Pyjo.Reactor.Asyncio with an event loop of its own
of uvloop, the event loop of asyncio on libuv, so that the servers of
Pyjoyment, daemon, prefork and prethread, and the blocking requests of
its user agent run on uvloop, with coroutines, tasks and the libraries of
asyncio along with them.
Installation
From PyPI, with Pyjoyment and uvloop, which it depends on, on Linux and macOS, with CPython:
pip install Pyjo-Reactor-Uvloop
or, in a project managed with uv:
uv add Pyjo-Reactor-Uvloop
The development version is installed from the Git repository:
pip install git+https://github.com/pyjoyment/Pyjo-Reactor-Uvloop
Usage
Select the reactor with PYJO_REACTOR before Pyjo.IOLoop is loaded:
PYJO_REACTOR=Pyjo.Reactor.Uvloop python myapp.py daemon
PYJO_REACTOR=Pyjo.Reactor.Uvloop python myapp.py prefork
The reactor takes the event loop that is running, as Pyjo.Reactor.Asyncio
does, so an ASGI server on uvloop, as uvicorn --loop uvloop or
hypercorn --worker-class uvloop, runs a Pyjoyment application on uvloop
with the default reactor already, and needs no reactor of uvloop.
Examples
examples/hello_world_uvloop.py runs Pyjo.HelloWorld on the server of
Pyjoyment on uvloop until the signal INT or TERM, in a with block,
which closes the listen sockets of the server at its end:
import os
# The reactor of Pyjoyment on uvloop, selected before Pyjo.IOLoop is loaded
os.environ['PYJO_REACTOR'] = 'Pyjo.Reactor.Uvloop'
import Pyjo.HelloWorld # noqa: E402
import Pyjo.Server.Daemon # noqa: E402
# The server of Pyjoyment on uvloop, until the signal INT or TERM, which closes its listen sockets at the end of the block
with Pyjo.Server.Daemon.new(app=Pyjo.HelloWorld.new(), listen=['http://*:3000']) as daemon:
daemon.run()
$ python examples/hello_world_uvloop.py
Web application available at http://127.0.0.1:3000
$ curl http://127.0.0.1:3000/
Your Pyjo is working!
examples/asyncio_uvloop.py is a coroutine on the loop of uvloop, which
requests the server of Pyjoyment in the same loop with the streams of asyncio
and with the user agent of Pyjoyment, as the libraries of asyncio run along
with the reactor:
import os
# The reactor of Pyjoyment on uvloop, selected before Pyjo.IOLoop is loaded
os.environ['PYJO_REACTOR'] = 'Pyjo.Reactor.Uvloop'
import Pyjo.HelloWorld # noqa: E402
import Pyjo.IOLoop # noqa: E402
import Pyjo.Server.Daemon # noqa: E402
import Pyjo.UserAgent # noqa: E402
import asyncio # noqa: E402
import uvloop # noqa: E402
# A coroutine on the loop of uvloop, with the streams of asyncio and the user agent of Pyjoyment, both requesting the
# server of Pyjoyment in the same loop
async def main(port):
reader, writer = await asyncio.open_connection('127.0.0.1', port)
writer.write(b'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n')
print(f'asyncio: {(await reader.readline()).decode().strip()}')
writer.close()
await writer.wait_closed()
with Pyjo.UserAgent.new() as ua:
tx = await ua.get_p(f'http://127.0.0.1:{port}/')
print(f'Pyjo.UserAgent: {tx.res.code} {tx.res.text}')
return 'uvloop' if isinstance(asyncio.get_running_loop(), uvloop.Loop) else 'asyncio'
# The server, on a port that the system picks, which closes its listen sockets at the end of the block
with Pyjo.Server.Daemon.new(app=Pyjo.HelloWorld.new(), listen=['http://127.0.0.1'], silent=True) as daemon:
port = daemon.start().ports()[0]
Pyjo.IOLoop.singleton.reactor.run_coroutine(
main(port),
lambda loop: (print(f'loop: {loop}'), Pyjo.IOLoop.stop()),
lambda err: (print(f'error: {err}'), Pyjo.IOLoop.stop()),
)
Pyjo.IOLoop.start()
$ python examples/asyncio_uvloop.py
asyncio: HTTP/1.1 200 OK
Pyjo.UserAgent: 200 Your Pyjo is working!
loop: uvloop
examples/loopback_uvloop.py is a server of Pyjoyment and its user agent on
the loop of uvloop, a blocking request, which runs the event loop until the
response, and the class of the reactor and whether its loop is one of uvloop, which
Build checks with the wheel:
import os
# The reactor of Pyjoyment on uvloop, selected before Pyjo.IOLoop is loaded
os.environ['PYJO_REACTOR'] = 'Pyjo.Reactor.Uvloop'
import Pyjo.HelloWorld # noqa: E402
import Pyjo.IOLoop # noqa: E402
import Pyjo.Server.Daemon # noqa: E402
import Pyjo.UserAgent # noqa: E402
import uvloop # noqa: E402
# The server, on a port that the system picks, and the user agent, in the same event loop, which close their sockets at
# the end of the block
with (
Pyjo.Server.Daemon.new(app=Pyjo.HelloWorld.new(), listen=['http://127.0.0.1'], silent=True) as daemon,
Pyjo.UserAgent.new(ioloop=Pyjo.IOLoop.singleton) as ua,
):
# A blocking request, which runs the event loop of the server on uvloop until the response
tx = ua.get(f'http://127.0.0.1:{daemon.start().ports()[0]}/')
reactor = Pyjo.IOLoop.singleton.reactor
print(type(reactor).__name__, 'uvloop' if isinstance(reactor.loop, uvloop.Loop) else 'asyncio')
print(tx.result.code, tx.result.text)
$ python examples/loopback_uvloop.py
Pyjo_Reactor_Uvloop uvloop
200 Your Pyjo is working!
Documentation
The API of the module and the examples are on Read the Docs.
Status
A reactor of Pyjoyment in a distribution of its own, as Pyjo-Reactor-Twisted.
License
The Artistic License 2.0, as Pyjoyment.
Metadata
Release files for Pyjo-Reactor-Uvloop 0.1.0
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 |
|---|---|---|---|---|
| pyjo_reactor_uvloop-0.1.0.tar.gz | 21.5 kB | With provenance | Details for pyjo_reactor_uvloop-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyjo_reactor_uvloop-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for pyjo_reactor_uvloop-0.1.0-py3-none-any.whl |
Total release size: 33.0 kB
Release files / pyjo_reactor_uvloop-0.1.0.tar.gz
| Download URL | pyjo_reactor_uvloop-0.1.0.tar.gz |
|---|---|
| Size | 21.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1d94c24e8fb6f409aed4b73b672ca3f822895886e8e039ee94c4d99380d245bf
|
|
BLAKE2b-256 checksum How to use checksums |
cf08a1db1ab406f67e645c0519c852e6220ef4afcb3e6b38fda0026a4007fae6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 5, 2026.
Transparency logRelease files / pyjo_reactor_uvloop-0.1.0-py3-none-any.whl
| Download URL | pyjo_reactor_uvloop-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
713773e6bdeeda8b04b1e4bbeebb7631914bd628a9621aa0dcba10d68f9ef172
|
|
BLAKE2b-256 checksum How to use checksums |
d481ba1f2ffb3af05df76db2e4b5f805b99b1a3fa3d834873c36285f0158affa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 5, 2026.
Transparency logSecurity for Pyjo-Reactor-Uvloop 0.1.0
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 2 files in this release have been uploaded with provenance metadata.
Attestation for pyjo_reactor_uvloop-0.1.0.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 Nov 5, 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.