Skip to content

ddorstijn/scripting-cpython

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

(Native) Python Scripting

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.

How to build in Eclipse (requires at least Eclipse Luna)

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.

Running from Python

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.

The scripting language

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

About

A scripting engine based on "real" Python

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 57.6%
  • Java 35.9%
  • C 6.5%