Metadata-Version: 2.1
Name: zookeeper
Version: 1.0b4
Summary: A small library for managing deep learning models, hyper parameters and datasets
Home-page: https://github.com/larq/zookeeper
Author: Plumerai
Author-email: lukas@plumerai.co.uk
License: Apache 2.0
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development
Requires-Python: >=3.6
Description-Content-Type: text/markdown
Requires-Dist: click (>=7.0)
Requires-Dist: prompt-toolkit (>=2.0.10)
Requires-Dist: tensorflow-datasets (>=1.3.0)
Requires-Dist: typeguard (>=2.5.1)
Provides-Extra: tensorflow
Requires-Dist: tensorflow (>=1.14.0) ; extra == 'tensorflow'
Provides-Extra: tensorflow_gpu
Requires-Dist: tensorflow-gpu (>=1.14.0) ; extra == 'tensorflow_gpu'
Provides-Extra: test
Requires-Dist: black (==19.10b0) ; extra == 'test'
Requires-Dist: flake8 (~=3.7.9) ; extra == 'test'
Requires-Dist: isort (~=4.3.21) ; extra == 'test'
Requires-Dist: pytest (>=4.3.1) ; extra == 'test'
Requires-Dist: pytest-cov (>=2.6.1) ; extra == 'test'
Requires-Dist: pytype (<2020.2.0,>=2019.10.17) ; extra == 'test'

# Zookeeper

[![GitHub Actions](https://github.com/larq/zookeeper/workflows/Unittest/badge.svg)](https://github.com/larq/zookeeper/actions?workflow=Unittest) [![Codecov](https://img.shields.io/codecov/c/github/larq/zookeeper)](https://codecov.io/github/larq/zookeeper?branch=master) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/zookeeper.svg)](https://pypi.org/project/zookeeper/) [![PyPI](https://img.shields.io/pypi/v/zookeeper.svg)](https://pypi.org/project/zookeeper/) [![PyPI - License](https://img.shields.io/pypi/l/zookeeper.svg)](https://github.com/plumerai/zookeeper/blob/master/LICENSE) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/larq)

A small library for configuring modular applications.

### Installation

```console
pip install zookeeper
```

### Components

The fundamental building blocks of Zookeeper are components. The
[`@component`](zookeeper/component.py) decorator is used to turn classes into
components. These component classes can have configurable parameters, which are
declared using class-level type annotations (in a similar way to [Python
dataclasses](https://docs.python.org/3/library/dataclasses.html)). These
parameters can be Python objects or nested sub-components, and need not be set
with a default value.

For example:

```python
from zookeeper import component

@component
class ChildComponent:
    a: int                  # An `int` parameter, with no default set
    b: str = "foo"          # A `str` parameter, which by default will be `foo`

@component
class ParentComponent:
    a: int                  # The same `int` parameter as the child
    child: ChildComponent   # A nested component parameter, of type `ChildComponent`
```

After instantiation, components can be 'configured' with a configuration
dictionary, containing values for a tree of nested parameters. This process
automatically injects the correct values into each parameter.

If a child sub-component declares a parameter which already exists in some
containing parent, then it will pick up the value that's set on the parent,
unless a 'scoped' value is set on the child.

For example:

```
from zookeeper import configure

p = ParentComponent()

configure(
    p,
    {
        "a": 5,
        "child.a": 4,
    }
)

>>> 'ChildComponent' is the only concrete component class that satisfies the type
>>> of the annotated parameter 'ParentComponent.child'. Using an instance of this
>>> class by default.

print(p)

>>> ParentComponent(
>>>     a = 5,
>>>     child = ChildComponent(
>>>         a = 4,
>>>         b = "foo"
>>>     )
>>> )
```

### Tasks and the CLI

The [`@task`](zookeeper/task.py) decorator is used to define Zookeeper tasks and
can be applied to any class that implements an argument-less `run` method. Such
tasks can be run through the Zookeeper CLI, with parameter values passed in
through CLI arguments (`configure` is implicitly called).

For example:

```python
from zookeeper import cli, task

@task
class UseChildA:
    parent: ParentComponent
    def run(self):
        print(self.parent.child.a)

@task
class UseParentA(UseChildA):
    def run(self):
        print(self.parent.a)

if __name__ == "__main__":
    cli()
```

Running the above file then gives a nice CLI interface:

```
python test.py use_child_a
>>> ValueError: No configuration value found for annotated parameter 'UseChildA.parent.a' of type 'int'.

python test.py use_child_a a=5
>>> 5

python test.py use_child_a a=5 child.a=3
>>> 3

python test.py use_parent_a a=5 child.a=3
>>> 5
```

### Using Zookeeper to define Larq or Keras experiments

See [examples/larq_experiment.py](examples/larq_experiment.py) for an example of
how to use Zookeeper to define all the necessary components (dataset,
preprocessing, and model) of a Larq experiment: training a BinaryNet on
MNIST. This example can be easily adapted to other Larq or Keras models and
other datasets.


