Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/yuanrui/json #213

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1a68255
Add to_json functionnality
zhang-yuanrui Nov 28, 2024
34c1726
Merge branch 'main' of github.com:ansys/pydynamicreporting into feat/…
zhang-yuanrui Dec 5, 2024
6c58183
Load templates
zhang-yuanrui Dec 5, 2024
c25fefc
Merge branch 'main' of github.com:ansys/pydynamicreporting into feat/…
zhang-yuanrui Dec 16, 2024
71b04c7
Add a testing folder for template json
zhang-yuanrui Dec 17, 2024
c389bed
Use a simpler test case
zhang-yuanrui Dec 17, 2024
367ed7b
ignore tests/test_data/template_json intermidate files
zhang-yuanrui Dec 17, 2024
e2ccc20
Add a fixture: adr_template_json
zhang-yuanrui Dec 17, 2024
4008b5d
Add a test for get_templates_as_json
zhang-yuanrui Dec 17, 2024
d2dab37
Add test_load_templates
zhang-yuanrui Dec 17, 2024
4e72d12
Remove 3 fields that are overlapped with params
zhang-yuanrui Dec 17, 2024
dd93bcc
Reformat
zhang-yuanrui Dec 17, 2024
866e5a3
Solve merge conflict
zhang-yuanrui Dec 18, 2024
9df2548
Remove some code to be consistent with the new conftest
zhang-yuanrui Dec 18, 2024
52d5866
Undo adding a new fixture
zhang-yuanrui Dec 18, 2024
408d053
Format
zhang-yuanrui Dec 18, 2024
704eb69
Use getattr to avoid part of hardcoding
zhang-yuanrui Dec 18, 2024
2fc2423
Cleanup
zhang-yuanrui Dec 18, 2024
1d49acc
format
zhang-yuanrui Dec 18, 2024
5a34447
Init templates_data[curr_template_key]
zhang-yuanrui Dec 18, 2024
4470afe
Delete templates after the testing
zhang-yuanrui Dec 19, 2024
62c7751
Merge branch 'main' of github.com:ansys/pydynamicreporting into feat/…
zhang-yuanrui Dec 20, 2024
63ce817
Use the new format
zhang-yuanrui Dec 20, 2024
732350a
Throw a customized exception when errors occur during JSON loading
zhang-yuanrui Dec 20, 2024
3228e61
Finish checking loaded JSON except for 'params' and 'sort_selection'
zhang-yuanrui Dec 23, 2024
3d29e5a
Finish error checking tests
zhang-yuanrui Dec 26, 2024
7aef10d
Merge branch 'main' of github.com:ansys/pydynamicreporting into feat/…
zhang-yuanrui Dec 30, 2024
9e0d12e
Move the def of TemplateEditorJSONLoadingError to exceptions.py
zhang-yuanrui Dec 30, 2024
3789a63
Move the def of TemplateEditorJSONLoadingError to exceptions.py; Avoi…
zhang-yuanrui Dec 30, 2024
9425e89
Throw an exception only when the input keys are missing necessary JSO…
zhang-yuanrui Jan 3, 2025
f81bf38
1. Throw an exception only when the input keys are missing necessary …
zhang-yuanrui Jan 3, 2025
6ac6288
Drop date
zhang-yuanrui Jan 3, 2025
b9d7ab8
Add a logger in the loading JSON interface
zhang-yuanrui Jan 3, 2025
195ed03
Format
zhang-yuanrui Jan 3, 2025
4d9a956
Merge branch 'main' of github.com:ansys/pydynamicreporting into feat/…
zhang-yuanrui Jan 7, 2025
97d9bad
Make get_report_types a public method
zhang-yuanrui Jan 7, 2025
3051b8e
_get_report_types --> get_report_types
zhang-yuanrui Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 121 additions & 3 deletions src/ansys/dynamicreporting/core/utils/report_remote_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@
from .encoders import BaseEncoder


class TemplateEditorJSONLoadingError(Exception):
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
"""
A specialized exception class for errors when loading a JSON file for the template editor
"""

def __init__(self, message):
super().__init__(message)
self.message = message


def disable_warn_logging(func):
# Decorator to suppress harmless warning messages
@functools.wraps(func)
Expand Down Expand Up @@ -983,7 +993,8 @@ def get_templates_as_json(self, root_guid):
_build_template_data(root_guid, templates_data, templates, template_guid_id_map)
return templates_data

def _populate_template(self, attr, parent_template):
def _populate_template(self, id_str, attr, parent_template):
_check_template(id_str, attr)
template = self.create_template(
name=attr["name"], parent=parent_template, report_type=attr["report_type"]
)
Expand All @@ -997,6 +1008,7 @@ def _populate_template(self, attr, parent_template):

def _update_changes(self, id_str, id_template_map, templates_json):
children_id_strs = templates_json[id_str]["children"]

if not children_id_strs:
return

Expand All @@ -1012,7 +1024,9 @@ def _build_templates_from_parent(self, id_str, id_template_map, templates_json):
child_templates = []
for child_id_str in children_id_strs:
child_attr = templates_json[child_id_str]
child_template = self._populate_template(child_attr, id_template_map[id_str])
child_template = self._populate_template(
child_id_str, child_attr, id_template_map[id_str]
)
child_templates.append(child_template)
id_template_map[child_id_str] = child_template

Expand All @@ -1033,14 +1047,118 @@ def load_templates(self, templates_json):
break

root_attr = templates_json[root_id_str]
root_template = self._populate_template(root_attr, None)
root_template = self._populate_template(root_id_str, root_attr, None)
self.put_objects(root_template)
id_template_map = {}
id_template_map[root_id_str] = root_template
self._build_templates_from_parent(root_id_str, id_template_map, templates_json)
self._update_changes(root_id_str, id_template_map, templates_json)


def _check_template(template_id_str, template_attr):
# Check template_id_str
if not _check_template_name_convention(template_id_str):
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file has an invalid template name: '{template_id_str}' as the key.\n"
"Please note that the naming convention is 'Template_{NONE_NEGATIVE_NUMBER}'"
)

# Check parent and children template name convention
if not _check_template_name_convention(template_attr["parent"]):
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file has an invalid template name: '{template_attr['parent']}' "
f"that does not have the correct name convection under the key: 'parent' of '{template_id_str}'\n"
"Please note that the naming convention is 'Template_{NONE_NEGATIVE_NUMBER}'"
)

for child_name in template_attr["children"]:
if not _check_template_name_convention(child_name):
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file has an invalid template name: '{child_name}' "
f"that does not have the correct name convection under the key: 'children' of '{template_id_str}'\n"
"Please note that the naming convention is 'Template_{NONE_NEGATIVE_NUMBER}'"
)

# Check key names
agreed_keys = {
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
"name",
"report_type",
"date",
"tags",
"params",
"sort_selection",
"item_filter",
"parent",
"children",
}
for key in template_attr.keys():
if key not in agreed_keys:
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file is using an unknown key: '{key}' other than any in the JSON schema.\n"
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
f"Please check the '{key}' entry under '{template_id_str}' in your JSON file as you might have a typo in that entry."
)

# Check missing keys
if len(template_attr) != len(agreed_keys): # Missing one or more entries
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
keys = template_attr.keys()
missing_keys = list(agreed_keys - set(keys))
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file is missing keys: {missing_keys}.\n"
f"Please check them under '{template_id_str}' in your JSON file for the missing keys."
)

# Check report_type
report_types = {
zhang-yuanrui marked this conversation as resolved.
Show resolved Hide resolved
"Layout:panel",
"Layout:basic",
"Layout:box",
"Layout:tabs",
"Layout:carousel",
"Layout:slider",
"Layout:footer",
"Layout:header",
"Layout:iterator",
"Layout:tagprops",
"Layout:toc",
"Layout:reportlink",
"Layout:userdefined",
}
if not template_attr["report_type"] in report_types:
raise TemplateEditorJSONLoadingError(
f"The loaded JSON file has an invalid 'report_type' value: '{template_attr['report_type']}'"
)

# Check item_filter
common_error_str = "The loaded JSON file does not follow the correct item_filter convention!\n"
for query_stanza in template_attr["item_filter"].split(";"):
if len(query_stanza) > 0:
parts = query_stanza.split("|")
if len(parts) != 4:
raise TemplateEditorJSONLoadingError(
f"{common_error_str}Each part should be divided by '|', "
f"while the input is '{query_stanza}' under '{template_id_str}', which does not have 3 '|'s"
)
if parts[0] not in ["A", "O"]:
raise TemplateEditorJSONLoadingError(
f"{common_error_str}The first part of the filter can only be 'A' or 'O', "
f"while the first part of the input is '{parts[0]}' under '{template_id_str}'"
)
prefix = ["i_", "s_", "d_", "t_"]
if parts[1][0:2] not in prefix:
raise TemplateEditorJSONLoadingError(
f"{common_error_str}The second part of the filter can only be '{prefix}', "
f"while the second part of the input is '{parts[1]}' under '{template_id_str}'"
)
# TODO: check 'sort_selection' and 'params'


def _check_template_name_convention(template_name):
if template_name is None:
return True
parts = template_name.split("_")
return len(parts) == 2 and parts[0] == "Template" and parts[1].isdigit()


def _build_template_data(guid, templates_data, templates, template_guid_id_map):
curr_template = None
for template in templates:
Expand Down
Loading
Loading