I know there is some support for running Mathematica from Python, but is there any way to do the reverse. For example, to import some Python classes and use them in Mathematica?
-
related: http://mathematica.stackexchange.com/q/1894/5 (I don't know enough to tell if it's a dupe or not) – rm -rf Dec 03 '12 at 21:59
-
@rm-rf: Different: that relies on .NET. – orome Dec 03 '12 at 22:01
-
use them how? what sort of thing would you like to do? – acl Dec 03 '12 at 22:03
-
I've given some answers where a Python script was assembled and then executed from within a notebook: here and here – Jens Dec 03 '12 at 22:06
-
@acl: Example: I have access to a library of classes written (by someone else, for example something like astropy) in Python that and I'd like to be able to "import" those classes and then call them from within Mathematica. – orome Dec 03 '12 at 22:12
-
2Google Pythonika – Mark McClure Dec 03 '12 at 22:19
-
@MarkMcClure I think Pythonika is the reverse of the reverse, and he's only asking for the reverse... – Jens Dec 03 '12 at 22:32
-
3@Jens He says he wants "to import some Python classes and use them in Mathematica". That's exactly what Pythonika does. I've used it to run sage from Mathematica. One of the dumbest things I've ever done, but I did it: http://facstaff.unca.edu/mcmcclur/Mathematica/Sage/ – Mark McClure Dec 03 '12 at 22:40
-
@MarkMcClure You're right, I think that's an excellent answer then. – Jens Dec 03 '12 at 22:52
-
2@MarkMcClure: Pythonica seems not to be a viable solution. I can't get it to load (0S X 10.8.2, Python 2.7.2, Mathematica 9.0). Are there any alternatives? – orome Dec 12 '12 at 01:52
-
This Pythonika link is no longer valid? https://sites.google.com/site/erocarrera/pythonika.html – sebastian c. Jan 23 '13 at 17:51
-
Pythonika doesn't work with version 10.x – M.R. Feb 22 '16 at 05:40
6 Answers
Building off of @M.R.'s idea, it is possible to set up an interactive python shell using StartProcess as opposed to RunProcess, allowing for much more flexible connectivity between Python and Wolfram without as much overhead. In it's simplest form, one can open a connection, interact with it, and close it using the following example:
path = "e:\\Programs\\python27\\python"; (*insert OS-appropriate path \
to python*)
p = StartProcess[{path, "-i"}]; (*the'-i' argument is important*)
cmd = "print 'hello'"; (*or any valid python expression*)
Pause[1]; (* important!!! *)
WriteLine[p, cmd];
out = ReadString[p, EndOfBuffer]
KillProcess@p;
Pausing after the StartProcess call is important in order to avoid the cmd being sent to the python interpreter before it has finished loading. A much shorter pause can be used on faster computers.
I've put together a short package to streamline python interactivity. The version I've posted below also reads the python shell text (which is delivered on stderr) and prints that to the Message window if the FrontEnd is active or simply Prints it if the command line is being used. It works nicely with simple commands pcmd@"print 'hello'" and I've had success with some sophisticated operations such as web scraping with Splinter and BeautifulSoup. It coughs when trying to use something like Tkinter, but it just doesn't work as opposed to throwing some form of error, making it a bit difficult to debug.
BeginPackage["wlPython`"];
$pythonprocess = Null;
$pythonpath = "e:\\Programs\\python27\\python";
$pythonpause = 0.250; (* Pause in seconds to receive error information *)
startPython::usage = "Starts the python process";
endPython::usage = "Ends the python process";
pcmd::usage = "issue a python command";
(* Check for FrontEnd and set as appropriate, can be overridden *)
$pyfrontend = $FrontEnd=!=Null;
Begin["`Private`"];
Clear[startPython]
startPython[path_:$pythonpath]:=Module[{err},
$pythonprocess = StartProcess[{path,"-i"}];
wlPython`pyerrcheck[];
$pythonprocess
]
Clear[endPython]
endPython[process_:Unevaluated@$pythonprocess]:=Module[{},
KillProcess@Evaluate@process;
NotebookWrite[MessagesNotebook[],
Cell[RawBoxes@ToBoxes["Python process ended",TraditionalForm],"Output"]];
]
Clear[pcmd]
pcmd[cmd_String,process_:Unevaluated@$pythonprocess]:=Module[{status,err,out,p},
p = Evaluate[process];
status = ProcessStatus[p];
If[status=="Running",
WriteLine[p,cmd];
wlPython`pyerrcheck[];
out = ReadString[p,EndOfBuffer]
];
out
]
Clear[pyerrcheck]
pyerrcheck[]:=Module[{err},
Pause@$pythonpause;
err = ReadString[ProcessConnection[$pythonprocess,"StandardError"],EndOfBuffer];
If[$pyfrontend,
NotebookWrite[MessagesNotebook[],
Cell[RawBoxes@ToBoxes[err,TraditionalForm],"Output"]];,
Print[err];
]
]
End[];
EndPackage[];
- 19,693
- 4
- 52
- 138
Here is a more robust solution using Process:
Clear[runPython];
runPython::badCommand ="Python code failed to run with message `StandardError`";
$pyimports="from random import randint
";
runPython[str_String, imports_:$pyimports] := Module[
{pyscrpt = ToString[$pyimports<>str, CharacterEncoding->"ASCII"], file=CreateTemporary[], res},
Export[file,pyscrpt,"Text"];
res = RunProcess[{"/anaconda/bin/python",file}];
DeleteFile[file];
If[res["ExitCode"]!=0,
Return @ Failure["badCommand",<|"MessageTemplate" :> runPython::badCommand,"MessageParameters"-> <|"Message" -> res["StandardError"]|>|>],
Return @ ImportString @ res["StandardOutput"]
]
]

I had to use anaconda's python executable - Mathematica was crashing the system's python runtime.
- 31,425
- 8
- 90
- 281
-
" Here is a more robust solution using
Process:" More robust than what? – Brian Moths Nov 30 '16 at 19:33 -
1
-
did you mean to write
(...) ToString[imports<>str (...)in the second line of the definition of the function? The way it is now the second argument ofrunPythonis useless – glS Jan 14 '17 at 21:06 -
Since 11.2 Mathematica has supported ExternalEvaluate and since 11.3 this functionality has been conveniently available simply by beginning an input cell with > which produces an external code cell:
The output of these cells is a Wolfram Language expression that you can then compute with.
- 12,819
- 3
- 52
- 100
-
3Please clarify with an example, say, for Python, including when Python is not the default OS system installation but another, e.g., anaconda's. – murray Mar 14 '18 at 19:06
-
1
-
1
-
But it seems that Mathematica complains when you try to import some python packages? – MKF Mar 02 '19 at 12:43
-
You may have to configure python by calling the
RegisterExternalEvaluators[]function and supplying a path to your executable – Reedinationer Apr 22 '19 at 23:42
If all you want is to invoke Python scripts and use the output they generate in Mathematica, then simply
pythonOutput = Import["!python fullpathtoscript/your_scipt.py --some_opt arg arg ...", "String"];
is sufficient.
- 12,819
- 3
- 52
- 100
-
-
-
@ThomasH: Can you give me a specific example of something that works that I can try. It doesn't even work for me anymore (10.0.2.0). – orome Apr 06 '15 at 20:24
-
For a MWE, I made a file in my home directory called test.py containing "print('hello world')", then in Mathematica (also pointed at my home directory by default), 'Import["!python test.py","String"]' produces the string "hello world". I have a simple but slightly more complicated example I can point you to on github if you'd like. – ThomasH Apr 09 '15 at 17:14
Here is an approach that works on Mac OS X or unix-like systems without the need to explicitly create any temp directory:
code = "print \\\"hello, starting\\\"
for i in [1,2,3]:
\t print i*i
"
(* ==>
"print \\\"hello, starting\\\"
for i in [1,2,3]:
print i*i
"
*)
RunProcess[$SystemShell, "StandardOutput",
"printf \"" <> code <> "\" | python
exit
"]
(* ==>
"hello, starting
1
4
9
"
*)
First, I define the string containing the Python code. I included a test message to illustrate how you have to escape the quotation marks using \\\" inside the string, because it's going to be passed into a printf command on the shell command line. THat printf is subsequently piped into python. Note that I didn't have to specify the path because it's found from the SystemShell environment.
The interaction with Mathematica takes place via RunProcess, and the standard output of the Python script is directly captured into Mathematica. Again, it's not necessary to bother with any temporary files in this approach.
- 97,245
- 7
- 213
- 499
-
Can you contrast this with the
Importapproach? Is it just that it avoids using an existing script? FWIW, I'd never write the Python code in the Mathematica environment: the code editing tools are just too poor. – orome Apr 05 '15 at 14:14 -
-
@raxacoricofallapatorius Yes, my main point is to have the script and everything it needs completely inside Mathematica. If you already have an existing script outside Mathematica, then it's not a real two-way interaction, I'd say. But what to do with an existing script specifically would depend on the application. I can't think of anything general to say about that, except that it would be possible, e.g., to pass arguments to it using my approach. An important advantage of my approach is, however, that it makes the entire process portable: you can email the notebook without attachments. – Jens Apr 05 '15 at 16:13
-
-
Actually, this doesn't work for me at all either. I get nothing. And —weirdly — after executing it I can't quite the front end. – orome Apr 05 '15 at 19:45
-
2Oh well, that's just a formatting error when I manually tried to put the python string into a form that looks right in the code cell above. One extra space crept in, and that kills python. I fixed it. If it still doesn't work, it could be dependent on the OS and version of Mathematica. This
RunProcesscommand doesn't work in earlier versions... by the way, another way of interacting with python is through the clipboard on Mac. But I don't know what your actual goal is, so I'll skip that for now. – Jens Apr 05 '15 at 21:19
There's a "Python link" called Pythonika. I have used it briefly and it works.
What it does:
- translates basic data types, including arbitrary size integers, to/from Python
- makes it possible to implement functions in Python and call them from Mathematica
It does not provide any means to work with classes directly. Also, the implementation is rather hackish using unsafe practices (e.g. symbols are not localized to a context, and this has bitten me). To implement a link properly it would take lot more work.
I made a few basic fixes (e.g. using contexts), but I haven't used the thing in a long time. Contact me if you want the fixes.
- 234,956
- 30
- 623
- 1,263
-
-
1
-
Hi, @Szabolcs, is there librarylink way use of python in Mathematica? – matheorem Sep 05 '16 at 14:19
-
@matheorem There's no simple way. LibraryLink or MathLink won't solve the problem of transferring and converting data structures between Python and Mathematica. Someone would have to think about how that conversion should work and implement it on top of LibraryLink or MathLink. (Actually the right choice is MathLink here in my opinion.) That is a job that would take several weeks of full time work, even for a simple version. I don't know who has time for that. – Szabolcs Sep 05 '16 at 14:22
-
@Szabolcs If there is no librarylink for python, then with Pythonika you mentioned, is it possible to write python function that exploit power of numy and scipy, and calling it in Mathematica? How efficient is that? – matheorem Sep 05 '16 at 14:27
-
@matheorem Sorry, this is 3.5 yr old answer and even then I said "I haven't used the thing in a long time". I don't remember. I wouldn't bother with Pythonika, as I remember it had a not very flexible design and no direct support for numpy. A proper Python link would take a lot more work to put together. Maybe you can write to Wolfram and suggest they create a Python link. If there are many requests, they may do it. – Szabolcs Sep 05 '16 at 14:30
-
@matheorem You can tell them what you want to use it for and point out that MATLAB has had a rather flexible Python link for quite a few versions. Python functions and classes can be used quite directly with it. – Szabolcs Sep 05 '16 at 14:31
-
@Szabolcs Ah, sorry, I didn't notice the date. Thank you so much for your answer : ) – matheorem Sep 05 '16 at 14:33
-
@matheorem Or if you want to create such a link yourself, then I suggest starting with exposing the MathLink (not LibraryLink!) API to Python. Then you will have a nice and easy to use interprocess communication solution between M and Py. You can write the rest of the link in these two high level langauges. – Szabolcs Sep 05 '16 at 14:33
-
@Szabolcs Ok, I'll try to write some suggestions to wolfram support about this: ) – matheorem Sep 05 '16 at 14:36
-
1@Szabolcs I'm developing a brand new PyWSTP. Currently I'm having some issues dealing with packed arrays. – kh40tika Aug 27 '18 at 05:53
