cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
EstelleS
Level III

How to configure Python Init path and sys path statements for new add-in users?

Hi All,

 

I am using Application Builder to develop an application with Python integration. I plan on compiling this into an add-in to be able to share with other users, however, I need a way to correctly set up the Python initialization for all users. 

 

The way I have been running the application will only work for me (user EstelleS1 and my environment, JMPPythonEnvironment):

 

appNS:PythonPathText = "C:\Users\EstelleS1\AppData\Local\Programs\Python\Python37\JMPPythonEnvironment\Scripts\python37.dll";
appNS:PythonSysPathText = {"", 
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\Scripts\\python37.zip",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\DLLs",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\lib",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\lib\\site-packages"};

Python Init(
	Path( PythonPathText ),
	Python Sys Path( PythonSysPathText )
);

(appNS refers to my application namespace)

 

The other users will have a lot of admin privileges so I was thinking of setting up a workflow where a new user will click a button in the app launcher to upload text files with the Python path and sys path strings, then the application will take those files and save copies in a new folder (where $DESKTOP should be an accessible location on all users' computers). 

 

PythonPathButtonPress=Function({this},
	// This function is called when the button is pressed
	name = this << Get Button Name;
		
	pickPythonPathFile = Pick File("Please select Python Path text file");
	pickPythonSysPathFile = Pick File("Please select Python Sys Path text file");
		
	PythonPathFile = Load Text File( pickPythonPathFile );
	PythonSysPathFile = Load Text File( pickPythonSysPathFile );
		
	PythonConfigFolder = ( "$DESKTOP/JMPPython Config/" );
	NEWPythonPathFile = (PythonConfigFolder || "PythonPath.txt" );
	NEWPythonSysPathFile = (PythonConfigFolder || "PythonSysPath.txt" );
	PythonConfigDir = Create Directory( PythonConfigFolder );
		
	Save Text File( NEWPythonPathFile, PythonPathFile );
	Save Text File( NEWPythonSysPathFile, PythonSysPathFile );
);

So after this is done the first time, the user shouldn't need to click the button to configure Python again after that. And then upon running the add-in's Python integration parts, the application will automatically search to open these copied files in the accessible folder location (whether that is $DESKTOP or something else better):

PythonPathFile = Convert File Path( "$DESKTOP\JMPPython Config\PythonPath.txt", search );
PythonSysPathFile = Convert File Path( "$DESKTOP\JMPPython Config\PythonSysPath.txt", search );
		
Try( appNS:PythonPathText = Load Text File( PythonPathFile ), New Window("Python Initialization Error", << Modal, Text Box("Need to configure Python first!") ); Throw() );
Try( appNS:PythonSysPathText = Load Text File( PythonSysPathFile ), New Window("Python Initialization Error", << Modal, Text Box("Need to configure Python first!") ); Throw() );
				
Python Init(
	Path( PythonPathText ),
	Python Sys Path( PythonSysPathText )
);

But this has not been working. I have been getting the error "The specified module could not be found. in access or evaluation of 'Python Init' , Python Init/*###*/(Path( PythonPathText ), Python Sys Path( PythonSysPathText ))". I am not sure exactly what is causing this error or how to fix it.

 

I would appreciate if anyone can give insight or a better solution to this problem.

2 ACCEPTED SOLUTIONS

Accepted Solutions
EstelleS
Level III

Re: How to configure Python Init path and sys path statements for new add-in users?

Thanks for the reply! I did have an issue like that... I think I got the python path to work properly by just having the file directory path to the dll in the text file with no quotations (and no blank lines).

 

Now some of the python code will run but I am still having some trouble and I believe it could be from the python sys path argument. I believe I may need to use some escape characters to load in the text file, but I do not have a great understanding of them yet... I have tried testing a few things but have not landed on the proper solution.

 

Would this be the correct way to have my sys path in my text file?

------------------------------------------------------------------------------------------------------------------------

{"",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\Scripts\\python37.zip",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\DLLs",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\lib",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\lib\\site-packages"}

------------------------------------------------------------------------------------------------------------------------

 

When I load it in JMP and use Show(), the log outputs:

 

PythonSysPathText = "{\!"\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\Scripts\\python37.zip\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\DLLs\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\lib\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\lib\\site-packages\!"}";

Is this correct? If yes, then I am having some other issue with Python Init.

 

 

View solution in original post

EstelleS
Level III

Re: How to configure Python Init path and sys path statements for new add-in users?

Actually, I figured out another way to do this:

PythonSysPathFile = Convert File Path( "$DESKTOP\JMPPython Config\PythonSysPath.txt", search );
PythonSysPathText = Load Text File( PythonSysPathFile );

PythonSysPathList = {""};
NListItems = NItems(Eval List(Words(PythonSysPathText, "\!N"))) + 1;
For( i = 1, i < NListItems, i++,
	string = Word(i, PythonSysPathText, "\!N");
	Insert Into(PythonSysPathList, string)
);

Python Init(
	Path( PythonPathText ),
	Python Sys Path( PythonSysPathList )
);
	
version = Python Get Version();
Show( version );

 

And the sys path list populates correctly and Python initiates... but now it does not see my virtual environment!...

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Edit: I believe Python Term() does not work the way I thought it did. It seems like if I initiate python correctly the first time I run a script, then mess up the initialization code later on, it will continue running fine based on the first correct initialization and vice versa. I needed to entirely close out of JMP and re-open to actually see that this initialization code is working, it was just stuck on using the first, incorrect initialization attempt I had made while troubleshooting the question I posted here.

 

Does Python Term() not actually close out of the initialized Python environment?

View solution in original post

4 REPLIES 4

Re: How to configure Python Init path and sys path statements for new add-in users?

View more...
I believe you are not getting what you expect back from the Load Text File().  Given you are loading the contents of a text file into a string, you cannot have any extraneous characters in the text file not even a newline, just the path string.  Put a show(PythonPathText) in your code and see if you get the path you are expecting or there is additional characters in the file.  On my machine running JMP's development branch, I have the following JSL.

PythonPathFile = Convert File Path( "$DESKTOP\pyPath.txt");
show(PythonPathFile);
pptxt = Load Text File(PythonPathFile);
show(pptx);
Python Init( Path(pptx,
...

Log contents
------
PythonPathFile = "/C:/Users/myuserid/Desktop/pyPath.txt";
pptxt = "c:\Users\myuserid\Anaconda3\envs\py39\python39.dll
";
Notice in my pyPath.txt file I have an extra carriage return, an empty blank line in the file after the path to the dll.  With this pyPath.txt file I get the same module not found error because JMP cannot locate a python dll with a newline as part of the file name.   If I remove the newline from the file I do successfully run and initialize my Python script loading the path from the text file.  Carefully check that the input from your files matches what the Python Init() parameters are expecting. You may want to make the JSL loading the files actually parse the files with appropriate error messages rather than depending that the contents is what you expect.
EstelleS
Level III

Re: How to configure Python Init path and sys path statements for new add-in users?

Thanks for the reply! I did have an issue like that... I think I got the python path to work properly by just having the file directory path to the dll in the text file with no quotations (and no blank lines).

 

Now some of the python code will run but I am still having some trouble and I believe it could be from the python sys path argument. I believe I may need to use some escape characters to load in the text file, but I do not have a great understanding of them yet... I have tried testing a few things but have not landed on the proper solution.

 

Would this be the correct way to have my sys path in my text file?

------------------------------------------------------------------------------------------------------------------------

{"",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\Scripts\\python37.zip",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\DLLs",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\lib",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment",
"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\lib\\site-packages"}

------------------------------------------------------------------------------------------------------------------------

 

When I load it in JMP and use Show(), the log outputs:

 

PythonSysPathText = "{\!"\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\Scripts\\python37.zip\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\DLLs\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\lib\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\!",
\!"C:\\Users\\EstelleS1\\AppData\\Local\\Programs\\Python\\Python37\\JMPPythonEnvironment\\lib\\site-packages\!"}";

Is this correct? If yes, then I am having some other issue with Python Init.

 

 

EstelleS
Level III

Re: How to configure Python Init path and sys path statements for new add-in users?

Actually, I figured out another way to do this:

PythonSysPathFile = Convert File Path( "$DESKTOP\JMPPython Config\PythonSysPath.txt", search );
PythonSysPathText = Load Text File( PythonSysPathFile );

PythonSysPathList = {""};
NListItems = NItems(Eval List(Words(PythonSysPathText, "\!N"))) + 1;
For( i = 1, i < NListItems, i++,
	string = Word(i, PythonSysPathText, "\!N");
	Insert Into(PythonSysPathList, string)
);

Python Init(
	Path( PythonPathText ),
	Python Sys Path( PythonSysPathList )
);
	
version = Python Get Version();
Show( version );

 

And the sys path list populates correctly and Python initiates... but now it does not see my virtual environment!...

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Edit: I believe Python Term() does not work the way I thought it did. It seems like if I initiate python correctly the first time I run a script, then mess up the initialization code later on, it will continue running fine based on the first correct initialization and vice versa. I needed to entirely close out of JMP and re-open to actually see that this initialization code is working, it was just stuck on using the first, incorrect initialization attempt I had made while troubleshooting the question I posted here.

 

Does Python Term() not actually close out of the initialized Python environment?

Re: How to configure Python Init path and sys path statements for new add-in users?

No, unfortunately.  The Term() only tries to rested some global variables and try to clean up the environment like it was started fresh.  The technical issues is unloading the Python shared library and all the shared libraries it may load isn't feasible.  So a badly initialized Python, or if you want to initialize a different version of Python requires relaunching JMP.