diff --git a/bonobo/_api.py b/bonobo/_api.py index 26ff253..7d0f15e 100644 --- a/bonobo/_api.py +++ b/bonobo/_api.py @@ -1,3 +1,5 @@ +import warnings + from bonobo.basics import Limit, PrettyPrint, Tee, count, identity, noop, pprint from bonobo.strategies import create_strategy from bonobo.structs import Bag, Graph @@ -11,22 +13,60 @@ def register_api(x, __all__=__all__): __all__.append(get_name(x)) return x + def register_api_group(*args): for attr in args: register_api(attr) -# bonobo.basics -register_api_group(Limit, PrettyPrint, Tee, count, identity, noop, pprint, ) +@register_api +def run(graph, *chain, strategy=None, plugins=None, services=None): + """ + Main entry point of bonobo. It takes a graph and creates all the necessary plumbery around to execute it. + + The only necessary argument is a :class:`Graph` instance, containing the logic you actually want to execute. + + By default, this graph will be executed using the "threadpool" strategy: each graph node will be wrapped in a + thread, and executed in a loop until there is no more input to this node. + + You can provide plugins factory objects in the plugins list, this function will add the necessary plugins for + interactive console execution and jupyter notebook execution if it detects correctly that it runs in this context. + + You'll probably want to provide a services dictionary mapping service names to service instances. + + :param Graph graph: The :class:`Graph` to execute. + :param str strategy: The :class:`bonobo.strategies.base.Strategy` to use. + :param list plugins: The list of plugins to enhance execution. + :param dict services: The implementations of services this graph will use. + :return bonobo.execution.graph.GraphExecutionContext: + """ + if len(chain): + warnings.warn('DEPRECATED. You should pass a Graph instance instead of a chain.') + from bonobo import Graph + graph = Graph(graph, *chain) -# bonobo.io -register_api_group(CsvReader, CsvWriter, FileReader, FileWriter, JsonReader, JsonWriter) + strategy = create_strategy(strategy) + plugins = plugins or [] + + if _is_interactive_console(): + from bonobo.ext.console import ConsoleOutputPlugin + if ConsoleOutputPlugin not in plugins: + plugins.append(ConsoleOutputPlugin) + + if _is_jupyter_notebook(): + from bonobo.ext.jupyter import JupyterOutputPlugin + if JupyterOutputPlugin not in plugins: + plugins.append(JupyterOutputPlugin) + + return strategy.execute(graph, plugins=plugins, services=services) + + +# bonobo.structs +register_api_group(Bag, Graph) # bonobo.strategies register_api(create_strategy) -# bonobo.structs -register_api_group(Bag, Graph) # Shortcut to filesystem2's open_fs, that we make available there for convenience. @register_api @@ -47,6 +87,12 @@ def open_fs(fs_url, *args, **kwargs): return _open_fs(str(fs_url), *args, **kwargs) +# bonobo.basics +register_api_group(Limit, PrettyPrint, Tee, count, identity, noop, pprint, ) + +# bonobo.io +register_api_group(CsvReader, CsvWriter, FileReader, FileWriter, JsonReader, JsonWriter) + def _is_interactive_console(): import sys @@ -60,29 +106,6 @@ def _is_jupyter_notebook(): return False -@register_api -def run(graph, *chain, strategy=None, plugins=None, services=None): - if len(chain): - warnings.warn('DEPRECATED. You should pass a Graph instance instead of a chain.') - from bonobo import Graph - graph = Graph(graph, *chain) - - strategy = create_strategy(strategy) - plugins = [] - - if _is_interactive_console(): - from bonobo.ext.console import ConsoleOutputPlugin - if ConsoleOutputPlugin not in plugins: - plugins.append(ConsoleOutputPlugin) - - if _is_jupyter_notebook(): - from bonobo.ext.jupyter import JupyterOutputPlugin - if JupyterOutputPlugin not in plugins: - plugins.append(JupyterOutputPlugin) - - return strategy.execute(graph, plugins=plugins, services=services) - - @register_api def get_examples_path(*pathsegments): import os @@ -94,5 +117,3 @@ def get_examples_path(*pathsegments): def open_examples_fs(*pathsegments): return open_fs(get_examples_path(*pathsegments)) - -print(__all__) diff --git a/bonobo/structs/bags.py b/bonobo/structs/bags.py index 8605b19..4d86f89 100644 --- a/bonobo/structs/bags.py +++ b/bonobo/structs/bags.py @@ -9,6 +9,30 @@ __all__ = [ class Bag: + """ + Bags are simple datastructures that holds arguments and keyword arguments together, that may be applied to a + callable. + + Example: + + >>> from bonobo import Bag + >>> def myfunc(foo, *, bar): + ... print(foo, bar) + ... + >>> bag = Bag('foo', bar='baz') + >>> bag.apply(myfunc) + foo baz + + A bag can inherit another bag, allowing to override only a few arguments without touching the parent. + + Example: + + >>> bag2 = Bag(bar='notbaz', _parent=bag) + >>> bag2.apply(myfunc) + foo notbaz + + """ + def __init__(self, *args, _flags=None, _parent=None, **kwargs): self._flags = _flags or () self._parent = _parent diff --git a/docs/contribute/index.rst b/docs/contribute/index.rst index 79d576b..6ee7e31 100644 --- a/docs/contribute/index.rst +++ b/docs/contribute/index.rst @@ -1,6 +1,21 @@ Contributing ============ +There's a lot of different ways you can contribute, and not all of them includes coding. Do not think that the codeless +contributions have less value, all contributions are very important. + +* You can contribute to the documentation. +* You can help reproducing errors and giving more infos in the issues. +* You can open issues with problems you're facing. +* You can help creating better presentation material. +* You can talk about it in your local python user group. +* You can enhance examples. +* You can enhance tests. +* etc. + +Code-related contributions (including tests and examples) +::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + Contributing to bonobo is usually done this way: * Discuss ideas in the `issue tracker `_ or on `Slack `_. diff --git a/docs/guide/index.rst b/docs/guide/index.rst index 02082aa..dab1b44 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -22,5 +22,6 @@ available as an optional extra dependency, and the maturity stage of each extens :maxdepth: 2 ext/docker + ext/jupyter ext/selenium ext/sqlalchemy diff --git a/docs/reference/api.rst b/docs/reference/api.rst index 13376ac..e401b9c 100644 --- a/docs/reference/api.rst +++ b/docs/reference/api.rst @@ -1,54 +1,13 @@ -Public API +Bonobo API ========== -All the "public api" callables, classes and other callables are available under the root :mod:`bonobo` package, even if -they are documented within their sub-namespace, for convenience. +The Bonobo API, available directly under the :mod:`bonobo` package, contains all the tools you need to get started with +bonobo. + +The :mod:`bonobo` package +::::::::::::::::::::::::: .. automodule:: bonobo - :members: create_strategy, get_examples_path, run - :undoc-members: - :show-inheritance: - -Config ------- - -.. automodule:: bonobo.config - :members: - :undoc-members: - :show-inheritance: - - -Context -------- - -.. automodule:: bonobo.context - :members: - :undoc-members: - :show-inheritance: - - -Core ----- - -.. automodule:: bonobo.core - :members: - :undoc-members: - :show-inheritance: - - -IO --- - -.. automodule:: bonobo.io - :members: - :undoc-members: - :show-inheritance: - - -Util ----- - -.. automodule:: bonobo.util :members: :undoc-members: :show-inheritance: diff --git a/docs/reference/api_config.rst b/docs/reference/api_config.rst new file mode 100644 index 0000000..c1010a7 --- /dev/null +++ b/docs/reference/api_config.rst @@ -0,0 +1,10 @@ +Config API +========== + +The Config API, located under the :mod:`bonobo.config` namespace, contains all the tools you need to create +configurable transformations, either class-based or function-based. + +.. automodule:: bonobo.config + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/reference/commands.rst b/docs/reference/commands.rst index 8d79fb6..f7c95af 100644 --- a/docs/reference/commands.rst +++ b/docs/reference/commands.rst @@ -1,5 +1,5 @@ -Commands Reference -================== +Command-line Reference +====================== Bonobo Init ::::::::::: diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 763a126..f255e22 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -1,11 +1,10 @@ References ========== -.. todo:: write the fucking doc! - .. toctree:: :maxdepth: 4 - commands api + api_config + commands examples diff --git a/docs/tutorial/index.rst b/docs/tutorial/index.rst index 324fed7..e57e154 100644 --- a/docs/tutorial/index.rst +++ b/docs/tutorial/index.rst @@ -10,7 +10,7 @@ We strongly advice that even if you're an advanced python developper, you go thr reasons: that should be sufficient to do anything possible with **Bonobo** and that's a good moment to learn the few concepts you'll see everywhere in the software. -If you're not familiar with python, you should first read :doc:`./python`. +If you're not familiar with python, you should first read :doc:`python`. .. toctree:: :maxdepth: 2 diff --git a/docs/tutorial/python.rst b/docs/tutorial/python.rst index dae49b8..d045031 100644 --- a/docs/tutorial/python.rst +++ b/docs/tutorial/python.rst @@ -6,16 +6,6 @@ Just enough Python for Bonobo This is a work in progress and it is not yet available. Please come back later or even better, help us write this guide! -This guide is intended to help programmers or enthusiasts to grasp the python basics necessary to use Bonobo. It should -definately not be considered as a general python introduction, neither a deep dive into details. - -.. toctree:: - :maxdepth: 2 - - python01 - python02 - python03 - python04 - python05 - + This guide is intended to help programmers or enthusiasts to grasp the python basics necessary to use Bonobo. It + should definately not be considered as a general python introduction, neither a deep dive into details.