diff --git a/README.md b/README.md index c0290647..6854eb64 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,20 @@ hydra-zen is a Python library that simplifies the process of writing code (resea - **Repeatable**: each run of your code will be self-documenting; the full configuration of your software is saved alongside your results. - **Scalable**: launch multiple runs of your software, be it on your local machine or across multiple nodes on a cluster. -It builds off – and is fully compatible with – [Hydra](https://hydra.cc/), a framework for elegantly -configuring complex applications. -hydra-zen helps simplify the process of using Hydra by providing -convenient functions for creating and validating configs, as well as launching Hydra jobs. It also provides novel -functionality such as wrapped instantiation and meta fields in configs. +It builds off – and is fully compatible with – [Hydra](https://hydra.cc/), a framework for elegantly +configuring complex applications. hydra-zen helps simplify the +process of using Hydra by providing specialized functions for :ref:`creating configs ` and +launching Hydra jobs. + +hydra-zen also also provides Hydra users with powerful, novel functionality. With it, we can: + +- Add enhanced runtime type-checking for our Hydra application, via pydantic, beartype, and other third-party libraries. +- Design configs with specialized behaviors, like partial configs, or configs with meta-fields. +- Use additional data types in our configs, like `pathlib.Path`, that are not natively supported by Hydra. +- Validate our configs at runtime, prior to launching our application. +- Leverage a powerful functionality-injection framework in our Hydra applications. +- Run static type-checkers on our config-creation code to catch incompatibilities with Hydra. ## Installation `hydra-zen` is lightweight: its only dependencies are `hydra-core` and `typing-extensions`. diff --git a/docs/source/_static/my_theme.css b/docs/source/_static/my_theme.css deleted file mode 100644 index d0c03e60..00000000 --- a/docs/source/_static/my_theme.css +++ /dev/null @@ -1,3 +0,0 @@ -.wy-nav-content { -max-width: 1000px !important; -} diff --git a/docs/source/conf.py b/docs/source/conf.py index 7e0e42fd..ff2ec24f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -117,7 +117,6 @@ def setup(app): - app.add_css_file("my_theme.css") app.add_js_file( "https://www.googletagmanager.com/gtag/js?id=UA-115029372-2", loading_method="async", diff --git a/docs/source/explanation/dont_repeat_yourself.rst b/docs/source/explanation/dont_repeat_yourself.rst index 8287029c..65a09c09 100644 --- a/docs/source/explanation/dont_repeat_yourself.rst +++ b/docs/source/explanation/dont_repeat_yourself.rst @@ -1,6 +1,7 @@ .. meta:: :description: hydra-zen eliminates the repetitive patterns involved in designing a Hydra-based project by providing users with functions for dynamically generating configurations for their project. +.. _dry: ======================================================================== Don't Repeat Yourself: Keeping DRY with Dynamically-Generated Configs 🌞 diff --git a/docs/source/explanation/type_refinement.rst b/docs/source/explanation/type_refinement.rst index ea810652..1cadbd95 100644 --- a/docs/source/explanation/type_refinement.rst +++ b/docs/source/explanation/type_refinement.rst @@ -100,6 +100,8 @@ In this way, we can still configure and build this function, but we also retain In general, hydra-zen will broaden types as-needed so that dynamically-generated configs will never include annotations that would cause Hydra to raise an error due to lack of support for that type. +.. _pydantic-support: + Using Third-Party Runtime Type-Checkers --------------------------------------- Although hydra-zen will broaden the types that get exposed to Hydra, the original diff --git a/docs/source/how_to/beartype.rst b/docs/source/how_to/beartype.rst index 2311f6a1..ab072894 100644 --- a/docs/source/how_to/beartype.rst +++ b/docs/source/how_to/beartype.rst @@ -5,6 +5,8 @@ Your must install `beartype `_ in your Python environment in order to complete this How-To guide. +.. _runtime-type-checking: + ================================================= Add Enhanced Runtime Type-Checking to a Hydra App ================================================= diff --git a/docs/source/index.rst b/docs/source/index.rst index cdd7f445..55abcee8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,31 +3,71 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. + +.. admonition:: Join the Discussion 💬 + + Share ideas, ask questions, and chat with us over at `hydra-zen's discussion board `_. + + +.. tip:: + + 🎓 Using hydra-zen for your research project? `Cite us `_! + + ===================================== Welcome to hydra-zen's documentation! ===================================== hydra-zen is a Python library that simplifies the process of writing code (be it research-grade or production-grade) that is: -- **Configurable**: you can configure all aspects of your code from a single interface (the command line or a Python function). +- **Configurable**: change deeply-nested parameters and swap out entire pieces of your program, all from the command line. - **Repeatable**: each run of your code will be self-documenting; the full configuration of your software is saved alongside your results. - **Scalable**: launch multiple runs of your software, be it on your local machine or across multiple nodes on a cluster. It builds off -- and is fully compatible with -- `Hydra `_, a framework for elegantly configuring complex applications. hydra-zen helps simplify the -process of using Hydra by providing convenient functions for creating configs and -launching Hydra jobs. It also provides novel functionality such as -:ref:`wrapped instantiation ` and :ref:`meta fields ` in configs. - -.. admonition:: Join the Discussion 💬 - - Share ideas, ask questions, and chat with us over at `hydra-zen's discussion board `_. +process of using Hydra by providing specialized functions for :ref:`creating configs ` and +launching Hydra jobs. + + +.. admonition:: Attention, Hydra users: + + If you are already use Hydra, let's cut to the chase: **the most important benefit of using hydra-zen is that it automatically and dynamically generates structured configs for you**. + + + +----------------------------------------------------------------+-----------------------------------------------------------------------+ + | .. code-block:: python | .. code-block:: python | + | :caption: Creating a structured config using vanilla Hydra | :caption: Creating an equivalent structured config using hydra-zen | + | | | + | from dataclasses import dataclass, field | from hydra_zen import builds | + | | | + | def foo(bar: int, baz: list[str], qux: float = 1.23): | def foo(bar: int, baz: list[str], qux: float = 1.23): | + | ... | ... | + | | | + | @dataclass | FooConf = builds(foo, bar=2, baz=["abc"], | + | class FooConf: | populate_full_signature=True) | + | _target_: str = "__main__.foo" | | + | bar: int = 2 | | + | baz: list[str] = field(default_factory=lambda: ["abc"]) | | + | qux: float = 1.23 | | + +----------------------------------------------------------------+-----------------------------------------------------------------------+ + + This means that it is much **easier and safer** to write and maintain the configs for your Hydra applications: + + - Write all of your configs in Python. No more yaml files! + - Write less, :ref:`stop repeating yourself `, and get more out of your configs. + - Get automatic type-safety via :func:`~hydra_zen.builds`'s signature inspection. + - :ref:`Validate your configs ` before launching your application. + +hydra-zen also also provides Hydra users with powerful, novel functionality. With it, we can: + +- Add :ref:`enhanced runtime type-checking ` for our Hydra application, via :ref:`pydantic `, `beartype `_, and other third-party libraries. +- Design configs with specialized behaviors, like :ref:`partial configs `, or :ref:`configs with meta-fields `. +- Use :ref:`additional data types ` in our configs, like :py:class:`pathlib.Path`, that are not natively supported by Hydra. +- Leverage a powerful :ref:`functionality-injection framework ` in our Hydra applications. +- Run static type-checkers on our config-creation code to catch incompatibilities with Hydra. -.. tip:: - - 🎓 Using hydra-zen for your research project? `Cite us `_! - Installation ============ @@ -45,6 +85,7 @@ the latest pre-release of hydra-zen with: $ pip install --pre hydra-zen + Learning About hydra-zen ======================== diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index 46bf25fd..d6477fa3 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -1,6 +1,8 @@ .. meta:: :description: Tutorials for getting started with Hydra and hydra-zen. +.. _tutorials: + Tutorials ========= diff --git a/src/hydra_zen/structured_configs/_implementations.py b/src/hydra_zen/structured_configs/_implementations.py index 559dd71e..b42d676b 100644 --- a/src/hydra_zen/structured_configs/_implementations.py +++ b/src/hydra_zen/structured_configs/_implementations.py @@ -784,7 +784,7 @@ def builds( I.e. setting/deleting an attribute of an instance will raise :py:class:`dataclasses.FrozenInstanceError` at runtime. - builds_bases : Tuple[DataClass, ...] + builds_bases : Tuple[Type[DataClass], ...] Specifies a tuple of parent classes that the resulting config inherits from. A ``PartialBuilds`` class (resulting from ``zen_partial=True``) cannot be a parent of a ``Builds`` class (i.e. where `zen_partial=False` was specified). @@ -953,6 +953,10 @@ def builds( >>> builds(func, 1, builds_bases=(BaseConf,)) # too many args (via inheritance) TypeError: Building: func .. + >>> builds(int, (i for i in range(10))) # value type not supported by Hydra + hydra_zen.errors.HydraZenUnsupportedPrimitiveError: Building: int .. + + .. _meta-field: **Using meta-fields** @@ -978,7 +982,7 @@ def builds( Let's use a wrapper to add a unit-conversion step to a config. We'll modify a config that builds a function, which converts a temperature in Farenheit to - Celcius, and add a wrapper it so that it will convert from Farenheit to Kelvin + Celcius, and add a wrapper to it so that it will convert from Farenheit to Kelvin instead. >>> def faren_to_celsius(temp_f): # our target