| Name | stream4py JSON |
| Version |
0.1.3
JSON |
| download |
| home_page | None |
| Summary | Stream4Py: Functional, chainable streams for Python with lazy evaluation |
| upload_time | 2025-10-12 07:27:53 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.9 |
| license | None |
| keywords |
functional
iterator
lazy
pipeline
stream
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# Stream4Py
[](https://pypi.org/project/stream4py)
[](https://pypi.org/project/stream4py)
[](https://results.pre-commit.ci/latest/github/FlavioAmurrioCS/stream4py/main)
A Python library inspired by **Java Streams**, **Haskell lists**, and **Linux pipes**, providing a powerful, lazy-evaluated `Stream` class for functional-style data manipulation. Stream4Py makes it easy to work with iterables, files, subprocess output, and general data pipelines.
---
## Features
* Lazy and eager evaluation methods.
* Chainable operations like `map`, `filter`, `flat_map`, `unique`, `enumerate`, `flatten`, `sections`.
* **File I/O operations** including text files, binary files, CSV, and JSON Lines (JSONL).
* File parsing and subprocess piping with `from_io` and `pipe`.
* Collection helpers like `to_list`, `to_dict`, `to_set`, and `cache`.
* Built-in itertools utilities (`islice`, `zip_longest`, `accumulate`, etc.).
* Inspired by Java Streams, Haskell functional programming, and Python itertools.
---
## Installation
Install via pip:
```bash
pip install stream4py
```
---
## Quick Start
```python
from stream4py import Stream
# Create a stream
s = Stream([1, 2, 3, 4, 5])
# Lazy operations
result = (
s.filter(lambda x: x % 2 == 0)
.map(lambda x: x * 10)
.unique()
)
# Convert to list (triggers evaluation)
print(result.to_list()) # [20, 40]
# File I/O operations
Stream.open("data.txt").filter(lambda x: "error" in x).for_each(print)
Stream([{"name": "Alice", "age": 30}]).to_csv("output.csv")
users = Stream.open_csv("users.csv").map(lambda row: row["name"])
# Stream lines from a file
lines = Stream.from_io(open("file.txt"))
lines.filter(lambda x: "error" in x).for_each(print)
# Subprocess streaming
Stream.subprocess_run(("seq", "100")).pipe(("grep", "1")).for_each(print)
```
---
## File I/O Operations
Stream4Py provides convenient methods for working with various file formats:
### Text Files
```python
# Reading text files
content = Stream.open("input.txt").to_list()
# Writing text files
Stream(["line 1\n", "line 2\n"]).to_file("output.txt")
# Processing large files lazily
(Stream.open("large_file.txt")
.filter(lambda line: "ERROR" in line)
.map(str.upper)
.to_file("errors.txt"))
```
### Binary Files
```python
# Reading binary files
binary_data = Stream.open_binary("data.bin").to_list()
# Processing binary content
(Stream.open_binary("image.jpg")
.take(1024) # First 1KB
.to_list())
```
### CSV Files
```python
# Reading CSV files as dictionaries
users = Stream.open_csv("users.csv")
adult_names = users.filter(lambda row: int(row["age"]) >= 18).map(lambda row: row["name"])
# Writing CSV files from dictionaries
data = [
{"name": "Alice", "age": 30, "city": "New York"},
{"name": "Bob", "age": 25, "city": "London"}
]
Stream(data).to_csv("output.csv")
# Processing large CSV files efficiently
(Stream.open_csv("large_dataset.csv")
.filter(lambda row: row["status"] == "active")
.map(lambda row: {"id": row["id"], "score": float(row["score"]) * 1.1})
.to_csv("processed.csv"))
```
### JSON Lines (JSONL) Files
```python
# Reading JSONL files
events = Stream.open_jsonl("events.jsonl")
user_events = events.filter(lambda obj: obj["type"] == "user_action")
# Type casting for better type hints
from typing import TypedDict
class Event(TypedDict):
type: str
user_id: int
timestamp: str
typed_events = Stream.open_jsonl("events.jsonl").typing_cast(Event)
```
### Working with IO Objects
```python
import io
# From StringIO
content = io.StringIO("line1\nline2\nline3")
lines = Stream.from_io(content).to_list()
# From file handles (automatically closed)
with open("data.txt") as f:
processed = Stream.from_io(f).map(str.strip).to_list()
```
---
## Quick Reference
| Method | Type | Description | Example |
| ------------------------------------- | ----- | --------------------------------------- | -------------------------------------------- |
| `map(func)` | Lazy | Apply a function to each item | `Stream([1,2,3]).map(lambda x: x*2)` |
| `filter(predicate)` | Lazy | Keep items satisfying a predicate | `Stream([1,2,3]).filter(lambda x: x>1)` |
| `filterfalse(predicate)` | Lazy | Keep items for which predicate is False | `Stream([1,2,3]).filterfalse(lambda x: x>1)` |
| `flat_map(func)` | Lazy | Map then flatten iterables | `Stream([1,2]).flat_map(lambda x: (x,x*10))` |
| `flatten()` | Lazy | Flatten nested iterables | `Stream([[1,2],[3]]).flatten()` |
| `unique(key=None)` | Lazy | Keep only unique items | `Stream([1,2,2]).unique()` |
| `type_is(cls)` | Lazy | Keep items of a specific type | `Stream([1,'a']).type_is(int)` |
| `enumerate(start=0)` | Lazy | Enumerate items | `Stream(['a','b']).enumerate(1)` |
| `peek(func)` | Lazy | Apply function without changing items | `Stream([1,2]).peek(print)` |
| `islice(start, stop, step)` | Lazy | Slice like `itertools.islice` | `Stream([1,2,3]).islice(1,3)` |
| `batched(size)` | Lazy | Yield items in batches | `Stream(range(5)).batched(2)` |
| `drop(n)` | Lazy | Drop first `n` items | `Stream([1,2,3]).drop(1)` |
| `take(n)` | Lazy | Take first `n` items | `Stream([1,2,3]).take(2)` |
| `dropwhile(predicate)` | Lazy | Drop items while predicate is true | `Stream([1,2,3]).dropwhile(lambda x: x<2)` |
| `takewhile(predicate)` | Lazy | Take items while predicate is true | `Stream([1,2,3]).takewhile(lambda x: x<3)` |
| `reverse()` | Lazy | Reverse the items | `Stream([1,2,3]).reverse()` |
| `zip(*iterables)` | Lazy | Zip with other iterables | `Stream([1,2]).zip(['a','b'])` |
| `zip_longest(*iterables)` | Lazy | Zip with padding | `Stream([1]).zip_longest([2,3])` |
| `accumulate(func=None, initial=None)` | Lazy | Cumulative sums or function | `Stream([1,2,3]).accumulate()` |
| `subprocess_run(command)` | Lazy | Run a subprocess and stream output | `Stream.subprocess_run(('ls',))` |
| `pipe(command)` | Lazy | Pipe stream to subprocess | `Stream(['foo']).pipe(('grep','f'))` |
| `sum(start=0)` | Eager | Sum all items | `Stream([1,2,3]).sum()` |
| `min(key=None, default=None)` | Eager | Minimum value | `Stream([1,2,3]).min()` |
| `max(key=None, default=None)` | Eager | Maximum value | `Stream([1,2,3]).max()` |
| `sorted(key=None, reverse=False)` | Eager | Sort items | `Stream([3,1,2]).sorted()` |
| `first(default=None)` | Eager | First item | `Stream([1,2]).first()` |
| `find(func)` | Eager | Find first item matching function | `Stream([1,2,3]).find(lambda x: x>1)` |
| `group_by(key)` | Eager | Group items by key | `Stream([1,2,3,4]).group_by(lambda x: x%2)` |
| `for_each(func)` | Eager | Apply function to all items | `Stream([1,2]).for_each(print)` |
| `cache()` | Eager | Cache stream items | `Stream(range(3)).cache()` |
| `to_list()` | Eager | Collect as list | `Stream([1,2]).to_list()` |
| `to_tuple()` | Eager | Collect as tuple | `Stream([1,2]).to_tuple()` |
| `to_set()` | Eager | Collect as set | `Stream([1,2]).to_set()` |
| `to_dict()` | Eager | Collect as dict (from tuples) | `Stream([(1,'a')]).to_dict()` |
| `collect(func)` | Eager | Apply function to iterable | `Stream([1,2]).collect(sum)` |
| `from_io(io)` | Lazy | Stream lines from file or binary IO | `Stream.from_io(open('file.txt'))` |
| `open(file)` | Lazy | Open and stream lines from text file | `Stream.open('data.txt')` |
| `open_binary(file)` | Lazy | Open and stream lines from binary file | `Stream.open_binary('data.bin')` |
| `open_csv(file)` | Lazy | Open CSV file as stream of dictionaries | `Stream.open_csv('data.csv')` |
| `open_jsonl(file)` | Lazy | Open JSONL file as stream of objects | `Stream.open_jsonl('data.jsonl')` |
| `to_file(file)` | Eager | Write stream contents to text file | `Stream(['line1\n']).to_file('out.txt')` |
| `to_csv(file)` | Eager | Write stream of dicts to CSV file | `Stream([{'a':1}]).to_csv('out.csv')` |
| `sections(predicate)` | Lazy | Split into sections based on predicate | `Stream([1,1,2]).sections(lambda x:x==2)` |
| `range(start, stop, step=1)` | Lazy | Stream over a range | `Stream.range(1,5)` |
---
## Contributing
Contributions are welcome! Please open an issue or pull request with improvements or bug fixes.
---
## License
`stream4py` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
Raw data
{
"_id": null,
"home_page": null,
"name": "stream4py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "functional, iterator, lazy, pipeline, stream",
"author": null,
"author_email": "Flavio Amurrio <25621374+FlavioAmurrioCS@users.noreply.github.com>",
"download_url": "https://files.pythonhosted.org/packages/04/17/3fe4574f3f849fec06ead014b1fafbf3dfadf52331a8a06c71c5e3223359/stream4py-0.1.3.tar.gz",
"platform": null,
"description": "# Stream4Py\n\n[](https://pypi.org/project/stream4py)\n[](https://pypi.org/project/stream4py)\n[](https://results.pre-commit.ci/latest/github/FlavioAmurrioCS/stream4py/main)\n\n\nA Python library inspired by **Java Streams**, **Haskell lists**, and **Linux pipes**, providing a powerful, lazy-evaluated `Stream` class for functional-style data manipulation. Stream4Py makes it easy to work with iterables, files, subprocess output, and general data pipelines.\n\n---\n\n## Features\n\n* Lazy and eager evaluation methods.\n* Chainable operations like `map`, `filter`, `flat_map`, `unique`, `enumerate`, `flatten`, `sections`.\n* **File I/O operations** including text files, binary files, CSV, and JSON Lines (JSONL).\n* File parsing and subprocess piping with `from_io` and `pipe`.\n* Collection helpers like `to_list`, `to_dict`, `to_set`, and `cache`.\n* Built-in itertools utilities (`islice`, `zip_longest`, `accumulate`, etc.).\n* Inspired by Java Streams, Haskell functional programming, and Python itertools.\n\n---\n\n## Installation\n\nInstall via pip:\n\n```bash\npip install stream4py\n```\n\n---\n\n## Quick Start\n\n```python\nfrom stream4py import Stream\n\n# Create a stream\ns = Stream([1, 2, 3, 4, 5])\n\n# Lazy operations\nresult = (\n s.filter(lambda x: x % 2 == 0)\n .map(lambda x: x * 10)\n .unique()\n)\n\n# Convert to list (triggers evaluation)\nprint(result.to_list()) # [20, 40]\n\n# File I/O operations\nStream.open(\"data.txt\").filter(lambda x: \"error\" in x).for_each(print)\nStream([{\"name\": \"Alice\", \"age\": 30}]).to_csv(\"output.csv\")\nusers = Stream.open_csv(\"users.csv\").map(lambda row: row[\"name\"])\n\n# Stream lines from a file\nlines = Stream.from_io(open(\"file.txt\"))\nlines.filter(lambda x: \"error\" in x).for_each(print)\n\n# Subprocess streaming\nStream.subprocess_run((\"seq\", \"100\")).pipe((\"grep\", \"1\")).for_each(print)\n```\n\n---\n\n## File I/O Operations\n\nStream4Py provides convenient methods for working with various file formats:\n\n### Text Files\n\n```python\n# Reading text files\ncontent = Stream.open(\"input.txt\").to_list()\n\n# Writing text files\nStream([\"line 1\\n\", \"line 2\\n\"]).to_file(\"output.txt\")\n\n# Processing large files lazily\n(Stream.open(\"large_file.txt\")\n .filter(lambda line: \"ERROR\" in line)\n .map(str.upper)\n .to_file(\"errors.txt\"))\n```\n\n### Binary Files\n\n```python\n# Reading binary files\nbinary_data = Stream.open_binary(\"data.bin\").to_list()\n\n# Processing binary content\n(Stream.open_binary(\"image.jpg\")\n .take(1024) # First 1KB\n .to_list())\n```\n\n### CSV Files\n\n```python\n# Reading CSV files as dictionaries\nusers = Stream.open_csv(\"users.csv\")\nadult_names = users.filter(lambda row: int(row[\"age\"]) >= 18).map(lambda row: row[\"name\"])\n\n# Writing CSV files from dictionaries\ndata = [\n {\"name\": \"Alice\", \"age\": 30, \"city\": \"New York\"},\n {\"name\": \"Bob\", \"age\": 25, \"city\": \"London\"}\n]\nStream(data).to_csv(\"output.csv\")\n\n# Processing large CSV files efficiently\n(Stream.open_csv(\"large_dataset.csv\")\n .filter(lambda row: row[\"status\"] == \"active\")\n .map(lambda row: {\"id\": row[\"id\"], \"score\": float(row[\"score\"]) * 1.1})\n .to_csv(\"processed.csv\"))\n```\n\n### JSON Lines (JSONL) Files\n\n```python\n# Reading JSONL files\nevents = Stream.open_jsonl(\"events.jsonl\")\nuser_events = events.filter(lambda obj: obj[\"type\"] == \"user_action\")\n\n# Type casting for better type hints\nfrom typing import TypedDict\n\nclass Event(TypedDict):\n type: str\n user_id: int\n timestamp: str\n\ntyped_events = Stream.open_jsonl(\"events.jsonl\").typing_cast(Event)\n```\n\n### Working with IO Objects\n\n```python\nimport io\n\n# From StringIO\ncontent = io.StringIO(\"line1\\nline2\\nline3\")\nlines = Stream.from_io(content).to_list()\n\n# From file handles (automatically closed)\nwith open(\"data.txt\") as f:\n processed = Stream.from_io(f).map(str.strip).to_list()\n```\n\n---\n\n## Quick Reference\n\n| Method | Type | Description | Example |\n| ------------------------------------- | ----- | --------------------------------------- | -------------------------------------------- |\n| `map(func)` | Lazy | Apply a function to each item | `Stream([1,2,3]).map(lambda x: x*2)` |\n| `filter(predicate)` | Lazy | Keep items satisfying a predicate | `Stream([1,2,3]).filter(lambda x: x>1)` |\n| `filterfalse(predicate)` | Lazy | Keep items for which predicate is False | `Stream([1,2,3]).filterfalse(lambda x: x>1)` |\n| `flat_map(func)` | Lazy | Map then flatten iterables | `Stream([1,2]).flat_map(lambda x: (x,x*10))` |\n| `flatten()` | Lazy | Flatten nested iterables | `Stream([[1,2],[3]]).flatten()` |\n| `unique(key=None)` | Lazy | Keep only unique items | `Stream([1,2,2]).unique()` |\n| `type_is(cls)` | Lazy | Keep items of a specific type | `Stream([1,'a']).type_is(int)` |\n| `enumerate(start=0)` | Lazy | Enumerate items | `Stream(['a','b']).enumerate(1)` |\n| `peek(func)` | Lazy | Apply function without changing items | `Stream([1,2]).peek(print)` |\n| `islice(start, stop, step)` | Lazy | Slice like `itertools.islice` | `Stream([1,2,3]).islice(1,3)` |\n| `batched(size)` | Lazy | Yield items in batches | `Stream(range(5)).batched(2)` |\n| `drop(n)` | Lazy | Drop first `n` items | `Stream([1,2,3]).drop(1)` |\n| `take(n)` | Lazy | Take first `n` items | `Stream([1,2,3]).take(2)` |\n| `dropwhile(predicate)` | Lazy | Drop items while predicate is true | `Stream([1,2,3]).dropwhile(lambda x: x<2)` |\n| `takewhile(predicate)` | Lazy | Take items while predicate is true | `Stream([1,2,3]).takewhile(lambda x: x<3)` |\n| `reverse()` | Lazy | Reverse the items | `Stream([1,2,3]).reverse()` |\n| `zip(*iterables)` | Lazy | Zip with other iterables | `Stream([1,2]).zip(['a','b'])` |\n| `zip_longest(*iterables)` | Lazy | Zip with padding | `Stream([1]).zip_longest([2,3])` |\n| `accumulate(func=None, initial=None)` | Lazy | Cumulative sums or function | `Stream([1,2,3]).accumulate()` |\n| `subprocess_run(command)` | Lazy | Run a subprocess and stream output | `Stream.subprocess_run(('ls',))` |\n| `pipe(command)` | Lazy | Pipe stream to subprocess | `Stream(['foo']).pipe(('grep','f'))` |\n| `sum(start=0)` | Eager | Sum all items | `Stream([1,2,3]).sum()` |\n| `min(key=None, default=None)` | Eager | Minimum value | `Stream([1,2,3]).min()` |\n| `max(key=None, default=None)` | Eager | Maximum value | `Stream([1,2,3]).max()` |\n| `sorted(key=None, reverse=False)` | Eager | Sort items | `Stream([3,1,2]).sorted()` |\n| `first(default=None)` | Eager | First item | `Stream([1,2]).first()` |\n| `find(func)` | Eager | Find first item matching function | `Stream([1,2,3]).find(lambda x: x>1)` |\n| `group_by(key)` | Eager | Group items by key | `Stream([1,2,3,4]).group_by(lambda x: x%2)` |\n| `for_each(func)` | Eager | Apply function to all items | `Stream([1,2]).for_each(print)` |\n| `cache()` | Eager | Cache stream items | `Stream(range(3)).cache()` |\n| `to_list()` | Eager | Collect as list | `Stream([1,2]).to_list()` |\n| `to_tuple()` | Eager | Collect as tuple | `Stream([1,2]).to_tuple()` |\n| `to_set()` | Eager | Collect as set | `Stream([1,2]).to_set()` |\n| `to_dict()` | Eager | Collect as dict (from tuples) | `Stream([(1,'a')]).to_dict()` |\n| `collect(func)` | Eager | Apply function to iterable | `Stream([1,2]).collect(sum)` |\n| `from_io(io)` | Lazy | Stream lines from file or binary IO | `Stream.from_io(open('file.txt'))` |\n| `open(file)` | Lazy | Open and stream lines from text file | `Stream.open('data.txt')` |\n| `open_binary(file)` | Lazy | Open and stream lines from binary file | `Stream.open_binary('data.bin')` |\n| `open_csv(file)` | Lazy | Open CSV file as stream of dictionaries | `Stream.open_csv('data.csv')` |\n| `open_jsonl(file)` | Lazy | Open JSONL file as stream of objects | `Stream.open_jsonl('data.jsonl')` |\n| `to_file(file)` | Eager | Write stream contents to text file | `Stream(['line1\\n']).to_file('out.txt')` |\n| `to_csv(file)` | Eager | Write stream of dicts to CSV file | `Stream([{'a':1}]).to_csv('out.csv')` |\n| `sections(predicate)` | Lazy | Split into sections based on predicate | `Stream([1,1,2]).sections(lambda x:x==2)` |\n| `range(start, stop, step=1)` | Lazy | Stream over a range | `Stream.range(1,5)` |\n\n---\n\n## Contributing\n\nContributions are welcome! Please open an issue or pull request with improvements or bug fixes.\n\n---\n\n## License\n\n`stream4py` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.\n",
"bugtrack_url": null,
"license": null,
"summary": "Stream4Py: Functional, chainable streams for Python with lazy evaluation",
"version": "0.1.3",
"project_urls": {
"Documentation": "https://github.com/FlavioAmurrioCS/stream4py#readme",
"Issues": "https://github.com/FlavioAmurrioCS/stream4py/issues",
"Source": "https://github.com/FlavioAmurrioCS/stream4py"
},
"split_keywords": [
"functional",
" iterator",
" lazy",
" pipeline",
" stream"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "954ac67c99480b6f761329b7768549e9808d2a00c9da899236d77a6ac476a168",
"md5": "c2d3ba835fc396c1a6e9dcb5941afc7a",
"sha256": "d18282d4a4898977cf2624a7fd91d09ed136b4004d9c8939f6ed28f203c65a50"
},
"downloads": -1,
"filename": "stream4py-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c2d3ba835fc396c1a6e9dcb5941afc7a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 16804,
"upload_time": "2025-10-12T07:27:51",
"upload_time_iso_8601": "2025-10-12T07:27:51.545924Z",
"url": "https://files.pythonhosted.org/packages/95/4a/c67c99480b6f761329b7768549e9808d2a00c9da899236d77a6ac476a168/stream4py-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "04173fe4574f3f849fec06ead014b1fafbf3dfadf52331a8a06c71c5e3223359",
"md5": "5f0b3ad71a4296d93f89fefb68ad14ea",
"sha256": "e754f17c6f6b146353599c1b92309518444f2675e16f51c58b3fb88cbafe19ee"
},
"downloads": -1,
"filename": "stream4py-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "5f0b3ad71a4296d93f89fefb68ad14ea",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 29790,
"upload_time": "2025-10-12T07:27:53",
"upload_time_iso_8601": "2025-10-12T07:27:53.172695Z",
"url": "https://files.pythonhosted.org/packages/04/17/3fe4574f3f849fec06ead014b1fafbf3dfadf52331a8a06c71c5e3223359/stream4py-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-12 07:27:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "FlavioAmurrioCS",
"github_project": "stream4py#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "stream4py"
}