Skip to content

Commit

Permalink
Use static info for tuigen
Browse files Browse the repository at this point in the history
  • Loading branch information
mkundu1 committed Jul 21, 2022
1 parent 5d92146 commit d979da5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 40 deletions.
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
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
"""
try:
request = DataModelProtoModule.GetStaticInfoRequest()
request.path = self._path
response = self._service.get_static_info(request)
return MessageToDict(response.info, including_default_value_fields=True)
except RuntimeError:
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()
info["menus"] = {}
info["commands"] = {}
child_names = menu.get_child_names()
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())
raise RuntimeError(ex.details()) from None

return func

0 comments on commit d979da5

Please sign in to comment.