Skip to content

Commit 36db6dd

Browse files
authored
Add filtering feature to report object (#122)
1 parent 4e7870e commit 36db6dd

File tree

5 files changed

+90
-59
lines changed

5 files changed

+90
-59
lines changed

codegen/adr_utils.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,58 @@ def get_logger(logfile=None):
7373
ch.setFormatter(formatter)
7474
logger.addHandler(ch)
7575
return logger
76+
77+
78+
def check_filter(filter: str = ""):
79+
"""
80+
Verify validity of the query string for filtering.
81+
82+
Parameters
83+
----------
84+
filter : str, optional
85+
Query string for filtering. The default is ``""``. The syntax corresponds
86+
to the syntax for Ansys Dynamic Reporting. For more information, see
87+
_Query Expressions in the documentation for Ansys Dynamic Reporting.
88+
89+
Returns
90+
-------
91+
bool
92+
``True`` if the query string is valid, ``False`` otherwise.
93+
"""
94+
for query_stanza in filter.split(";"):
95+
if len(query_stanza) > 0:
96+
if len(query_stanza.split("|")) != 4:
97+
return False
98+
if query_stanza.split("|")[0] not in ["A", "O"]:
99+
return False
100+
if query_stanza.split("|")[1][0:2] not in ["i_", "s_", "d_", "t_"]:
101+
return False
102+
return True
103+
104+
105+
def build_query_url(logger = None, filter: str = "") -> str:
106+
"""
107+
Build the query section of report url.
108+
109+
Parameters
110+
----------
111+
logger: logging.logger
112+
The logger object.
113+
114+
filter : str, optional
115+
Query string for filtering. The default is ``""``. The syntax corresponds
116+
to the syntax for Ansys Dynamic Reporting. For more information, see
117+
_Query Expressions in the documentation for Ansys Dynamic Reporting.
118+
119+
Returns
120+
-------
121+
str
122+
query section of the report url corresponding to the query string.
123+
"""
124+
valid = check_filter(filter)
125+
if valid is False:
126+
logger.warning("Warning: filter string is not valid. Will be ignored.")
127+
return ""
128+
else:
129+
query_str = "&query={}".format(filter.replace("|", "%7C").replace(";", "%3B").replace("&", "%2C"))
130+
return query_str

src/ansys/dynamicreporting/core/adr_report.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from typing import Optional
2222
import webbrowser
2323

24-
from ansys.dynamicreporting.core.adr_utils import in_ipynb
24+
from ansys.dynamicreporting.core.adr_utils import build_query_url, in_ipynb
2525
from ansys.dynamicreporting.core.utils import report_objects
2626

2727
try:
@@ -75,7 +75,7 @@ def __find_report_obj__(self) -> bool:
7575
success = True
7676
return success
7777

78-
def visualize(self, new_tab: bool = False) -> None:
78+
def visualize(self, new_tab: bool = False, filter: str = "") -> None:
7979
"""
8080
Render the report.
8181
@@ -86,6 +86,10 @@ def visualize(self, new_tab: bool = False) -> None:
8686
is a Jupyter notebook. The default is ``False``, in which case the
8787
report is rendered in the current location. If the environment is
8888
not a Jupyter notebook, the report is always rendered in a new tab.
89+
filter : str, optional
90+
Query string for filtering. The default is ``""``. The syntax corresponds
91+
to the syntax for Ansys Dynamic Reporting. For more information, see
92+
_Query Expressions in the documentation for Ansys Dynamic Reporting.
8993
9094
Returns
9195
-------
@@ -110,16 +114,23 @@ def visualize(self, new_tab: bool = False) -> None:
110114
else:
111115
display(iframe)
112116
else:
113-
url = self.get_url()
117+
url = self.get_url(filter=filter)
114118
if url == "": # pragma: no cover
115119
self.service.logger.error("Error: could not obtain url for report")
116120
else:
117121
webbrowser.open_new(url)
118122

119-
def get_url(self) -> str:
123+
def get_url(self, filter: str = "") -> str:
120124
"""
121125
Get the URL corresponding to the report.
122126
127+
Parameters
128+
----------
129+
filter : str, optional
130+
Query string for filtering. The default is ``""``. The syntax corresponds
131+
to the syntax for Ansys Dynamic Reporting. For more information, see
132+
_Query Expressions in the documentation for Ansys Dynamic Reporting.
133+
123134
Returns
124135
-------
125136
str
@@ -157,9 +168,10 @@ def get_url(self) -> str:
157168
)
158169
return ""
159170
url += "usemenus=off"
171+
url += build_query_url(self.service.logger, filter)
160172
return url
161173

162-
def get_iframe(self, width: int = 1000, height: int = 800):
174+
def get_iframe(self, width: int = 1000, height: int = 800, filter: str = ""):
163175
"""
164176
Get the iframe object corresponding to the report.
165177
@@ -169,6 +181,10 @@ def get_iframe(self, width: int = 1000, height: int = 800):
169181
Width of the iframe object. The default is ``1000``.
170182
height : int, optional
171183
Height of the iframe object. The default is ``800``.
184+
filter : str, optional
185+
Query string for filtering. The default is ``""``. The syntax corresponds
186+
to the syntax for Ansys Dynamic Reporting. For more information, see
187+
_Query Expressions in the documentation for Ansys Dynamic Reporting.
172188
173189
Returns
174190
-------
@@ -187,7 +203,7 @@ def get_iframe(self, width: int = 1000, height: int = 800):
187203
report_iframe = my_report.get_iframe()
188204
"""
189205
if "IPython.display" in sys.modules:
190-
url = self.get_url()
206+
url = self.get_url(filter=filter)
191207
iframe = IFrame(src=url, width=width, height=height)
192208
else:
193209
iframe = None

src/ansys/dynamicreporting/core/adr_service.py

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
from .adr_item import Item
3737
from .adr_report import Report
38-
from .adr_utils import dict_items, get_logger, in_ipynb, type_maps
38+
from .adr_utils import build_query_url, check_filter, dict_items, get_logger, in_ipynb, type_maps
3939
from .constants import DOCKER_DEFAULT_PORT, DOCKER_REPO_URL
4040
from .docker_support import DockerLauncher
4141
from .exceptions import (
@@ -636,32 +636,6 @@ def stop(self) -> None:
636636
self.serverobj = None
637637
self._url = None
638638

639-
def __check_filter__(self, filter: str = ""):
640-
"""
641-
Verify validity of the query string for filtering.
642-
643-
Parameters
644-
----------
645-
filter : str, optional
646-
Query string for filtering. The default is ``""``. The syntax corresponds
647-
to the syntax for Ansys Dynamic Reporting. For more information, see
648-
_Query Expressions in the documentation for Ansys Dynamic Reporting.
649-
650-
Returns
651-
-------
652-
bool
653-
``True`` if the query string is valid, ``False`` otherwise.
654-
"""
655-
for query_stanza in filter.split(";"):
656-
if len(query_stanza) > 0:
657-
if len(query_stanza.split("|")) != 4:
658-
return False
659-
if query_stanza.split("|")[0] not in ["A", "O"]:
660-
return False
661-
if query_stanza.split("|")[1][0:2] not in ["i_", "s_", "d_", "t_"]:
662-
return False
663-
return True
664-
665639
def visualize_report(
666640
self,
667641
report_name: Optional[str] = "",
@@ -724,17 +698,9 @@ def visualize_report(
724698
url += "usemenus=off"
725699
query_str = ""
726700
if filter:
727-
valid = self.__check_filter__(filter)
728-
if valid is False:
729-
self.logger.warning("Warning: filter string is not valid. Will be ignored.")
730-
else:
731-
query_str = "&query="
732-
for q_stanza in filter.split(";"):
733-
if len(q_stanza) > 1:
734-
each_item = q_stanza.split("|")
735-
query_str += each_item[-4] + "%7C" + each_item[-3]
736-
query_str += "%7C" + each_item[-2]
737-
query_str += "%7C" + each_item[-1]
701+
query_str = build_query_url(self.logger, filter)
702+
else:
703+
query_str = ""
738704
url += query_str
739705
if in_ipynb() and not new_tab:
740706
display(IFrame(src=url, width=1000, height=800))
@@ -803,7 +769,7 @@ def query(self, query_type: str = "Item", filter: Optional[str] = "") -> list:
803769
imgs = adr_service.query(query_type='Item', filter='A|i_type|cont|image;')
804770
"""
805771
queried_items = []
806-
valid = self.__check_filter__(filter)
772+
valid = check_filter(filter)
807773
if valid is False:
808774
self.logger.warning("Warning: filter string is not valid. Will be ignored.")
809775
filter = ""

tests/test_report.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ def test_geturl_report(adr_service_query) -> bool:
1414
assert "http:" in url
1515

1616

17+
@pytest.mark.ado_test
18+
def test_geturl_report_with_filter(adr_service_query) -> bool:
19+
my_report = adr_service_query.get_report(report_name="My Top Report")
20+
url = my_report.get_url(filter='"A|b_type|cont|image;"')
21+
adr_service_query.stop()
22+
assert "http:" in url
23+
24+
1725
def test_visualize_report(adr_service_query) -> bool:
1826
success = False
1927
try:

tests/test_service.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,6 @@ def test_unit_query() -> bool:
9999
assert query_list == []
100100

101101

102-
@pytest.mark.ado_test
103-
def test_unit_invalidqueryone() -> bool:
104-
a = Service()
105-
valid = a.__check_filter__("F|i_type|cont|html;")
106-
assert valid is False
107-
108-
109-
@pytest.mark.ado_test
110-
def test_unit_invalidquerytwo() -> bool:
111-
a = Service()
112-
valid = a.__check_filter__("A|b_type|cont|html;")
113-
assert valid is False
114-
115-
116102
@pytest.mark.ado_test
117103
def test_unit_delete_invalid(request) -> bool:
118104
logfile = join(request.fspath.dirname, "outfile_4.txt")

0 commit comments

Comments
 (0)