diff --git a/README.md b/README.md index 9a1117b6..f5505147 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,11 @@ recent features, bugfixes, and hotfixes. See [Releases](https://github.com/fidelity/spock/releases) for more information. +### March 18th, 2021 + +* Support for Google docstring style annotation of `spock` class (and Enums) and attributes +* Added in ability to print docstring annotated help information to command line with `--help` argument + #### March 1st, 2021 * Removed legacy backend and API (dataclasses and custom typed interface) @@ -44,13 +49,6 @@ See [Releases](https://github.com/fidelity/spock/releases) for more information. input files * Changed tuples to support length restrictions -#### November 25th, 2020 - -* Addition of [Advanced Types](docs/advanced_features/Advanced-Types.md) -* Bumped support to include Python 3.9 -* Checks for circular dependencies in composed config files -* Pickle support for dynamically created `spock` class - ## Documentation Current documentation and more information can be found [here](https://fidelity.github.io/spock/). diff --git a/docs/Quick-Start.md b/docs/Quick-Start.md index cf05f4ed..1a273742 100644 --- a/docs/Quick-Start.md +++ b/docs/Quick-Start.md @@ -25,8 +25,9 @@ found [here](https://github.com/fidelity/spock/blob/master/docs/legacy) A basic python script, `simple.py`. -First we import the necessary functionality from `spock`. We define our class using the `@spock` -decorator and our parameters with supported argument types from `typing`. +First we import the necessary functionality from `spock`. We define our class using the `@spock` decorator and our +parameters with supported argument types from the `typing` library. Lastly, we write simple Google style +docstrings to provide command line `--help` information. ```python from spock.builder import ConfigArgBuilder @@ -35,6 +36,15 @@ from typing import List @spock class BasicConfig: + """Basic spock configuration for example purposes + + Attributes: + parameter: simple boolean that flags rounding + fancy_parameter: parameter that multiplies a value + fancier_parameter: parameter that gets added to product of val and fancy_parameter + most_fancy_parameter: values to apply basic algebra to + + """ parameter: bool fancy_parameter: float fancier_parameter: float @@ -70,7 +80,7 @@ second function. ```python def main(): # Chain the generate function to the class call - config = ConfigArgBuilder(BasicConfig).generate() + config = ConfigArgBuilder(BasicConfig, desc='Quick start example').generate() # One can now access the Spock config object by class name with the returned namespace print(config.BasicConfig.parameter) # And pass the namespace to our first function @@ -97,8 +107,28 @@ fancier_parameter: 64.64 most_fancy_parameter: [768, 768, 512, 128] ``` -Finally, we would then pass the path to the configuration file to the command line (-c or --config): +Finally, we would run our script and pass the path to the configuration file to the command line (-c or --config): ```bash $ python simple.py -c simple.yaml ``` + +To get help for our `spock` class and defined parameters: + +```bash +$ python simple.py --help +``` + +``` +usage: /Users/a635179/Documents/git_repos/open_source/spock/examples/quick-start/simple.py -c [--config] config1 [config2, config3, ...] + +Quick start example + +configuration(s): + + BasicConfig (Basic spock configuration for example purposes) + parameter bool simple boolean that flags rounding (default: False) + fancy_parameter float parameter that multiplies a value + fancier_parameter float parameter that gets added to product of val and fancy_parameter + most_fancy_parameter List[int] values to apply basic algebra to +``` \ No newline at end of file diff --git a/docs/basic_tutorial/Define.md b/docs/basic_tutorial/Define.md index cbd083f7..63476c82 100644 --- a/docs/basic_tutorial/Define.md +++ b/docs/basic_tutorial/Define.md @@ -30,7 +30,7 @@ Exception if not value is specified. `spock` supports more than just basic types. More information can be found in the [Advanced Types](../advanced_features/Advanced-Types.md) section. -### Defining A spock Class +### Defining a spock Class Let's start building out an example (a simple neural net in PyTorch) that we will continue to use within the tutorial: `tutorial.py` @@ -62,6 +62,79 @@ class ModelConfig: activation: Activation ``` +### Adding Help Information + +`spock` uses the [Google](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) docstring style +format to support adding help information to classes and Enums. `spock` will look for the first contiguous line of text +within the docstring as the class help information. `spock` looks within the `Attributes` section of the docstring +for help information for each parameter. Modifying the above code to include help information: + +```python +from enum import Enum +from spock.args import SavePath +from spock.config import spock +from typing import List +from typing import Tuple + +class Activation(Enum): + """Options for activation functions + + Attributes: + relu: relu activation + gelu: gelu activation + tanh: tanh activation + """ + relu = 'relu' + gelu = 'gelu' + tanh = 'tanh' + + +@spock +class ModelConfig: + """Main model configuration for a basic neural net + + Attributes: + save_path: spock special keyword -- path to write out spock config state + n_features: number of data features + dropout: dropout rate for each layer + hidden_sizes: hidden size for each layer + activation: choice from the Activation enum of the activation function to use + """ + save_path: SavePath + n_features: int + dropout: List[float] + hidden_sizes: Tuple[int] + activation: Activation +``` + +If we run our `tutorial.py` script with the `--help` flag: + +```bash +$ python tutorial.py --help +``` + +We should see the help information we added to the docstring(s): + +``` +usage: /Users/a635179/Documents/git_repos/open_source/spock/examples/tutorial/basic/tutorial.py -c [--config] config1 [config2, config3, ...] + +spock Basic Tutorial + +configuration(s): + + ModelConfig (Main model configuration for a basic neural net) + save_path Optional[SavePath] spock special keyword -- path to write out spock config state (default: None) + n_features int number of data features + dropout List[float] dropout rate for each layer + hidden_sizes Tuple[int] hidden size for each layer + activation Activation choice from the Activation enum of the activation function to use + + Activation (Options for activation functions) + relu str relu activation + gelu str gelu activation + tanh str tanh activation +``` + ### Using spock Parameters: Writing More Code In another file let's write our simple neural network code: `basic_nn.py` diff --git a/docs/basic_tutorial/Run.md b/docs/basic_tutorial/Run.md index 2566257e..87fe8d8d 100644 --- a/docs/basic_tutorial/Run.md +++ b/docs/basic_tutorial/Run.md @@ -17,4 +17,14 @@ To run `tutorial.py` we pass the path to the configuration file as a command lin $ python tutorial.py --config tutorial.yaml ``` +### Help + +To get help for parameters need to run our `tutorial.py` script: + +```bash +$ python tutorial.py --help +``` + + + The complete basic example can be found [here](https://github.com/fidelity/spock/blob/master/examples). \ No newline at end of file diff --git a/examples/quick-start/simple.py b/examples/quick-start/simple.py index e9b4b3e6..0f00a00f 100644 --- a/examples/quick-start/simple.py +++ b/examples/quick-start/simple.py @@ -5,6 +5,15 @@ @spock class BasicConfig: + """Basic spock configuration for example purposes + + Attributes: + parameter: simple boolean that flags rounding + fancy_parameter: parameter that multiplies a value + fancier_parameter: parameter that gets added to product of val and fancy_parameter + most_fancy_parameter: values to apply basic algebra to + + """ parameter: bool fancy_parameter: float fancier_parameter: float @@ -31,7 +40,7 @@ def add_by_parameter(multiply_param, list_vals, add_param, tf_round): def main(): # Chain the generate function to the class call - config = ConfigArgBuilder(BasicConfig).generate() + config = ConfigArgBuilder(BasicConfig, desc='Quick start example').generate() # One can now access the Spock config object by class name with the returned namespace print(config.BasicConfig.parameter) # And pass the namespace to our first function diff --git a/examples/tutorial/basic/tutorial.py b/examples/tutorial/basic/tutorial.py index 88d1f6e4..aac3da3c 100644 --- a/examples/tutorial/basic/tutorial.py +++ b/examples/tutorial/basic/tutorial.py @@ -9,6 +9,13 @@ class Activation(Enum): + """Options for activation functions + + Attributes: + relu: relu activation + gelu: gelu activation + tanh: tanh activation + """ relu = 'relu' gelu = 'gelu' tanh = 'tanh' @@ -16,6 +23,15 @@ class Activation(Enum): @spock class ModelConfig: + """Main model configuration for a basic neural net + + Attributes: + save_path: spock special keyword -- path to write out spock config state + n_features: number of data features + dropout: dropout rate for each layer + hidden_sizes: hidden size for each layer + activation: choice from the Activation enum of the activation function to use + """ save_path: SavePath n_features: int dropout: List[float] @@ -25,7 +41,7 @@ class ModelConfig: def main(): # A simple description - description = 'spock Tutorial' + description = 'spock Basic Tutorial' # Build out the parser by passing in Spock config objects as *args after description config = ConfigArgBuilder( ModelConfig, desc=description, create_save_path=True).save(file_extension='.toml').generate()