{"id":7457,"library":"nr-stream","title":"nr-stream","description":"The `nr-stream` package provides utilities for writing functional-style code in Python, offering `Stream`, `Optional`, and `Refreshable` classes. The `Stream` class wraps iterables to enable chained modifiers, simplifying common operations. `Optional` represents a value that might be `None`, allowing for safe chaining, while `Refreshable` acts as a container for values that can be updated, propagating changes to listeners. The current version is 1.1.5, released on February 14, 2023, with an active but irregular release cadence.","status":"active","version":"1.1.5","language":"en","source_language":"en","source_url":"https://github.com/NiklasRosenstein/python-nr.stream","tags":["functional programming","stream","optional","refreshable","utility","iterator"],"install":[{"cmd":"pip install nr-stream","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"Stream","correct":"from nr.stream import Stream"},{"symbol":"Optional","correct":"from nr.stream import Optional"},{"symbol":"Refreshable","correct":"from nr.stream import Refreshable"}],"quickstart":{"code":"from nr.stream import Stream\n\nvalues = [3, 6, 4, 7, 1, 2, 5]\n\n# Create a Stream, chunk it, map each chunk to its sum, and collect the results\nprocessed_stream = Stream(values).chunks(3, fill=0).map(sum)\n\nprint(list(processed_stream))\n# Expected output: [13, 10, 5]\n\nfrom nr.stream import Optional\nimport os\n\n# Example with Optional\nopt_var = Optional(os.getenv(\"NON_EXISTENT_VAR\"))\nvalue_or_default = opt_var.or_else_get(lambda: \"default_value\")\nprint(f\"Value or default: {value_or_default}\")\n\nfrom nr.stream import Refreshable\n\n# Example with Refreshable\nroot_refreshable = Refreshable[int | None](None)\nchild_refreshable = root_refreshable.map(lambda v: 42 if v is None else v)\n\nprint(f\"Initial root: {root_refreshable.get()}, child: {child_refreshable.get()}\")\nroot_refreshable.update(10)\nprint(f\"Updated root: {root_refreshable.get()}, child: {child_refreshable.get()}\")","lang":"python","description":"This quickstart demonstrates the core `Stream` class for chained iterable operations, as well as basic usage of the `Optional` and `Refreshable` utilities. The `Stream` example shows how to chunk and transform data, while `Optional` handles potentially absent values, and `Refreshable` illustrates reactive updates."},"warnings":[{"fix":"If you need to perform multiple independent operations on the same data, create a new `Stream` instance for each operation, or materialize the `Stream` (e.g., into a list) before branching operations.","message":"Stream objects immediately convert the underlying iterable to an iterator upon creation. This means a `Stream` object can only be consumed once. Attempting to iterate or perform operations on it a second time will result in an empty stream or unexpected behavior, as the underlying iterator will be exhausted.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware that any `map` or `filter` operations on a `Refreshable` create new `Refreshable` instances that will re-evaluate their transformation eagerly when the source `Refreshable` is updated. Design your computation graphs accordingly, avoiding heavy computations in frequently updated chains unless intended.","message":"`Refreshable` objects use eager evaluation. Chained modifications on a `Refreshable` are replayed immediately when the parent `Refreshable` is updated, not lazily when `.get()` is called. This can lead to computations being performed more often than expected if not understood.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Create a new `Stream` instance from the original data source (e.g., `Stream(my_list)`) for each sequence of operations that needs to start from the beginning of the data.","cause":"The `Stream` object's internal iterator has been exhausted by a previous operation. `Stream` objects are single-use by design.","error":"Stream is empty or produces no output after first use."},{"fix":"Understand that `Refreshable` is designed for 'reactive' updates where all dependants are immediately notified and re-evaluated. If you require lazy evaluation or deferment of computation until explicitly requested, `Refreshable` might not be the appropriate tool, or you need to manage when updates are triggered more carefully.","cause":"Chained `Refreshable` operations are evaluated eagerly. Any `map` or `filter` operations on a `Refreshable` will cause their respective transformation functions to execute immediately whenever the upstream `Refreshable` is updated.","error":"Unexpected performance overhead or computations triggered by `Refreshable` updates."}]}