Free-threaded Python¶
rivers supports free-threaded CPython 3.14 and later (3.14t, 3.15t, PEP 703). These interpreters run without the GIL, so Python threads run in parallel.
Install¶
Create a free-threaded environment, then install rivers as usual:
rivers publishes free-threaded wheels for Linux (glibc and musl, x86_64 and aarch64), macOS (x86_64 and arm64), and Windows (x86_64): a cp314t wheel for 3.14t, and an abi3t wheel for 3.15t and later.
On 3.15t, the obstore dependency has no wheel yet. The install then compiles it from source, which needs a Rust toolchain.
import rivers keeps the GIL disabled:
If your code imports an extension module that does not support free-threading, Python turns the GIL back on and prints a RuntimeWarning that names the module.
Extras¶
These extras work on 3.14t: pyarrow, pandas, datafusion, and otel.
The delta, delta-*, iceberg, iceberg-*, polars, duckdb, and dlt extras do not install yet: deltalake, pyiceberg-core, polars, duckdb, and the pendulum and orjson packages that dlt needs have no free-threaded wheels.
On 3.15t, only otel installs for now: pyarrow and datafusion have no 3.15t wheels yet.
Thread safety of your code¶
Without the GIL, rivers runs your code on several threads at the same time:
- The daemon evaluates up to four sensors and schedules at once.
- Runs started by the daemon, the gRPC server, or your own threads run in parallel.
Resources, IO handlers, and assets that share state (a cache, a counter, a client that is not thread-safe) must protect it, for example with a threading.Lock.
Do not change a dict while another thread passes it to rivers, for example as metadata=. The call can then raise pyo3_runtime.PanicException.