Skip to content

FEAT: Add an App method to print project tree for embedding scenario #779

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

Merged
merged 12 commits into from
Jun 21, 2024
Merged
1 change: 1 addition & 0 deletions doc/changelog.d/779.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FEAT: Add an App method to print project tree for embedding scenario
75 changes: 75 additions & 0 deletions src/ansys/mechanical/core/embedding/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,78 @@
def _update_all_globals(self) -> None:
for scope in self._updated_scopes:
scope.update(global_entry_points(self))

def _print_tree(self, node, max_lines, lines_count, indentation):
"""Recursively print till provided maximum lines limit.

Parameters
----------
lines_count: int, optional
The current count of lines printed. Default is 0.
indentation: str, optional
The indentation string used for printing the tree structure. Default is "".
"""
if lines_count >= max_lines and max_lines != -1:
print(f"... truncating after {max_lines} lines")
return lines_count

if not hasattr(node, "Name"):
raise AttributeError("Object must have a 'Name' attribute")

node_name = node.Name
if hasattr(node, "Suppressed") and node.Suppressed is True:
node_name += " (Suppressed)"

Check warning on line 353 in src/ansys/mechanical/core/embedding/app.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/app.py#L353

Added line #L353 was not covered by tests
print(f"{indentation}├── {node.Name}")
lines_count += 1

if hasattr(node, "Children") and node.Children is not None and node.Children.Count > 0:
for child in node.Children:
_lines_count = self._print_tree(child, max_lines, lines_count, indentation + "| ")
if _lines_count >= max_lines and max_lines != -1:
break

return lines_count

def print_tree(self, node, max_lines=80, lines_count=0, indentation=""):
"""
Print the hierarchical tree representation of the Mechanical project structure.

Each object in the tree is expected to have the following attributes:
- Name: The name of the object.
- Suppressed : Print as suppressed, if object is suppressed.
- Children: Checks if object have children.
Each child node is expected to have the all these attributes.

Parameters
----------
node: ExtAPI object
The starting object of the tree.
max_lines: int, optional
The maximum number of lines to print. Default is 80. If set to -1, no limit is applied.

Raises
------
AttributeError
If the node does not have the required attributes.

Examples
--------
>>> import ansys.mechanical.core as mech
>>> app = mech.App()
>>> app.update_globals(globals())
>>> app.print_tree(DataModel.Project)
... ├── Project
... | ├── Model
... | | ├── Geometry Imports
... | | ├── Geometry
... | | ├── Materials
... | | ├── Coordinate Systems
... | | | ├── Global Coordinate System
... | | ├── Remote Points
... | | ├── Mesh

>>> app.print_tree(DataModel.Project, 1)
... ├── Project
... ... truncating after 1 lines
"""
self._print_tree(node, max_lines, lines_count, indentation)
22 changes: 22 additions & 0 deletions tests/embedding/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,28 @@ def test_nonblock_sleep(embedded_app):
assert (t2 - t1) >= 1


@pytest.mark.embedding
def test_app_print_tree(embedded_app, capsys, assets):
"""Test printing hierarchical tree of Mechanical ExtAPI object"""
embedded_app.update_globals(globals())
geometry_file = os.path.join(assets, "Eng157.x_t")
geometry_import = Model.GeometryImportGroup.AddGeometryImport()
geometry_import.Import(geometry_file)
allbodies = Model.GetChildren(DataModelObjectCategory.Body, True)
allbodies[0].Suppressed = True
embedded_app.print_tree(DataModel.Project, 1)
captured = capsys.readouterr()
printed_output = captured.out.strip()
assert "Project" in printed_output
embedded_app.print_tree(DataModel.Project, 2)
captured = capsys.readouterr()
printed_output = captured.out.strip()
assert "Model" in printed_output

with pytest.raises(AttributeError):
embedded_app.print_tree(DataModel)


@pytest.mark.embedding
def test_app_poster(embedded_app):
"""The getters of app should be usable after a new().
Expand Down
Loading