Tuesday, April 22, 2014

Jython and Scala

It is possible to run python libraries and scripts in a JVM application with Jython. Jython is an implementation of python in Java and in this post we'll look at how to use Python from Scala code.

Download Jython from here. I grabbed version 2.7

In this example I'm going to create a simple REST-server in Python and start it from a Scala application. The python code:

 from flask import Flask  
 app = Flask(__name__)  
   
 @app.route('/')  
 def hello():  
   return 'Hello World!'  
   
 @app.errorhandler(404)  
 def page_not_found(e):  
   return 'Sorry, Nothing at this URL.', 404  
   
 @app.errorhandler(500)  
 def page_not_found(e):  
   return 'Sorry, unexpected error: {}'.format(e), 500  
   
 if __name__ == "__main__":  
   app.run()  

Before you run this make sure you install Flask.

$pip install flask.

Try it:

$python restserver.py

You should see this output in your terminal
* Running on http://127.0.0.1:5000/

so point your browser to this URL to confirm the client access.

Now we are going to start the server from Scala using Jython. There are several ways to use this Python code from Scala, for example the Python code can be emedded in the scala file but since we have already saved a .py file we'll load the file as a stream.

We setup a new sbt project as per usual with the folders/files:

build.sbt
src/main/python/restserver.py
src/main/scala/Program.scala
lib/jython.jar

The jython.jar is copied to the lib folder so sbt knows where to find it. The Program.scala looks like this.

 import org.python.util.PythonInterpreter  
 import org.python.core.{Py, PyString}  
   
 object Program extends App{  
 
val sys = Py.getSystemState()  
   sys.path.append(new PyString("jython2.7b1/Lib/"))  
   sys.path.append(new PyString("/usr/local/lib/python2.7/dist-packages/"))  
   
   val interp = new PythonInterpreter()  
   val scriptFile = new java.io.FileInputStream("src/main/python/restserver.py")  
   interp.execfile(scriptFile)  
   
   println("press any key to exit...")  
   readLine()  
 }  

You may need to update the paths to the Lib folder of your Jython installation and the place where python modules are installed

It's well known that Jython doesn't support C extensions so for this to work you may need to install or upgrade MarkupSafe. To list installed modules

$pip freeze

Look for a line with MarkupSafe. If its not found then install otherwise upgrade.

$pip install --upgrade MarkupSafe

You should see a confirmation that a Plain-Python version is installed, i.e. ==================================================
    WARNING: The C extension could not be compiled, speedups are not enabled.
    Plain-Python installation succeeded.
==================================================

Compile and run your Scala project with sbt. You can now visit the same URL.

To sum up, Jython takes the Python programming language syntax and enables it to run on the Java platform. This allows seamless integration of Python and Java based libraries and applications. I've shown a sample of python a REST-server started by a Scala application.

No comments:

Post a Comment