creek
A simple facade for streams: wrap an iterable, layer transformations on it, and read unbounded streams as if they were lists.
To install: pip install creek
The smallest complete example: a Creek subclass that parses each line of a file-like stream.
>>> from io import StringIO
>>> from creek import Creek
>>> class CsvCreek(Creek):
... def data_to_obj(self, line):
... return [x.strip() for x in line.strip().split(',')]
>>> stream = CsvCreek(StringIO('a, b, c\n1,2, 3\n'))
>>> list(stream)
[['a', 'b', 'c'], ['1', '2', '3']]
For AI agents
creek ships tooling for coding agents. If you are one, start here.
The documentation, machine-readable: llms.txt indexes every page; creek.md is the whole documentation in one file; every page has a .md twin; objects.inv maps symbols to URLs.
If you are a control freak, the rest of this README is written for you, starting at The Creek layers.
The Creek layers
The Creek base class offers a layer-able wrap of the stream interface. There are three layering methods, pre_iter, data_to_obj and post_iter, each the identity by default. Iterating over a creek is exactly:
yield from self.post_iter(map(self.data_to_obj, self.pre_iter(self.stream)))
pre_iter(stream): prepare and/or filter the raw stream (skip a header, enumerate lines, ...)data_to_obj(item): transform each item the stream yieldspost_iter(objs): further process or filter the transformed objects
Everything else (seek, close, the context manager protocol, ...) is delegated to the wrapped stream:
>>> src = StringIO(
... '''a, b, c
... 1,2, 3
... 4, 5,6
... '''
... )
>>> class MyCreek(Creek):
... def data_to_obj(self, line):
... return [x.strip() for x in line.strip().split(',')]
...
>>> stream = MyCreek(src)
>>> list(stream)
[['a', 'b', 'c'], ['1', '2', '3'], ['4', '5', '6']]
>>> stream.seek(0) # oh!... but we consumed the stream already, so let's go back to the beginning
0
>>> list(stream)
[['a', 'b', 'c'], ['1', '2', '3'], ['4', '5', '6']]
>>> stream.seek(0) # rewind again
0
>>> next(stream)
['a', 'b', 'c']
>>> next(stream)
['1', '2', '3']
Let's add a filter! There are two kinds you can use: one applied to the line before the data is transformed by data_to_obj (in pre_iter), and one applied after, to the objects (in post_iter).
>>> src = StringIO(
... '''a, b, c
... 1,2, 3
... 4, 5,6
... ''')
>>> class MyFilteredCreek(MyCreek):
... def post_iter(self, objs):
... yield from filter(lambda obj: str.isnumeric(obj[0]), objs)
>>>
>>> s = MyFilteredCreek(src)
>>> list(s)
[['1', '2', '3'], ['4', '5', '6']]
>>> s.seek(0)
0
>>> list(s)
[['1', '2', '3'], ['4', '5', '6']]
>>> s.seek(0)
0
>>> next(s)
['1', '2', '3']
Recipes:
pre_iter:itertools.isliceto skip header linespre_iter:enumerateto get line indices in the stream iteratorpre_iter = functools.partial(map, line_pre_proc_func)to preprocess all lines withline_pre_proc_funcpre_iter:functools.partial(filter, condition)to filter beforedata_to_objpost_iter:itertools.chain.from_iterableto flatten a chunked/segmented streampost_iter:functools.partial(filter, condition)to filter the yielded objects
Beyond Creek
InfiniteSeqandIndexedBuffer(creek.infinite_sequence): list-likes[i:j]access to an unbounded stream, through a bounded buffer.BufferStatsandSegmenter(creek.tools): rolling-window statistics and segmentation of a stream.dynamically_indexandfilter_and_index_stream(creek.tools):enumeratewith a custom index rule, and filtered indexing.
Documentation
- Rendered docs: https://i2mint.github.io/creek/
- The whole API in one Markdown file: https://i2mint.github.io/creek/creek.md
Metadata
Release files for creek 0.1.36
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| creek-0.1.36.tar.gz | 45.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| creek-0.1.36-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 94.1 kB
Release files / creek-0.1.36.tar.gz
| Download URL | creek-0.1.36.tar.gz |
|---|---|
| Size | 45.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4dbd4592185b35d2d9c3a08c618d555a5c1fb8f7781b8958f6fa9a9a94d770ba
|
|
BLAKE2b-256 checksum How to use checksums |
129fbac920b05b272349699e7da8a45bb99482ef37ddbc50861d0c7daca75810
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.14 {"installer":{"name":"uv","version":"0.12.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / creek-0.1.36-py3-none-any.whl
| Download URL | creek-0.1.36-py3-none-any.whl |
|---|---|
| Size | 48.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2134b8feab4fcbfb6fde4a3ba0fb6a2eca2b61d35769ecd11149941361ad2a30
|
|
BLAKE2b-256 checksum How to use checksums |
afecd3585869dd25520379dc343d7e77a9c0790b42ac7960a0b8dee9fa9bfea6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.14 {"installer":{"name":"uv","version":"0.12.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|