-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Configuration management: Allow for creating / saving / loading confi…
…guration on the fly. (#23) * Add config module and .yaml file prototype The config module defines a new config class and implements a config object to be shared globally across modules. The .yaml file prototype contains the supported structure (yaml) and variables including defaults. * config: Add license text * config: Simplify yaml-config file locating. * confg.yaml: Rename config default files. * config: Change default behaviour. Constructor now returns empty objects if neither dictionary nor path are provided. The default locations are only searched for and evaluated when the module is first imported. * config: Change packages used internally. * Update .atlite.default.config.yaml Include instructions. * resource: Switch to config.py and absolute paths * default.config.yaml: Change description * config: Change config.yaml file name and location * config: Fix default.config.yaml name. * utils: Add function for determining relative paths. * resource: Implement relative paths standard. * Restructure the way the config module works. Change the config to work as a singelton (module) instead of a class and objects. The config is now really shared among modules, instead only of a copy of the same object. * Implement new config in all modules. * Update example create_cutout for new config * cutout: Fix cutout_dir when not explicitly provided. * config: Do not reset config_path with update(...) * README: Include configuration management * default.config: Set reasonable defaults. * README: Fix formatting issues. * README: Fix more formatting * Update .gitignore * Revert "Update .gitignore" This reverts commit d67cb2e. * Revert "Revert "Update .gitignore"" This reverts commit d58ff0e. * Revert "Update .gitignore" This reverts commit d67cb2e. * config: Refractor style. * cutout: Set cutout_dir correctly based on constructor parameters. * example/create_cutout: Adjust for changed function keywords. * Update configuration management to always load defaults from package dir. * cutout: Restructure cutout_dir and cutout_name extraction for portability (windows). * create_cutout: Simplify example. * config.example.yaml: Correct typo. * cutout: Adjust parsing of 'cutout_dir' from 'name' constructor argument.
- Loading branch information
Showing
11 changed files
with
302 additions
and
50 deletions.
There are no files selected for viewing
This file contains 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 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,19 @@ | ||
# -------------------*DEFAULT SETTINGS*------------------- # | ||
# --------------------*DO NOT CHANGE*--------------------- # | ||
# For custom settings, see the 'config.example.yaml' file. # | ||
# --------------------*DO NOT CHANGE*--------------------- # | ||
|
||
# Folder for storing prepared cutout files | ||
cutout_dir: <ATLITE>/cutouts | ||
|
||
# Folder containing raw dataset data | ||
gebco_path: <ATLITE>/data/gebco | ||
ncep_dir: <ATLITE>/data/ncep | ||
cordex_dir: <ATLITE>/data/cordex | ||
sarah_dir: <ATLITE>/data/sarah | ||
|
||
# Folder for different wind turbine configuration files | ||
windturbine_dir: <ATLITE>/resources/windturbine | ||
|
||
# Folder for different solar panel configuration files | ||
solarpanel_dir: <ATLITE>/resources/solarpanel |
This file contains 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,35 @@ | ||
# Exemplary Settings for atlite | ||
|
||
|
||
## How to use this file. | ||
# 1. Copy this file into your home directory, usually that is | ||
# "~" for linux users and "C:\Users\<Your Username>" for windows users. | ||
# 2. Rename the file to ".atlite.config.yaml" (note the trailing dot). | ||
# 3. Uncomment any setting you want to differ from the default settings. | ||
|
||
## Remarks | ||
# * Relative paths: | ||
# Are relative to the location of the currently loaded config file, | ||
# e.g. if the config file is located in your home directory, | ||
# then any relative paths are considered relative to the homedirectory. | ||
# Exception: Relative paths starting with "<ATLITE>/" (case-sensitive) are | ||
# considered relative to the atlite-package directory. | ||
# * Custom location: | ||
# You can use this configuration file and place it at custom locations with | ||
# a custom file name. In this case you need to manually load the configuration | ||
# after importing atlite with "atlite.config.read(<path with filename>)". | ||
|
||
# Folder for storing prepared cutout files | ||
# cutout_dir: <ATLITE>/cutouts | ||
|
||
# Folder containing raw dataset data | ||
# gebco_path: <ATLITE>/data/gebco | ||
# ncep_dir: <ATLITE>/data/ncep | ||
# cordex_dir: <ATLITE>/data/cordex | ||
# sarah_dir: <ATLITE>/data/sarah | ||
|
||
# Folder for different wind turbine configuration files | ||
# windturbine_dir: <ATLITE>/resources/windturbine | ||
|
||
# Folder for different solar panel configuration files | ||
# solarpanel_dir: <ATLITE>/resources/solarpanel |
This file contains 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,120 @@ | ||
## Copyright 2019 Johannes Hampp (Justus-Liebig University Giessen) | ||
|
||
## This program is free software; you can redistribute it and/or | ||
## modify it under the terms of the GNU General Public License as | ||
## published by the Free Software Foundation; either version 3 of the | ||
## License, or (at your option) any later version. | ||
|
||
## This program is distributed in the hope that it will be useful, | ||
## but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
## GNU General Public License for more details. | ||
|
||
## You should have received a copy of the GNU General Public License | ||
## along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
import os | ||
import pkg_resources | ||
import yaml | ||
import logging | ||
logger = logging.getLogger(__name__) | ||
|
||
|
||
_FILE_NAME = ".atlite.config.yaml" | ||
_FILE_SEARCH_PATH = os.path.join(os.path.expanduser("~"), _FILE_NAME) | ||
_DEFAULT_FILE_NAME = "config.default.yaml" | ||
_DEFAULT_SEARCH_PATH = pkg_resources.resource_filename(__name__, _DEFAULT_FILE_NAME) | ||
|
||
# List of all supported attributes for the config | ||
ATTRS = [] | ||
|
||
# Implemented attributes | ||
cutout_dir = None | ||
windturbine_dir = None | ||
solarpanel_dir = None | ||
ncep_dir = None | ||
cordex_dir = None | ||
sarah_dir = None | ||
|
||
# Path of the configuration file. | ||
# Automatically updated when using provided API. | ||
config_path = "" | ||
|
||
def read(path): | ||
"""Read and set the configuration based on the file in 'path'.""" | ||
|
||
if not os.path.isfile(path): | ||
raise TypeError("Invalid configuration file path: " | ||
"{p}".format(p=path)) | ||
|
||
with open(path, "r") as config_file: | ||
config_dict = yaml.safe_load(config_file) | ||
|
||
config_dict['config_path'] = path | ||
update(config_dict) | ||
|
||
logger.info("Configuration from {p} successfully read.".format(p=path)) | ||
|
||
def save(path, overwrite=False): | ||
"""Write the current configuration into a config file in the specified path. | ||
Parameters | ||
---------- | ||
path : string or os.path | ||
Including name of the new config file. | ||
overwrite : boolean | ||
(Default: False) Allow overwriting of existing files. | ||
""" | ||
|
||
if os.path.exists(path) and overwrite is False: | ||
raise FileExistsError("Overwriting disallowed for {p}".format(p=path)) | ||
|
||
# New path now points to the current config | ||
global config_path | ||
config_path = path | ||
|
||
# Construct attribute dict | ||
global ATTRS | ||
_update_variables() | ||
|
||
config = {key:globals()[key] for key in ATTRS} | ||
|
||
with open(path, "w") as config_file: | ||
yaml.dump(config, config_file, default_flow_style=False) | ||
|
||
def update(config_dict): | ||
"""Update the existing config based on the `config_dict` dictionary; resets `config_path`.""" | ||
|
||
globals().update(config_dict) | ||
_update_variables() | ||
|
||
def reset(): | ||
"""Reset the configuration to its initial values.""" | ||
|
||
# Test for file existence in order to not try to read | ||
# non-existing configuration files at this point (do not confuse the user) | ||
for path in [_DEFAULT_SEARCH_PATH, _FILE_SEARCH_PATH]: | ||
if os.path.isfile(path): | ||
read(path) | ||
|
||
# Notify user of empty config | ||
if not config_path: | ||
logger.warn("No valid configuration file found in default and home directories. " | ||
"No configuration is loaded, manual configuration required.") | ||
|
||
def _update_variables(): | ||
"""Update list of provided attributes by the module.""" | ||
|
||
global ATTRS | ||
|
||
ATTRS = {k for k,v in globals().items() if not k.startswith("_") and not callable(v)} | ||
|
||
# Manually remove imported modules and the attribute itself from the list | ||
ATTRS = ATTRS - {"ATTRS", "logging", | ||
"logger", "os", "pkg_resources", "yaml"} | ||
|
||
|
||
# Load the configuration at first module import | ||
reset() |
This file contains 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 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 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 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
Oops, something went wrong.