Karrigell Documentation

Version 2.2.1 13 12 05

English

5. Programmation

Karrigell propose plusieurs styles de programmation :

Ces différents styles sont décrits dans la documentation ; ils partagent tous les mêmes principes pour accéder à l'environnement HTTP et aux variables de formulaires

Vous pouvez aussi ajouter la prise en charge d'autres types de scripts : si vous voulez gérer les scripts qui ont l'extension .foo, vous devez écrire un module appelé mod_foo. Voir l'exemple de mod_tmpl.py pour gérer le système de template Cheetah

5.1 Accès à l'environnement HTTP

L'accès à l'environnement HTTP est fourni par des variables globales disponibles dans l'espace de noms du script :
  • HEADERS est un dictionnaire avec les en-têtes HTTP : la clé est le nom de l'en- tête, la valeur est la valeur de l'en-tête. Par exemple HEADERS["accept-language"] donne la valeur de l'en-tête accept-language
  • RESPONSE est un dictionnaire dans lequel on peut définir des valeurs pour l'en-tête de réponse qui sera envoyé au serveur. Ce dictionnaire ne tient pas compte de la casse des clés : RESPONSE['Content-type'] et RESPONSE['CONTENT-type'] donnent le même résultat
  • AUTH_USER et AUTH_PASSWORD sont des valeurs utilisées pour l'authentification
  • SET_COOKIE est un objet SimpleCookie (du module Python Cookie) qui se comporte comme un dictionnaire, et auquel on peut affecter des valeurs qui seront sauvegardées par le navigateur de l'utilisateur sous forme de cookies
  • Pour une utilation plus avancée, REQUEST_HANDLER représente l'instance courante de RequestHandler (gestionnaire de requête). Il expose des attributs tels que client_address, un couple constitué de l'adresse IP et du port du client. Voyez la documentation de BaseHTTPServer et de SimpleHTTPServer dans la distribution standard de Python
  • THIS est une instance de la classe Script (dans Template.py) représentant le script courant

5.2 Champs de formulaires

La variable QUERY est un dictionnaire qui représente la chaîne de requête si le script est appelé par la méthode HTTP GET, ou les champs d'un formulaire soumis par la méthode HTTP POST. Les clés de QUERY sont les noms des champs, et les valeurs sont soit la valeur du champ sous forme de chaîne, soit une liste contenant les valeurs si le nom du champ se termine par [] (s'il vient d'un champ de formulaire <SELECT MULTIPLE> par exemple)

Supposons que vous ayez un formulaire HTML comme celui-ci :

<form action="monScript.py">
  Spam <input name="spam">
  <br><select multiple name="animal[]">
  <option value="chien">Chien
  <option value="chat">Chat
  <option value="grenouille">Grenouille
  </select>
  <br><input type="submit" value="Ok">
</form>

Dans monScript.py vous afficherez les valeurs d'entrée avec :

print "<br>Spam est ",QUERY["spam"]
if QUERY.has_key("animal"):
    print "<br>Animal est",str(QUERY["animal"])

L'accès à ces données est disponible sous forme d'un raccourci, constitué du caractère de soulignement _ suivi du nom du champ. Ainsi, le code ci-dessus pourrait s'écrire plus simplement :

print "<br>Spam est ",_spam
if QUERY.has_key("animal"):
    print "<br>Animal est",str(_animal)

Ce caractère de soulignement est introduit pour limiter les risques de conflits avec des noms réservés de Python ou avec des noms de module fréquemment employés

5.3 Téléchargement de fichier

Pour télécharger un fichier depuis le client vers le serveur, la balise input doit avoir le type "file". Par exemple, le formulaire HTML sera de la forme suivante :

<FORM ENCTYPE="multipart/form-data" ACTION="fileUpload.py" METHOD=POST>
Fichier à charger: <INPUT NAME="monfichier" TYPE="file">
<INPUT TYPE="submit" VALUE="Envoyer">
</FORM>

Le script qui doit traiter le téléchargment utilisera la variable QUERY['myfile'] ou _myfile, qui est une instance de la classe FieldStorage dans le module intégré cgi. Cet objet a deux attributs utiles :

  • filename : le nom du fichier
  • file : un objet de type fichier depuis lequel on peut lire le contenu du fichier

Par exemple si vous voulez stocker le fichier dans le système de fichiers du serveur, en conservant le nom du fichier d'origine :

import os
f = _monfichier.file # objet de type fichier
nom_dest = os.path.basename(_monfichier.filename)
out = open(nom_dest,'wb')
# copier le fichier
import shutil
shutil.copyfileobj(f,out)
out.close()

5.4 Exceptions

Dans les scripts Python on peut lever des exceptions spéciales qui sont gérées par Karrigell
  • SCRIPT_END
    A utiliser pour cesser d'envoyer des données de sortie au navigateur sans avoir à aller jusqu'à la fin du fichier. Ceci peut être utile si vous êtes en train de déboguer un script et que vous vouliez arrêter son exécution à un endroit dans votre script pour voir l'état de certaines variables

    maVar=10
    ...
    print maVar
    raise SCRIPT_END
    ... (reste du code - ne sera pas exécuté)
    

  • SCRIPT_ERROR
    Faites raise SCRIPT_ERROR,msg pour arrêter l'exécution du script et écrire le message

  • HTTP_ERROR
    raise HTTP_ERROR,(codeErreur,messageErreur) a pour effet d'envoyer un message d'erreur HTTP avec les codes et message d'erreur spécifiés

  • HTTP_REDIRECTION
    raise HTTP_REDIRECTION,uri fait que Karrigell redirigera la requête vers l'URI indiquée

5.5 HTMLStream

HTMLStream est une classe du module HIP qui rend l'affichage de données plus facile qu'avec une suite de print. C'est la même idée que HTML Inside Python mais implémentée différemment

Créez une instance de cette classe :

import HIP
H = HIP.HTMLStream()

Ensuite utilisez "+" et "-" pour envoyer des données sur la sortie standard : avec "+" la representation en chaîne de caractère de la donnée est imprimée ; avec "-", la fonction cgi.escape est exécutée sur cette chaîne

dico={"un":"unan","deux":"daou","trois":"tri"}
H + dico - type(dico)

revient au même que :

dico={"un":"unan","deux":"daou","trois":"tri"}
print str(dico),cgi.escape(type(dico))

5.6 Gestion des erreurs et débogueur

Si une erreur survient quand on appelle une URL, une trace est affichée dans le navigateur

L'information fournie consiste en :

  • l'url appelée
  • une table relative au script dans lequel l'erreur s'est produite : il se peut que ce ne soit pas celui dont le nom correspond à l'URL, si l'erreur est survenue dans un script inclus par la fonction Include(). La table montre le nom du script, le nom de l'exception, le numéro et le texte de la ligne dans le script erronné
  • la trace Python brute
  • un bouton "debug"
Par exemple :

Error in /demo/errors/ErrorInIncludedTest1.py

/demo/errors/ErrorInIncludedTest1.py
 includes /demo/errors/ErrorInIncludedTest2.py
Script /demo/errors/ErrorInIncludedTest1.py
NameError: name 'bonjour' is not defined Line 1     print 'Script 1'
Traceback (most recent call last):
  File "C:\cygwin\home\Karrigell\Template.py", line 153, in render
    exec self.pythonCode() in ns
  File "<string>", line 1, in ?
NameError: name 'bonjour' is not defined
Avec ce bouton "Debug" on accède à plus d'informations au sujet de l'erreur :
  • le code source, avec syntaxe colorée et la ligne où s'est produite l'erreur mise en évidence
  • une vue de l'environnement, dans laquelle on peut naviguer pour trouver la valeur des variables, le code source des fonctions et méthodes, etc

Aperçu :