Python pipeline utility library
In the process of building machine learning things at Zendesk, we have noticed that a lot of the steps are sequential where later steps rely on outputs of previous steps. Because Python functions only return a single value (return
with multiple values are returned as a tuple), deconstructing and keeping track of return values becomes tedious for long sequences of steps, especially when inputs are not returned from the immediately previous step.
PAKKR is an utility created to remediate these pain points; it provides the user with a way to specify how return values should be interpreted and optionally caches results and injects them in later steps automatically.
bash
pip install pakkr
bash
git clone [email protected]:zendesk/pakkr.git
cd pakkr
python setup.py install
```python from pakkr import Pipeline, returns
@returns(int, original_num_as_string=str) # this function returns an integer and insert original_num_as_string into the meta cache def times_two(n): return n*2, {'original_num_as_string': str(n)}
@returns(int, int) # this functions returns two integers and will be passed on as two arguments def plus_five_and_three(n): return n + 5, n + 3
@returns(str) def summary(a, b, original_num_as_string): # a and b are passed in as positional arguments, # but original_num_as_string would be injected from the meta cache return f'Original input was {original_num_as_string} and it became {str(a)} and {str(b)} after processing'
pipeline = Pipeline(times_two, plus_five_and_three, summary, _name='process_int')
print(pipeline(3))
Running the above code should print:
Original input was 3 and it became 11 and 9 after processing
```
returns
is used to indicate how the return values should be interpreted; @returns(int, str, x=bool)
means the Callable
should be returning something like return 10, 'hello', {'x': True}
and the 10
and 'hello'
will be passed as two positional arguments into the next Callable
while x
would be cached in the meta space and be injected if any following Callable
s require x
but not being given as positional argument from the previous Callable
.
This project uses tox
to manage testing on multiple Python versions assuming the required Python versions are available.
git clone [email protected]:zendesk/pakkr.git
cd pakkr
pip install tox
tox
Optionally, uses pyenv
and pipenv
to manage Python installation and development dependencies.
```bash
git clone [email protected]:zendesk/pakkr.git
cd pakkr
pyenv local 3.6.10 3.7.6 3.8.1
pip install pipenv pipenv sync --dev
pipenv run tox ```
Please raise an issue via GitHub.
Improvements are always welcome. Please follow these steps to contribute
Use of this software is subject to important terms and conditions as set forth in the LICENSE file.
Bumps certifi from 2021.5.30 to 2022.12.7.
9e9e840
2022.12.07b81bdb2
2022.09.24939a28f
2022.09.14aca828a
2022.06.15.2de0eae1
Only use importlib.resources's new files() / Traversable API on Python ≥3.11 ...b8eb5e9
2022.06.15.147fb7ab
Fix deprecation warning on Python 3.11 (#199)b0b48e0
fixes #198 -- update link in license9d514b4
2022.06.154151e88
Add py.typed to MANIFEST.in to package in sdist (#196)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps ipython from 7.25.0 to 7.31.1.
e321e76
release 7.31.167ca2b3
Merge pull request from GHSA-pq7m-3gw7-gq5x2794330
back to devbe343e7
release 7.31.00fcf2c4
Merge pull request #13428 from meeseeksmachine/auto-backport-of-pr-13427-on-7.xb8db9b1
Backport PR #13427: wn 7317f253dc
Merge pull request #13412 from bnavigator/backport-inspect4f26796
fix xxlimited_35 import name77ca4a6
don't run nose-based iptest on py310, only pytest533e509
back to decorator skipDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Rather than adding an attribute onto the function/class being decorated, it would be great if we could specify the return type, i.e. @returns(...)
directly as type annotation like def do_something(x: int) -> returns(int, some_meta=str)
etc.
Initial release to PyPi