Gefr with multiple backends support

Sat 09 April 2011
  • ANN tags:
  • gefr
  • jython
  • project
  • wsgi published: true comments: true

I have been working on gefr this week to add apache MINA backend for it. The goal of gefr is to provide adapters between Python's WSGI and Java network infrastructures. In cPython world, most WSGI servers are implemented with C code(fapws, meinheld, etc.), which is not applicable on Jython platform. However, the Java world has its own reliable network foundations. So my gefr turns them into WSGI servers. The ultimate goal of gefr is to make it possible to port any of your WSGI web applications to Jython seamlessly.

There has been many attempts to use Jython in Java web development. Most of them is focusing on applying Jython in Servlet framework. This is helpful, but it doesn't take the whole advantage of Python web programming. The most valuable thing in Python web development is its various web frameworks and agile tools. But inside servlet framework, we can hardly apply them, the only things we have is Jython's beautiful syntax. That should not be enough.

OK. You are eager to meet gefr? Let's get hands dirty with some setup. I just assume that you have some essential software installed in the right place. Is it true for you?

Create Jython virtual environment: $ virtualenv -p /usr/local/bin/jython gefr-test
$ cd gefr-test
$ source bin/activate

Install jip. jip is a great tool to manage Java dependencies for your Jython application. jip>=0.3 is required in this guide, and pip will handle this for you. $ pip install jip

Install gefr. Since gefr is a pure Python package, pip is still helpful. $ pip install gefr

Now create a jip configuration file called .jip in your virtual home. We should add sonatype oss repository.
[cc lang="ini"]
[repos:oss]
uri=http://oss.sonatype.org/content/repositories/snapshots/
type=remote

[repos:central]
uri=http://repo1.maven.org/maven2/
type=remote

[repos:local]
uri=/home/sun/.m2/repository/
type=local
[/cc]

New in jip 0.3, we can use a single command to resolve dependencies of gefr. $ jip install-dependencies info.sunng.gefr:gefr:0.2-SNAPSHOT

OK. Then everything is ready. Create your first Jython WSGI application. Actually, there is no difference.
I just copy the example of gefr here, you can find it in the code repository.
[cc lang="python"]
#! /usr/bin/python

__author__="Sun Ning "
__date__ ="$Jan 5, 2011 10:14:27 PM$"

import sys
from gefr.core import Gefr

def simple(environ, start_response):
"""a static app"""
headers = []
headers.append(('Content-Type', "text/html"))
start_response("200 OK", headers)

return ["

it works.

"]

if __name__ == "__main__":
from optparse import OptionParser
parser = OptionParser()
parser.add_option('-b', '--backend', dest='backend', help='server backend')
(options, args) = parser.parse_args()

if options.backend == 'soldat':
from gefr.backends.soldat import SoldatBackend as backend
elif options.backend == 'mina':
from gefr.backends.mina import MinaBackend as backend
else:
print 'backend %s not supported.' % options.backend
sys.exit(1)

g = Gefr(simple, backend)
g.start()
[/cc]
With the command line options, you can control which backend to be used. Now start it with: $ jython-all example.py -b soldat or $ jython-all example.py -b mina

Soldat is another network framework written by myself. And MINA, you must know. Open your browser, redirect it to http://localhost:8080 , now you see it works.

Sure, that's not enough for your needs. Let's have an advanced example. Among all the web frameworks in Python, I like bottle most. So we just build a simple application with GET and POST in bottle.

$ pip install bottle
$ pip install mako
$ mkdir bottleapp
$ cd bottleapp

The bottle application looks like:
echo.py
[cc lang="python"]
# -*- coding:utf-8 -*-

from bottle import Bottle, mako_view, request
from gefr.core import Gefr
from gefr.backends.mina import MinaBackend

bapp = Bottle()

@bapp.get('/')
@mako_view('edit')
def display_form():
return dict(ip=request.environ.get('REMOTE_ADDR'))

@bapp.post('/')
@mako_view('show')
def display_content():
content = request.POST.get('content')
return dict(content=content)

Gefr(bapp, MinaBackend).start()
[/cc]

The simple mako templates are:

edit.tpl
[cc lang="html"] Bottle on MINA

Bottle on MINA

User from ${ip}, leave your words please:

[/cc]

show.tpl
[cc lang="html"] Bottle on MINA

Bottle on MINA

${content | h}

[/cc]

Start the bottle app: $ jython-all echo.py

This is rather simple but it covers the most basic features of a web server.

I should say thank you for reaching here. Gefr is still an experimental project in early development. So there must be bugs and potential performance improvements in it. Feel free to contact me if you are also interested in it. The project is hosted on bitbucket: https://bitbucket.org/sunng/gefr