Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config with pydantic #334

Closed
wants to merge 21 commits into from
Closed

Config with pydantic #334

wants to merge 21 commits into from

Conversation

sverhoeven
Copy link
Member

@sverhoeven sverhoeven commented Feb 21, 2023

Fixes #332

Also

  • moves tests for parametersetdb module to own subdir

TODO:

  • append CFG.parameterset_dir to ParameterSet.config and ParameterSet.directory
  • remove ParameterSetConfig workaround
  • make CFG.save_to_file() less ugly do later, has TODO in code

@sverhoeven sverhoeven changed the base branch from main to apptainer February 21, 2023 14:38
Was getting
```
RuntimeError: The Poetry configuration is invalid:
            - [extras.pipfile_deprecated_finder.2] 'pip-shims<=0.3.4' does not match '^[a-zA-Z-_.0-9]+$'

```
Also
* made . the default value for directories
* renamed Config class to Configuration, as mypy was confused by nested Config.Config class
* added filename to validation error
* create dir before assigning to CFG field
* docstrings for Configuration fields
* dropped test in tests/parameter_sets/__init__.py, as it rewrote my config file
@sverhoeven sverhoeven mentioned this pull request Mar 6, 2023
@sonarcloud
Copy link

sonarcloud bot commented Mar 6, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 6 Code Smells

82.2% 82.2% Coverage
0.5% 0.5% Duplication

@sverhoeven sverhoeven marked this pull request as ready for review March 6, 2023 14:06
@sverhoeven sverhoeven mentioned this pull request Mar 7, 2023
5 tasks
Copy link
Collaborator

@Peter9192 Peter9192 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, dot notation looks so much better! Perhaps we can do some more testing on a new demo machine? Fine to merge before that, and sync with other open PRs

Comment on lines +131 to +134
"""Load user configuration from the given file.

The config is cleared and updated in-place.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this complex mechanism still necessary? Now that we have all default values, a simple Configuration.from_file would suffice, wouldn't it? No need to clear the config and overwrite stuff. Or do I miss something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ewatercycle.CFG is a single instance and can not be re-assigned aka CFG = Configuration() as on import time the pointer to CFG was set, any reassignments would not be visible to the rest of the code. We need all this overwriting stuff to make sure we change the single instance.

We could switch to a singleton patternwhere we can reassign it, but this changes the public API.

Comment on lines +27 to +29
"""Set of model versions that are
supported by this parameter set. If not set then parameter set will be
supported by all versions of model"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Set of model versions that are
supported by this parameter set. If not set then parameter set will be
supported by all versions of model"""
"""Set of model versions that are compatible with this parameterset."""

I'd love to also rename the setting to compatible_model_versions, but that might break stuff.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about this suggestion.
With your suggestion how would a model developer know what the behavior is of an empty set. An empty set could also mean zero versions are supported/compatible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make it optional so

  • None means compatible with all versions
  • set() means no versions are compatible

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern was more about the word "supported" than the behavior for not setting it. Sorry if that was unclear. With respect to making it optional, perhaps we should reconsider this behaviour altogether. Imagine I make a new (backward compatible) release of the model. Then I'd like for my existing parameter sets to work out of the box.

src/ewatercycle/parameter_set.py Show resolved Hide resolved
Comment on lines +34 to +43
def __str__(self):
"""Nice formatting of parameter set."""
return "\n".join(
[
"Parameter set",
"-------------",
]
+ [f"{k}={v!s}" for k, v in self.__dict__.items()]
)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please remove this now in favour of the default pydantic printing? Especially their integration with Rich makes things look much better(https://docs.pydantic.dev/usage/rich/):

In [10]: from rich import print
In [11]: print(CFG)
Configuration(
    grdc_location=PosixPath('.'),
    container_engine='docker',
    apptainer_dir=PosixPath('.'),
    singularity_dir=None,
    output_dir=PosixPath('.'),
    parameterset_dir=PosixPath('.'),
    parameter_sets={},
    ewatercycle_config=None
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an end user I like that they now see /bla instead of PosixPath('/bla').

If we do that then the Forcing and ParameterSet and models have different str outputs. I think they should look similar. We should do them all on none of them?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather do all then. But I do agree that PosixPaths are not so nice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made same in 990eb31

The notebooks in docs/ still use old format, but created #344 to make it even nicer.

Comment on lines +94 to +96
from ._config_object import CFG, SYSTEM_CONFIG, USER_HOME_CONFIG, Configuration

__all__ = ["CFG", "Config", "DEFAULT_CONFIG", "SYSTEM_CONFIG", "USER_HOME_CONFIG"]
__all__ = ["CFG", "Configuration", "SYSTEM_CONFIG", "USER_HOME_CONFIG"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to move documentation to the user guide, and reduce the config to a single-file module called config.py?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the content of src/ewatercycle/config/_config_object.py to src/ewatercycle/config/init.py in c86f3b7.
I also added a link from docs/system_setup.rst to api docs.
To not increase the public API I prefixed private things with underscore.

Moving it to src/ewatercycle/config.py could be done once src/ewatercycle/config/_lisflood_versions.py has been moved to its own plugin/repo.

@Peter9192
Copy link
Collaborator

Just out of curiosity. Have you also considered using pydantic for the forcing classes?

@Peter9192 Peter9192 mentioned this pull request Mar 10, 2023
@sverhoeven
Copy link
Member Author

Just out of curiosity. Have you also considered using pydantic for the forcing classes?

I tried at #345 but got stuck on save/load.

@Peter9192
Copy link
Collaborator

Merged as part of #340

@Peter9192 Peter9192 closed this Mar 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace config validation with pydantic validation
2 participants