-
Notifications
You must be signed in to change notification settings - Fork 48
Implement importable config object in experimental API submodule #868
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
Merged
Merged
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
eeffeed
Add hidden defaults and make config-user.yml valid as default fallback
stefsmeets 71dc0da
Expose functionality to load config developer
stefsmeets 04d56cb
Implement importable config object for future API
stefsmeets 0768806
Add tests for config + validation
stefsmeets fc2e1f2
Fix for default config file
stefsmeets b5ab46b
Add parenthesis to lru_cache decorator for Py3.7 compatibility
stefsmeets efb4ac4
Tackle linter issues
stefsmeets 486247b
Tackle linter issues
stefsmeets c6542c7
Address Codacy issues
stefsmeets 1ddb0c0
Fix typo __del__ -> __delitem__
stefsmeets 73717e6
Change how session object gets initialized
stefsmeets 5a30a5f
Adjust variable names to address Codacy issues
stefsmeets ff3cbee
Address Codacy issues
stefsmeets 3157957
Update tests to reflect variable name change
stefsmeets 7539975
Fix docstring
stefsmeets 1b9e0b9
Default to None if 'max_years' not in config
stefsmeets fcc9e39
Revert adding hidden config parameters to config-user.yml
stefsmeets 43f7082
Add warning for unstable API
stefsmeets 9fd553f
Remove unneeded code
stefsmeets f3346a2
Add function to reload the config file
stefsmeets 41b1583
Rename submodule future -> experimental
stefsmeets 4d4860c
Fix imports and rename some variables
stefsmeets 63d0bfb
Improve error message
stefsmeets 99b0db6
Merge branch 'master' into importable-config-episode-2
stefsmeets 05d0be1
Ignore flake8 import warning
stefsmeets 3089ac1
Format warning messages in a bit friendlier way
stefsmeets 060078c
Add module docstring
stefsmeets dac9a40
Fix linter warnings
stefsmeets 2b9267b
Add api entry page
stefsmeets 9c69619
Add documentation for config/session
stefsmeets f9a16fd
Update doc/api/esmvalcore.api.rst
stefsmeets ec2a5fa
Clarify text/code in documentation
stefsmeets 50215a3
Remove support for environment variables
stefsmeets cbdcb1e
Clarify deprecation message
stefsmeets 4c82878
Make validate/config reader functions private
stefsmeets 953d2ab
Fix bug with `session_dir` not updating automatically
stefsmeets b6ba919
Remove global statements
stefsmeets 2191035
Warn if config parameters are missing
stefsmeets fe79f05
Add custom validation error
stefsmeets a089e81
Make Config/Session available via public API
stefsmeets 0bf4df7
Update docstring
stefsmeets abac115
Re-organize class
stefsmeets cc70b32
Move imports to top
stefsmeets dcae185
Move import to top
stefsmeets 581085f
Update docstring to reflect code changes
stefsmeets a81a970
Remove redundant clear statement
stefsmeets File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| .. _experimental_api: | ||
|
|
||
| Experimental API | ||
| ================ | ||
|
|
||
| This page describes the new ESMValCore API. | ||
| The API module is available in the submodule ``esmvalcore.experimental``. | ||
| The API is under development, so use at your own risk! | ||
|
|
||
| Config | ||
| ****** | ||
|
|
||
| Configuration of ESMValCore/Tool is done via the ``Config`` object. | ||
| The global configuration can be imported from the ``esmvalcore.experimental`` module as ``CFG``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> from esmvalcore.experimental import CFG | ||
| >>> CFG | ||
| Config({'auxiliary_data_dir': PosixPath('/home/user/auxiliary_data'), | ||
| 'compress_netcdf': False, | ||
| 'config_developer_file': None, | ||
| 'config_file': PosixPath('/home/user/.esmvaltool/config-user.yml'), | ||
| 'drs': {'CMIP5': 'default', 'CMIP6': 'default'}, | ||
| 'exit_on_warning': False, | ||
| 'log_level': 'info', | ||
| 'max_parallel_tasks': None, | ||
| 'output_dir': PosixPath('/home/user/esmvaltool_output'), | ||
| 'output_file_type': 'png', | ||
| 'profile_diagnostic': False, | ||
| 'remove_preproc_dir': True, | ||
| 'rootpath': {'CMIP5': '~/default_inputpath', | ||
| 'CMIP6': '~/default_inputpath', | ||
| 'default': '~/default_inputpath'}, | ||
| 'save_intermediary_cubes': False, | ||
| 'write_netcdf': True, | ||
| 'write_plots': True}) | ||
|
|
||
| The parameters for the user configuration file are listed `here <https://docs.esmvaltool.org/projects/ESMValCore/en/latest/quickstart/configure.html#user-configuration-file>`__. | ||
|
|
||
| ``CFG`` is essentially a python dictionary with a few extra functions, similar to ``matplotlib.rcParams``. | ||
| This means that values can be updated like this: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG['output_dir'] = '~/esmvaltool_output' | ||
| >>> CFG['output_dir'] | ||
| PosixPath('/home/user/esmvaltool_output') | ||
|
|
||
| Notice that ``CFG`` automatically converts the path to an instance of ``pathlib.Path`` and expands the home directory. | ||
| All values entered into the config are validated to prevent mistakes, for example, it will warn you if you make a typo in the key: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG['otoptu_dri'] = '~/esmvaltool_output' | ||
| InvalidConfigParameter: `otoptu_dri` is not a valid config parameter. | ||
|
|
||
| Or, if the value entered cannot be converted to the expected type: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG['max_years'] = '🐜' | ||
| InvalidConfigParameter: Key `max_years`: Could not convert '🐜' to int | ||
|
|
||
| ``Config`` is also flexible, so it tries to correct the type of your input if possible: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG['max_years'] = '123' # str | ||
| >>> type(CFG['max_years']) | ||
| int | ||
|
|
||
| By default, the config is loaded from the default location (``/home/user/.esmvaltool/config-user.yml``). | ||
| If it does not exist, it falls back to the default values. | ||
| to load a different file: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG.load_from_file('~/my-config.yml') | ||
|
|
||
| Or to reload the current config: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> CFG.reload() | ||
|
|
||
|
|
||
| Session | ||
| ******* | ||
|
|
||
| Recipes and diagnostics will be run in their own directories. | ||
| This behaviour can be controlled via the ``Session`` object. | ||
| A ``Session`` can be initiated from the global ``Config``. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> session = CFG.start_session(name='my_session') | ||
|
|
||
| A ``Session`` is very similar to the config. | ||
| It is also a dictionary, and copies all the keys from the ``Config``. | ||
| At this moment, ``session`` is essentially a copy of ``CFG``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> print(session == CFG) | ||
| True | ||
| >>> session['output_dir'] = '~/my_output_dir' | ||
| >>> print(session == CFG) # False | ||
| False | ||
|
|
||
| A ``Session`` also knows about the directories where the data will stored. | ||
| The session name is used to prefix the directories. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| >>> session.session_dir | ||
| /home/user/my_output_dir/my_session_20201203_155821 | ||
| >>> session.run_dir | ||
| /home/user/my_output_dir/my_session_20201203_155821/run | ||
| >>> session.work_dir | ||
| /home/user/my_output_dir/my_session_20201203_155821/work | ||
| >>> session.preproc_dir | ||
| /home/user/my_output_dir/my_session_20201203_155821/preproc | ||
| >>> session.plot_dir | ||
| /home/user/my_output_dir/my_session_20201203_155821/plots | ||
|
|
||
| Unlike the global configuration, of which only one can exist, multiple sessions can be initiated from the ``Config``. | ||
|
|
||
|
|
||
| API reference | ||
| ************* | ||
|
|
||
| .. autoclass:: esmvalcore.experimental.config.CFG | ||
| :no-inherited-members: | ||
| :no-show-inheritance: | ||
|
|
||
| .. autoclass:: esmvalcore.experimental.config.Config | ||
| :no-inherited-members: | ||
| :no-show-inheritance: | ||
|
|
||
| .. autoclass:: esmvalcore.experimental.config.Session | ||
| :no-inherited-members: | ||
| :no-show-inheritance: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| """ESMValCore experimental API module.""" | ||
|
|
||
| from ._warnings import warnings | ||
|
|
||
| warnings.warn( | ||
| '\n Thank you for trying out the new ESMValCore API.' | ||
| '\n Note that this API is experimental and may be subject to change.' | ||
| '\n More info: https://github.com/ESMValGroup/ESMValCore/issues/498', ) | ||
|
|
||
| from .config import CFG # noqa: E402 | ||
|
|
||
| __all__ = [ | ||
| 'CFG', | ||
| ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| """ESMValCore exceptions.""" | ||
|
|
||
| import sys | ||
|
|
||
|
|
||
| class SuppressedError(Exception): | ||
| """Errors subclassed from SuppressedError hide the full traceback. | ||
|
|
||
| This can be used for simple user-facing errors that do not need the | ||
| full traceback. | ||
| """ | ||
|
|
||
|
|
||
| def _suppressed_hook(error, message, traceback): | ||
|
stefsmeets marked this conversation as resolved.
|
||
| """https://stackoverflow.com/a/27674608.""" | ||
| if issubclass(error, SuppressedError): | ||
| # Print only the message and hide the traceback | ||
| print(f'{error.__name__}: {message}'.format(error.__name__, message)) | ||
| else: | ||
| # Print full traceback | ||
| sys.__excepthook__(error, message, traceback) | ||
|
|
||
|
|
||
| sys.excepthook = _suppressed_hook | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """ESMValTool warnings.""" | ||
|
|
||
| import warnings | ||
|
|
||
|
|
||
| def _warning_formatter(message, | ||
| category, | ||
| filename, | ||
| lineno, | ||
| file=None, | ||
| line=None): | ||
| """Patch warning formatting to not mention itself.""" | ||
| return f'{filename}:{lineno}: {category.__name__}: {message}\n' | ||
|
|
||
|
|
||
| warnings.formatwarning = _warning_formatter |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| """ESMValTool config module.""" | ||
|
|
||
| from ._config_object import CFG, Config, Session | ||
|
|
||
| __all__ = [ | ||
| 'CFG', | ||
| 'Config', | ||
| 'Session', | ||
| ] | ||
|
stefsmeets marked this conversation as resolved.
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.