Skip to content

Commit 4a48d24

Browse files
authored
Merge pull request #56 from shashank-boyapally/cmd-templating
Cmd templating
2 parents 77b3aa5 + 5ebee63 commit 4a48d24

File tree

4 files changed

+71
-50
lines changed

4 files changed

+71
-50
lines changed

orion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import uvicorn
1212
from fmatch.logrus import SingletonLogger
1313
from pkg.runTest import run
14-
from pkg.utils import load_config
14+
from pkg.config import load_config
1515
import pkg.constants as cnsts
1616

1717
warnings.filterwarnings("ignore", message="Unverified HTTPS request.*")

pkg/config.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# pylint: disable = line-too-long
2+
"""
3+
Module file for config reading and loading
4+
"""
5+
6+
7+
import os
8+
import sys
9+
from typing import Any, Dict, Set
10+
11+
from jinja2 import Environment, Template, meta
12+
from fmatch.logrus import SingletonLogger
13+
import yaml
14+
15+
16+
def load_config(config: str, parameters: Dict= None) -> Dict[str, Any]:
17+
"""Loads config file
18+
19+
Args:
20+
config (str): path to config file
21+
logger (Logger): logger
22+
23+
Returns:
24+
dict: dictionary of the config file
25+
"""
26+
env_vars = {k.lower(): v for k, v in os.environ.items()}
27+
merged_parameters = {}
28+
merged_parameters.update(env_vars)
29+
if parameters:
30+
merged_parameters.update(parameters)
31+
logger_instance = SingletonLogger.getLogger("Orion")
32+
try:
33+
with open(config, "r", encoding="utf-8") as template_file:
34+
template_content = template_file.read()
35+
logger_instance.debug("The %s file has successfully loaded", config)
36+
except FileNotFoundError as e:
37+
logger_instance.error("Config file not found: %s", e)
38+
sys.exit(1)
39+
except Exception as e: # pylint: disable=broad-exception-caught
40+
logger_instance.error("An error occurred: %s", e)
41+
sys.exit(1)
42+
43+
required_parameters = get_template_variables(template_content)
44+
logger_instance.debug(f"Variables required by the template: {required_parameters}")
45+
46+
# Check for missing variables
47+
missing_vars = required_parameters - merged_parameters.keys()
48+
if missing_vars:
49+
logger_instance.error(f"Missing required parameters: {missing_vars}, use environment variables to set")
50+
sys.exit(1)
51+
52+
template = Template(template_content)
53+
rendered_config_yaml = template.render(merged_parameters)
54+
rendered_config = yaml.safe_load(rendered_config_yaml)
55+
return rendered_config
56+
57+
58+
def get_template_variables(template_content: str) -> Set[str]:
59+
"""Extracts all variables from the Jinja2 template content."""
60+
env = Environment()
61+
parsed_content = env.parse(template_content)
62+
variables = meta.find_undeclared_variables(parsed_content)
63+
return variables

pkg/daemon.py

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
import os
77
from typing import Any
88
from fastapi import FastAPI, HTTPException
9-
from jinja2 import Template
109
import pkg_resources
11-
import yaml
1210
from fmatch.logrus import SingletonLogger
11+
from pkg.config import load_config
1312
import pkg.constants as cnsts
1413

1514
from . import runTest
@@ -37,7 +36,8 @@ async def daemon_changepoint( # pylint: disable = R0913
3736
json: json object of the changepoints and metrics
3837
"""
3938
parameters = {"version": version}
40-
config_file_name=test_name+".yml"
39+
config_file_name=f"{test_name}.yml"
40+
config_path = pkg_resources.resource_filename("configs", config_file_name)
4141
option_arguments = {
4242
"config": config_file_name,
4343
"save_data_path": "output.csv",
@@ -47,7 +47,7 @@ async def daemon_changepoint( # pylint: disable = R0913
4747
"uuid": uuid,
4848
"lookback":lookback,
4949
"baseline": baseline,
50-
"configMap": render_template(config_file_name, parameters),
50+
"configMap": load_config(config_path, parameters),
5151
"convert_tinyurl": convert_tinyurl.lower() not in "false",
5252
}
5353
filter_changepoints = (
@@ -90,7 +90,7 @@ async def get_options() -> Any:
9090
raise HTTPException(status_code=500, detail=str(e)) from e
9191

9292
@app.get("/daemon/anomaly")
93-
async def daemon_anomaly( # pylint: disable = R0913
93+
async def daemon_anomaly( # pylint: disable = R0913, R0914
9494
version: str = "4.17",
9595
uuid: str = "",
9696
baseline: str = "",
@@ -111,6 +111,7 @@ async def daemon_anomaly( # pylint: disable = R0913
111111
"""
112112
parameters = {"version": version}
113113
config_file_name=test_name+".yml"
114+
config_path = pkg_resources.resource_filename("configs", config_file_name)
114115
option_arguments = {
115116
"config": config_file_name,
116117
"save_data_path": "output.csv",
@@ -120,7 +121,7 @@ async def daemon_anomaly( # pylint: disable = R0913
120121
"uuid": uuid,
121122
"lookback":lookback,
122123
"baseline": baseline,
123-
"configMap": render_template(config_file_name, parameters),
124+
"configMap": load_config(config_path, parameters),
124125
"anomaly_window": int(anomaly_window),
125126
"min_anomaly_percent":int(min_anomaly_percent),
126127
"convert_tinyurl": convert_tinyurl.lower() not in "false",
@@ -136,22 +137,3 @@ async def daemon_anomaly( # pylint: disable = R0913
136137
for key, value in result.items():
137138
result[key] = list(filter(lambda x: x.get("is_changepoint", False), value))
138139
return result
139-
140-
141-
def render_template(test_name: str, parameters: dict[str,Any]) -> Any:
142-
"""replace parameters in the config file
143-
144-
Args:
145-
file_name (str): the config file
146-
parameters (dict): parameters to be replaces
147-
148-
Returns:
149-
dict: configMap in dict
150-
"""
151-
config_path = pkg_resources.resource_filename("configs", test_name)
152-
with open(config_path, "r", encoding="utf-8") as template_file:
153-
template_content = template_file.read()
154-
template = Template(template_content)
155-
rendered_config_yaml = template.render(parameters)
156-
rendered_config = yaml.safe_load(rendered_config_yaml)
157-
return rendered_config

pkg/utils.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
from tabulate import tabulate
1717
from fmatch.matcher import Matcher
1818
from fmatch.logrus import SingletonLogger
19-
20-
import yaml
2119
import pandas as pd
22-
2320
import pyshorteners
2421

2522

@@ -132,28 +129,7 @@ def extract_metadata_from_test(test: Dict[str, Any]) -> Dict[Any, Any]:
132129
return metadata
133130

134131

135-
def load_config(config: str) -> Dict[str, Any]:
136-
"""Loads config file
137-
138-
Args:
139-
config (str): path to config file
140-
logger (Logger): logger
141132

142-
Returns:
143-
dict: dictionary of the config file
144-
"""
145-
logger_instance = SingletonLogger.getLogger("Orion")
146-
try:
147-
with open(config, "r", encoding="utf-8") as file:
148-
data = yaml.safe_load(file)
149-
logger_instance.debug("The %s file has successfully loaded", config)
150-
except FileNotFoundError as e:
151-
logger_instance.error("Config file not found: %s", e)
152-
sys.exit(1)
153-
except Exception as e: # pylint: disable=broad-exception-caught
154-
logger_instance.error("An error occurred: %s", e)
155-
sys.exit(1)
156-
return data
157133

158134

159135
def get_datasource(data: Dict[Any, Any]) -> str:

0 commit comments

Comments
 (0)