Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about python (old posts, page 48)

Juno and middleware

This is how you add ba­sic au­then­ti­ca­tion to your Juno ap­p:

init({
    'middleware':[('paste.auth.basic.AuthBasicHandler',
                      {'realm':'Admin',
                       'authfunc':valid_user})],
    })

Where valid_us­er is the ob­vi­ous func­tion that takes user/­pass and re­turns true/­false.

Not ex­act­ly a so­phis­ti­cat­ed role-based au­th, but I don't need that for my app (L­DAP's ac­cess con­trols take care of it).

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.

Translations coming

The span­ish trans­la­tions of most ses­sions of "PyQt by Ex­am­ple" are al­most done, thanks to sev­er­al vol­un­teer­s.

To­mor­row I will up­load at least one.

If any­one wants to trans­late them to oth­er lan­guages, I will be hap­py to in­clude those too.


Contents © 2000-2023 Roberto Alsina