[Python] Programmazione web

Manlio Perillo manlio_perillo a libero.it
Ven 25 Apr 2008 15:09:43 CEST


Lawrence Oluyede ha scritto:
> On Fri, Apr 25, 2008 at 11:45 AM, Manlio Perillo
> <manlio_perillo a libero.it> wrote:
>>  Ovviamente hai bisogno di qualche funzione di "supporto", ma il punto è
>>  che IMHO non è necessario introdurre astrazioni ad alto livello (oggetti
>>  Request/Response, etc).
> 
> Io trovo comode astrazioni come WebOb sull'environ di wsgi. Tanto alla
> fine ti scriveresti utility simili.
> 

No, non è affatto necessario.

Innanzitutto l'oggetto Request non serve, tanto lo "stato" della request 
è tutto nel dizionario `environ`.

E lo stesso per l'oggetto Response, wsgiref contiene una classe Headers 
per gestire gli headers, infatti io uso quella.

In Python abbiamo la fortuna di avere dizionari che possono contanere 
qualsiasi oggetto, perchè mai dobbiamo introdurre una classe Request?

Avere oggetti di questo tipo mi sembra più che altro una necessità che 
si ha nei linguaggi staticamente tipizzati, ma non di certo in Python.


Tanto per farti due esempi di come uso io WSGI:


def info(environ, start_response):
     headers = [
             ('Content-Type', 'text/html; charset=utf-8'),
             ]

     cookie = http.parse_cookie(environ)

     template = environ['wsgix.lookup'].get_template('info.html')
     ctx = {
         'environ': environ,
         'page_title': 'environ'
         }

     body = template.render(**ctx)
     start_response(http.responses[http.OK], headers)

     return [body]


def xxx(environ, start_response):
     headers = Headers([])

     obj = manager.get_obj(environ)
     if not obj:
         return http.not_found_response(
             environ, start_response, headers)

     model = model.model(environ)
     action, values, errors = model.submit(environ)
     if errors:
         return http.bad_request_response(
             environ, start_response, headers)

     id = manager.create_some_object(
         environ['app.engine'], environ, obj, **values)


     u = util.application_uri(environ)
     u = u + environ['app.base_url'] + 'xxx/' + id + '/'

     return http.redirect_response(
         environ, start_response, headers, u)


In pratica tutto gira attorno al dizionario environ e all'instanza della 
classe Headers, e tutto è a livello abbastanza basso ma comunque 
conveniente.

Tutto lo stato (incluso le opzioni, ad esempio caricate da un file di 
configurazione tramite un middleware) sono nel `environ`.

Le funzioni per il parsing prendono tutti i dati (incluse le eventuali 
opzioni) dall'`environ`, e se serve conservono dentro all'`environ` il 
risultato del parsing, per il caching.


Almeno fino ad ora non sento nessuna necessità di mettere in mezzo 
oggetti sopra il dizionario environ.

L'unica astrazione che sto usando è quella per gestire i forms (basata 
sul modello di XForms).


>>  Appunto.
>>  Questo perchè, sempre IMHO, le implementazioni si "allontanano" da WSGI,
>>  usandolo solo come "dettaglio implementativo".
> 
> Secondo me è anche il modello a middleware agnostici che in teoria è
> perfetto e in pratica un po' meno.
> Questa specie di decorator pattern in cui però alcuni middleware non
> perfettamente scritti impattano sull'environ e rompono le uova nel
> paniere di altri middleware non mi piace molto. 

Se un middleware non è ben scritto e "rompe" la tua applicazione, non lo 
usi. Quale è il problema?

> Tra l'altro framework
> come Pylons wrappano la tua applicazione con 3 o 4 middleware ogni
> volta, il che rende difficile qualsiasi tipo di debug cross-middleware
> (data la natura opaca del modello)
> 


Mi interessa questo aspetto, mi potresti dare maggiori informazioni?

Io fino ad ora non ho incontrato problemi, anzi con i middleware (ma 
fino ad ora direi che ne sto usando solo di semplici) trovo che 
l'applicazione si gestisca meglio.




Ciao  Manlio Perillo


Maggiori informazioni sulla lista Python