Integrating Python and Javascript with PyV8
A hobby project of mine would be made much easier if I could run the same code on the server as I run in the web browser. Projects like Node.js have made Javascript on the server a more realistic prospect, but I don’t want to give up on Python and Django, my preferred web development tools.
The obvious solution to this problem is to embed Javascript in Python and to call the key bits of Javascript code from Python. There are two major Javascript interpreters, Mozilla’s SpiderMonkey and Google’s V8.
Unfortunately the python-spidermonkey project is dead and there’s no way of telling if it works with later version of SpiderMonkey. The PyV8 project by contrast is still undergoing active development.
Although PyV8 has a wiki page entitled How To Build it’s not simple to get the project built. They recommend using prebuilt packages, but there are none for recent version of Ubuntu. In this post I’ll describe how to build it on Ubuntu 11.11 and give a simple example of it in action.
The first step is make sure you have the appropriate packages. There may be others that are required and not part of the default install, but there are what I had to install.
sudo aptitude install scons libboost-python-dev
Next you need to checkout both the V8 and PyV8 projects using the commands below.
svn checkout http://v8.googlecode.com/svn/trunk/ v8
svn checkout http://pyv8.googlecode.com/svn/trunk/ pyv8
The key step before building PyV8 is to set the V8_HOME
environment variable to the directory where
you checked out the V8 code. This allows PyV8 to patch V8 and build it as a static library rather than the
default dynamic library. Once you’ve set that you can use the standard Python setup.py
commands to
build and install the library.
cd v8
export PyV8=`pwd`
cd ../pyv8
python setup.py build
sudo python setup.py install
In future I’ll write more detailed posts about how to use PyV8, but let’s start with a simple example. Mustache is a simple template language that is ideal when you want to create templates in Javascript. There’s actually a Python implementation of Mustache, but let’s pretend that it doesn’t exist.
To start import the PyV8
library and create a JSContext
object. These are equivalent to
sub-interpreters so you have several instance of your Javascript code running at once.
>>> import PyV8
>>> ctxt = PyV8.JSContext()
Before you can run any Javascript code you need enter()
the context. You should also exit()
it when you are complete. JSContext
objects can be used with with
statements to automate
this, but for a console session it’s simplest to call the method explicitly. Next we call eval()
to
run our Javascript code, first by reading in the Mustache library and then to set up our template as a
variable.
>>> ctxt.enter()
>>> ctxt.eval(open("mustache.js").read())
>>> ctxt.eval("var template = 'Javascript in Python is ';")
The final stage is to render the template by dynamically created some Javascript code. The results of the
expressions are returned as Python objects, so here rendered
contains a Python string.
>>> import random
>>> opinion = random.choice(["cool", "great", "nice", "insane"])
>>> rendered = ctxt.eval("Mustache.to_html(template, { opinion: '%s' })" % (opinion, ))
>>> print rendered
Javascript in Python is nice
There’s much more to PyV8 than I’ve described in this post, including calling Python code from Javascript but unfortunately the V8 and PyV8 documentation is a bit lacking. I will post some more of my discoveries in future posts.
Comments
Looking foward to more related posts - I want to parse a page / DOM with v8, then manipulate it with python / pyQuery / jQuery
Joe
27 Aug 2012
Thank You
This was extreamly useful post for me . I wanted JS eval inside scrapy spiders.
Keep up the good work
Anil
06 Oct 2012
This is all good.. But after installing v8 , how to call a particular function of javascript file from python file ?
sugesh
25 Oct 2012
Its not working for python3..!!
ram
25 Oct 2012
I always get this error after running the command "python setup.py build"..
Error : /usr/bin/ld: cannot find -lv8
please help me to fix it..thank you in advance
ram
29 Oct 2012
[...] I also found that others had similar experiences. For example, see: http://andrewwilkinson.wordpress.com/2012/01/23/integrating-python-and-javascript-with-pyv8/ [...]
Integrating Python and Javascript | Sai's Blog
10 Apr 2013
[…] am trying to install PyV8 on a Debian machine. I have been using this link as a guide, using the v8 and pyv8 check outs found on that web page. I also believe I have all […]
Trouble installing PyV8 on Debian - different functions between PyV8 and v8 | BlogoSfera
05 Jun 2013
I think you mean "export V8_HOME=`pwd`" and not "export PyV8=`pwd`". Otherwise pyv8's setup.py will run "svn clone" instead of "svn up".
kanzure
21 Sep 2013