Subscribe Bookmark RSS Feed

Running Python Script from JSL

felix_doktorman

Community Trekker

Joined:

Nov 7, 2015

I would like to run Python script from my JSL code. What is the best way to do that? Thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Craige_Hales

Staff

Joined:

Mar 21, 2013

Solution

Here's an example I was playing with

txt=runprogram(executable("python"),options({"C:\Users\User\Desktop\tweepy\twpy2.py"}),readfunction("text"));

Tweepy is a python package for twitter.  This example expects the python program to start, produce output, and terminate, before the JSL continues.  There are other ways to use RunProgram.

Craige
10 REPLIES
txnelson

Super User

Joined:

Jun 22, 2012

Use the
RunProgram()
function.
For details, go to:
Help==>Scripting Indes==>RunProgram
Jim
vt_sailor

Occasional Contributor

Joined:

May 11, 2017

I'm struggling with the 'run program' command.  The line below works fine from a command prompt:

c:\mycompany\anaconda3\python.exe "c:\users\myuserid\temp\pythonsqltest.py"

 

I'm trying to run it by executing this script:

 

Names Default To Here( 1 );
RP = RunProgram(
Executable( "c:\mycompany\anaconda3\python.EXE" ),
Options( {"c:\users\myuserid\temp\pythonsqltest.py"} ),
ReadFunction( Function( {this}, Write( this << read ) ) )
);

 

I'm thinking I don't really understand the role 'ReadFunction' plays here.  What am I missing?

 

Craige_Hales

Staff

Joined:

Mar 21, 2013

readFunction tells RunProgram how to deal with the output of your python program (the data written to stdout). If you supply an actual JSL function, compiled by the function function, as in your example, then JSL and python are running independently and whenever JMP is idle, your JSL function can be called to retrieve some more output from python. This might be useful if the python program runs forever and makes an infinite stream of output. The other example posted here uses readfunction("text"), which is a simple way to get back all of the output from the python program (which must terminate, of course). The output comes back as the result of the runProgram function.

If you supply a function for runProgram to call, then you must also keep the runprogram object in a JSL variable so the connection between JMP and Python isn't destroyed too soon: obj = runProgram(...)

The this parameter in the readFunction is the same as the obj variable above. It gives you access to the methods of the runProgram object, like <<read.

edit: And the output of the write function goes to the JMP log; be sure to look there for your results.

Craige
vt_sailor

Occasional Contributor

Joined:

May 11, 2017

Craig,

Thank you for the quick response. What I'm trying to do is to call the
python program and pause execution of the JSL until the python program
terminates. The python program writes its output to a file which I would
then open and retrieve via JSL. I'm basically trying to use Python to
retrieve data from a database for use by my JSL code. The sequence should
be:

1. Run JSL and prepare the SQL query, this then gets pulled together to
create the python script.
2. Run the python program and pause the JSL
3. When the python completes the JSL continues, opening up the file
python saved and processing it.

Craige_Hales

Staff

Joined:

Mar 21, 2013

Use

txt = runprogram( ... readfunction("text"));

If the python program produces any stdout (print statement, etc) it will come back to JSL as the result of runProgram. JSL won't continue until the Python program terminates with readfunction("text"). You might want to print something like 

filename.dat,100

so JSL can know there are 100 lines of data in that file. Or print an error message and handle that if the database is unavailable.

(JSL also has some SQL capabilities that might be more appropriate @erichill )

 

Craige
pmroz

Super User

Joined:

Jun 23, 2011

Might be simpler and faster to read data directly in to JMP using an ODBC driver.  What's your SQL database?  I have a lot of experience with Oracle and could help with that.

vt_sailor

Occasional Contributor

Joined:

May 11, 2017

I'm using the ODBC drivers now and they are not reliable.  I don't really think it's JMP but switching from JMP 12 - 13 and oracle 11-12 definitely upset the applecart.  I know have to close and reopen the database connections about every five queries in order for things to run reliably.

pmroz

Super User

Joined:

Jun 23, 2011

I'm using Oracle's 64-bit ODBC driver for Oracle 11 to talk to an Oracle v12 database.  I haven't seen any behavior like you mentioned.  I've used this for JMP 11 and 12.  We haven't transitioned fully to JMP 13 yet; v13.1.0 fixed a bug where V13.0 couldn't read a CLOB.

 

I could never get the Oracle ODBC driver from Microsoft to work btw.

 

Good luck!

Byron_JMP

Staff

Joined:

Apr 26, 2012

x = RunProgram(
	executable( "/path/anaconda/bin/python" ),
	options( "/path/filename.py" ),
	readfunction( "blob" )
);

Then to do the opposite, run JSL from a python script.  This works on a Mac, JMP 13.2  (and this is python not jsl)

import os
os.system('open /Applications/JMP\ Pro\ 13.app/Contents/MacOS/JMP /path/script.jsl')

the open argument has the application path, one space and then the path/file to open.

Its probably imporant to have 

//!

 on the first row of the script so it will auto run. And then on the last line, include this

Quit();

This will close the instance of JMP that os.sytem started.