IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à programmer avec Python


précédentsommairesuivant

Chapitre 17 : Applications web

Vous avez certainement déjà appris par ailleurs un grand nombre de choses concernant la rédaction de pages web. Vous savez que ces pages sont des documents au format HTML, que l'on peut consulter via un réseau (intranet ou internet) à l'aide d'un logiciel appelé browser web ou navigateur (Netscape, Konqueror, Internet explorer, ...).

Les pages HTML sont installées dans les répertoires publics d'un autre ordinateur où fonctionne en permanence un logiciel appelé serveur Web (Apache, IIS, Zope, ...). Lorsqu'une connexion a été établie entre cet ordinateur et le vôtre, votre logiciel navigateur peut dialoguer avec le logiciel serveur (par l'intermédiaire de toute une série de dispositifs matériels et logiciels dont nous ne traiterons pas ici : lignes téléphoniques, routeurs, caches, protocoles de communication ...).

Le protocole HTTP qui gère la transmission des pages web autorise l'échange de données dans les deux sens. Mais dans la grande majorité des cas, le transfert d'informations n'a pratiquement lieu que dans un seul, à savoir du serveur vers le navigateur : des textes, des images, des fichiers divers lui sont expédiés en grand nombre (ce sont les pages consultées) ; en revanche, le navigateur n'envoie guère au serveur que de toutes petites quantités d'information : essentiellement les adresses URL des pages que l'internaute désire consulter.

17-1. Pages web interactives

Vous savez cependant qu'il existe des sites web où vous êtes invité à fournir vous-même des quantités d'information plus importantes : vos références personnelles pour l'inscription à un club ou la réservation d'une chambre d'hôtel, votre numéro de carte de crédit pour la commande d'un article sur un site de commerce électronique, votre avis ou vos suggestions, etc.

Dans un cas comme ceux-là, vous vous doutez bien que l'information transmise doit être prise en charge, du côté du serveur, par un programme spécifique. Il faut donc que les pages web destinées à accueillir cette information soient dotées d'un mécanisme assurant son transfert vers le logiciel destiné à la traiter. Il faudra également que ce logiciel puisse lui-même transmettre en retour une information au serveur, afin que celui-ci puisse présenter le résultat de l'opération à l'internaute, sous la forme d'une nouvelle page web.

Le but du présent chapitre est de vous expliquer comment vous pouvez vous servir de vos compétences de programmeur Python pour ajouter une telle interactivité à un site web, en y intégrant de véritables applications.

Remarque importante : Ce que nous allons expliquer dans les paragraphes qui suivent sera directement fonctionnel sur l'intranet de votre établissement scolaire ou de votre entreprise (à la condition toutefois que l'administrateur de cet intranet ait configuré son serveur de manière appropriée). En ce qui concerne l'internet, par contre, les choses sont un peu plus compliquées. Il va de soi que l'installation de logiciels sur un ordinateur serveur relié à l'internet ne peut se faire qu'avec l'accord de son propriétaire. Si un fournisseur d'accès à l'internet a mis a votre disposition un certain espace où vous êtes autorisé à installer des pages web « statiques » (c'est-à-dire de simples documents à consulter), cela ne signifie pas pour autant que vous pourrez y faire fonctionner des scripts Python. Pour que cela puisse marcher, vous devrez demander une autorisation et un certain nombre de renseignements à votre fournisseur d'accès. Il faudra en particulier lui demander si vous pouvez activer des scripts CGI écrits en Python à partir de vos pages, et dans quel(s) répertoire(s) vous pouvez les installer.

17-2. L'interface CGI

L'interface CGI (pour Common Gateway Interface) est un composant de la plupart des logiciels serveurs de pages web. Il s'agit d'une passerelle qui leur permet de communiquer avec d'autres logiciels tournant sur le même ordinateur. Avec CGI, vous pouvez écrire des scripts dans différents langages (Perl, C, Tcl, Python ...).

Plutôt que de limiter le web à des documents écrits à l'avance, CGI permet de générer des pages web sur le champ, en fonction des données que fournit l'internaute par l'intermédiaire de son logiciel de navigation. Vous pouvez utiliser les scripts CGI pour créer une large palette d'applications : des services d'inscription en ligne, des outils de recherche dans des bases de données, des instruments de sondage d'opinions, des jeux, etc.

L'apprentissage de la programmation CGI peut faire l'objet de manuels entiers. Dans cet ouvrage d'initiation, nous vous expliquerons seulement quelques principes de base, afin de vous faire comprendre, par comparaison, l'énorme avantage que présentent les modules serveurs d'applications spécialisés tels que Karrigell, CherryPy ou Zope, pour le programmeur désireux de développer un site web interacif.

17-2-1. Une interaction CGI rudimentaire

Pour la bonne compréhension de ce qui suit, nous supposerons que l'administrateur réseau de votre établissement scolaire ou de votre entreprise a configuré un serveur web d'intranet d'une manière telle que vous puissiez installer des pages HTML et des scripts Python dans un répertoire personnel.

Notre premier exemple sera constitué d'une page web extrêmement simple. Nous n'y placerons qu'un seul élément d'interactivité, à savoir un unique bouton. Ce bouton servira à lancer l'exécution d'un petit programme que nous décrirons par après.

Veuillez donc encoder le document HTML ci-dessous à l'aide d'un éditeur quelconque (n'encodez pas les numéros de lignes, ils ne sont là que pour faciliter les explications qui suivent) :

 
Sélectionnez
1. <HTML>
2. <HEAD><TITLE>Exercice avec Python</TITLE></HEAD>
3. <BODY>
4.
5. <DIV ALIGN="center">
6. <IMG SRC="penguin.gif">
7. <H2>Page Web interactive</H2>
8. <P>Cette page est associée à un script Python</P>
9.
10.<FORM ACTION="http://Serveur/cgi-bin/input_query.py" METHOD="post">
11.<INPUT TYPE="submit" NAME="send" VALUE="Exécuter le script">
12.</FORM>
13.
14.</DIV></BODY></HTML>

Vous savez certainement déjà que les balises initiales <HTML>, <HEAD>, <TITLE>, <BODY>, ainsi que les balises finales correspondantes, sont communes à tous les documents HTML. Nous ne détaillerons donc pas leur rôle ici.

La balise <DIV> utilisée à la ligne 5 sert habituellement à diviser un document HTML en sections distinctes. Nous l'utilisons ici pour définir une section dans laquelle tous les éléments seront centrés (horizontalement) sur la page.

A la ligne 6, nous insérons une petite image.

La ligne 7 définit une ligne te texte comme étant un titre de 2e importance.

La ligne 8 est un paragraphe ordinaire.

Les lignes 10 à 12 contiennent le code important (pour ce qui nous occupe ici). Les balises <FORM> et </FORM> définissent en effet un formulaire, c'est-à-dire une portion de page Web susceptible de contenir divers widgets à l'aide desquels l'internaute pourra exercer une certaine activité : champs d'entrée, boutons, cases à cocher, boutons radio, etc.

La balise FORM doit contenir deux indications essentielles : l'action à accomplir lorsque le formulaire sera expédié (il s'agit en fait de fournir ici l'adresse URL du logiciel à invoquer pour traiter les données transmises), et la méthode à utiliser pour transmettre l'information (en ce qui nous concerne, ce sera toujours la méthode « post »).

Dans notre exemple, le logiciel que nous voulons invoquer est un script Python nommé input_query.py qui est situé dans un répertoire particulier du serveur d'intranet. Sur de nombreux serveurs, ce répertoire s'appelle souvent cgi-bin , par pure convention. Nous supposerons ici que l'administrateur de votre intranet scolaire vous autorise à installer vos scripts Python dans le même répertoire que celui où vous placez vos pages Web personnelles.

Vous devrez donc modifier la ligne 10 de notre exemple, en remplaçant l'adresse http://Serveur/cgi-bin/input_query.py par ce que votre professeur vous indiquera68.

La ligne 11 contient la balise qui définit un widget de type « bouton d'envoi » (balise <INPUT TYPE="submit">). Le texte qui doit apparaître sur le bouton est précisé par l'attribut VALUE ="texte". L'indication NAME est facultative dans le cas présent. Elle mentionne le nom du widget lui-même (au cas où le logiciel destinataire en aurait besoin).

Lorsque vous aurez terminé l'encodage de ce document, sauvegardez-le dans le répertoire que l'on vous a attribué spécifiquement pour y placer vos pages, sous un nom quelconque, mais de préférence avec l'extension .html ou .htm (par exemple : essai.html).


Le script Python input_query.py est détaillé ci-dessous. Comme déjà signalé plus haut, vous pouvez installer ce script dans le même répertoire que votre document HTML initial :

 
Sélectionnez
1. #! /usr/bin/python
2.
3. # Affichage d'un formulaire HTML simplifié :
4. print "Content-Type: text/html\n"
5. print """
6. <H3><FONT COLOR="Royal blue">
7. Page web produite par un script Python
8. </FONT></H3>
9.
10.<FORM ACTION="print_result.py" METHOD="post">
11.<P>Veuillez entrer votre nom dans le champ ci-dessous, s.v.p. :</P>
12.<P><INPUT NAME="visiteur" SIZE=20 MAXLENGTH=20 TYPE="text"></P>
13.<P>Veuillez également me fournir une phrase quelconque :</P>
14.<TEXTAREA NAME="phrase" ROWS=2 COLS=50>Mississippi</TEXTAREA>
15.<P>J'utiliserai cette phrase pour établir un histogramme.</P>
16.<INPUT TYPE="submit" NAME="send" VALUE="Action">
17.</FORM>
18."""

Ce script ne fait rien d'autre que d'afficher une nouvelle page web, laquelle contient encore une fois un formulaire, mais celui-ci nettement plus élaboré que le précédent.

La première ligne est absolument nécessaire : elle indique à l'interface CGI qu'il faut lancer l'interpréteur Python pour pouvoir exécuter le script. La seconde ligne est un simple commentaire.

La ligne 4 est indispensable. Elle permet à l'interpréteur Python d'initialiser un véritable document HTML qui sera transmis au serveur web. Celui-ci pourra à son tour le réexpédier au logiciel navigateur de l'internaute, et celui-ci le verra donc s'afficher dans la fenêtre de navigation.

La suite est du pur code HTML, traité par Python comme une simple chaîne de caractères que l'on affiche à l'aide de l'instruction print. Pour pouvoir y insérer tout ce que nous voulons, y compris les sauts à la ligne, les apostrophes, les guillemets, etc., nous délimitons cette chaîne de caractères à l'aide de « triples guillemets » (Rappelons également ici que les sauts à la ligne sont complètement ignorés en HTML : nous pouvons donc en utiliser autant que nous voulons pour « aérer » notre code et le rendre plus lisible).

68 Par exemple : http://192.168.0.100/cgi/Classe6A/Dupont/input_query.py .

17-2-2. Un formulaire HTML pour l'acquisition des données

Analysons à présent le code HTML lui-même. Nous y trouvons essentiellement un nouveau formulaire, qui comporte plusieurs paragraphes, parmi lesquels on peut reconnaître quelques widgets. La ligne 10 indique le nom du script CGI auquel les données du formulaire seront transmises : il s'agira bien évidemment d'un autre script Python.

A la ligne 12, on trouve la définition d'un widget de type « champ d'entrée » (Balise INPUT, avec TYPE="text"). L'utilisateur est invité à y encoder son nom. Le paramètre MAXLENGTH définit une longueur maximale pour la chaîne de caractères qui sera entrée ici (20 caractères, en l'occurrence). Le paramètre SIZE définit la taille du champ tel qu'il doit apparaître à l'écran, et le paramètre NAME est le nom que nous choisissons pour la variable destinée à mémoriser la chaîne de caractères attendue.

Un second champ d'entrée un peu différent est défini à la ligne 14 (balise TEXTAREA). Il s'agit d'un réceptacle plus vaste, destiné à accueillir des textes de plusieurs lignes. (Ce champ est automatiquement pourvu d'ascenseurs si le texte à insérer se révèle trop volumineux). Ses paramètres ROWS et COLS sont assez explicites. Entre les balises initiale et finale, on peut insérer un texte par défaut (« Mississippi » dans notre exemple).

Comme dans l'exemple précédent, la ligne 16 contient la définition du bouton qu'il faudra actionner pour transmettre les données au script CGI destinataire, lequel est décrit ci-après.

17-2-3. Un script CGI pour le traitement des données

Le mécanisme utilisé à l'intérieur d'un script CGI pour réceptionner les données transmises par un formulaire HTML est fort simple, comme vous pouvez l'analyser dans l'exemple ci-dessous :

 
Sélectionnez
1. #! /usr/bin/python
2. # Traitement des données transmises par un formulaire HTML
3.
4. import cgi                        # Module d'interface avec le serveur web
5. form = cgi.FieldStorage()         # Réception de la requête utilisateur :
6.                                   # il s'agit d'une sorte de dictionnaire
7. if form.has_key("phrase"):        # La clé n'existera pas si le champ
8.    text = form["phrase"].value    # correspondant est resté vide
9. else:
10.   text ="*** le champ phrase était vide ! ***"
11.
12.if form.has_key("visiteur"):      # La clé n'existera pas si le champ
13.   nomv = form["visiteur"].value  # correspondant est resté vide
14.else:
15.   nomv ="mais vous ne m'avez pas indiqué votre nom"
16.
17.print "Content-Type: text/html\n"
18.print """
19.<H3>Merci, %s !</H3>
20.<H4>La phrase que vous m'avez fournie était : </H4>
21.<H3><FONT Color="red"> %s </FONT></H3>""" % (nomv, text)
22.
23.histogr ={}
24.for c in text:
25.   histogr[c] = histogr.get(c, 0) +1
26.
27.liste = histogr.items()       # conversion en une liste de tuples
28.liste.sort()                  # tri de la liste
29.print "<H4>Fréquence de chaque caractère dans la phrase :</H4>"
30.for c, f in liste:
31.   print 'le caractère <B>"%s"</B> apparaît %s fois <BR>' % (c, f)

Les lignes 4 et 5 sont les plus importantes :

Le module cgi importé à la ligne 4 assure la connexion du script Python avec l'interface CGI , laquelle permet de dialoguer avec le serveur web.

A la ligne 5, la fonction FieldStorage() de ce module renvoie un objet qui contient l'ensemble des données transmises par le formulaire HTML. Nous plaçons cet objet, lequel est assez semblable à un dictionnaire classique, dans la variable form.

Par rapport à un véritable dictionnaire, l'objet placé dans form présente la différence essentielle qu'il faudra lui appliquer la méthode value() pour en extraire les données. Les autres méthodes applicables aux dictionnaires, telles la méthode has_key() , par exemple, peuvent être utilisées de la manière habituelle.

Une caractéristique importante de l'objet dictionnaire retourné par FieldStorage() est qu'il ne possédera aucune clé pour les champs laissés vides dans le formulaire HTML correspondant.

Dans notre exemple, le formulaire comporte deux champs d'entrée, auxquels nous avons associé les noms « visiteur » et « phrase ». Si ces champs ont effectivement été complétés par l'utilisateur, nous trouverons leurs contenus dans l'objet dictionnaire, aux index « visiteur » et « phrase ». Par contre, si l'un ou l'autre de ces champs n'a pas été complété, l'index correspondant n'existera tout simplement pas. Avant toute forme de traitement de valeurs, il est donc indispensable de s'assurer de la présence de chacun des index attendus, et c'est ce que nous faisons aux lignes 7 à 15.


(17) Exercice :

17.1. Pour vérifier ce qui précède, vous pouvez par exemple désactiver (en les transformant en commentaires) les lignes 7, 9, 10, 12, 14 & 15 du script. Si vous testez le fonctionnement de l'ensemble, vous constaterez que tout se passe bien si l'utilisateur complète effectivement les champs qui lui sont proposés. Si l'un des champs est laissé vide, par contre, une erreur se produit.

Note importante : le script étant lancé par l'intermédiaire d'une page web, les messages d'erreur de Python ne seront pas affichés dans cette page, mais plutôt enregistrés dans le journal des événements du serveur web. Veuillez consulter l'administrateur de ce serveur pour savoir comment vous pouvez accéder à ce journal. De toute manière, attendez-vous à ce que la recherche des erreurs dans un script CGI soit plus ardue que dans une application ordinaire.

Le reste du script est assez classique.

  • Aux lignes 17 à 21, nous ne faisons qu'afficher les données transmises par le formulaire. Veuillez noter que les variables nomv et text doivent exister au préalable, ce qui rend indispensables les lignes 9, 10, 14 & 15.
  • Aux lignes 23, 24 & 25, nous nous servons d'un dictionnaire pour construire un histogramme simple, comme nous l'avons expliqué à la page 149.
  • A la ligne 27, nous convertissons le dictionnaire résultant en une liste de tuples, pour pouvoir trier celle-ci dans l'ordre alphabétique à la ligne 28.
  • La boucle for des lignes 30 et 31 se passe de commentaires.

17-3. Un serveur web en pur Python !

Dans les pages précédentes, nous vous avons expliqué quelques rudiments de programmation CGI afin que vous puissiez mieux comprendre comment fonctionne une application web. Mais si vous voulez véritablement développer une telle application (par exemple un site web personnel doté d'une certaine interactivité), vous constaterez rapidement que l'interface CGI est un outil trop sommaire. Son utilisation telle quelle dans des scripts se révèle fort lourde, et il est donc préférable de faire appel à des outils plus élaborés.

L'intérêt pour le développement web est devenu très important, et il existe donc une forte demande pour des interfaces et des environnements de programmation bien adaptés à cette tâche. Or, même s'il ne peut pas prétendre à l'universalité de langages tels que C/C++, Python est déjà largement utilisé un peu partout dans le monde pour écrire des programmes très ambitieux, y compris dans le domaine des serveurs d'applications web. La robustesse et la facilité de mise en oeuvre du langage ont séduit de nombreux développeurs de talent, qui ont réalisé des outils de développement web de très haut niveau. Plusieurs de ces applications peuvent vous intéresser si vous souhaitez réaliser vous-même des sites web interactifs de différents types.

Les produits existants sont pour la plupart des logiciels libres. Ils permettent de couvrir une large gamme de besoins, depuis le petit site personnel de quelques pages, jusqu'au gros site commercial collaboratif, capable de répondre à des milliers de requêtes journalières, et dont les différents secteurs sont gérés sans interférence par des personnes de compétences variées (infographistes, programmeurs, spécialistes de bases de données, etc.).

Le plus célèbre de ces produits est le logiciel Zope, déjà adopté par de grands organismes privés et publics pour le développement d'intranets et d'extranets collaboratifs. Il s'agit en fait d'un système serveur d'applications, très performant, sécurisé, presqu'entièrement écrit en Python, et que l'on peut administrer à distance à l'aide d'une simple interface web. Il ne nous est pas possible de décrire l'utilisation de Zope dans ces pages : le sujet est trop vaste, et un livre entier n'y suffirait pas. Sachez cependant que ce produit est parfaitement capable de gérer de très gros sites d'entreprise en offrant d'énormes avantages par rapport à des solutions classiques telles que PHP ou Java.

D'autres outils moins ambitieux mais tout aussi intéressants sont disponibles. Tout comme Zope, la plupart d'entre eux peuvent être téléchargés librement depuis l'internet. Le fait qu'ils soient écrits en Python assure en outre leur portabilité : vous pourrez donc les employer aussi bien sous Windows que sous Linux ou MacOs. Chacun d'eux peut être utilisé en conjonction avec un serveur web « classique » tel que Apache ou Xitami (c'est préférable si le site à réaliser est destiné à supporter une charge de connexions très importante), mais certains d'entre eux intègrent en outre leur propre serveur web, ce qui leur permet de fonctionner également de manière tout à fait autonome. Cette possibilité se révèle particulièrement intéressante au cours de la mise au point d'un site, car elle facilite la recherche des erreurs.

Cette totale autonomie alliée à la grande facilité de leur mise en oeuvre fait de ces produits de fort bonnes solutions pour la réalisation de sites web d'intranet spécialisés, notamment dans des petites et moyennes entreprises, des administrations, ou dans des écoles. Si vous souhaitez développer une application Python qui soit accessible par l'intermédiaire d'un simple navigateur web, via un intranet d'entreprise (ou même via l'internet, si la charge prévisible n'est pas trop importante), ces applications sont faites pour vous.

Il en existe une grande variété : Poor man's Zope, Spyce, Karrigell, Webware, Cherrypy, Quixote, Twisted, etc. Choisissez en fonction de vos besoins : vous n'aurez que l'embarras du choix. Dans les lignes qui suivent, nous allons décrire une petite application web fonctionnant à l'aide de Karrigell. Vous pouvez trouver ce système à l'adresse : http://karrigell.sourceforge.net. Il s'agit d'une solution de développement web simple, bien documentée en anglais et en français (son auteur, Pierre Quentel, est en effet originaire de Bretagne, tout comme le mot karrigell, d'ailleurs, lequel signifie « charrette »).

17-3-1. Installation de Karrigell

L'installation de Karrigell est un jeu d'enfant : il vous suffit d'extraire dans un répertoire quelconque le fichier archive que vous aurez téléchargé depuis l'internet. L'opération de désarchivage crée automatiquement un sous-répertoire nommé Karrigell-numéro de version. C'est ce répertoire que nous considérerons comme répertoire racine dans les lignes qui suivent.

Si vous ne comptez pas utiliser le serveur de bases de données Gadfly69 qui vous est fourni en complément de Karrigell lui-même, c'est tout ! Sinon, entrez dans le sous-répertoire gadfly-1.0.0 et lancez la commande : python setup.py install (Sous Linux, il faut être root). Vous devez effectuer cette opération si vous souhaitez visualiser la totalité de la démonstration intégrée.

69 Voyez le chapitre précédent : Gadfly est un serveur de bases de données écrit en Python.

17-3-2. Démarrage du serveur :

Il s'agit donc bel et bien de mettre en route un serveur web, auquel vous pourrez accéder ensuite à l'aide d'un navigateur quelconque, localement ou par l'intermédiaire d'un réseau. Avant de le faire démarrer, il est cependant conseillé de jeter un petit coup d'oeil dans son fichier de configuration, lequel se nomme Karrigell.ini et se trouve dans le répertoire-racine.

Par défaut, Karrigell attend les requêtes http sur le port n° 80. Et c'est bien ce numéro de port que la plupart des logiciels navigateurs utilisent eux-mêmes par défaut. Cependant, si vous installez Karrigell sur une machine Linux dont vous n'êtes pas l'administrateur, vous n'avez pas le droit d'utiliser les numéros de port inférieurs à 1024 (pour des raisons de sécurité). Si vous êtes dans ce cas, vous devez donc modifier le fichier de configuration afin que Karrigell utilise un numéro de port plus élevé. En général, vous choisirez d'enlever simplement le caractère # au début de la ligne 39, ce qui activera l'utilisation du n° de port 8080. Plus tard, vous souhaiterez peut-être encore modifier le fichier de configuration afin de modifier l'emplacement du répertoire racine pour votre site web (par défaut, c'est le répertoire du serveur lui-même).

Une fois le fichier de configuration modifié, entrez dans le répertoire racine du serveur, si vous n'y êtes pas déjà, et lancez simplement la commande :

python Karrigell.py

C'est tout. Votre serveur Karrigell se met en route, et vous pouvez en vérifier le fonctionnement tout de suite à l'aide de votre navigateur web préféré. Si vous lancez celui-ci sur la même machine que le serveur, vous le dirigerez vers une adresse telle que : http://localhost:8080/index.html, « localhost » étant le terme consacré pour désigner la machine locale, « 8080 » le numéro de port choisi dans le fichier de configuration, et « index.html » le nom du fichier qui contient la page d'accueil du site. Par contre, si vous voulez accéder à cette même page d'accueil depuis une autre machine, vous devrez (dans le navigateur de celle-ci) indiquer le nom ou l'adresse IP du serveur, en lieu et place de localhost.

Avec l'adresse indiquée au paragraphe précédent70, vous atteindrez la page d'accueil d'un site de démonstration de Karrigell, qui est déjà pré-installé dans le répertoire racine. Vous y retrouverez la documentation de base, ainsi que toute une série d'exemples.

Dans ce qui précède, il est sous-entendu que vous avez lancé le serveur depuis une console texte, ou depuis une fenêtre de terminal. Dans un cas comme dans l'autre, les messages de contrôle émis par le serveur apparaîtront dans cette console ou cette fenêtre. C'est là que vous pourrez rechercher des messages d'erreur éventuels. C'est là aussi que vous devrez intervenir si vous voulez arrêter le serveur (avec la combinaison de touches CTRL-C).

70 Si vous avez laissé en place le n° de port par défaut (80), il est inutile de le rappeler dans les adresses, puisque c'est ce n° de port qui est utilisé par défaut par la plupart des navigateurs. Une autre convention consiste à considérer que la page d'accueil d'un site Web se trouve presque toujours dans un fichier nommé index.htm ou index.html, Lorsque l'on souhaite visiter un site Web en commençant par sa page d'accueil, on peut donc en général omettre ce nom dans l'adresse. Karrigell respecte cette convention, et vous pouvez donc vous connecter en utilisant une adresse simplifiée telle que : http://localhost:8080 ou même : http://localhost (si le n° de port est 80).

17-3-3. Ébauche de site web

Essayons à présent de réaliser notre propre ébauche de site web. À la différence d'un serveur web classique, Karrigell peut gérer non seulement des pages HTML statiques (fichiers .htm, .html, .gif, . jpg, .css) mais également :

  • des scripts Python (fichiers .py)
  • des scripts hybrides Python Inside HTML (fichiers .pih)
  • des scripts hybrides HTML Inside Python (fichiers .hip)

Laissons de côté les scripts hybrides, dont vous pourrez étudier vous-même la syntaxe (par ailleurs très simple) si vous vous lancez dans une réalisation d'une certaine importance (ils pourront vous faciliter la vie). Dans le contexte limité de ces pages, nous nous contenterons de quelques expériences de base avec des scripts Python ordinaires.

Comme tous les autres éléments du site (fichiers .html, .gif, .jpeg, etc.), ces scripts Python devront être placés dans le répertoire racine71. Vous pouvez tout de suite effectuer un test élémentaire en rédigeant un petit script d'une seule ligne, tel que :

 
Sélectionnez
print "Bienvenue sur mon site web !"

Sauvegardez ce script sous le nom hello.py dans le répertoire racine, puis entrez l'adresse : http://localhost/hello.py (ou même : http://localhost/hello - l'extension .py peut être omise) dans votre navigateur. Vous devriez y voir apparaître le message. Cela signifie donc que dans l'environnement Karrigell, la sortie de l'instruction print est redirigée vers la fenêtre du navigateur client, plutôt que la console (ou la fenêtre de terminal) du serveur.

Étant donné que l'affichage a lieu dans une fenêtre de navigateur web, vous pouvez utiliser toutes les ressources de la syntaxe HTML afin d'obtenir un formatage déterminé. Vous pouvez par exemple afficher un petit tableau de 2 lignes et 3 colonnes, avec les instructions suivantes :

 
Sélectionnez
print """
<TABLE BORDER="1" CELLPADDING="5">
<TR> <TD> Rouge </TD> <TD> Vert </TD> <TD> Bleu </TD> </TR>
<TR> <TD> 15 % </TD> <TD> 62 % </TD> <TD> 23 % </TD> </TR>
</TABLE>
"""

Rappelons que la balise TABLE définit un tableau. Son option BORDER spécifie la largeur des bordures de séparation, et CELLPADDING l'écart à réserver autour du contenu des cellules. Les Balises TR et TD (Table Row et Table Data) définissent les lignes et les cellules du tableau.

Vous pouvez bien entendu utiliser également toutes les ressources de Python, comme dans l'exemple cidessous où nous construisons une table des sinus, cosinus et tangentes des angles compris entre 0° et 90°, à l'aide d'une boucle classique.

Ligne 7 : Nous nous servons de la fonction range() pour définir la gamme d'angles à couvrir (de zéro à 60 degrés par pas de 10).

Ligne 9 : Les fonctions trigonométriques de Python nécessitent que les angles soient exprimés en radians. Il faut donc effectuer une conversion.

Ligne 12 : Chaque ligne du tableau comporte quatre valeurs, lesquelles sont mises en forme à l'aide du système de formatage des chaînes de caractères décrit déjà à la page 130 : le marqueur de conversion « %8.7f » force un affichage à 8 chiffres, dont 7 après la « virgule » décimale. Le marqueur « %8.7g » fait à peu près la même chose, mais passe à la notation scientifique lorsque c'est nécessaire.
Image non disponible
 
Sélectionnez
1. from math import sin, cos, tan, pi
2.
3. # Construction de l'en-tête du tableau avec les titres de colonnes :
4. print """<TABLE BORDER="1" CELLPADDING="5">
5. <TR><TD>Angle</TD><TD>Sinus</TD><TD>Cosinus</TD><TD>Tangente</TD></TR>"""
6.
7. for angle in range(0,62,10):    
8.     # conversion des degrés en radians :
9.     aRad = angle * pi / 180
10.    # construction d'une ligne de tableau, en exploitant le formatage des
11.    # chaînes de caractères pour fignoler l'affichage :
12.    print "<TR><TD>%s</TD><TD>%8.7f</TD><TD>%8.7f</TD><TD>%8.7g</TD></TR>"\
13.          % (angle, sin(aRad), cos(aRad), tan(aRad))
14.    
15.print "</TABLE>"

À ce stade, vous vous demandez peut-être où se situe la différence entre ce que nous venons d'expérimenter ici et un script CGI classique (tels ceux des pages 266 et suivantes).

L'intérêt de travailler dans un environnement plus spécifique tel que Karrigell apparaît cependant très vite si vous faites des erreurs. En programmation CGI classique, les messages d'erreur émis par l'interpréteur Python ne s'affichent pas dans la fenêtre du navigateur. Ils sont enregistrés dans un fichier journal du serveur (Apache, par exemple), ce qui ne facilite pas leur consultation.

Avec un outil comme Karrigell, par contre, vous disposez d'une signalisation très efficace, ainsi que d'un outil de déboguage complet. Faites l'expérience d'introduire une petite erreur dans le script ci-dessus, et relancez votre navigateur sur la page modifiée. Par exemple, en supprimant le double point à la fin de la ligne 7, nous avons obtenu nous-mêmes l'affichage suivant :

Image non disponible

En cliquant sur le bouton « Debug », on obtient encore une foule d'informations complémentaires (affichage du script complet, variables d'environnement, etc.).

71 ...ou bien dans des sous-répertoires du répertoire racine, comme il est d'usage de le faire lorsque l'on cherche à structurer convenablement le site en construction. Il vous suffira dans ce cas d'inclure le nom de ces sousrépertoires dans les adresses correspondantes.

17-3-4. Prise en charge des sessions

Lorsque l'on élabore un site web interactif, on souhaite fréquemment que la personne visitant le site puisse s'identifier et fournir un certain nombre de renseignements tout au long de sa visite dans différentes pages (l'exemple type étant le remplissage d'un « caddy » au cours de la consultation d'un site commercial), toutes ces informations étant conservées quelque part jusqu'à la fin de sa visite. Et il faut bien entendu réaliser cela indépendamment pour chaque client connecté.

Il serait possible de transmettre les informations de page en page à l'aide de champs de formulaires cachés, mais ce serait compliqué et très contraignant. Il est préférable que le système serveur soit doté d'un mécanisme spécifique, qui attribue à chaque client une session particulière. Karrigell réalise cet objectif par l'intermédiaire de cookies. Lorsqu'un nouveau visiteur du site s'identifie, le serveur génère un cookie appelé sessionId et l'envoie au navigateur web, qui l'enregistre. Ce cookie contient un « identifiant de session » unique, auquel correspond un objetsession sur le serveur. Lorsque le visiteur parcourt les autres pages du site, son navigateur renvoie à chaque fois le contenu du cookie au serveur, et celui-ci peut donc retrouver l'objet-session correspondant, à l'aide de son identifiant. L'objet-session reste donc disponible tout au long de la visite de l'internaute : il s'agit d'un objet Python ordinaire, dans lequel on mémorise un nombre quelconque d'informations sous forme d'attributs.

Au niveau de la programmation, voici comment cela se passe :

Pour chaque page dans laquelle vous voulez consulter ou modifier une information de session, vous commencez par créer un objet de la classe Session() :

 
Sélectionnez
objet_session = Session()

Si vous êtes au début de la session, Karrigell génère un identifiant unique, le place dans un cookie et envoie celui-ci au navigateur web. Vous pouvez alors ajouter un nombre quelconque d'attributs à l'objet-session :

 
Sélectionnez
objet_session.nom = "Jean Dupont"

Dans les autres pages, vous procédez de la même manière, mais l'objet produit dans ce cas par la classe Session() n'est pas nouveau : c'est l'objet créé en début de session, retrouvé en interne par le serveur grâce à son identifiant relu dans le cookie. Vous pouvez accéder aux valeurs de ses attributs, et aussi en ajouter de nouveaux :

 
Sélectionnez
obj_sess = Session()               # récupérer l'objet indiqué par le cookie
om = obj_sess.nom                  # retrouver la valeur d'un attribut existant
obj_sess.article = 49137           # ajouter un nouvel attribut

Les objets-sessions prennent aussi en charge une méthode close(), qui a pour effet d'effacer l'information de session. Vous n'êtes cependant pas obligé de clore explicitement les sessions : Karrigell s'assure de toute façon qu'il n'y ait jamais plus de 1000 sessions simultanées : il efface les plus anciennes quand on arrive à la 1000ème.


Exemple de mise en oeuvre :

Sauvegardez les trois petits scripts ci-dessous dans le répertoire-racine. Le premier génère un formulaire HTML similaire à ceux qui ont été décrits plus haut. Nommez-le sessionTest1.py :

 
Sélectionnez
1. # Affichage d'un formulaire d'inscription :
2.
3. print """
4. <H3>Veuillez vous identifier, SVP :</H3>
5.
6. <FORM ACTION = "sessionTest2.py">
7. Votre nom : <INPUT NAME = "nomClient"> <BR> 
8. Votre prénom : <INPUT NAME = "prenomClient"> <BR>
9. Votre sexe (m/f) : <INPUT NAME = "sexeClient" SIZE ="1"> <BR>
10.<INPUT TYPE = "submit" VALUE = "OK">
11.</FORM>"""

Le suivant sera nommé sessionTest2.py. C'est le script mentionné dans la balise d'ouverture du formulaire ci-dessus à la ligne 6, et qui sera invoqué lorsque l'utilisateur actionnera le bouton mis en place à la ligne 10. Ce script recevra les valeurs entrées par l'utilisateur dans les différents champs du formulaire, par l'intermédiaire d'un dictionnaire de requête situé dans la variable d'environnement QUERY de Karrigell72 :

 
Sélectionnez
1. obSess = Session()
2.
3. obSess.nom = QUERY["nomClient"]
4. obSess.prenom = QUERY["prenomClient"]
5. obSess.sexe = QUERY["sexeClient"]
6.
7. if obSess.sexe.upper() == "M":
8.     vedette ="Monsieur"
9. else:
10.    vedette ="Madame"
11.print "<H3> Bienvenue, %s %s </H3>" % (vedette, obSess.nom)
12.print "<HR>"
13.print """
14.<a href = "sessionTest3.py"> Suite...</a>"""

La première ligne de ce script crée l'objet-session, génère pour lui un identifiant unique, et expédie celui-ci au navigateur sous la forme d'un cookie.

Dans les lignes 3, 4, 5, on récupère les valeurs entrées dans les champs du formulaire précédent, en utilisant leurs noms comme clés d'accès au dictionnaire de requêtes.

La ligne 14 définit un lien http pointant vers le troisième script, nommé sessionTest3.py :

 
Sélectionnez
1. suiviSess = Session()           # retrouver l'objet-session
2. suiviSess.article = 12345       # lui ajouter des attributs
3. suiviSess.prix = 43.67
4.
5. print """
6. <H3> Page suivante </H3> <HR>
7. Suivi de la commande du client : <BR> %s %s <BR>
8. Article n° %s, Prix : %s <HR>
9. """ % (suiviSess.prenom, suiviSess.nom,
10.       suiviSess.article, suiviSess.prix)

Dirigez votre navigateur web vers l'adresse : http://localhost:8080/sessionTest1. Entrez des valeurs de votre choix dans les champs du formulaire, et cliquez sur le bouton OK :

Image non disponible Image non disponible

Comme attendu, les informations entrées dans le formulaire sont transmises à la deuxième page. À présent, si vous cliquez sur le lien : « Suite... » dans celle-ci, vous dirigez encore une fois votre navigateur vers une nouvelle page, mais celle-ci n'aura fait l'objet d'aucune transmission de données (puisqu'on n'y accède pas par l'intermédiaire d'un formulaire). Dans le script sessionTest3.py qui génère cette page, vous ne pouvez donc pas utiliser la variable QUERY pour retrouver les informations entrées par le visiteur.

C'est ici qu'intervient le mécanisme des objets-sessions. Lors du lancement de ce troisième script, le cookie mémorisé par le navigateur est relu par le serveur, ce qui lui permet de régénérer l'objet-session créé dans le script précédent.

Image non disponible

Analysez les trois premières lignes du script sessionTest3.py : l'objet suiviSess instancié à partit de la classe Session() est l'objet-session régénéré. Il contient les informations sauvegardées à la page précédente, et on peut lui en ajouter d'autres dans des attributs supplémentaires.

Vous aurez compris que vous pouvez désormais récupérer toutes ces informations de la même manière dans n'importe quelle autre page, car elles persisteront jusqu'à ce que l'utilisateur termine sa visite du site, à moins que vous ne fermiez vous-même cette session par programme, à l'aide de la méthode close() évoquée plus haut.

Exercice :

17.2. Ajoutez au script précédent un lien vers une quatrième page, et écrivez le script qui générera celle-ci. Les informations devront cette fois être affichées dans un tableau :

Nom Prénom Sexe Article Prix
         

72 Karrigell met en place un certain nombre de variables globales dont les noms sont en majuscules pour éviter un conflit éventuel avec les vôtres. Celle-ci joue le même rôle que la fonction FieldStorage() du module cgi. Veuillez consulter la documentation de Karrigell si vous souhaitez obtenir des explications plus détaillées.

17-3-5. Autres développements

Nous terminons ici cette brève étude de Karrigell, car il nous semble vous avoir expliqué l'essentiel de ce qu'il vous faut connaître pour démarrer. Si vous désirez en savoir davantage, il vous suffira de consulter la documentation et les exemples fournis avec le produit. Comme nous l'avons déjà signalé plus haut, l'installation de Karrigell inclut l'installation du système de bases de données Gadfly. Vous pouvez donc très rapidement et très aisément réaliser un site interactif permettant la consultation à distance d'un ensemble de données quelconques, en admettant bien entendu que la charge de requêtes de votre site reste modérée, et que la taille de la base de données elle-même ne devienne pas gigantesque. N'espérez pas gérer à l'aide de Karrigell un site commercial susceptible de traiter plusieurs millions de requêtes journalières !

Si vous ambitionnez de réaliser ce genre de choses, il vous faudra étudier d'autres offres logicielles, comme par exemple CherryPy ou Zope associés à Apache pour le système serveur, et SQLite, MySQL ou PostgreSQL pour le gestionnaire de bases de données.


précédentsommairesuivant

Licence Creative Commons
Le contenu de cet article est rédigé par Gérard Swinnen et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.