Skip to content

Latest commit

 

History

History
142 lines (96 loc) · 3.27 KB

File metadata and controls

142 lines (96 loc) · 3.27 KB

Getting Started

This page covers the parts most Python users will touch first.

Install

From PyPI:

pip install rsloop

With uv:

uv add rsloop

The public API

The package exports a small public surface:

  • rsloop.Loop
  • rsloop.EventLoopPolicy
  • rsloop.new_event_loop()
  • rsloop.run(...)
  • rsloop.install()
  • rsloop.uninstall()
  • rsloop.profile()
  • rsloop.start_profiler()
  • rsloop.stop_profiler()
  • rsloop.profiler_running()

For most programs, rsloop.run(...) is enough.

Simplest way to use it

import rsloop


async def main() -> str:
    return "done"


result = rsloop.run(main())
print(result)

This is similar to asyncio.run(...), but it creates and uses an rsloop loop.

Install as the default asyncio loop

Use install() when you want plain asyncio entry points to create rsloop loops:

import asyncio
import rsloop


rsloop.install()
try:
    asyncio.run(main())
finally:
    rsloop.uninstall()

uninstall() restores the event loop policy that was active before install(), which is useful in tests that switch between loop implementations. If another library has already installed a different policy, uninstall() leaves that newer policy in place.

Manual loop creation

Use manual loop creation when you need more control:

import asyncio
import rsloop


loop = rsloop.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(asyncio.sleep(0))
finally:
    asyncio.set_event_loop(None)
    loop.close()

What still feels like normal asyncio?

A lot of the programming model stays the same. For example:

  • async def coroutines
  • await
  • asyncio.create_task(...)
  • protocols and transports
  • socket helpers such as sock_recv(...)
  • servers and connections
  • subprocess helpers

The big difference is the implementation of the event loop itself.

Import-time behavior

Importing rsloop does a little setup work:

  • it boots the native extension
  • it patches asyncio.set_event_loop(...) for compatibility, especially on older Python versions
  • it can patch asyncio.open_connection(...) and asyncio.start_server(...) to use rsloop's fast stream path

That fast stream behavior is controlled by RSLOOP_USE_FAST_STREAMS.

Disable it like this:

export RSLOOP_USE_FAST_STREAMS=0

Useful examples

The examples/ directory is the best hands-on tour of the project:

  • examples/01_basics.py: loop lifecycle, callbacks, tasks, executors
  • examples/02_fd_and_sockets.py: file descriptor watchers and socket helpers
  • examples/03_streams.py: TCP protocols, connections, and servers
  • examples/04_unix_and_accepted_socket.py: Unix sockets and accepted sockets
  • examples/05_pipes_signals_subprocesses.py: pipes, signals, and subprocesses

If you are new to lower-level asyncio features, start with 01_basics.py and 03_streams.py.

There is also a shorter docs page with copy-paste snippets in Examples.

Adding your own async Rust code

If you want to keep using rsloop in Python while exposing your own async Rust functions from a separate PyO3 extension, read Rust Extensions.

That page explains how to turn a Rust future into a Python awaitable with rsloop::rust_async::future_into_py(...).