Skip to content

Commit

Permalink
feat: add globals kwarg to app and adjust ideconfig behavior (#1017)
Browse files Browse the repository at this point in the history
Co-authored-by: Mohamed Koubaa <koubaa@github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com>
  • Loading branch information
4 people authored Feb 12, 2025
1 parent 8eb620d commit 8879d7c
Show file tree
Hide file tree
Showing 14 changed files with 423 additions and 156 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ jobs:

coverage:
name: Merging coverage
needs: [remote-connect, embedding-tests, embedding-scripts-tests, launch-tests]
needs: [remote-connect, embedding-tests, embedding-scripts-tests, embedding-rpc-tests, launch-tests]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/1017.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add `globals` kwarg to app and adjust `ideconfig` behavior
3 changes: 1 addition & 2 deletions examples/embedding_n_remote/embedding_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,7 @@ def write_file_contents_to_console(path, number_lines=-1):
# Find the mechanical installation path & version.
# Open an embedded instance of Mechanical and set global variables.

app = mech.App()
app.update_globals(globals())
app = mech.App(globals=globals())
print(app)


Expand Down
20 changes: 18 additions & 2 deletions src/ansys/mechanical/core/embedding/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ def _start_application(configuration: AddinConfiguration, version, db_file) -> "
return Ansys.Mechanical.Embedding.Application(db_file)


def is_initialized():
"""Check if the app has been initialized."""
return len(INSTANCES) != 0


class GetterWrapper(object):
"""Wrapper class around an attribute of an object."""

Expand Down Expand Up @@ -124,6 +129,9 @@ class App:
private_appdata : bool, optional
Setting for a temporary AppData directory. Default is False.
Enables running parallel instances of Mechanical.
globals : dict, optional
Global variables to be updated. For example, globals().
Replaces "app.update_globals(globals())".
config : AddinConfiguration, optional
Configuration for addins. By default "Mechanical" is used and ACT Addins are disabled.
copy_profile : bool, optional
Expand All @@ -140,6 +148,10 @@ class App:
>>> app = App(private_appdata=True, copy_profile=False)
Update the global variables with globals
>>> app = App(globals=globals())
Create App with "Mechanical" configuration and no ACT Addins
>>> from ansys.mechanical.core.embedding import AddinConfiguration
Expand All @@ -163,6 +175,7 @@ def __init__(self, db_file=None, private_appdata=False, **kwargs):
return
if len(INSTANCES) > 0:
raise Exception("Cannot have more than one embedded mechanical instance!")

version = kwargs.get("version")
if version is not None:
try:
Expand Down Expand Up @@ -193,6 +206,10 @@ def __init__(self, db_file=None, private_appdata=False, **kwargs):
self._subscribe()
self._messages = None

globals = kwargs.get("globals")
if globals:
self.update_globals(globals)

def __repr__(self):
"""Get the product info."""
import clr
Expand Down Expand Up @@ -590,8 +607,7 @@ def print_tree(self, node=None, max_lines=80, lines_count=0, indentation=""):
Examples
--------
>>> from ansys.mechanical.core import App
>>> app = App()
>>> app.update_globals(globals())
>>> app = App(globals=globals())
>>> app.print_tree()
... ├── Project
... | ├── Model
Expand Down
1 change: 0 additions & 1 deletion src/ansys/mechanical/core/embedding/enum_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
A useful subset of what is imported by
Ansys Inc/v{NNN}/ACT/apis/Mechanical.py
"""

import clr

clr.AddReference("Ansys.Mechanical.DataModel")
Expand Down
50 changes: 50 additions & 0 deletions src/ansys/mechanical/core/embedding/global_importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Import Mechanical globals."""

from ansys.mechanical.core.embedding.app import is_initialized

if not is_initialized():
raise Exception("Globals cannot be imported until the embedded app is initialized.")

import clr

clr.AddReference("Ansys.Mechanical.DataModel")
clr.AddReference("Ansys.ACT.Interfaces")


clr.AddReference("System.Collections")
clr.AddReference("Ansys.ACT.WB1")
clr.AddReference("Ansys.Mechanical.DataModel")

# from Ansys.ACT.Mechanical import Transaction
# When ansys-pythonnet issue #14 is fixed, uncomment above
from Ansys.ACT.Core.Math import Point2D, Point3D # noqa isort: skip
from Ansys.ACT.Math import Vector3D # noqa isort: skip
from Ansys.Core.Units import Quantity # noqa isort: skip
from Ansys.Mechanical.DataModel import MechanicalEnums # noqa isort: skip
from Ansys.Mechanical.Graphics import Point, SectionPlane # noqa isort: skip

from ansys.mechanical.core.embedding.transaction import Transaction # noqa isort: skip

import System # noqa isort: skip
import Ansys # noqa isort: skip
88 changes: 30 additions & 58 deletions src/ansys/mechanical/core/embedding/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,37 @@ def global_variables(app: "ansys.mechanical.core.App", enums: bool = False) -> t
To also import all the enums, set the parameter enums to true.
"""
vars = global_entry_points(app)
import clr # isort: skip

clr.AddReference("System.Collections")
clr.AddReference("Ansys.ACT.WB1")
clr.AddReference("Ansys.Mechanical.DataModel")
# from Ansys.ACT.Mechanical import Transaction
# When ansys-pythonnet issue #14 is fixed, uncomment above
from Ansys.ACT.Core.Math import Point2D, Point3D
from Ansys.ACT.Math import Vector3D
from Ansys.ACT.Mechanical.Fields import VariableDefinitionType
from Ansys.Core.Units import Quantity
from Ansys.Mechanical.DataModel import MechanicalEnums
from Ansys.Mechanical.Graphics import Point, SectionPlane

import System # isort: skip
import Ansys # isort: skip

vars["Quantity"] = Quantity
vars["System"] = System
vars["Ansys"] = Ansys

from ansys.mechanical.core.embedding.app import is_initialized
from ansys.mechanical.core.embedding.transaction import Transaction

vars["Transaction"] = Transaction
vars["MechanicalEnums"] = MechanicalEnums
# Graphics
vars["Point"] = Point
vars["SectionPlane"] = SectionPlane
# Math
vars["Point2D"] = Point2D
vars["Point3D"] = Point3D
vars["Vector3D"] = Vector3D
vars["VariableDefinitionType"] = VariableDefinitionType

# Import modules if the app is initialized
if is_initialized():
from ansys.mechanical.core.embedding.global_importer import (
Ansys,
MechanicalEnums,
Point,
Point2D,
Point3D,
Quantity,
SectionPlane,
System,
Vector3D,
)

vars["Quantity"] = Quantity
vars["System"] = System
vars["Ansys"] = Ansys
vars["MechanicalEnums"] = MechanicalEnums
# Graphics
vars["Point"] = Point
vars["SectionPlane"] = SectionPlane
# Math
vars["Point2D"] = Point2D
vars["Point3D"] = Point3D
vars["Vector3D"] = Vector3D

if enums:
vars.update(get_all_enums())
Expand All @@ -95,32 +96,3 @@ def get_all_enums() -> typing.Dict[str, typing.Any]:
if type(the_enum).__name__ == "CLRMetatype":
enums[attr] = the_enum
return enums


class Transaction: # When ansys-pythonnet issue #14 is fixed, this class will be removed
"""
A class to speed up bulk user interactions using Ansys ACT Mechanical Transaction.
Example
-------
>>> with Transaction() as transaction:
... pass # Perform bulk user interactions here
...
"""

def __init__(self):
"""Initialize the Transaction class."""
import clr

clr.AddReference("Ansys.ACT.WB1")
import Ansys

self._transaction = Ansys.ACT.Mechanical.Transaction()

def __enter__(self):
"""Enter the context of the transaction."""
return self

def __exit__(self, exc_type, exc_val, exc_tb):
"""Exit the context of the transaction and disposes of resources."""
self._transaction.Dispose()
51 changes: 51 additions & 0 deletions src/ansys/mechanical/core/embedding/transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""A class to speed up bulk user interactions using Ansys ACT Mechanical Transaction."""


class Transaction: # When ansys-pythonnet issue #14 is fixed, this class will be removed
"""
A class to speed up bulk user interactions using Ansys ACT Mechanical Transaction.
Example
-------
>>> with Transaction() as transaction:
... pass # Perform bulk user interactions here
...
"""

def __init__(self):
"""Initialize the Transaction class."""
import clr

clr.AddReference("Ansys.ACT.WB1")
import Ansys

self._transaction = Ansys.ACT.Mechanical.Transaction()

def __enter__(self):
"""Enter the context of the transaction."""
return self

def __exit__(self, exc_type, exc_val, exc_tb):
"""Exit the context of the transaction and disposes of resources."""
self._transaction.Dispose()
28 changes: 21 additions & 7 deletions src/ansys/mechanical/core/ide_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import re
import site
import sys
import warnings

import ansys.tools.path as atp
import click
Expand Down Expand Up @@ -151,13 +152,23 @@ def _cli_impl(
stubs_location = get_stubs_location()
# Get all revision numbers available in ansys-mechanical-stubs
revns = get_stubs_versions(stubs_location)
# Check the IDE and raise an exception if it's not VS Code
if revision < min(revns) or revision > max(revns):

# Check if the user revision number is less or greater than the min and max revisions
# in the ansys-mechanical-stubs package location
if revision < min(revns):
raise Exception(f"PyMechanical Stubs are not available for {revision}")
elif ide != "vscode":
elif revision > max(revns):
warnings.warn(
f"PyMechanical Stubs are not available for {revision}. Using {max(revns)} instead.",
stacklevel=2,
)
revision = max(revns)

# Check the IDE and raise an exception if it's not VS Code
if ide != "vscode":
raise Exception(f"{ide} is not supported at the moment.")
else:
return _vscode_impl(target, revision)

return _vscode_impl(target, revision)


@click.command()
Expand Down Expand Up @@ -202,8 +213,11 @@ def cli(ide: str, target: str, revision: int) -> None:
$ ansys-mechanical-ideconfig --ide vscode --target user --revision 251
"""
exe = atp.get_mechanical_path(allow_input=False, version=revision)
version = atp.version_from_path("mechanical", exe)
if not revision:
exe = atp.get_mechanical_path(allow_input=False, version=revision)
version = atp.version_from_path("mechanical", exe)
else:
version = revision

return _cli_impl(
ide,
Expand Down
Loading

0 comments on commit 8879d7c

Please sign in to comment.