Sommaire
William Dodé http://flibuste.net
Les bases d'un script CGI en python
Un script CGI est un script comme un autre, il envoie des données sur la sortie standard (print) et reçoit des données dans l'environement:
- os.getenv(nom_de_la_variable)
cgi.FieldStorage() pour les paramètres (GET et POST)
Pour pouvoir être appelé, le script doit avoir les droits en exécution (chmod +x) et commencer par #!/usr/bin/python. Suivant la configuration du serveur, le script doit être placé dans le répertoire cgi-bin.
Exemple d'affichage de Hello world !
print "Content-Type: text/html" print print "Hello world !"
L'utilisation des triples quotes est bien pratique, bien qu'il n'est pas conseillé de mélanger le code et la présentation (voir les templates plus loin)
print "Content-Type: text/html" print print """ <html> <body> Ceci est une page html un peu plus conforme </body> </html> """
Gotcha: Attention. Sous Windows, si vous voulez renvoyer un fichier binaire (par exemple un fichier zip (Content-Type: application/octet-stream)), vous devez forcer Windows à passer la console en mode binaire (sans quoi votre fichier binaire sera corrompu). Voir l'explication en anglais. Cette bidouille n'est nécessaire que sous Windows (Unix/Linux gérant parfaitement les binaires en console).
Récupération des paramètres GET et POST
Python ne fait pas la différence entre GET et POST.
Le module cgi permet de récupérer les paramètres passés par GET (http:''''''//.../...?p1=...&p2=...&p3=...) ou par POST (<form method=post>...) grâce à la fonction FieldStorage().
Attention, cette fonction ne doit être appelée qu'une fois ! (le résultat sera vide la fois suivante). Il est également déconseillé de faire un from cgi import * (voir la doc officielle).
Exemple d'un script affichant les valeurs des paramètres a et b
print "Content-Type: text/html" print import cgi form=cgi.FieldStorage() print "a=%s b=%s"%(form.getvalue("a","valeur par défaut de a"), form.getvalue("b","..."))
Avec l'url suivante : http:''''''//monserver/monscript.py?a=5&b=2
Nous obtiendrons :
a=5 b=2
Récupération d'un fichier
De la même manière, nous pouvons récupérer un fichier envoyé par un form :
<form action=monscript.py enctype='multipart/form-data' method=post> <input type=file name=monfichier> <input type=submit> </form>
script monscript.py qui va récupérer le fichier, l'enregistrer et l'afficher :
print "Content-Type: text/html" print import cgi form=cgi.FieldStorage() contenu=form["monfichier"].value f=open("fic","w") f.write(contenu) f.close() print contenu
Il est également possible de traiter ce fichier comme un fichier plutôt que de récupérer tout son contenu d'un seul coup
print "Content-Type: text/html" print import cgi form=cgi.FieldStorage() file_item=form["monfichier"] contenu=file_item.file.read() f=open("fic","w") f.write(contenu) f.close() print contenu
Rattrapage des erreurs
Les erreurs éventuelles vont être envoyée sur la sortie stderr. Hors vous ne la verrez pas ! Plusieurs solutions :
Diriger la sortie stderr sur stdout
import sys sys.stderr=sys.stdout
Rattraper l'erreur pour l'afficher ou l'enregistrer dans un fichier
try: le script except: import traceback print ("<pre>") traceback.print_exc() print ("</pre>")
Utiliser python2.2 et le module cgitb
import cgitb cgitb.enable() ...
Récupération des variables d'environement
Pour avoir un aperçu de toutes les variables récupérables :
import cgi cgi.test()
Pour récupérer les variables qui nous intéressent, par exemple dans le cas de l'url :
http:''''''//monserver/monscript?a=5
REQUEST_URI: /monscript?a=5
QUERY_STRING: a=5
SCRIPT_NAME: /monscript.py
import os print """<pre> REQUEST_URI: %s QUERY_STRING: %s SCRIPT_NAME: %s </pre>"""%( os.getenv("REQUEST_URI",""), os.getenv("QUERY_STRING",""), os.getenv("SCRIPT_NAME","") )
Gestion des cookies
Envoi d'un cookie à durée limité à la session (lorsque le navigateur ferme le cookie disparait)
import Cookie c=Cookie.SimpleCookie() c["theme"]="classique" print c print "Content-Type: text/html" print
Envoi d'un cookie à durée d'une heure
import Cookie c=Cookie.SimpleCookie() c["theme"]="classique" c["theme"]["max-age"]="3600" print c print "Content-Type: text/html" print
Récupération d'un cookie (par la variable d'environement HTTP_COOKIE, que l'on peu visualiser avec cgi.test())
print "Content-Type: text/html" print import os import Cookie c=Cookie.SimpleCookie() c.load(os.getenv("HTTP_COOKIE","")) print "theme=%s<br>" % ( c["theme"].value )
Frameworks pour le développement web
modpython
- Module apache, une alternative plus performante aux cgi, l'interpréteur est "embedded" (i.e. embarqué) dans le serveur web.
Présentation des divers frameworks : http://colorstudy.com/docs/shootout.html
eric3 (http://wikipython.flibuste.net/moin.py/EditeursEtIDE#eric3)
eric3 est une IDE permettant (entre autres!) de débugger les scripts CGI. Pour ce faire, il faut configurer le débogueur de la façon suivante :
- dans les préférences, aller dans "Deboggeur/General"
- activer le débogueur passif en cochant la case "Debogueur passif activé". Laisser le port à sa valeur par défaut (42424)
- fermer puis relancer eric
- au début du script cgi, ajouter la ligne suivante:
import eric3.Debugger.eric3dbgstub as eric3dbgstub
- et en dessous, après l'instruction de début de programme, ajouter les deux lignes suivantes:
if eric3dbgstub.initDebugger("standard"): eric3dbgstub.debugger.startDebugger(redirect=0)
Finalement, ca doit donner qqchose comme:
import eric3.Debugger.eric3dbgstub as eric3dbgstub def... def... if __name__ == "__main__": if eric3dbgstub.initDebugger("standard"): eric3dbgstub.debugger.startDebugger(redirect=0) ...code principal ici...
Pour lancer le débogage, on appelle le script normalement depuis l'url de mozilla. Normalement, le lancement rebascule automatiquement l'execution du script dans eric3.
Templates
ExempleTemplate : exemple très simple
TemplateCode : exemple avec incorporation de code python dans une page html (genre PHP, ASP, JSP), le tout bytecompilé !
Cheetah : Script dans le même esprit que Smarty pour php http://cheetahtemplate.org Un page de présentation en français par ici : http://satz.free.fr/blog/index.php?2004/06/09/15-les-templates-avec-cheetah