Calling functions from a compiled wbex using journaling
I recently compiled my ACT wbex and noticed that some functionality in my scripts no longer works. Specifically, I am sending a command to Mechanical from the workbench project page using the wbjn.ExecuteCommand function to call in a function once Mechanical has been opened using model.SendCommand(Language="Python", Command={}).
The issue appears to be that when the wbex compiles it no longer is able to understand an import command of a function in mechanical. This is a good thing as the end user can't see or use the commands from the wbex, but is causing problems as it breaks the code that I am calling to automate workflows between spaceclaim/mechanical.
As an example I have a function that exists within the projects folder structure like this:
The goal is to call the "example function.py" after opening mechanical during journaling.
Currently I did this using an import and then called the function after:
`model.Edit()
model.SendCommand(Language="Python", Command="from folder_of_functions.example_function import example_function
model.SendCommand(Language="Python", Command="example_function()`
The issue being that the function can no longer be imported after the project has been turned into a wbex. Is there a recommended way to call a function using the project page journaling? There is an alternate command that could be used:“model.SendCommand(Language=‘Python’,Command=‘my_callback()’,ExtensionName=‘My_app’)”
In this case it is unclear if the function needs to be imported in the main.py file? or how it can be loaded/called.
Best Answer
-
@Nick Ramseyer , @Landon Mitchell Kanner ,
I typically get confused when dealing with the various levels of project scripting vs. mechanical scripting. To avoid confusion I like to implement a wrapper function that does exactly what I want that is located within the main ACT python module. It can for sure import and work with submodules, but the method I call is from the main ACT module (no import statements)To call a function from a particular ACT I use the following syntax:
ThisExtName = ExtAPI.ExtensionManager.CurrentExtension.Name
Ext = ExtAPI.ExtensionManager.GetExtensionByName('"""+ThisExtName+"""')
ExtMod = Ext.GetModule()
ExtMod.DoSomething()You can verify the behavior in mechanical that it is doing what you want via the console. To then migrate this to a project page call, you simply dynamically create the same three lines to call any method from any ACT loaded.
This seems to work well for all the contexts I have tried it.
1
Answers
-
@Mike.Thompson Do you have a solution for this issue?
0 -
Are files and folders being copied to the installation directory (e.g. %appdata%/Ansys/v241/ACT/extensions)?
If so, I think (I have not tested it) you just need to do something like:import sys import os extension_dir = ExtAPI.ExtensionManager.GetExtensionByName("example").InstallDir module_folder = os.path.join(extension_dir ,'folder_of_fuctions') sys.path.append(module_folder)
Alternatively, if you want to list example_function.py as a src file in xml, you can use something like:
dmScript = """ extension = ExtAPI.ExtensionManager.GetExtensionByName("<Name of extension>").GetModule() extension.NewConvectionFunction()""" geometry1 = system1.GetContainer(ComponentName="Geometry") geometry1.SendCommand(Command=dmScript,Language="Python")
In this way, you hide the source code for example_function from the end user.
1 -
I can take a look at that! the other wrench I'll throw in is that it would be needed to have the code not visible to the end users (so in the xml having compiled="true"). So, I'm not sure I can retrieve the functions this way.
0 -
The second method should work regardless of whether compiled="true". For the first method, you might be able to hide the source code by using a .pyc file instead of .py (again, haven't tried it).
0