Pyjamas and Juno

I am cur­rent­ly in dire need of cre­at­ing a nice ad­min page for a LDAP ad­dress­book, which should do some slight­ly un­usu­al things with the da­ta (like ma­nip­u­lat­ing Post­fix’s vir­tu­al table).

So, what the heck, let’s al­so learn some­thing new while I’m at it. The vic­tim­s: Py­ja­mas and Juno.

Py­ja­mas is sort of a Python ver­sion of GWT and is blis­s. Fi­nal­ly I can code HTML and JS in python ;-)

And Juno is re­fresh­ing­ly sim­ple. Since the whole fron­tend is done by Py­ja­mas, all I need­ed is a way to route JSON­R­PC calls to python code and op­er­ate in the back­end.

So, here are two use­ful snip­pet­s:

# This decorator decodes JSONRPC arguments as sent by Pyjamas to
# Juno, and calls the target function with the decoded version.
def JSONRemote(target):
    def wrapper(web,*args,**kwargs):
        postdata=web.input().keys()[0]
        data = json.loads(postdata)
        id, method, params = data["id"],data["method"],[web,]+data["params"][1]
      kwargs['method']=method
        return target(*params,**kwargs)
    return wrapper

Us­ing this, any plain juno method works as a JSON­R­PC method!

For ex­am­ple:

@route('/user')
@JSONRemote
def list(web,startwith='*',method=None):
    try:
        result=search(filter='(&(uid=*@bigclient.ar)(sn=%s*))'%startwith)
        resp=JSONResponse(result)
    except ldap.LDAPError, e:
        resp=JSONResponse(None,e.desc)
    return resp

See? No JSON de­cod­ing. And no en­cod­ing ei­ther, be­cause I am cre­at­ing the re­sponse us­ing this:

# This class creates a correct JSON response from Juno as required by Pyjamas
class JSONResponse(JunoResponse):
    def __init__(self,result=None,error=None,id=None,code=200):
        JunoResponse.__init__(self)
        self.headers['Content-Type']='text/javascript'
        self.append(json.dumps({'result':result,'error':error,'id':id,'code':code}))

This is prob­a­bly not a great im­ple­men­ta­tion but it’s good enough for me right now.

Comments

Comments powered by Disqus
Contents © 2000-2013 Roberto Alsina
Share