10. Migration de Karrigell 2.x à 3.y
Bien que la version 3 soit une réécriture complète des modules coeur de Karrigell, elle est presque entièrement compatible avec les versions précédentes. Les deux principaux changements sont la façon dont les modules écrits par l'utilateur sont importés, par une fonction intégrée Import(url_module)
; et la résolution des chemins relatifs dans le système de fichiers
1 - Configuration
1.1 Les fichiers de configuration sont des scripts Python au lieu d'un fichier .ini unique : un pour le serveur, et un pour chaque hôte. La plupart des options de configuration sont les mêmes, si ce n'est que tous les noms ont été normalisés : en minuscules, avec des blancs soulignés entre les mots. Par exemple, rootDir
devient root_dir
- mais pour réduire l'incompatibilité, les "vieux" noms seront toujours reconnus
1.2 La seule option qui peut être définie sur la ligne de commande est le chemin du dossier dans lequel se trouve le fichier de configuration du serveur. Toutes les autres options telles que le port du serveur sont définies dans les scripts de configuration du serveur ou des hôtes
1.3 L'équivalent de l'option "protected" n'est pas encore implémenté
2 - Syntaxe
2.1 Noms de fichiers relatifs
-
os.getcwd()
n'est PAS modifié par le canevas comme c'était le cas dans les versions précédentes, parce que sa valeur n'est pas stable dans un environnement multithreads : on ne peut pas s'en servir de façon fiable dans les scripts - la chaîne intégrée
CWD
est le chemin complet du répertoire du script courant - la fonction intégrée
REL(nom_de_fichier)
convertit un nom de fichier relatif en un nom de fichier absolu, en se basant sur le répertoire du script courant - pour simplifier et rester compatible avec les versions précédentes, les fonctions intégrées de Python
open()
etfile()
convertissent les chemins relatifs de fichiers en chemins absolus en se basant sur le répertoire du script courant
2.2 Importations
- pour importer des modules Python situés dans la distribution standard, on utilise le mot-clé habituel
import
- vous pouvez aussi utiliser
import
pour des modules installés dans le répertoire karrigell/package - pour des modules écrits par l'utilisateur à l'intérieur d'une application,
import
ne peut pas fonctionner de manière fiable dans un environnement multi-threads où la valeur desys.path
peut être modifiée par les scripts, et parce que le partage desys.modules
au niveau de l'interpréteur peut conduire à des confusions sur les noms de modules. Il faut utiliser la fonction intégréeImport()
:module = Import(url_du_module)
- pour faciliter la migration, le script karrigell/core/migrate_2_to_3.py, à exécuter en ligne de commande, examine les scripts et produit un rapport avec tous les cas où
import
est utilisé pour importer des modules qui ne figurent pas dans la distribution Python installée sur la machine
2.3 Include
En Karrigell 2.x, avec Include(url)
, une url relative était résolue relativement à l'url complète du script, y compris le nom de fonction dans les scripts, les éventuels arguments d'"url intelligente", etc
Dans la version 3 la résolution est relative à l'url du script, sans tenir compte des éléments qui le suivent dans l'url
Soit par exemple le script ks_script.ks :
Include("entete.html") def mafonction(**kw): Include("info.txt")
Quand on appelle l'url hote/dossier/ks_script.ks/mafonction?arg1=val1 la résolution se base sur l'url du script, hote/dossier/ks_script.ks. Donc :
- l'url relative entete.html est résolue comme l'url absolue hote/dossier/entete.html
- l'url relative info.txt est résolue comme l'url absolue hote/dossier/info.txt
2.4 Résultats
- quand un script est exécuté, il peut donner des valeurs spécifiques à des entêtes de réponse tels que
Content-type, Set-Cookie
etc, et il renvoie généralement des données à afficher par l'agent utilisateur. La réponse HTTP renvoyée par le serveur consiste en une ligne de réponse, des entêtes de réponse et des données - pour cette raison,
sys.stdout
ne peut pas être utilisé directement dans un script pour envoyer la réponse à l'agent utilisateur, parce que le résultat serait envoyé AVANT la ligne de réponse et les entêtes. La fonction intégréeprint
peut être utilisée pour cela ; elle est traduite en interne en la fonction intégréePRINT()
, qui peut d'ailleur aussi être utilisée directement :PRINT(data)
donne le même résultat queprint data
- en interne, cette fonction
PRINT
accumule les données dans un tampon ; quand la requête est terminée, le serveur envoie la ligne de réponse, puis les entêtes de réponse, et finalement le contenu du tampon - pour éviter les espaces et les sauts de ligne introduits par
print
ouPRINT
, utilisez la fonction intégréeSTDOUT()
2.5 Environnement
Un dictionnaire intégré, ENVIRON
, contient les mêmes informations que os.environ
pour les scripts CGI
2.6 Gestion des utilisateurs
En version 3, la fonction intégrée Logout()
efface les cookies de session et redirige vers la page spécifiée (par défaut, le script où la fonction a été appelée). Dans les versions précéentes elle renvoyait une chaîne de caractères avec un lien vers le script de déconnection
Vous devez donc remplacer toutes les lignes du style :
if Role(): print Logout()
par quelque chose comme :
if Role(): print '<a href="logout">Déconnection</a>'
et ajouter une fonction logout() comme ceci
def logout(): Logout()
3 - Implémentation
3.1 Serveur multithread
Le serveur web par défaut, lancé par python Karrigell.py, est un serveur multithead, capable de servir des requêtes à long temps de traitement sans bloquer le traitement des autres requêtes
Un autre serveur multi process donne également d'excellentes performances
3.2 Gestion des sessions
Les sessions sont stockées sur disque, sauf si on a donné la valeur False
à l'option persistent_session
(ce qui ne fonctionnera pas de façon fiable dans des environnements multithread : si vous avez besoin de cette fonctionnalité, utilisez les versions asynchrone ou mono process du serveur). La durée de vie d'une session dans la base de données de sessions peut être configurée
3.3 Types de données
HEADERS
et RESP_HEADERS
sont des instances de email.Message
(ils se comportent à peu près comme des dictionnaires dont les clés sont insensibles à la casse)
4 - Web 2.0
4.1 editarea
La librairie Javascript EditArea est incluse, pour permettre l'édition de scripts en ligne. Elle est utilisée dans l'éditeur de scripts accessible depuis le menu d'administration, et dans le cas d'erreur ou d'exception, le bouton Debug donne accès à une page où le script peut être édité en ligne
4.2 jQuery
La libraire JavaScript jQuery et jQueryFileTree sont également inclus. Elles sont utilisées par l'application d'édition de scripts dans le menu d'administration, pour parcourir les fichiers sans avoir à recharger toute la page