Skip to content

Commit

Permalink
Merge branch 'main' into saf-desktop-1.0-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
alexciurana committed Nov 24, 2023
2 parents 4515f8a + c51caf0 commit caea59b
Show file tree
Hide file tree
Showing 13 changed files with 954 additions and 906 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/solutions_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Trigger end-to-end tests for solution templates
on:
pull_request:
paths:
- 'src/ansys/templates/python/solution/**'
- 'src/ansys/templates/python/osl_solution/**'

jobs:

solutions-e2e-tests:
name: Trigger solutions e2e tests
runs-on: ubuntu-latest
steps:
- name: github workflow dispatch
shell: bash
env:
GH_TOKEN: ${{ secrets.ANSYS_SOLUTIONS_E2E_TESTS }}
run: |
gh workflow run \
_ansys-templates-remote-ci.yml \
--repo "https://github.com/Solution-Applications/solution-templates-end-to-end-testing" \
--field ansys_templates_sha="${{ github.event.pull_request.head.sha }}" \
--ref "refs/heads/main"
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@ on:
synchronize,
ready_for_review
]
release:
types: [published]
workflow_dispatch:

env:
MAIN_PYTHON_VERSION: "3.8"
MAIN_PYTHON_VERSION: "3.10"
DOCUMENTATION_CNAME: ""
POETRY_HTTP_BASIC_SOLUTIONS_PRIVATE_PYPI_USERNAME: "PAT"
POETRY_HTTP_BASIC_SOLUTIONS_PRIVATE_PYPI_PASSWORD: {{ '${{ secrets.SOLUTIONS_PRIVATE_PYPI_PAT }}' }}

concurrency:
group: {{ '${{ github.workflow }}-${{ github.ref ' }}
group: {{ '${{ github.workflow }}-${{ github.ref }}' }}
cancel-in-progress: true

jobs:
Expand All @@ -34,20 +32,19 @@ jobs:
runs-on: [ubuntu-latest]
steps:
- name: Check copyright
uses: Solution-Applications/actions/check-copyright@v4.0.0
uses: Solution-Applications/actions/check-copyright@v6
with:
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN ' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN }}' }}

check-code-style:
name: Check code style
runs-on: [ubuntu-latest]
steps:
- name: Check code style
uses: Solution-Applications/actions/check-code-style@v4.0.0
uses: Solution-Applications/actions/check-code-style@v6
with:
python-version: {{ '${{ env.MAIN_PYTHON_VERSION ' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN ' }}
dependencies-source: "build-system"
python-version: {{ '${{ env.MAIN_PYTHON_VERSION }}' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN }}' }}
check-poetry-lock: "true"
check-poetry: "true"

Expand All @@ -56,29 +53,14 @@ jobs:
runs-on: [ubuntu-latest]
steps:
- name: Build
uses: Solution-Applications/actions/build@v4.0.0
uses: Solution-Applications/actions/build@v6
with:
artifact-name: "wheel"
python-version: {{ '${{ env.MAIN_PYTHON_VERSION ' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN ' }}
python-version: {{ '${{ env.MAIN_PYTHON_VERSION }}' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN }}' }}
scripts-version: "v0.5.0"
dependencies-source: "build-system"
check-poetry-lock: "true"
check-poetry: "true"
retention-days: "7"
modern-installation: "true"

release:
if: |
github.event_name == 'release'
name: Release
needs: [check-copyright, check-code-style, build]
runs-on: [ubuntu-latest]
steps:
- name: Release
uses: Solution-Applications/actions/release@v4.0.0
with:
python-version: {{ '${{ env.MAIN_PYTHON_VERSION ' }}
gh-token: {{ '${{ secrets.WORKFLOW_TOKEN ' }}
solutions-pypi-token: {{ '${{ secrets.SOLUTIONS_PRIVATE_PYPI_ADMIN_TOKEN ' }}
solutions-pypi-repository-url: https://pkgs.dev.azure.com/pyansys/_packaging/ansys-solutions/pypi/upload/

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ ansys-optislang-core = "0.4"
ansys-saf-glow = {version = "0.4.1", source = "solutions-private-pypi"}
ansys-saf-pim-light-server = {version = "^0.2.0", source = "solutions-private-pypi"}
ansys-saf-portal = {version = "0.5.0", source = "solutions-private-pypi"}
ansys-solutions-optislang-frontend-components = {version = "0.1.1", source = "solutions-private-pypi"}
ansys-solutions-optislang-frontend-components = {version = "0.1.2", source = "solutions-private-pypi"}
ansys-web-components-dash = {version = "^0.0.dev2", source = "solutions-private-pypi"}
optislang-dash-lib = {version = "^0.2.1", source = "solutions-private-pypi"}
dash = "^2.6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ def extract_project_status_info(full_project_status_info: dict) -> dict:
return data


def extract_actor_information_data(actor_status_info: dict, kind: str) -> dict:
def extract_actor_information_data(actor_status_info: dict, actor_info: dict, kind: str) -> dict:
""" Extract actor information data from the optiSLang server response.
Parameters
----------
actor_status_info: dict
Actor status info.
actor_info: dict
Actor info.
kind: str
Actor kind (actor/system).
Expand Down Expand Up @@ -86,7 +88,7 @@ def extract_actor_information_data(actor_status_info: dict, kind: str) -> dict:
succeeded_designs = actor_status_info["succeeded_designs"]
failed_designs = actor_status_info["failed_designs"]
pending_designs = actor_status_info["pending_designs"]
total_designs = actor_status_info["total_designs"]
total_designs = actor_info["max_designs"]
processed_designs = total_designs - pending_designs
try:
status = int(processed_designs / total_designs * 100)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MonitoringStep(StepModel):
commands_locked: bool = False
auto_update_activated: bool = True
actor_uid: Optional[str] = None
selected_page: int = 0
project_command_execution_status: dict = {"alert-message": "", "alert-color": "info"}
actor_command_execution_status: dict = {"alert-message": "", "alert-color": "info"}
project_btn_group_options: List = [
Expand Down Expand Up @@ -144,17 +145,18 @@ class MonitoringStep(StepModel):
def control_node_state(self, osl_manager: OptislangManager) -> None:
"""Update the state of root or actor node based on the selected command in the UI."""
osl = osl_manager.instance
if not self.selected_actor_from_command == "shutdown":
if not self.selected_command == "shutdown":
if self.selected_actor_from_command == osl.project.root_system.uid:
node = osl.project.root_system
self.actor_uid = None
else:
node = osl.project.root_system.find_node_by_uid(self.selected_actor_from_command, search_depth=-1)
self.actor_uid = node
else:
node = osl.project.root_system

status = node.control(self.selected_command, wait_for_completion=True, timeout=self.command_timeout)
status = node.control(self.selected_command, wait_for_completion=True, timeout=self.command_timeout)

if not status:
raise Exception(f"{self.selected_command.replace('_', ' ').title()} command against node {node.get_name()} failed.")
else:
osl_manager.shutdown()

if not status:
raise Exception(f"{self.selected_command.replace('_', ' ').title()} command against node {node.get_name()} failed.")
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def write_updated_properties_file(self) -> None:
upload=["placeholders", "registered_files", "settings", "parameter_manager", "criteria"],
)
)
@long_running
def update_osl_placeholders_with_ui_values(self) -> None:
"""Update placeholders with values selected by the user in the UI."""
properties = apply_placeholders_to_properties_file(self.ui_placeholders, self.properties_file.path)
Expand Down Expand Up @@ -334,7 +335,7 @@ def start_and_monitor_osl_project(self, osl_manager: OptislangManager) -> None:
# Get actor status info (TCP REQUEST)
actor_status_info = self._make_osl_server_request(osl, "get_actor_status_info", actor_uid=node_props["uid"], hid=hid)
# Collect actor information data
project_data["actors"][node_props["uid"]]["information"][hid] = datamodel.extract_actor_information_data(actor_status_info, node_props["kind"])
project_data["actors"][node_props["uid"]]["information"][hid] = datamodel.extract_actor_information_data(actor_status_info, actor_info, node_props["kind"])
# Collect design table data
if node_props["kind"] == "system":
project_data["actors"][node_props["uid"]]["design_table"][hid] = datamodel.extract_design_table_data(actor_status_info)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ids:

ids = ids

def __init__(self, data: dict, aio_id: str = None):
def __init__(self, data: dict, store_value: int= None, aio_id: str = None):
"""ActorLogsTableAIO is an All-in-One component that is composed
of a `dash_table.DataTable` component.
Expand All @@ -42,6 +42,7 @@ def __init__(self, data: dict, aio_id: str = None):
"font_size": "15px",
},
"style_as_list_view": True,
"page_current": store_value
}

super().__init__([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import webbrowser

from dash.exceptions import PreventUpdate
from dash_extensions.enrich import Input, Output, State, callback_context, dcc, html
from dash_extensions.enrich import Input, Output, State, callback_context, dcc, html, no_update

from ansys.saf.glow.client.dashclient import DashClient, callback
from ansys.saf.glow.core.method_status import MethodStatus
Expand All @@ -31,7 +31,7 @@
id="progress_bar_update",
interval=1000,
n_intervals=0,
disabled=False
disabled=True
),
dcc.Store(id='trigger_layout_display'),
dcc.Store(id='trigger_treeview_display'),
Expand All @@ -55,7 +55,7 @@ def initialization(pathname):
project.steps.problem_setup_step.get_default_placeholder_values()
project.steps.problem_setup_step.project_initialized = True

raise PreventUpdate
return True


@callback(
Expand Down Expand Up @@ -88,7 +88,7 @@ def update_progress_bar(n_intervals, pathname):
completion_rate = round(completion_rate / len(methods) * 100)

return (
True,
no_update,
[
dbc.Progress(
value=completion_rate,
Expand All @@ -107,13 +107,13 @@ def update_progress_bar(n_intervals, pathname):


@callback(
Output("trigger_body_display", "data"),
Output("trigger_treeview_display", "data"),
Output("page_layout", "children"),
Input("url", "pathname"),
Input("trigger_layout_display", "data"),
State("url", "pathname"),
prevent_initial_call=True,
)
def display_page_layout(pathname, trigger_layout_display):
def display_page_layout(trigger_layout_display, pathname):
"""Display page layout."""
project = DashClient[{{ cookiecutter.__solution_definition_name }}].get_project(pathname)
problem_setup_step = project.steps.problem_setup_step
Expand Down Expand Up @@ -173,9 +173,8 @@ def display_page_layout(pathname, trigger_layout_display):
multi=False,
height=950,
items=problem_setup_step.treeview_items,
selectedItemIds=["problem_setup"]
selectedItemIds=["problem_setup_step"]
),

],
width=2,
style={"background-color": "rgba(242, 242, 242, 0.6)"}, # Ansys grey
Expand Down Expand Up @@ -209,18 +208,19 @@ def display_page_layout(pathname, trigger_layout_display):
@callback(
Output("body_content", "children"),
Output("bottom_button_group", "children"),
Output("navigation_tree", "focusRequested"),
Output("navigation_tree", "selectedItemIds"),
Input("navigation_tree", "treeItemClicked"),
Input("url", "pathname"),
Input("trigger_body_display", "data"),
State("navigation_tree", "selectedItemIds"),
State("url", "pathname"),
prevent_initial_call=True,
)
def display_body_content(value, pathname, trigger_body_display):
def display_body_content(value, trigger_body_display, selectedItemIds, pathname):
"""Display body content."""
project = DashClient[{{ cookiecutter.__solution_definition_name }}].get_project(pathname)
problem_setup_step = project.steps.problem_setup_step
monitoring_step = project.steps.monitoring_step

last_selected_item=[selectedItemIds[0]]
if problem_setup_step.project_initialized:
triggered_id = callback_context.triggered[0]["prop_id"].split(".")[0]
footer_buttons = [
Expand All @@ -242,15 +242,17 @@ def display_body_content(value, pathname, trigger_body_display):
size="sm"
)
)
if triggered_id == "url" or triggered_id == "trigger_body_display" or trigger_body_display and len(triggered_id) == 0:
if triggered_id == "trigger_body_display":
page_layout = problem_setup_page.layout(problem_setup_step)
focusRequested = ""
if triggered_id == "navigation_tree":
focusRequested = value["id"]
elif triggered_id == "navigation_tree":
if value["id"] is None:
page_layout = html.H1("Welcome!")
elif value["id"] == "problem_setup_step":
page_layout = problem_setup_page.layout(problem_setup_step)
if "problem_setup_step" not in last_selected_item: # this is to minimize the number of times the page is reloaded. I noticed issues with the creation of the layout when the page is reloaded too many times closely together
page_layout = problem_setup_page.layout(problem_setup_step)
last_selected_item = ["problem_setup_step"]
else:
raise PreventUpdate
else:
# Get project data
project_data = json.loads(problem_setup_step.project_data_file.read_text())
Expand All @@ -263,6 +265,7 @@ def display_body_content(value, pathname, trigger_body_display):
monitoring_step.selected_state_id = None
# Get page layout
page_layout = monitoring_page.layout(problem_setup_step, monitoring_step)
last_selected_item = ["monitoring_step"]
# Update footer buttons
footer_buttons.insert(
0,
Expand Down Expand Up @@ -293,25 +296,26 @@ def display_body_content(value, pathname, trigger_body_display):
return (
page_layout,
footer,
focusRequested
last_selected_item
)
else:
raise PreventUpdate


@callback(
Output("navigation_tree", "items"),
Input("url", "pathname"),
Output("trigger_body_display", "data"),
Input("trigger_treeview_display", "data"),
State("url", "pathname"),
prevent_initial_call=True,
)
def display_tree_view(pathname, trigger_treeview_display):
def display_tree_view(trigger_treeview_display, pathname):
"""Display treeview with all project nodes."""
project = DashClient[{{ cookiecutter.__solution_definition_name }}].get_project(pathname)
problem_setup_step = project.steps.problem_setup_step

if problem_setup_step.project_initialized:
return problem_setup_step.treeview_items
return problem_setup_step.treeview_items, True
else:
raise PreventUpdate

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
def layout(problem_setup_step: ProblemSetupStep) -> html.Div:
"""Layout of the problem setup step."""
if problem_setup_step.ui_placeholders and not problem_setup_step.project_locked:
while problem_setup_step.get_long_running_method_state("update_osl_placeholders_with_ui_values").status == MethodStatus.Running: # current workaround to avoid raising ConflictError: {"detail":"update_osl_placeholders_with_ui_values is already running"} # current workaround to avoid raising ConflictError: {"detail":"update_osl_placeholders_with_ui_values is already running"}
time.sleep(0.1)
problem_setup_step.update_osl_placeholders_with_ui_values()
project_properties_sections = to_dash_sections(
problem_setup_step.placeholders, problem_setup_step.registered_files, problem_setup_step.project_locked
Expand Down Expand Up @@ -290,7 +292,7 @@ def initialize_dictionary_of_ui_placeholders(n_clicks, data, ids, input_file_ids
else:
parameters[key] = data[index]
ui_data.update({placeholder_name: parameters})
elif isinstance(data[index], list) == list and isinstance(data[index][0], bool):
elif isinstance(data[index], list):
value = data[index]
if True in value:
new_value = True
Expand Down Expand Up @@ -362,7 +364,7 @@ def update_ui_placeholders(value, id, pathname):
elif isinstance(value, list) and False in value:
value = False
ui_data[pm_name][key] = value
elif isinstance(value, list) and isinstance(value[0], bool):
elif isinstance(value, list):
if True in value:
value = True
else:
Expand Down Expand Up @@ -469,7 +471,7 @@ def update_start_designs_table(n_clicks_add, n_clicks_del, disabled_states, row_
ui_data.update({"StartDesigns": new_designs})

problem_setup_step.ui_placeholders = ui_data
while problem_setup_step.get_method_state("update_osl_placeholders_with_ui_values").status == MethodStatus.Running: # current workaround to avoid raising ConflictError: {"detail":"update_osl_placeholders_with_ui_values is already running"}
while problem_setup_step.get_long_running_method_state("update_osl_placeholders_with_ui_values").status == MethodStatus.Running: # current workaround to avoid raising ConflictError: {"detail":"update_osl_placeholders_with_ui_values is already running"}
time.sleep(0.1)
problem_setup_step.update_osl_placeholders_with_ui_values()

Expand Down
Loading

0 comments on commit caea59b

Please sign in to comment.