Skip to content

Commit

Permalink
feat: support Jinja2 templates with spaces in variable names
Browse files Browse the repository at this point in the history
- Modified the parser to handle variables like {{Instance Type}}
- Replaced spaces in variable names with underscores for compatibility

Signed-off-by: seolmin <seolmin@megazone.com>
  • Loading branch information
stat-kwon committed Jan 6, 2025
1 parent 8954e3f commit 90bf1f4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/spaceone/dashboard/manager/data_table_manager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, *args, **kwargs):
self.data_keys = None
self.label_keys = None
self.jinja_variables = None
self.jinja_variables_contain_space = []
self.state = None
self.error_message = None

Expand Down Expand Up @@ -224,12 +225,38 @@ def apply_page_df(self, page: dict) -> None:
self.df = self.df.iloc[start - 1 : start + limit - 1]

def is_jinja_expression(self, expression: str) -> bool:
if not expression:
return False

env = Environment()

parsed_content = env.parse(expression)
jinja_pattern = re.compile(r"\{\{\s*(.*?)\s*\}\}")

modified_expression = re.sub(
jinja_pattern,
lambda m: "{{" + m.group(1).replace(" ", "_") + "}}",
expression,
)

jinja_keys_with_space = {}
if expression != modified_expression:
keys_with_space = re.findall(jinja_pattern, expression)
for key in keys_with_space:
jinja_keys_with_space[key.replace(" ", "_")] = key

parsed_content = env.parse(modified_expression)
variables = meta.find_undeclared_variables(parsed_content)

if variables:
if jinja_keys_with_space:
for key, key_with_space in jinja_keys_with_space.items():
self.jinja_variables_contain_space.append(
{
"origin_key": key_with_space,
"modified_key": key,
}
)

self.jinja_variables = variables

return bool(variables)
Expand Down Expand Up @@ -276,6 +303,15 @@ def change_global_variables(self, expression: str, vars: dict):

@staticmethod
def remove_jinja_braces(expression: str) -> Union[str, float, list]:
jinja_pattern = re.compile(r"\{\{\s*(.*?)\s*\}\}")

modified_expression = re.sub(
jinja_pattern,
lambda m: "{{" + m.group(1).replace(" ", "_") + "}}",
expression,
)
expression = modified_expression

while "{{" in expression and "}}" in expression:
if re.match(r"{{\s*(\w+)\s*}}", expression):
expression = re.sub(r"{{\s*(\w+)\s*}}", r"\1", expression)
Expand Down Expand Up @@ -310,6 +346,15 @@ def change_expression_data_type(expression: str, gv_type_map: dict) -> str:

return expression

def change_space_variable(self, expression: str) -> str:
if self.jinja_variables_contain_space:
for space_variable in self.jinja_variables_contain_space:
expression = expression.replace(
space_variable["modified_key"], f"`{space_variable['origin_key']}`"
)

return expression

def _prepare_query_data(
self,
data_table_id: str,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def query_data_table(
condition, gv_type_map = self.change_global_variables(condition, vars)
condition = self.remove_jinja_braces(condition)
condition = self.change_expression_data_type(condition, gv_type_map)
condition = self.change_space_variable(condition)

try:
df = df.query(condition)
Expand Down Expand Up @@ -298,6 +299,7 @@ def evaluate_data_table(
)
condition = self.remove_jinja_braces(condition)
condition = self.change_expression_data_type(condition, gv_type_map)
condition = self.change_space_variable(condition)

if self.is_jinja_expression(value_expression):
value_expression, gv_type_map = self.change_global_variables(
Expand All @@ -307,6 +309,7 @@ def evaluate_data_table(
value_expression = self.change_expression_data_type(
value_expression, gv_type_map
)
value_expression = self.change_space_variable(value_expression)

template_vars = {}
for key in self.data_keys:
Expand Down Expand Up @@ -875,6 +878,7 @@ def filter_data(self, df: pd.DataFrame, vars: dict) -> pd.DataFrame:
condition, gv_type_map = self.change_global_variables(condition, vars)
condition = self.remove_jinja_braces(condition)
condition = self.change_expression_data_type(condition, gv_type_map)
condition = self.change_space_variable(condition)

return df.query(condition).copy()

Expand Down

0 comments on commit 90bf1f4

Please sign in to comment.