This library provides a JSR-223-compliant scripting plugin for Python. In contrast to the Jython support, this library accesses CPython (i.e. native Python) via JNI.
It is implemented as a ScriptLanguage
plugin for the SciJava
Common platform, which means that
in addition to being usable directly as a javax.script.ScriptEngineFactory
,
it also provides some functionality on top, such as the ability to generate
lines of script code based on SciJava events.
For a complete list of scripting languages available as part of the SciJava platform, see the Scripting page on the SciJava Common wiki.
Please note that a C compiler needs to be found via the command-line and that
python.h
needs to be found by the compiler.
With these prerequisites in place, it should be as simple as File>Import>Maven>Existing Maven Project....
You might want to make sure that target/nar/nar-generated is added as a source directory to the project (if not, you might need to restart Eclipse). This directory is generated by the NAR plugin.
As things stand now, scripting-cpython relies on your installed version of Python and the javabridge package. You can install javabridge using PIP - the installation instructions are documented at the page referenced by the link above.
As an example, here's how to start ImageJ 2.0 from Python:
- Unzip the ImageJ application.
- Put the scripting-cpython JAR in the application's
jars
folder
Now assuming that you have the application in /foo/ImageJ.app
and the
library that maven compiled for you in /bar/lib
, the following script
will launch ImageJ with CPython scripting support:
import os
import javabridge
path_imagej = "/foo/ImageJ.app/jars"
jars = [os.path.join(path_imagej, x)
for x in os.listdir(path_imagej):
if x.endswith(".jar")]
lib_path = os.environ["PATH"]+";/bar/lib"
library_path_arg = "-Djava.library.path=%s" % lib_path
javabridge.start_vm([library_path_arg], class_path=javabridge.JARS+jars)
javabridge.activate_awt()
env = javabridge.get_env()
jargs = env.make_object_array(0, env.find_class("java/lang/String"))
runnable = javabridge.run_script("""
new java.lang.Runnable() {
run: function () {
Packages.net.imagej.Main.launch(args);
} };""", dict(args=jargs))
javabridge.execute_runnable_in_main_thread(runnable)
You should be able to start a script editor from File->New->Script...
and
then choose CPython
from the language menu and you should be good to go.
Inputs to your script are either translated to Python native types or,
if they are Java types, they are wrapped using reflection. You can import
classes into your local scope using importClass
. Here is an example:
importClass("java.lang.Integer")
Integer.toString(Integer.MAX_VALUE) # returns 2^31 - 1
and another:
importClass("java.util.ArrayList")
a = ArrayList()
a.add("Hello")
a.add("World")
str(a) # returns [ Hello, World ]
If you want to wrap an object retrieved from the javabridge, you can use JWrapper:
import javabridge
a = JWrapper(javabridge.make_instance("java/util/ArrayList", "()V"))
a.add("Hello")
a.add("World")
str(a.size()) # returns 2