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() et file() 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 de sys.path peut être modifiée par les scripts, et parce que le partage de sys.modules au niveau de l'interpréteur peut conduire à des confusions sur les noms de modules. Il faut utiliser la fonction intégrée Import() :
        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ée print peut être utilisée pour cela ; elle est traduite en interne en la fonction intégrée PRINT(), qui peut d'ailleur aussi être utilisée directement : PRINT(data) donne le même résultat que print 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 ou PRINT, utilisez la fonction intégrée STDOUT()

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