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

Use static info for tuigen #651

Merged
merged 3 commits into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 10 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ jobs:
src/ansys/fluent/core/meshing/tui.py
src/ansys/fluent/core/solver/settings
src/ansys/fluent/core/solver/tui.py
key: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}-${{ github.sha }}
restore-keys: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}
doc/source/api/core/meshing/tui
doc/source/api/core/meshing/datamodel
doc/source/api/core/solver/tui
doc/source/api/core/solver/datamodel
key: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}
mkundu1 marked this conversation as resolved.
Show resolved Hide resolved
restore-keys: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}

- name: Login to GitHub Container Registry
if: steps.cache-api-code.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -177,9 +181,9 @@ jobs:
uses: actions/cache@v3
with:
path: doc/source/examples
key: Examples-v${{ env.RESET_EXAMPLES_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('examples/**') }}-${{ github.sha }}
key: Examples-v${{ env.RESET_EXAMPLES_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('examples/**') }}
restore-keys: |
Examples-v${{ env.RESET_EXAMPLES_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('examples/**') }}
Examples-v${{ env.RESET_EXAMPLES_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}

- name: Build Documentation
run: make build-doc DOCS_CNAME=fluentdocs.pyansys.com
Expand Down Expand Up @@ -256,8 +260,8 @@ jobs:
doc/source/api/core/meshing/datamodel
doc/source/api/core/solver/tui
doc/source/api/core/solver/datamodel
key: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}-${{ github.sha }}
restore-keys: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}
key: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}-${{ hashFiles('codegen/**') }}
mkundu1 marked this conversation as resolved.
Show resolved Hide resolved
restore-keys: API-Code-v${{ env.API_CODE_CACHE }}-${{ steps.version.outputs.PYFLUENT_VERSION }}-${{ matrix.image-tag }}

- name: Login to GitHub Container Registry
if: steps.cache-api-code.outputs.cache-hit != 'true'
Expand Down
66 changes: 30 additions & 36 deletions codegen/tuigen.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import shutil
import string
import subprocess
from typing import Iterable
from typing import Any, Dict
import xml.etree.ElementTree as ET

from data.fluent_gui_help_patch import XML_HELP_PATCH
Expand All @@ -28,7 +28,6 @@
from ansys.fluent.core import LOG
from ansys.fluent.core.launcher.launcher import FLUENT_VERSION, get_fluent_path
from ansys.fluent.core.services.datamodel_tui import (
DatamodelService,
PyMenu,
convert_path_to_grpc_path,
convert_tui_menu_to_func_name,
Expand Down Expand Up @@ -148,32 +147,30 @@ def _populate_xml_helpstrings():
_XML_HELPSTRINGS[k] = v


class _TUIMenuGenerator:
"""Wrapper over PyMenu to extract TUI menu metadata from Fluent."""

def __init__(self, path: str, service: DatamodelService):
self._menu = PyMenu(service, path)

def get_child_names(self) -> Iterable[str]:
return self._menu.get_child_names(True)

def get_doc_string(self) -> str:
return self._menu.get_doc_string(True)
def _is_valid_tui_menu_name(name):
return name and not all(x in string.punctuation for x in name)


class _TUIMenu:
"""Class representing Fluent's TUI menu."""

def __init__(self, path: str):
def __init__(self, path: str, doc: str, is_command: bool = False):
self.path = path
self.tui_name = path[-1] if path else ""
self.name = convert_tui_menu_to_func_name(self.tui_name)
self.is_command = is_command
tui_path = convert_path_to_grpc_path(path)
self.doc = _XML_HELPSTRINGS.get(tui_path, None)
if self.doc:
del _XML_HELPSTRINGS[tui_path]
else:
self.doc = doc
self.doc = self.doc.replace("\\*", "*")
self.doc = self.doc.replace("*", "\*")
self.doc = self.doc.strip()
if not self.doc.endswith("."):
self.doc = self.doc + "."
self.children = {}
self.is_command = False

def get_command_path(self, command: str) -> str:
return convert_path_to_grpc_path(self.path + [command])
Expand All @@ -200,26 +197,22 @@ def __init__(
shutil.rmtree(Path(self._tui_doc_dir))
self.session = pyfluent.launch_fluent(meshing_mode=meshing)
self._service = self.session._datamodel_service_tui
self._main_menu = _TUIMenu([])

def _populate_menu(self, menu: _TUIMenu):
menugen = _TUIMenuGenerator(menu.path, self._service)
if not menu.doc:
menu.doc = menugen.get_doc_string()
menu.doc = menu.doc.replace("\\*", "*")
menu.doc = menu.doc.replace("*", "\*")
menu.doc = menu.doc.strip()
if not menu.doc.endswith("."):
menu.doc = menu.doc + "."
child_names = menugen.get_child_names()
if child_names:
for child_name in child_names:
if child_name and not all(x in string.punctuation for x in child_name):
child_menu = _TUIMenu(menu.path + [child_name])
menu.children[child_menu.name] = child_menu
self._populate_menu(child_menu)
else:
menu.is_command = True
self._main_menu = _TUIMenu([], "")

def _populate_menu(self, menu: _TUIMenu, info: Dict[str, Any]):
for child_menu_name, child_menu_info in info["menus"].items():
if _is_valid_tui_menu_name(child_menu_name):
child_menu = _TUIMenu(
menu.path + [child_menu_name], child_menu_info["help"]
)
menu.children[child_menu.name] = child_menu
self._populate_menu(child_menu, child_menu_info)
for child_command_name, child_command_info in info["commands"].items():
if _is_valid_tui_menu_name(child_command_name):
child_menu = _TUIMenu(
menu.path + [child_command_name], child_command_info["help"], True
)
menu.children[child_menu.name] = child_menu

def _write_code_to_tui_file(self, code: str, indent: int = 0):
self.__writer.write(" " * _INDENT_STEP * indent + code)
Expand Down Expand Up @@ -317,7 +310,8 @@ def _write_doc_for_menu(self, menu, doc_dir: Path, heading, class_name) -> None:
def generate(self) -> None:
Path(self._tui_file).parent.mkdir(exist_ok=True)
with open(self._tui_file, "w", encoding="utf8") as self.__writer:
self._populate_menu(self._main_menu)
info = PyMenu(self._service, self._main_menu.path).get_static_info()
self._populate_menu(self._main_menu, info)
self.session.exit()
if self._tui_file == _SOLVER_TUI_FILE:
self._write_code_to_tui_file('"""Fluent Solver TUI Commands"""\n')
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/fluent/core/launcher/fluent_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def start_fluent_container(mounted_from: str, mounted_to: str, args: List[str])
"-e",
"FLUENT_LAUNCHED_FROM_PYFLUENT=1",
"ghcr.io/pyansys/pyfluent",
"-g",
"-gu",
mkundu1 marked this conversation as resolved.
Show resolved Hide resolved
f"-sifile={container_sifile}",
]
+ args
Expand Down
46 changes: 45 additions & 1 deletion src/ansys/fluent/core/services/datamodel_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import keyword
import types
from typing import Any, Iterable, List, Tuple, Union
from typing import Any, Dict, Iterable, List, Tuple, Union

from google.protobuf.json_format import MessageToDict
import grpc

from ansys.api.fluent.v0 import datamodel_tui_pb2 as DataModelProtoModule
Expand Down Expand Up @@ -57,6 +58,10 @@ def execute_query(
) -> DataModelProtoModule.ExecuteQueryResponse:
return self.__stub.ExecuteQuery(request, metadata=self.__metadata)

@catch_grpc_error
def get_static_info(self, request):
return self.__stub.GetStaticInfo(request, metadata=self.__metadata)


def _convert_value_to_gvalue(val: Any, gval: Variant):
"""Convert Python datatype to Value type of
Expand Down Expand Up @@ -197,6 +202,45 @@ def get_doc_string(self, include_unavailable: bool = False) -> str:
response = self._service.get_attribute_value(request)
return _convert_gvalue_to_value(response.value)

def get_static_info(self) -> Dict[str, Any]:
"""Get static info at menu level.

Returns
-------
DataModelProtoModule.StaticInfo
static info
"""
if hasattr(DataModelProtoModule, "GetStaticInfoRequest"):
mkundu1 marked this conversation as resolved.
Show resolved Hide resolved
request = DataModelProtoModule.GetStaticInfoRequest()
request.path = self._path
response = self._service.get_static_info(request)
return MessageToDict(response.info, including_default_value_fields=True)
else:
return _get_static_info_at_level(self)


def _get_static_info_at_level(menu: PyMenu) -> Dict[str, Any]:
info = {}
info["help"] = menu.get_doc_string(include_unavailable=True)
info["menus"] = {}
info["commands"] = {}
child_names = menu.get_child_names(include_unavailable=True)
if child_names:
for child_name in child_names:
if child_name:
child_menu = PyMenu(
menu._service,
menu._path + ("" if menu._path.endswith("/") else "/") + child_name,
)
child_info = _get_static_info_at_level(child_menu)
if child_info.pop("is_command", False):
info["commands"][child_name] = child_info
else:
info["menus"][child_name] = child_info
else:
info["is_command"] = True
return info


class TUIMenu:
"""Base class for the generated menu classes."""
Expand Down
3 changes: 0 additions & 3 deletions src/ansys/fluent/core/services/error_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

import grpc

from ansys.fluent.core.utils.logging import LOG


def catch_grpc_error(f: Callable) -> Callable:
"""Decorator to catch gRPC errors."""
Expand All @@ -14,7 +12,6 @@ def func(*args, **kwargs) -> Callable:
try:
return f(*args, **kwargs)
except grpc.RpcError as ex:
LOG.error("GRPC_ERROR: %s", ex.details())
mkundu1 marked this conversation as resolved.
Show resolved Hide resolved
raise RuntimeError(ex.details()) from None

return func