Skip to content

feat: First tentative for Plugin Mapdl Mechanism python API #3627

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7a8a716
First tentative for plugin mapdl mechanism
FredAns Dec 19, 2024
538936d
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Dec 19, 2024
35bcf88
chore: adding changelog file 3627.miscellaneous.md [dependabot-skip]
pyansys-ci-bot Dec 19, 2024
2dea3bc
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Dec 19, 2024
a1d7ee2
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Jan 7, 2025
57e2de6
Merge branch 'main' into feat/plugins
germa89 Feb 17, 2025
cd63cc8
Merge branch 'main' into feat/plugins
germa89 Mar 7, 2025
1d2d4d5
chore: merge remote-tracking branch 'origin/main' into feat/plugins
germa89 Apr 23, 2025
4afa907
feat: add plugin error handling classes and improve plugin loading/un…
germa89 Apr 23, 2025
16c744d
test: adding plugin tests
germa89 Apr 23, 2025
6eaf391
Merge branch 'main' into feat/plugins
germa89 Jul 16, 2025
83997de
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Jul 16, 2025
ff30eae
chore: adding changelog file 3627.miscellaneous.md [dependabot-skip]
pyansys-ci-bot Jul 16, 2025
fec2b24
feat: rename plugin to plugins. Enhance plugin functionality with com…
germa89 Jul 16, 2025
f4e9ef5
feat: add plugin property to _MapdlCore and remove from MapdlGrpc
germa89 Jul 16, 2025
302ecc1
fix: streamline command replacement in ansPlugin class
germa89 Jul 16, 2025
6dc488f
Update tests/test_plugin.py
germa89 Jul 16, 2025
d1e8471
fix: update plugin response handling to return an empty list and add …
germa89 Jul 16, 2025
3c25fe9
Merge branch 'feat/plugins' of https://github.com/ansys/pymapdl into …
germa89 Jul 16, 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
1 change: 1 addition & 0 deletions doc/changelog.d/3627.miscellaneous.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat: First tentative for Plugin Mapdl Mechanism python API
3 changes: 3 additions & 0 deletions src/ansys/mapdl/core/mapdl_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
from ansys.mapdl.core.parameters import Parameters
from ansys.mapdl.core.solution import Solution
from ansys.mapdl.core.xpl import ansXpl
from ansys.mapdl.core.plugin import ansPlugin

from ansys.mapdl.core.post import PostProcessing

Expand Down Expand Up @@ -341,6 +342,8 @@ def __init__(

self._xpl: Optional[ansXpl] = None # Initialized in mapdl_grpc

self._plugin: Optional[ansPlugin] = None # Initialized in mapdl_grpc

from ansys.mapdl.core.component import ComponentManager

self._componentmanager: ComponentManager = ComponentManager(self)
Expand Down
21 changes: 21 additions & 0 deletions src/ansys/mapdl/core/mapdl_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
from ansys.platform.instancemanagement import Instance as PIM_Instance

from ansys.mapdl.core.database import MapdlDb
from ansys.mapdl.core.plugin import ansPlugin
from ansys.mapdl.core.xpl import ansXpl

VOID_REQUEST = anskernel.EmptyRequest()
Expand Down Expand Up @@ -2829,6 +2830,26 @@
self._xpl = ansXpl(self)
return self._xpl

@property
def plugin(self) -> "ansPlugin":
"""MAPDL plugin handler

Plugin Manager for MAPDL

Examples
--------

>>> from ansys import Mapdl
>>> mapdl = Mapdl()
>>> plugin = mapdl.plugin
>>> plugin.load('PluginDPF')
"""
if self._plugin is None:
from ansys.mapdl.core.plugin import ansPlugin

Check warning on line 2848 in src/ansys/mapdl/core/mapdl_grpc.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/mapdl_grpc.py#L2847-L2848

Added lines #L2847 - L2848 were not covered by tests

self._plugin = ansPlugin(self)
return self._plugin

Check warning on line 2851 in src/ansys/mapdl/core/mapdl_grpc.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/mapdl_grpc.py#L2850-L2851

Added lines #L2850 - L2851 were not covered by tests

@protect_grpc
def scalar_param(self, pname: str) -> float:
"""Return a scalar parameter as a float.
Expand Down
141 changes: 141 additions & 0 deletions src/ansys/mapdl/core/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Copyright (C) 2016 - 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.

"""Contains the ansPlugin class."""
import json
import pathlib
import weakref

Check warning on line 26 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L24-L26

Added lines #L24 - L26 were not covered by tests

from ansys.api.mapdl.v0 import mapdl_pb2

Check warning on line 28 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L28

Added line #L28 was not covered by tests

from .common_grpc import ANSYS_VALUE_TYPE
from .errors import MapdlRuntimeError
from .misc import random_string

Check warning on line 32 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L30-L32

Added lines #L30 - L32 were not covered by tests


class ansPlugin:

Check warning on line 35 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L35

Added line #L35 was not covered by tests
"""
ANSYS MAPDL Plugin Manager.

Examples
--------
>>> from ansys.mapdl.core import launch_mapdl
>>> mapdl = launch_mapdl()
>>> plugin = mapdl.plugin

Load a plugin in the MAPDL Session
"""

def __init__(self, mapdl):

Check warning on line 48 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L48

Added line #L48 was not covered by tests
"""Initialize the class."""
from ansys.mapdl.core.mapdl_grpc import MapdlGrpc

Check warning on line 50 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L50

Added line #L50 was not covered by tests

if not isinstance(mapdl, MapdlGrpc): # pragma: no cover
raise TypeError("Must be initialized using MapdlGrpc class")

self._mapdl_weakref = weakref.ref(mapdl)
self._filename = None
self._open = False

Check warning on line 57 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L55-L57

Added lines #L55 - L57 were not covered by tests

@property
def _mapdl(self):

Check warning on line 60 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L59-L60

Added lines #L59 - L60 were not covered by tests
"""Return the weakly referenced instance of mapdl."""
return self._mapdl_weakref()

Check warning on line 62 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L62

Added line #L62 was not covered by tests

def load(self, plugin_name: str, feature: str = "CMD") -> str:

Check warning on line 64 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L64

Added line #L64 was not covered by tests
"""
Loads a plugin into MAPDL.

Parameters
----------
plugin_name : str
Name of the plugin to load.
feature : str
Feature or module to activate in the plugin.

Returns
-------
str
Confirmation message about the loaded plugin.

Raises
------
PluginLoadError
If the plugin fails to load.
"""

command = f"*PLUG,LOAD,{plugin_name},{feature}"
response = self._mapdl.run(command)
if "error" in response.lower():
raise PluginLoadError(

Check warning on line 89 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L86-L89

Added lines #L86 - L89 were not covered by tests
f"Failed to load plugin '{plugin_name}' with feature '{feature}'."
)
return f"Plugin '{plugin_name}' with feature '{feature}' loaded successfully."

Check warning on line 92 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L92

Added line #L92 was not covered by tests

def unload(self, plugin_name: str) -> str:

Check warning on line 94 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L94

Added line #L94 was not covered by tests
"""
Unloads a plugin from MAPDL.

Parameters
----------
plugin_name : str
Name of the plugin to unload.

Returns
-------
str
Confirmation message about the unloaded plugin.

Raises
------
PluginUnloadError
If the plugin fails to unload.
"""

command = f"*PLUG,UNLOAD,{plugin_name}"
response = self._mapdl.run(command)
if "error" in response.lower():
raise PluginUnloadError(f"Failed to unload plugin '{plugin_name}'.")
return f"Plugin '{plugin_name}' unloaded successfully."

Check warning on line 118 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L114-L118

Added lines #L114 - L118 were not covered by tests

def list(self) -> list:

Check warning on line 120 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L120

Added line #L120 was not covered by tests
"""
Lists all currently loaded plugins in MAPDL.

Returns
-------
list
A list of loaded plugin names.

Raises
------
RuntimeError
If the plugin list cannot be retrieved.
"""

command = "*PLUG,LIST"
response = self._mapdl.run(command)
if "error" in response.lower():
raise RuntimeError("Failed to retrieve the list of loaded plugins.")

Check warning on line 138 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L135-L138

Added lines #L135 - L138 were not covered by tests
# Parse response and extract plugin names (assuming response is newline-separated text)
plugins = [line.strip() for line in response.splitlines() if line.strip()]
return plugins

Check warning on line 141 in src/ansys/mapdl/core/plugin.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mapdl/core/plugin.py#L140-L141

Added lines #L140 - L141 were not covered by tests
Loading