Skip to content

Commit

Permalink
Read config from ENV variable.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcrivenaes committed Nov 16, 2021
1 parent 9177d43 commit c9652ff
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 22 deletions.
57 changes: 35 additions & 22 deletions src/fmu/dataio/dataio.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import re
import sys
import uuid
import warnings
from collections import OrderedDict
from typing import Any, List, Optional, Union

Expand Down Expand Up @@ -114,9 +115,8 @@ class ExportData:
from FMU global variables (via fmuconfig). The dictionary must contain
some predefined main level keys to work with fmu-dataio. If the key is
missing or key value is None, then it will look for the environment variable
FMU_CONFIG_FILE to detect the file. If that is missing it will assume
the the FMU config is ../../fmuconfig/output/global_variables.yml. If
no success in finding the file, a RuntimeError will be raised.
FMU_GLOBAL_CONFIG to detect the file. If no success in finding the file,
a UserWarning is made.
content: Is a string or a dictionary with one key. Example is "depth" or
{"fluid_contact": {"xxx": "yyy", "zzz": "uuu"}}
subfolder: It is possible to set one level of subfolders for file output.
Expand Down Expand Up @@ -196,10 +196,13 @@ def __init__(
# developer setting when running tests e.g. in pytest's tmp_path
# dryrun: Set instance variables but do not run functions (for unit testing)
# inside_rms: If forced to true then pretend to be in rms env.
self._verbosity = verbosity
logger.setLevel(level=self._verbosity)

self._runpath = runpath
self._access_ssdl = access_ssdl
if config is None:
self.detect_config()
self._try_get_config()
else:
self._config = config
self._content = content
Expand All @@ -223,16 +226,13 @@ def __init__(
self._description = description
self._unit = unit

self._verbosity = verbosity

# keep track of case
self._case = False

# store iter and realization folder names (when running ERT)
self._iterfolder = None
self._realfolder = None

logger.setLevel(level=self._verbosity)
self._pwd = pathlib.Path().absolute() # process working directory

# developer option (for testing): set another pwd
Expand Down Expand Up @@ -375,20 +375,28 @@ def pwd(self):
# Private metadata methods which retrieve metadata that are not closely linked to
# the actual instance to be exported.

def _detect_config(self):
"""Try to detect the config from env variable or standard location."""

if "FMU_GLOBAL_CONFIG" in os.environ:
cfg_file = os.environ["FMU_GLOBAL_CONFIG"]
with open(cfg_file, "r", encoding="utf8") as stream:
try:
self._config = yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
def _try_get_config(self):
"""Try to detect and get the config from env variable."""
envvar = "FMU_GLOBAL_CONFIG"

if envvar in os.environ:
cfg = os.environ[envvar]
logger.info("Set global config from env variable %s as %s", envvar, cfg)
else:
warnings.warn(
"The key 'config' is set to None, and not able to detect a "
f"config file from environment variable {envvar}. Use None as config.",
UserWarning,
)
self._config = None
return

default = "../../fmuconfig/output/global_variables.yml"
with open(cfg, "r", encoding="utf8") as stream:
try:
self._config = yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
raise

def _get_meta_masterdata(self) -> None:
"""Get metadata from masterdata section in config.
Expand Down Expand Up @@ -768,7 +776,9 @@ class InitializeCase(ExportData): # pylint: disable=too-few-public-methods
Args:
config: A configuation dictionary. In the standard case this is read
from FMU global vaiables (via fmuconfig). The dictionary must contain
some predefined main level keys.
some predefined main level keys. If config is None and the env variable
FMU_GLOBAL_CONFIG pointing to file is provided, then it will attempt to
parse that file.
verbosity: Is logging/message level for this module. Input as
in standard python logging; e.g. "WARNING", "INFO".
"""
Expand All @@ -779,13 +789,16 @@ def __init__( # pylint: disable=super-init-not-called
verbosity: Optional[str] = "CRITICAL",
**kwargs,
) -> None:

self._config = config
self._verbosity = verbosity
logger.setLevel(level=self._verbosity)

if config is None:
self._try_get_config()
else:
self._config = config

self._case = True

logger.setLevel(level=self._verbosity)
self._pwd = pathlib.Path().absolute()
logger.info("Create instance of InitializeCase")

Expand Down
41 changes: 41 additions & 0 deletions tests/test_fmu_dataio_generic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Test the main class DataExporter and functions in the dataio module, ExportData."""
import json
import logging
import os
import re
import shutil
from collections import OrderedDict
Expand Down Expand Up @@ -31,8 +32,12 @@
RUNPATH = "tests/data/drogon/ertrun1/realization-0/iter-0"
# case real iter

GLOBAL_CONFIG = "tests/data/drogon/global_config2/global_variables.yml"
GLOBAL_CONFIG_INVALID = "tests/data/drogon/global_config2/not_valid_yaml.yml"

FMUP1 = "share/results"


logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

Expand Down Expand Up @@ -100,6 +105,42 @@ def test_get_folderlist():
assert folderlist[-2] == "realization-0"


def test_process_fmu_config_from_env():
"""Apply config from the env variabel FMU_GLOBAL_CONFIG"""
os.environ["FMU_GLOBAL_CONFIG"] = GLOBAL_CONFIG

edata = fmu.dataio.ExportData(
config=None, runfolder=RUN, verbosity="INFO", dryrun=True
)
assert (
edata._config["masterdata"]["smda"]["coordinate_system"]["identifier"]
== "ST_WGS84_UTM37N_P32637"
)


def test_process_fmu_config_from_env_fail():
"""Apply config from the env variabel FMU_GLOBAL_CONFIG"""
os.environ["FMU_GLOBAL_CONFIG"] = "non_existing_file"

with pytest.raises(FileNotFoundError):
_ = fmu.dataio.ExportData(
config=None, runfolder=RUN, verbosity="INFO", dryrun=True
)
del os.environ["FMU_GLOBAL_CONFIG"]


def test_process_fmu_config_from_env_invalid_yaml():
"""Apply config from the env variabel FMU_GLOBAL_CONFIG but the file is not YAML."""
os.environ["FMU_GLOBAL_CONFIG"] = GLOBAL_CONFIG_INVALID

with pytest.raises(yaml.YAMLError):
_ = fmu.dataio.ExportData(
config=None, runfolder=RUN, verbosity="INFO", dryrun=True
)

del os.environ["FMU_GLOBAL_CONFIG"]


def test_process_fmu_realisation():
"""The (second order) private routine that provides realization and iteration."""
case = fmu.dataio.ExportData(runfolder=RUN, verbosity="INFO", dryrun=True)
Expand Down

0 comments on commit c9652ff

Please sign in to comment.