Top Related Projects
A reactive programming library for JavaScript
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Reactive Programming in Swift
RxJava bindings for Kotlin
Reactive Extensions for C++
The Reactive Extensions for Dart
Quick Overview
ReactiveX/RxPY is a Python implementation of ReactiveX, a library for composing asynchronous and event-based programs using observable sequences. It provides a powerful set of tools for handling streams of data or events, allowing developers to create complex asynchronous operations with ease.
Pros
- Simplifies complex asynchronous operations and event handling
- Provides a consistent API across multiple programming languages
- Offers powerful operators for transforming and combining streams of data
- Enhances code readability and maintainability for event-driven applications
Cons
- Steep learning curve for developers new to reactive programming
- Can be overkill for simple asynchronous tasks
- May introduce unnecessary complexity in small-scale projects
- Performance overhead for simple operations compared to traditional approaches
Code Examples
- Creating and subscribing to an Observable:
from rx import of
observable = of(1, 2, 3, 4, 5)
observable.subscribe(
on_next=lambda i: print(f"Received: {i}"),
on_error=lambda e: print(f"Error: {e}"),
on_completed=lambda: print("Done!")
)
- Using operators to transform data:
from rx import operators as ops
of(1, 2, 3, 4, 5).pipe(
ops.map(lambda x: x * 2),
ops.filter(lambda x: x > 5)
).subscribe(print)
- Combining multiple Observables:
from rx import merge, interval
from rx import operators as ops
source1 = interval(1.0).pipe(ops.map(lambda x: f"First: {x}"))
source2 = interval(2.0).pipe(ops.map(lambda x: f"Second: {x}"))
merge(source1, source2).subscribe(print)
Getting Started
To get started with RxPY, first install it using pip:
pip install rx
Then, import the necessary modules and create your first Observable:
from rx import of, operators as ops
observable = of(1, 2, 3, 4, 5)
observable.pipe(
ops.map(lambda x: x * 2),
ops.filter(lambda x: x > 5)
).subscribe(print)
This example creates an Observable, doubles each value, filters out values less than or equal to 5, and prints the results.
Competitor Comparisons
A reactive programming library for JavaScript
Pros of rxjs
- Larger community and ecosystem, with more resources and third-party libraries
- Better integration with TypeScript and modern JavaScript frameworks
- More frequent updates and active development
Cons of rxjs
- Steeper learning curve due to its extensive API and concepts
- Larger bundle size, which may impact performance in browser environments
- JavaScript-specific, limiting its use in other programming languages
Code Comparison
RxPY:
from rx import Observable
Observable.from_([1, 2, 3, 4, 5]) \
.map(lambda x: x * 2) \
.filter(lambda x: x > 5) \
.subscribe(print)
rxjs:
import { from } from 'rxjs';
import { map, filter } from 'rxjs/operators';
from([1, 2, 3, 4, 5]).pipe(
map(x => x * 2),
filter(x => x > 5)
).subscribe(console.log);
Both libraries provide similar functionality for reactive programming, but rxjs is more tailored for JavaScript environments, while RxPY is designed for Python. The syntax and usage are similar, with minor differences in naming conventions and method chaining. rxjs offers more advanced features and better integration with modern web development tools, while RxPY provides a simpler API that may be easier for Python developers to adopt.
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Pros of RxJava
- More mature and widely adopted in the Java ecosystem
- Extensive documentation and community support
- Better performance for high-throughput scenarios
Cons of RxJava
- Steeper learning curve due to Java's verbosity
- More complex setup and configuration
- Heavier memory footprint
Code Comparison
RxJava:
Observable.just("Hello", "World")
.map(String::toUpperCase)
.subscribe(System.out::println);
RxPY:
Observable.from_(["Hello", "World"]) \
.map(lambda x: x.upper()) \
.subscribe(print)
Both libraries provide similar functionality, but RxJava's syntax is more verbose due to Java's nature. RxPY offers a more concise and Pythonic approach, making it easier to read and write for Python developers.
RxJava is generally preferred for large-scale, performance-critical applications in enterprise environments, while RxPY is more suitable for smaller projects or when working within the Python ecosystem.
The choice between the two often depends on the primary programming language of the project, team expertise, and specific performance requirements.
Reactive Programming in Swift
Pros of RxSwift
- Better performance due to Swift's compiled nature
- Stronger type safety and compile-time checks
- More extensive documentation and community support
Cons of RxSwift
- Limited to iOS and macOS development
- Steeper learning curve for developers new to Swift
- Larger codebase and more complex implementation
Code Comparison
RxSwift:
Observable.from([1, 2, 3, 4, 5])
.filter { $0 % 2 == 0 }
.map { $0 * 2 }
.subscribe(onNext: { print($0) })
RxPY:
Observable.from_([1, 2, 3, 4, 5]) \
.filter(lambda x: x % 2 == 0) \
.map(lambda x: x * 2) \
.subscribe(on_next=print)
Both RxSwift and RxPY implement the ReactiveX paradigm, providing similar functionality for reactive programming. RxSwift offers better performance and type safety for iOS and macOS development, while RxPY provides cross-platform support and easier integration with existing Python projects. The code syntax is similar, with minor differences in method names and language-specific features. RxSwift's compiled nature may lead to faster execution, while RxPY's interpreted nature offers more flexibility and ease of use for rapid prototyping and cross-platform development.
RxJava bindings for Kotlin
Pros of RxKotlin
- Better performance due to Kotlin's efficiency and JVM optimization
- Seamless integration with Android development and other JVM-based projects
- Strong typing and null safety features of Kotlin
Cons of RxKotlin
- Steeper learning curve for developers not familiar with Kotlin
- Smaller community compared to Python, potentially leading to fewer resources and third-party libraries
Code Comparison
RxPY:
import rx
from rx import operators as ops
source = rx.of(1, 2, 3, 4, 5)
subscription = source.pipe(
ops.map(lambda x: x * 2),
ops.filter(lambda x: x > 5)
).subscribe(print)
RxKotlin:
import io.reactivex.rxjava3.core.Observable
val source = Observable.just(1, 2, 3, 4, 5)
val subscription = source
.map { it * 2 }
.filter { it > 5 }
.subscribe { println(it) }
Both libraries provide similar functionality, but RxKotlin's syntax is more concise due to Kotlin's language features. RxPY may be more accessible for Python developers, while RxKotlin offers better performance and integration with JVM ecosystems. The choice between them often depends on the project requirements and the team's expertise.
Reactive Extensions for C++
Pros of RxCpp
- Performance: C++ offers better performance and lower-level control compared to Python
- Static typing: Provides stronger type checking and potential for fewer runtime errors
- Closer to hardware: Suitable for systems programming and embedded systems
Cons of RxCpp
- Steeper learning curve: C++ is generally more complex than Python
- Less extensive ecosystem: Python has a larger community and more libraries available
- Slower development: C++ typically requires more code and time to implement features
Code Comparison
RxCpp:
auto values = rxcpp::observable<>::range(1, 5)
| rxcpp::operators::map([](int n) { return n * n; })
| rxcpp::operators::sum();
values.subscribe([](int result) { std::cout << result << std::endl; });
RxPY:
values = rx.range(1, 5).pipe(
ops.map(lambda x: x * x),
ops.sum()
)
values.subscribe(lambda result: print(result))
Both examples demonstrate similar functionality, but RxCpp requires more verbose syntax and explicit typing. RxPY's Python implementation is more concise and easier to read, showcasing Python's simplicity. However, the C++ version may offer better performance for computationally intensive tasks.
The Reactive Extensions for Dart
Pros of rxdart
- Specifically designed for Dart and Flutter, offering seamless integration
- Provides Flutter-specific operators and utilities
- More active development and frequent updates
Cons of rxdart
- Limited to Dart ecosystem, less versatile across different platforms
- Smaller community compared to RxPY, potentially fewer resources and third-party extensions
Code Comparison
RxPY:
from rx import Observable
Observable.from_([1, 2, 3, 4, 5]) \
.map(lambda x: x * 2) \
.filter(lambda x: x > 5) \
.subscribe(print)
rxdart:
import 'package:rxdart/rxdart.dart';
Stream.fromIterable([1, 2, 3, 4, 5])
.map((x) => x * 2)
.where((x) => x > 5)
.listen(print);
Key Differences
- Syntax: RxPY uses Python's syntax, while rxdart uses Dart syntax
- Integration: rxdart is tightly integrated with Dart's Stream API
- Platform: RxPY is more versatile across different Python environments, while rxdart is optimized for Dart and Flutter development
Both libraries implement the ReactiveX pattern, providing similar core functionality for reactive programming. The choice between them largely depends on the target platform and ecosystem requirements of your project.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
=============================== The ReactiveX for Python (RxPY)
.. image:: https://github.com/ReactiveX/RxPY/workflows/Python%20package/badge.svg :target: https://github.com/ReactiveX/RxPY/actions :alt: Build Status
.. image:: https://img.shields.io/coveralls/ReactiveX/RxPY.svg :target: https://coveralls.io/github/ReactiveX/RxPY :alt: Coverage Status
.. image:: https://img.shields.io/pypi/v/reactivex.svg :target: https://pypi.org/project/reactivex/ :alt: PyPY Package Version
.. image:: https://img.shields.io/readthedocs/rxpy.svg :target: https://readthedocs.org/projects/rxpy/builds/ :alt: Documentation Status
A library for composing asynchronous and event-based programs using observable collections and query operator functions in Python
ReactiveX for Python v4
For v3.X please go to the v3 branch <https://github.com/ReactiveX/RxPY/tree/release/v3.2.x>
_.
ReactiveX for Python v4.x runs on Python <http://www.python.org/>
_ 3.7 or above. To
install:
.. code:: console
pip3 install reactivex
About ReactiveX
ReactiveX for Python (RxPY) is a library for composing asynchronous and event-based programs using observable sequences and pipable query operators in Python. Using Rx, developers represent asynchronous data streams with Observables, query asynchronous data streams using operators, and parameterize concurrency in data/event streams using Schedulers.
.. code:: python
import reactivex as rx
from reactivex import operators as ops
source = rx.of("Alpha", "Beta", "Gamma", "Delta", "Epsilon")
composed = source.pipe(
ops.map(lambda s: len(s)),
ops.filter(lambda i: i >= 5)
)
composed.subscribe(lambda value: print("Received {0}".format(value)))
Learning ReactiveX
Read the documentation <https://rxpy.readthedocs.io/en/latest/>
_ to learn
the principles of ReactiveX and get the complete reference of the available
operators.
If you need to migrate code from RxPY v1.x or v3.x, read the migration <https://rxpy.readthedocs.io/en/latest/migration.html>
_ section.
There is also a list of third party documentation available here <https://rxpy.readthedocs.io/en/latest/additional_reading.html>
_.
Community
Join the conversation on GitHub Discussions <https://github.com/ReactiveX/RxPY/discussions>
_! if you have any questions or
suggestions.
Differences from .NET and RxJS
ReactiveX for Python is a fairly complete implementation of
Rx <http://reactivex.io/>
_ with more than
120 operators <https://rxpy.readthedocs.io/en/latest/operators.html>
, and
over 1300 passing unit-tests <https://coveralls.io/github/ReactiveX/RxPY>
. RxPY
is mostly a direct port of RxJS, but also borrows a bit from Rx.NET and RxJava in
terms of threading and blocking operators.
ReactiveX for Python follows PEP 8 <http://legacy.python.org/dev/peps/pep-0008/>
_, so
all function and method names are snake_cased
i.e lowercase with words separated by
underscores as necessary to improve readability.
Thus .NET code such as:
.. code:: c#
var group = source.GroupBy(i => i % 3);
need to be written with an _
in Python:
.. code:: python
group = source.pipe(ops.group_by(lambda i: i % 3))
With ReactiveX for Python you should use named keyword arguments <https://docs.python.org/3/glossary.html>
_ instead of positional arguments when an
operator has multiple optional arguments. RxPY will not try to detect which arguments
you are giving to the operator (or not).
Development
This project is managed using Poetry <https://python-poetry.org/>
. Code is formatted
using Black <https://github.com/psf/black>
, isort <https://github.com/PyCQA/isort>
. Code is statically type checked using pyright <https://github.com/microsoft/pyright>
and mypy <http://mypy-lang.org/>
_.
If you want to take advantage of the default VSCode integration, then first configure Poetry to make its virtual environment in the repository:
.. code:: console
poetry config virtualenvs.in-project true
After cloning the repository, activate the tooling:
.. code:: console
poetry install
poetry run pre-commit install
Run unit tests:
.. code:: console
poetry run pytest
Run code checks (manually):
.. code:: console
poetry run pre-commit run --all-files
Top Related Projects
A reactive programming library for JavaScript
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Reactive Programming in Swift
RxJava bindings for Kotlin
Reactive Extensions for C++
The Reactive Extensions for Dart
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot