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

feat: add globals kwarg to app and adjust ideconfig behavior #1017

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8b947db
improve autocomplete and add option to import without globals
Jan 2, 2025
f680502
add ideconfig version check code & test
klmcadams Jan 2, 2025
9a97bdc
add globals kwarg to app & add global imports if app is initialized
klmcadams Jan 3, 2025
efe09a8
fix pyproject.toml
klmcadams Jan 3, 2025
0ff1147
Merge branch 'main' into autocomplete
klmcadams Jan 3, 2025
d1b5aa5
chore: auto fixes from pre-commit hooks
pre-commit-ci[bot] Jan 3, 2025
1790e77
chore: adding changelog file 1017.added.md [dependabot-skip]
pyansys-ci-bot Jan 3, 2025
6c03afc
chore: auto fixes from pre-commit hooks
pre-commit-ci[bot] Jan 3, 2025
bd4c46d
fix transaction file format
klmcadams Jan 3, 2025
16e5071
Merge branch 'autocomplete' of https://github.com/ansys/pymechanical …
klmcadams Jan 3, 2025
2dfe7c0
chore: auto fixes from pre-commit hooks
pre-commit-ci[bot] Jan 3, 2025
1be2b71
Merge branch 'main' into autocomplete
klmcadams Jan 30, 2025
00a2b06
move is_initialized function & adjust code
klmcadams Jan 30, 2025
be93db8
fix import statement for tests
klmcadams Jan 30, 2025
9d642c3
add more tests
klmcadams Jan 30, 2025
011dff7
add --version to test
klmcadams Feb 5, 2025
4063ae9
add args for run_embedded_app subprocess
klmcadams Feb 5, 2025
bc4a6b6
Merge branch 'main' into autocomplete
klmcadams Feb 5, 2025
a6dc760
add tests for cli
klmcadams Feb 5, 2025
e6e39c0
use globals argument in example
klmcadams Feb 5, 2025
fd47155
add embedding-rpc-tests as a req for coverage step
klmcadams Feb 5, 2025
fbd19d4
automatically use globals kwarg in embedding scripts
klmcadams Feb 6, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,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
23 changes: 19 additions & 4 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 True if len(INSTANCES) != 0 else False


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 @@ -192,6 +205,10 @@ def __init__(self, db_file=None, private_appdata=False, **kwargs):
self._updated_scopes: typing.List[typing.Dict[str, typing.Any]] = []
self._subscribe()

globals = kwargs.get("globals")
if globals is not None and is_initialized():
self.update_globals(globals)

def __repr__(self):
"""Get the product info."""
import clr
Expand Down Expand Up @@ -501,8 +518,7 @@ def update_globals(
Examples
--------
>>> from ansys.mechanical.core import App
>>> app = App()
>>> app.update_globals(globals())
>>> app = App(globals=globals())
"""
self._updated_scopes.append(globals_dict)
globals_dict.update(global_variables(self, enums))
Expand Down Expand Up @@ -580,8 +596,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.")

Check warning on line 27 in src/ansys/mechanical/core/embedding/global_importer.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/global_importer.py#L27

Added line #L27 was not covered by tests

import clr
klmcadams marked this conversation as resolved.
Show resolved Hide resolved

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
Loading