Package: tinystream
tinystream / python-streamsThis is a simple and lightweight Streams API inspired by Java Streams with support for type hinting.This package is release astinystreamat pypi.Basic APIfromtinystreamimportStreamstream=Stream([1,2,3,4,5])# Stream.of_many(*), Stream.of_dict()stream\.map(lambdax:x+1)\# flatmap(), peek(), map_key(), map_kwargs(), map_keys().filter(lambdax:x>2)\# filter_key(), filter_type().sorted(reverse=True)\# sort().reverse()\.limit(2)\.concat([4])\.sum()# reduce(), max(), min(), collect(), count(), find()AggregatorsAggregators likesum(),count(),max()willcollect()the data and end the stream.collect()also caches the data and can be called multiple times, since it returns only alist.Built-in Optional supportSome aggregators likesum(),max()areoptional:assertStream((1,2,3,4,5)).sum().presentGet next value asoptional:assertStream((1,2,3,4,5)).next().presentCreate customoptional:fromtinystreamimportOptassertOpt(None).absentMapoptional:assertOpt("String").map(str.lower).len==6Get default value:assertOpt(None).get(6)==6assertOpt(None).get(lambda:6)==6assertOpt(None).if_absent(lambda:3).presentFilter value:assertOpt(0).filter(lambdax:x>0).absentYou can also access optional index elements of the stream, but this willcollect()and end the stream.assertStream([])[2].absentType hintingYou can typehint datatypes like:fromdataclassesimportdataclass@dataclassclassNode:name:strparent:"Node"=Noneparent=Node(name="B")child=Node(name="A",parent=parent)for lambdas:stream=Stream([child])assertstream.map(lambdax:x.parent).type(Node).next().get().name=="B"This is not necessary when you pass a mapping function:defmap_parent(n:Node):returnn.parentassertstream.map(map_parent).next().get().name=="B"More featuresTyped dictionariesDictionaries are streamed astuple(key, value)children={"a":Node(name="Child")}stream=Stream.of_dict(children)foriteminstream:# item[0] is known as str# item[1] is known as NodeThis is the same like (but without known types):stream=Stream(children)Filter by existing keyitems_with_name=Stream([child]).filter_key("name")Filter by typenodes_only=Stream([child]).filter_type(Node)Map object name attributenames=Stream([child]).map_key("name")Deep mapping of name attributeslist=[{"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 joinall_names=Stream([child]).map_key("name").join(", ")Map kwargslist=[{"name":"Node A"},{"name":"Node B"},]# Short cut for map(lambda x: Node(**x))nodes=Stream(list).map_kwargs(Node)Stream manymany=Stream.of_many([1,2,3],(4,5,6))many=many.concat([7,8,9])End of streamstream=Stream(["a","b","c"]).on_end(lambda:print("Finished"))char=stream.next().get()ifchar=="a":stream.end()ExamplesA given data structure like:data={"ranges":[timedelta(days=3),]}Without tinystream:if"ranges"indata:range_data:timedeltaforrange_datainfilter(lambdax:isinstance(x,timedelta),data["ranges"]):passWith tinystream:forrange_datainOpt(data).map_key("ranges").stream().filter_type(timedelta):passComparison with other librariesThere are a couple of other implementation to fulfill similar requirements.https://github.com/vxgmichel/aiostream(most professional)https://github.com/alemazzo/Python-Java-Streamhttps://github.com/ramsteak/streamshttps://pypi.org/project/fluentpyhttps://github.com/JaviOverflow/python-streams(outdated)https://github.com/9seconds/streams/(outdated)https://github.com/tolsac/streampy(outdated)Apache SparkRun the testsPYTHONPATH="."pytest--cov=tinystream-n4tests/Release updateUpdate version insetup.pyPackage librarypythonsetup.pysdistPublish librarytwineuploaddist/tinystream-[version].tar.gzReferenceshttps://github.com/MichaelKim0407/tutorial-pip-packagehttps://packaging.python.org/en/latest/guides/making-a-pypi-friendly-readme/