Skip to content

Commit

Permalink
Merge branch 'NOAA-EMC:develop' into config_env_xor
Browse files Browse the repository at this point in the history
  • Loading branch information
TerrenceMcGuinness-NOAA committed Jun 26, 2024
2 parents 57af2f5 + 5dad7dd commit 761bcdf
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/wxflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
save_as_yaml, vanilla_yaml)

__docformat__ = "restructuredtext"
__version__ = "0.1.0"
__version__ = "0.2.0"
wxflow_directory = os.path.dirname(__file__)
3 changes: 3 additions & 0 deletions src/wxflow/jinja.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import sys
from functools import reduce
from pathlib import Path
from typing import Dict, List, Union

Expand Down Expand Up @@ -110,6 +111,7 @@ def get_set_env(self, loader: jinja2.BaseLoader, filters: Dict[str, callable] =
getenv: read variable from environment if defined, else UNDEFINED
to_timedelta: convert a string to a timedelta object
add_to_datetime: add time to a datetime, return new datetime object
replace_tmpl: replace substrings of an input string with replacements specified by an input dictionary
The Expression Statement extension "jinja2.ext.do", which enables
{% do ... %} statements. These are useful for appending to lists.
Expand Down Expand Up @@ -146,6 +148,7 @@ def get_set_env(self, loader: jinja2.BaseLoader, filters: Dict[str, callable] =
if not (isinstance(dt, SilentUndefined) or isinstance(delta, SilentUndefined))
else dt if isinstance(dt, SilentUndefined) else delta)
env.filters["to_timedelta"] = lambda delta_str: to_timedelta(delta_str) if not isinstance(delta_str, SilentUndefined) else delta_str
env.filters["replace_tmpl"] = lambda string, tmpl_dict: reduce(lambda ss, kk: ss.replace(kk, tmpl_dict[kk]), tmpl_dict, string)

# Add any additional filters
if filters is not None:
Expand Down
24 changes: 9 additions & 15 deletions src/wxflow/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,29 @@ def __init__(self, config: Dict, *args, **kwargs):
"""

# Store the config and arguments as attributes of the object
self.config = AttrDict(config)
self._config = AttrDict(config)

for arg in args:
setattr(self, str(arg), arg)

for key, value in kwargs.items():
setattr(self, key, value)

# Pull out basic runtime keys values from config into its own runtime config
self.runtime_config = AttrDict()
runtime_keys = ['PDY', 'cyc', 'DATA', 'RUN', 'CDUMP'] # TODO: eliminate CDUMP and use RUN instead
for kk in runtime_keys:
try:
self.runtime_config[kk] = config[kk]
logger.debug(f'Deleting runtime_key {kk} from config')
del self.config[kk]
except KeyError:
raise KeyError(f"Encountered an unreferenced runtime_key {kk} in 'config'")
# Create task_config with everything that is inside _config and whatever the user chooses to
# extend it with when initializing a child subclass of Task. Only task_config should be referenced
# in any application, not _config.
self.task_config = self._config.deepcopy()

# Any other composite runtime variables that may be needed for the duration of the task
# can be constructed here

# Construct the current cycle datetime object
self.runtime_config['current_cycle'] = add_to_datetime(self.runtime_config['PDY'], to_timedelta(f"{self.runtime_config.cyc}H"))
logger.debug(f"current cycle: {self.runtime_config['current_cycle']}")
self.task_config['current_cycle'] = add_to_datetime(self._config['PDY'], to_timedelta(f"{self._config.cyc}H"))
logger.debug(f"current cycle: {self.task_config['current_cycle']}")

# Construct the previous cycle datetime object
self.runtime_config['previous_cycle'] = add_to_datetime(self.runtime_config.current_cycle, -to_timedelta(f"{self.config['assim_freq']}H"))
logger.debug(f"previous cycle: {self.runtime_config['previous_cycle']}")
self.task_config['previous_cycle'] = add_to_datetime(self.task_config.current_cycle, -to_timedelta(f"{self._config['assim_freq']}H"))
logger.debug(f"previous cycle: {self.task_config['previous_cycle']}")

pass

Expand Down
13 changes: 13 additions & 0 deletions tests/test_jinja.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime

import jinja2
import pytest

from wxflow import Jinja, to_isotime
Expand Down Expand Up @@ -29,6 +30,12 @@ def test_render_stream():
j = Jinja(j2tmpl, data, allow_missing=False)
assert j.render == f"Hello Jane! How are you? It is: {to_isotime(current_date)}"

tmpl_dict = {"{{ name }}": "Jane", "{{ greeting }}": "How are you?", "{{ current_date | to_isotime }}": to_isotime(current_date)}
j = Jinja(j2tmpl, data, allow_missing=False)
loader = jinja2.BaseLoader()
env = j.get_set_env(loader)
assert env.filters['replace_tmpl'](j2tmpl, tmpl_dict) == f"Hello Jane! How are you? It is: {to_isotime(current_date)}"


def test_render_file(tmp_path, create_template):

Expand All @@ -41,6 +48,12 @@ def test_render_file(tmp_path, create_template):
j = Jinja(str(file_path), data, allow_missing=False)
assert j.render == f"Hello Jane! How are you? It is: {to_isotime(current_date)}"

tmpl_dict = {"{{ name }}": "Jane", "{{ greeting }}": "How are you?", "{{ current_date | to_isotime }}": to_isotime(current_date)}
j = Jinja(str(file_path), data, allow_missing=False)
loader = jinja2.BaseLoader()
env = j.get_set_env(loader)
assert env.filters['replace_tmpl'](j2tmpl, tmpl_dict) == f"Hello Jane! How are you? It is: {to_isotime(current_date)}"


def test_include(tmp_path, create_template):

Expand Down

0 comments on commit 761bcdf

Please sign in to comment.