Serveur HTTP Python + CGI
Un serveur HTTP Python permet d’afficher des pages HTML.
Ces pages seront disponibles sur le serveur, et envoyées à la demande vers le client. Elles peuvent contenir du code, mais exécutable du coté client uniquement (JavaScript) !
Pour exécuter du code coté serveur, il faut que le serveur HTTP soit capable de lancer l’exécution de code (Python, Perl, C, …), dont les scripts se trouvent à sa disposition.
On peut, par exemple, utiliser une interface CGI :
Structure du serveur
D’une manière générale, il convient de bien organiser les fichiers qui constitueront l’application :
|
|
Serveur avec CGI
On a d’abord besoin d’un serveur HTTP :
import http.server server = http.server.HTTPServer # classe du serveur HTTP
Ensuite, il faut utiliser un gestionnaire de requêtes, prenant en charge le CGI, auquel il faut indiquer le chemin (relatif !) des scripts CGI :
handler = http.server.CGIHTTPRequestHandler # classe du gestionnaire handler.cgi_directories = ["/cgi-bin"]
On choisit quelle(s) interface(s) réseau utiliser (rappel : « » = toutes les interfaces) et sur quel port écouter :
PORT = 8080 server_address = ("", PORT)
Et enfin on instancie le serveur, en lui indiquant son adresse et le gestionnaire de requêtes à utiliser :
httpd = server(server_address, handler) # objet "serveur"
Et on le démarre :
httpd.serve_forever()
- Créer un fichier Python serveur.py réalisant cette fonction Serveur.
- Tester son fonctionnement :
- Créer un fichier index.html à la racine du dossier de l’application :
<!DOCTYPE html> <html> Bonjour Blaise ! </html>
- Depuis un autre poste du réseau, avec un navigateur Web, taper l’adresse IP du serveur : <IP serveur>:8080
- Créer un fichier index.html à la racine du dossier de l’application :
Les scripts CGI
On les place dans un sous dossier cgi-bin .
Exécution
Ils doivent être exécutables ! Sous Linux, cela implique de leur donner l’attribut x .
Pour que l’interface CGI puisse exécuter les scripts demandés, ceux-ci doivent contenir le chemin vers l’interpréteur Python, que l’on indique à la première ligne du script :
#!usr/bin/python3
Données
Pour que les scripts Python aient la capacité de recevoir les données (en provenance de requêtes GET ou POST), il faut utiliser la bibliothèque Python cgi :
import cgi
Puis déclarer le type de donnée qui sera envoyé :
print("Content-Type: text/html; charset=utf-8\n")
Ainsi, les arguments de la requête peuvent être récupérés dans une variable de type FieldStorage, grâce à cette commande :
data = cgi.FieldStorage()
Ainsi chaque argument de la requête (quelle que soit la méthode, GET ou POST) peut être obtenu ainsi, par exemple :
<input type="text" name="nom" value="" />
nom = data.getvalue('nom')
Page HTML
Le script renvoie le contenu de la page HTML grâce à des fonctions print() :
print("""<!DOCTYPE html> <html> Bonjour Blaise ! </html>""")
Test
Pour s’assurer que le script est exécutable, on peut lancer cette commande (sous Linux, depuis le dossier racine de l’application) :
$ ./cgi-bin/index.py
Le script suivant comporte une page HTML contenant un formulaire qui permet, par une méthode POST, d’envoyer une expression mathématique, que le serveur doit se charger d’évaluer.
#!/usr/bin/python3 import cgi page = """<!DOCTYPE html> <html> <body> <h1>Calculatrice</h1> <form action="calcul.py" method="post"> <input type="text" name="formule" value="" /> <input type="submit" name="calc" value="Calculer"> </form> </body> </html>"""
- Compléter le script Python/CGI permettant de réaliser une simple calculatrice.
Erreurs fréquentes
Exec format error: ‘index.py’
Problème de format de fichier : les lignes du script se terminent par CR/LF (format Windows) au lieu de LF (format UNIX).
Utiliser un outil de conversion :
$ dos2unix index.py
Ou utiliser les outils intégrés dans l’éditeur :
exemple Notpad++ : Edition/Convertir les sauts de ligne/Convertir en format UNIX (LF)
Permission denied: ‘index.py’
Il faut que le script python soit exécutable.
Sous Linux, il faut lui donner cet attribut par la commande :
$ sudo chmod +x index.py
No such file or directory: ‘index.py’
L’interface CGI n’arrive pas à lancer index.py , non parce qu’il ne le trouve pas (on peut facilement vérifier que le fichier existe bien), mais parce qu’il ne trouve pas l’interpréteur, c’est à dire Python !!
Identifier l’emplacement de l’interpréteur Python :
$ which python3
En principe, sur un Raspberry Pi, cette commande renvoie /usr/bin/python3
Puis rajouter cette ligne au début du fichier index.py (et de tous les fichiers Python qui doivent être lancés par la CGI) :
#!/usr/bin/python3