# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['baobao', 'baobao.utils']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'baobao',
    'version': '0.2.1',
    'description': '',
    'long_description': '![image.png](notebooks/baobao_logo.png)\n\nBaobao is a small library that attempts writing and maintaining data pipelines easier. It was written with Pandas in mind, but is not limited to it or even depends on it. It\'s AIP closely models Pandas pipe functionality.\n\nDesign principles are:\n- Simple in the core\n- Minimal dependencies\n- Additional functionality is optional\n\nPipelines can be build like this:\n\n\n```python\nimport pandas as pd\nfrom baobao import Pipeline  # To define pipelines\nfrom baobao import Step  # Pipelines are build from Steps which may contain Pipelines\n\n# some functions that return pd.Dataframes to play with\nfrom baobao.utils.examples import load_1, load_2, load_3\n\nPipeline(\n    root_node=load_1,  # We have to start somewhere, could be any object or callable\n    pipeline=(  # Pipelines are build from Steps\n        Step(\n            # Each Step is build from a function that takes \n            # the output of the previous Step as input in \n            # the first argument\n            func=pd.merge,\n            # Any argoments to [func] can be given\n            left_index=True, right_index=True,\n            right=Pipeline(load_2),  # including additional Pipelines\n        ),\n        Step(func=pd.merge, right=Pipeline(load_3), left_index=True, right_index=True),\n    )\n).run()  # Call the run method to actually run the pipeline, enjoy some logging out of the box\n```\n    INFO:root:Pipeline(root_node=load_1(),memory=None)\n    INFO:root:    Step(func=merge,args=(),left_index=True,right_index=True,right=Pipeline(root_node=l[...])\n    INFO:root:Pipeline(root_node=load_2(),memory=None)\n    Load 1\n    INFO:root:Complete pipeline after 3.02s\n    INFO:root:    Step(func=merge,args=(),right=Pipeline(root_node=l[...],left_index=True,right_index=True)\n    INFO:root:Pipeline(root_node=load_3(),memory=None)\n    Load 2\n    INFO:root:Complete pipeline after 3.02s\n    INFO:root:Complete pipeline after 9.06s\n    Load 3\n\n\n\nA neat way of speeding this up is caching results to disk:\n\n\n```python\n# Baobao doesn\'t depend on any caching but respects Joblibs \n# API in case you want to chose some other caching strategy  \nfrom joblib import Memory\n\n# Baobao options are separated into a dedicated object in\n# order to make it simple to push options down to Pipelines\n# included in Steps of the root Pipeline\nfrom baobao import PipelineOpts\n\n# Define the pipeline:\npipeline = Pipeline(\n    root_node=load_1,\n    opts=PipelineOpts(\n        memory=Memory("./cache", verbose=0),\n        push_options=True  # Pushing options down to included Pipelines\n    ),\n    pipeline=(\n        Step(func=pd.merge, right=Pipeline(load_2), left_index=True, right_index=True),\n        Step(func=pd.merge, right=Pipeline(load_3), left_index=True, right_index=True),\n    )\n)\n# Run the pipeline:\npipeline.run()\n```\n\n    INFO:root:Pipeline(root_node=load_1(),memory=Memory(location=./cache/joblib))\n    INFO:root:    Step(func=merge,args=(),right=Pipeline(root_node=l[...],left_index=True,right_index=True)\n    INFO:root:    Pipeline(root_node=load_2(),memory=Memory(location=./cache/joblib))\n    INFO:root:    Complete pipeline after 0.00s\n    INFO:root:    Step(func=merge,args=(),right=Pipeline(root_node=l[...],left_index=True,right_index=True)\n    INFO:root:    Pipeline(root_node=load_3(),memory=Memory(location=./cache/joblib))\n    INFO:root:    Complete pipeline after 0.01s\n    INFO:root:Complete pipeline after 0.04s\n\nReasoning over pipelines might be simpler with this printing utility:\n\n\n```python\nfrom baobao.utils import print_pipeline\nprint_pipeline(pipeline)\n```\n\n    pipeline << load_1\n     ╠══ Step 0:merge\n     ║   ╠══ right = DataFrame shape:(10, 1), columns:[\'c2\']\n     ║   ╠══ left_index = True\n     ║   ╚══ right_index = True\n     ╚══ Step 1:merge\n         ╠══ right = DataFrame shape:(10, 1), columns:[\'c3\']\n         ╠══ left_index = True\n         ╚══ right_index = True\n\n\nPrinting can be adjusted using the multiple dispatch pattern:\n\n\n```python\nfrom baobao.pipeline import str_\n@str_.register\ndef _(inp: pd.DataFrame):\n    return f"DataFrame(shape:{inp.shape})"\n@str_.register\ndef _(inp: bool):\n    return f"Bool:{inp}"\n\nprint_pipeline(pipeline)\n```\n\n    pipeline << load_1\n     ╠══ Step 0:merge\n     ║   ╠══ right = DataFrame(shape:(10, 1))\n     ║   ╠══ left_index = Bool:True\n     ║   ╚══ right_index = Bool:True\n     ╚══ Step 1:merge\n         ╠══ right = DataFrame(shape:(10, 1))\n         ╠══ left_index = Bool:True\n         ╚══ right_index = Bool:True\n\n\nA little more depth added:\n\n\n```python\nfrom baobao.utils.examples import *  # Import more load_X functions\n\ndef mk_pipeline():  # get fresh pipeline each time we call this function\n    return Pipeline(\n        root_node=load_1,\n        opts=PipelineOpts(\n            memory=None,#Memory("./cache", verbose=0),\n            push_options=True\n        ),\n        pipeline=(\n            Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(load_2)),\n            Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(\n                root_node=load_3,\n                pipeline=(\n                    Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(load_4)),\n                    Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(\n                        root_node=load_2,\n                        pipeline=(\n                            Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(load_5)),\n                            Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(load_6)),\n                        )\n                    )),\n                ))\n                ),\n            Step(func=pd.merge, left_index=True, right_index=True, right=Pipeline(load_5)),\n        )\n    )\n```\n\nLets print this one again:\n\n\n```python\nprint_pipeline(mk_pipeline())\n```\n\n    pipeline << load_1\n     ╠══ Step 0:merge\n     ║   ╠══ left_index = Bool:True\n     ║   ╠══ right_index = Bool:True\n     ║   ╚══ right\n     ║       ╚══ pipeline << load_2\n     ╠══ Step 1:merge\n     ║   ╠══ left_index = Bool:True\n     ║   ╠══ right_index = Bool:True\n     ║   ╚══ right\n     ║       ╚══ pipeline << load_3\n     ║           ╠══ Step 0:merge\n     ║           ║   ╠══ left_index = Bool:True\n     ║           ║   ╠══ right_index = Bool:True\n     ║           ║   ╚══ right\n     ║           ║       ╚══ pipeline << load_4\n     ║           ╚══ Step 1:merge\n     ║               ╠══ left_index = Bool:True\n     ║               ╠══ right_index = Bool:True\n     ║               ╚══ right\n     ║                   ╚══ pipeline << load_2\n     ║                       ╠══ Step 0:merge\n     ║                       ║   ╠══ left_index = Bool:True\n     ║                       ║   ╠══ right_index = Bool:True\n     ║                       ║   ╚══ right\n     ║                       ║       ╚══ pipeline << load_5\n     ║                       ╚══ Step 1:merge\n     ║                           ╠══ left_index = Bool:True\n     ║                           ╠══ right_index = Bool:True\n     ║                           ╚══ right\n     ║                               ╚══ pipeline << load_6\n     ╚══ Step 2:merge\n         ╠══ left_index = Bool:True\n         ╠══ right_index = Bool:True\n         ╚══ right\n             ╚══ pipeline << load_5\n\n\nand run it in a sequential manner:\n\n\n```python\nmk_pipeline().run()\n```\n    INFO:root:Pipeline(root_node=load_1(),memory=None)\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:    Pipeline(root_node=load_2(),memory=None)\n    Load 1\n    INFO:root:    Complete pipeline after 3.01s\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:    Pipeline(root_node=load_3(),memory=None)\n    Load 2\n    INFO:root:        Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:        Pipeline(root_node=load_4(),memory=None)\n    Load 3\n    INFO:root:        Complete pipeline after 3.02s\n    INFO:root:        Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:        Pipeline(root_node=load_2(),memory=None)\n    Load 4\n    INFO:root:            Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:            Pipeline(root_node=load_5(),memory=None)\n    Load 2\n    INFO:root:            Complete pipeline after 3.01s\n    INFO:root:            Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:            Pipeline(root_node=load_6(),memory=None)\n    Load 5\n    INFO:root:            Complete pipeline after 3.01s\n    INFO:root:        Complete pipeline after 9.05s\n    INFO:root:    Complete pipeline after 15.10s\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:    Pipeline(root_node=load_5(),memory=None)\n    Load 6\n    INFO:root:    Complete pipeline after 3.01s\n    INFO:root:Complete pipeline after 24.15s\n    Load 5\n\nWe can speed things up by submitting those pipelines that do not contain further pipelines to a multiprocess Pool and enjoy some nice speedups:\n\n\n```python\nfrom baobao.utils import run_parallel\n\nrun_parallel(mk_pipeline(), n_jobs=4)\n```\n\n    INFO:root:Submit: Pipeline(root_node=load_2(),memory=None) to: <multiprocessing.pool.Pool state=RUN pool_size=4>\n    INFO:root:Submit: Pipeline(root_node=load_4(),memory=None) to: <multiprocessing.pool.Pool state=RUN pool_size=4>\n    INFO:root:Submit: Pipeline(root_node=load_5(),memory=None) to: <multiprocessing.pool.Pool state=RUN pool_size=4>\n    INFO:root:Pipeline(root_node=load_2(),memory=None)\n    INFO:root:Submit: Pipeline(root_node=load_6(),memory=None) to: <multiprocessing.pool.Pool state=RUN pool_size=4>\n    INFO:root:Pipeline(root_node=load_4(),memory=None)\n    INFO:root:Submit: Pipeline(root_node=load_5(),memory=None) to: <multiprocessing.pool.Pool state=RUN pool_size=4>\n    INFO:root:Pipeline(root_node=load_1(),memory=None)\n    INFO:root:Pipeline(root_node=load_5(),memory=None)\n    INFO:root:Pipeline(root_node=load_6(),memory=None)\n    Load 4\n    Load 2\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=<multiprocessing.poo[...])\n    Load 6\n    INFO:root:Complete pipeline after 3.04s\n    Load 5\n    INFO:root:Pipeline(root_node=load_5(),memory=None)\n    INFO:root:Complete pipeline after 3.04s\n    INFO:root:Complete pipeline after 3.06s\n    INFO:root:Complete pipeline after 3.06s\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:    Pipeline(root_node=load_3(),memory=None)\n    Load 1\n    Load 5\n    INFO:root:Complete pipeline after 3.02s\n    INFO:root:        Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=<multiprocessing.poo[...])\n    INFO:root:        Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=Pipeline(root_node=l[...])\n    INFO:root:        Pipeline(root_node=load_2(),memory=None)\n    Load 3\n    INFO:root:            Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=<multiprocessing.poo[...])\n    INFO:root:            Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=<multiprocessing.poo[...])\n    INFO:root:        Complete pipeline after 3.02s\n    INFO:root:    Complete pipeline after 6.04s\n    INFO:root:    Step(func=merge,args=(),left_index=Bool:True,right_index=Bool:True,right=<multiprocessing.poo[...])\n    INFO:root:Complete pipeline after 9.15s\n    Load 2\n',
    'author': 'André Hollstein',
    'author_email': 'andre@dr-hollstein.de',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
