Django, le wsgi et paste: status
Cette après-midi, j'ai retrouvé mon collègue de geekerie, Olivier. Pendant que lui tentait de faire apprendre à rêver à son cher Dr Gumby, je me suis atteler à faire fonctionner django avec paste. Pas une mince affaire à priori. J'avais vu une tentative pour faire un paste.django qui semblait évoluer péniblement. Mais bon, je suis plein de courage.
J'ai finalement été assez surpris. Déjà, on trouve dans le trunk de django un WSGIHandler. C'est la fête ! Il ne reste plus qu'as l'associer à paste. Bon, je me lance.
La première chose que j'ai faites a été de transformer l'application en egg. Je comprends pas que ce ne soit pas fait de fait dans la template django... Soit, un simple setup.py et mon application peut-être intégrée dans mon buidlout.
Ensuite, première tentative pour utiliser ce précieux handler: créer une usine qui renvois le WSGIHandler tel quel. Échec. Forcément, django attends son fameux module de settings. Soit, avec un peu de chance, en le plaçant dans l'environ utilisé par l'usine, on vas y arriver. Re-échec.
Pourquoi ? Tout bêtement parce que django vas chercher cette valeur dans os.environ. Et là, c'est le drame. Enfin non, c'est à moitié le drame. En effet, en initialisant correctement la variable qui vas bien, on arrive finalement à utiliser ce handler.
Second problème, les url générées par l'application sont toutes erronées. En effet, un bug fait que django ne tiens pas compte de la variable SCRIPT_NAME. C'est bien dommage, mais un bon vieux hack permet de fixer le problème relativement facilement. Il suffit d'initialiser le PATH_INFO en le précédent du SCRIPT_NAME et le tour est joué.
Voici le résultat:
# -*- coding: utf-8 -*-
import os
from paste.deploy.config import ConfigMiddleware
from django.core.handlers.wsgi import WSGIHandler
def factory(global_config, **local_config):
os.environ['DJANGO_SETTINGS_MODULE'] = 'jobsafpyorg.settings'
conf = global_config.copy()
conf.update(**local_config)
app = ConfigMiddleware(WSGIHandler(), conf)
def django_app(environ, start_response):
environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
return app(environ, start_response)
return django_app
On peut ensuite se servir de cette usine comme point d'entrée et l'utiliser dans un fichier de configuration paste. Notez que le ConfigMiddleware est indipensable. Le handler de django semble renvoyer des choses peu ordinaire de type class, parfois. Le middleware permet de corriger tout cela.
Problème, si on veut plusieurs instance django dans un seul environnement wsgi, ça devient problématique. Comment initialiser plusieurs configuration avec une seul clé du dictionnaire environ... Je me le demande.
Cela dit, c'est un problème auquel je vais être confronter car j'aimerais fair cohabiter les deux applications django qui ont été faites pout l'AFPy. Donc, la suite au prochaine épisode.
django monte en puissance
Je crois que django a de l'avenir. Google viens de sortir son app engine qui s'appuie en grande partie sur django et le WSGI (ça me fait penser qu'il faudrait que je prépare ma conf pour pycon un jour). C'est plutôt très bon signe pour django et pour python plus généralement, d'ailleurs. Google se lance dans le mass-hosting et c'est en python que ça se fait. Cet hébergement gratuit grand publique est-il le début de la vrai vulgarisation de python ? On ne peut que l'espérer ! Jusqu'à présent, objectis était le seul hébergeur gratuit (au monde ?) a proposer une solution python gratuite. Cela manquait vraiment.
Suite à cette annonce, j'ai eu aussi l'occasion de découvrir playlive.fm. Un site musico-social 2.0 basé sur django. Le résultat est joli (j'ai eu une invite, héhé) et j'ai été agréablement surpris de voir que Hocus-Pocus (je suis super fan, ils tuent. naoned représente !) est déjà présent sur la plate-forme.