Yet another python streams library
Project description
tinystream / python-streams
This is a simple and lightweight Streams API inspired by Java Streams with support for type hinting.
This package is released as tinystream
at pypi.
Basic API
from tinystream import Stream
stream = Stream([1, 2, 3, 4, 5]) # Stream.of_many(*), Stream.of_dict()
stream \
.map(lambda x: x + 1) \ # flatmap(), peek(), map_key(), map_kwargs(), map_keys()
.filter(lambda x: x > 2) \ # filter_key(), filter_type()
.sorted(reverse=True) \ # sort()
.reverse() \
.limit(2) \
.concat([4]) \
.sum() # reduce(), max(), min(), collect(), count(), find()
Aggregators
Aggregators like sum()
, count()
, max()
will collect()
the data and end the stream. collect()
also caches the data and can be called multiple times, since it returns only a list
.
Built-in Optional support
Some aggregators like sum()
, max()
are optional:
assert Stream((1, 2, 3, 4, 5)).sum().present
Get next value as optional:
assert Stream((1, 2, 3, 4, 5)).next().present
Create custom optional:
from tinystream import Opt
assert Opt(None).absent
Map optional:
assert Opt("String").map(str.lower).len == 6
Get default value:
assert Opt(None).get(6) == 6
assert Opt(None).get(lambda: 6) == 6
assert Opt(None).if_absent(lambda: 3).present
Filter value:
assert Opt(0).filter(lambda x: x > 0).absent
You can also access optional index elements of the stream, but this will collect()
and end the stream.
assert Stream([])[2].absent
Type hinting
You can typehint datatypes like:
from dataclasses import dataclass
@dataclass
class Node:
name: str
parent: "Node" = None
parent = Node(name="B")
child = Node(name="A", parent=parent)
for lambdas:
stream = Stream([child])
assert stream.map(lambda x: x.parent).type(Node).next().get().name == "B"
This is not necessary when you pass a mapping function:
def map_parent(n: Node):
return n.parent
assert stream.map(map_parent).next().get().name == "B"
More features
Typed dictionaries
Dictionaries are streamed as tuple(key, value)
children = {"a": Node(name="Child")}
stream = Stream.of_dict(children)
for item in stream:
# item[0] is known as str
# item[1] is known as Node
This is the same like (but without known types):
stream = Stream(children)
Filter by existing key
items_with_name = Stream([child]).filter_key("name")
Filter by key value
items_with_name = Stream([child]).filter_key_value("name", "Child")
Filter by type
nodes_only = Stream([child]).filter_type(Node)
Map object name attribute
names = Stream([child]).map_key("name")
Deep mapping of name attributes
list = [
{"node": Node(name="Node A")},
{"node": Node(name="Node B")},
{"node": Node(name="Node C")},
{"node": Node(name="Node D")},
]
names = Stream(list).map_keys("node", "name")
Collected join
all_names = Stream([child]).map_key("name").join(", ")
Map kwargs
list = [
{"name": "Node A"},
{"name": "Node B"},
]
# Short cut for map(lambda x: Node(**x))
nodes = Stream(list).map_kwargs(Node)
Stream many
many = Stream.of_many([1, 2, 3], (4, 5, 6))
many = many.concat([7, 8, 9])
End of stream
stream = Stream(["a", "b", "c"]).on_end(lambda: print("Finished"))
char = stream.next().get()
if char == "a":
stream.end()
Examples
A given data structure like:
data = {
"ranges": [
{"days": 3},
{"weeks": 1},
]
}
Without tinystream:
if "ranges" in data:
range_data: timedelta
for range_data in map(lambda x: timedelta(**x), data["ranges"]):
pass
With tinystream:
for range_data in Opt(data).map_key("ranges").stream().map_kwargs(timedelta):
pass
Comparison with other libraries
There are a couple of other implementation to fulfill similar requirements.
- https://github.com/vxgmichel/aiostream
- https://github.com/python-streamz/streamz
- https://pypi.org/project/fluentpy
- https://github.com/ramsteak/streams
- https://github.com/alemazzo/Python-Java-Stream (outdated)
- https://github.com/JaviOverflow/python-streams (outdated)
- https://github.com/9seconds/streams/ (outdated)
- https://github.com/tolsac/streampy (outdated)
- Apache Spark
Run the tests
PYTHONPATH="." pytest --cov=tinystream -n 4 tests/
Release update
- Update version in
setup.py
- Package library
python setup.py sdist
- Publish library
twine upload dist/tinystream-[version].tar.gz
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file tinystream-0.1.16.tar.gz
.
File metadata
- Download URL: tinystream-0.1.16.tar.gz
- Upload date:
- Size: 6.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 379eb3b571fca1706889de4f472e017b1cb43ca13f4f33df530b414f0c0fb639 |
|
MD5 | 29a73f4b7104169234911b7084f5f6e6 |
|
BLAKE2b-256 | 4fec519e0f7062552886d435402f560dc12f1f0bfb79890a3a9d8ac91ef0a6e2 |