Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»

Mise à jour du livre

Le chapitre "Autoriser la livraison des fichiers HTML" a été mis à jour. ..

Si vous voulez en savoir plus, veuillez "aimer" ou "me suivre" dans Book ;-)


Ce qui suit est un extrait du contenu du livre.


Interpréter la requête et lui permettre de renvoyer le fichier HTML spécifié

Jusqu'au chapitre précédent, nous avons pu créer un serveur capable de renvoyer une réponse au format HTTP.

Cependant, il n'implémente aucun traitement pour interpréter la requête envoyée depuis le navigateur, donc le corps renvoie toujours «Cela fonctionne!

Cela ne suffit pas, alors préparez à l'avance un fichier HTML séparément du code source du programme afin que le fichier spécifié par le chemin de la requête puisse être renvoyé comme corps de la réponse.

Il s'agit d'une fonction dite de * distribution de fichier statique *.

Il n'est pas nécessaire de publier le code source du serveur via le serveur, alors ** placez les fichiers que vous souhaitez publier via le serveur dans le répertoire study / static / **

Exemple) Le chemin de la requête est / index.html => Le contenu de study / static / index.html est renvoyé sous forme de corps de réponse

Etc.

Code source

Il n'y a rien d'autre à expliquer, alors passons directement au code source.

Voici une version améliorée du fichier HTML préparée à l'avance afin qu'il puisse être renvoyé en tant que corps de réponse.

study/WebServer.py

import os
import socket
from datetime import datetime


class WebServer:
    """
Une classe qui représente un serveur Web
    """
    #Répertoire avec fichiers exécutables
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    #Répertoire pour placer les fichiers à livrer de manière statique
    DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")

    def serve(self):
        """
Démarrez le serveur
        """

        print("===Démarrez le serveur===")

        try:
            #Générer une socket
            server_socket = socket.socket()
            server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

            #Attribuez le socket au port 8080 de localhost
            server_socket.bind(("localhost", 8080))
            server_socket.listen(10)

            #Attendez une connexion de l'extérieur et établissez une connexion s'il y a une connexion
            print("===Attendez une connexion du client===")
            (client_socket, address) = server_socket.accept()
            print(f"===La connexion avec le client est complète à distance_address: {address} ===")

            #Récupérez les données envoyées par le client
            request = client_socket.recv(4096)

            #Ecrire les données envoyées par le client dans un fichier
            with open("server_recv.txt", "wb") as f:
                f.write(request)

            #La demande entière
            # 1.Ligne de demande(La première ligne)
            # 2.Demander un corps(2e ligne vierge)
            # 3.Demander un corps(Ligne vide ~)
            #Analyser
            request_line, remain = request.split(b"\r\n", maxsplit=1)
            request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)

            #Analyser la ligne de demande
            method, path, http_version = request_line.decode().split(" ")

            #Au début du chemin/Et gardez-le comme un chemin relatif
            relative_path = path.lstrip("/")
            #Obtenez le chemin du fichier
            static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)

            #Générer le corps de la réponse à partir du fichier
            with open(static_file_path, "r") as f:
                response_body = f.read()

            #Générer une ligne de réponse
            response_line = "HTTP/1.1 200 OK\r\n"
            #Générer un en-tête de réponse
            response_header = ""
            response_header += f"Date: {datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')}\r\n"
            response_header += "Host: HenaServer/0.1\r\n"
            response_header += f"Content-Length: {len(response_body.encode())}\r\n"
            response_header += "Connection: Close\r\n"
            response_header += "Content-Type: text/html\r\n"

            #Générer la réponse entière
            response = (response_line + response_header + "\r\n" + response_body).encode()

            #Envoyer une réponse au client
            client_socket.send(response)

            #Mettre fin à la communication
            client_socket.close()

        finally:
            print("===Arrêtez le serveur.===")


if __name__ == '__main__':
    server = WebServer()
    server.serve()

https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/WebServer.py

De plus, pour vérifier si le programme fonctionne correctement, vous devez préparer un fichier HTML séparément, alors créez-le également. Créez un nouveau répertoire static directement sous le répertoire study et créez-y un index.html.

Comme c'est un gros problème, je l'ai changé pour quelque chose qui n'est pas la rondelle d'Apache. Vous pouvez utiliser ce que vous voulez. Cependant, si vous changez le nom de fichier, cela ne fonctionnera pas comme décrit dans ce manuel, laissez donc le nom de fichier comme index.html.

study/static/index.html

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>HenaServer</title>
</head>
<body>
  <h1>Welcome to HenaServer!</h1>
</body>
</html>

https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/static/index.html

Commentaire

Lignes 10-13: Définition du répertoire pour mettre les fichiers HTML

Définit le répertoire dans lequel les fichiers HTML seront placés (appelé DOCUMENT_ROOT).

    #Répertoire avec fichiers exécutables
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    #Répertoire pour placer les fichiers à livrer de manière statique
    DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")

Cela peut être difficile à lire si vous n'êtes pas familier avec les chemins de fichiers en python, --BASE_DIR: chemin absolu de study vers le répertoire --DOCUMENT_ROOT: chemin absolu du répertoire study / static

Est stocké.

Lignes 43-61: Génère un corps de réponse à partir d'un fichier

C'est le principal.

La requête HTTP est analysée (décomposée) et les informations de chemin sont extraites.

Après cela, le fichier est lu en fonction du chemin et le corps de la réponse est généré.

            #La demande entière
            # 1.Ligne de demande(La première ligne)
            # 2.Demander un corps(2e ligne vierge)
            # 3.Demander un corps(Ligne vide ~)
            #Analyser
            request_line, remain = request.split(b"\r\n", maxsplit=1)
            request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)

            #Analyser la ligne de demande
            method, path, http_version = request_line.decode().split(" ")

            #Au début du chemin/Et gardez-le comme un chemin relatif
            relative_path = path.lstrip("/")
            #Obtenez le chemin du fichier
            static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)

            #Générer le corps de la réponse à partir du fichier
            with open(static_file_path, "r") as f:
                response_body = f.read()

Après avoir obtenu le chemin, je le combine avec DOCUMENT_ROOT pour obtenir le static_file_path, mais sachez que j'ai supprimé le premier/avant cela.

C'est parce que la spécification os.path.join (base, path) de python ignore le premier argument base si le second argument path reçoit un chemin absolu commençant par/. est.

Essayez de bouger

Si vous savez ce que vous voulez faire, le code source n'est pas difficile, alors déplaçons-le immédiatement.


Continuez avec Book!

Chapitre "Rendre les fichiers HTML disponibles"

Recommended Posts

Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
[Introduction à l'application Udemy Python3 +] 43. instruction for else
Introduction à Python pour, pendant
[Introduction à l'application Udemy Python3 +] 42. pour instruction, instruction break et instruction continue
[Présentation de l'application Udemy Python3 +] 58. Lambda
[Présentation de l'application Udemy Python3 +] 31. Commentaire
[Présentation de l'application Udemy Python3 +] 57. Décorateur
[Présentation de l'application Udemy Python3 +] 56. Clôture
[Présentation de l'application Udemy Python3 +] 59. Générateur
[Introduction à l'application Udemy Python3 +] Résumé
Premiers pas avec Python pour les non-ingénieurs
Explication facile à comprendre de l'application Web Python (Django) même pour les débutants (5) [Introduction au fonctionnement de la base de données avec le shell Django]
[Introduction à Udemy Python3 + Application] 18. Méthode List
[Introduction à Udemy Python3 + Application] 63. Notation d'inclusion du générateur
[Introduction à l'application Udemy Python3 +] 28. Type collectif
[Introduction à Udemy Python3 + Application] 25. Méthode de type dictionnaire
[Introduction à l'application Udemy Python3 +] 33. instruction if
[Introduction à Udemy Python3 + Application] 13. Méthode de caractères
[Introduction à l'application Udemy Python3 +] 55. Fonctions intégrées
[Introduction à l'application Udemy Python3 +] 48. Définition des fonctions
[Introduction à l'application Udemy Python3 +] 10. Valeur numérique
[Introduction à l'application Udemy Python3 +] 21. Type Taple
[Introduction à l'application Udemy Python3 +] 45. fonction enumerate
[Introduction à l'application Udemy Python3 +] 41. fonction d'entrée
[Introduction à l'application Udemy Python3 +] 17. Opération de liste
[Introduction à l'application Udemy Python3 +] 65. Gestion des exceptions
[Introduction à l'application Udemy Python3 +] 11. Chaîne de caractères
[Introduction à l'application Udemy Python3 +] 44. fonction range
[Introduction à l'application Udemy Python3 +] 46. fonction zip
[Introduction à l'application Udemy Python3 +] 24. Type de dictionnaire
[Python] Conception d'applications Web pour l'apprentissage automatique
Une introduction à Python pour l'apprentissage automatique
[Introduction à Udemy Python3 + Application] 8. Déclaration de variable
[Introduction à Udemy Python3 + Application] 29. Méthode Set
[Introduction à l'application Udemy Python3 +] 16. Type de liste
[Introduction à Udemy Python3 + Application] 61. Notation d'inclusion de dictionnaire
[Introduction à l'application Udemy Python3 +] 22. Déballage de taples
Une introduction à Python pour les programmeurs en langage C
[Introduction à Udemy Python3 + Application] 47. Traitez le dictionnaire avec une instruction for
Prenons la version gratuite "Introduction à Python pour l'apprentissage automatique" en ligne jusqu'au 27/04
Une introduction aux applications Web Python auto-conçues pour un ingénieur Web de troisième année paresseux
Explication facile à comprendre de l'application Web Python (Django) même pour les débutants (4) [Route setting / Introduction to MTV design patterns]
Mis à jour vers Python 2.7.9
[Introduction à Udemy Python3 + Application] 26. Copie du dictionnaire
[Introduction à Udemy Python3 + Application] 60. Notation d'inclusion de liste
[Introduction à Udemy Python3 + Application] 19. Copie de la liste
[Introduction à Udemy Python3 + Application] 38. Lors du jugement Aucun
Introduction à Tornado (1): Framework Web Python démarré avec Tornado
[Introduction à l'application Udemy Python3 +] 40. Instruction while else
[Introduction à Udemy Python3 + Application] 62. Définir la notation d'inclusion
Étapes pour développer une application Web en Python
[Introduction à l'application Udemy Python3 +] 64. Espace de noms et portée
[Introduction à Python3 Jour 20] Chapitre 9 Démêler le Web (9.1-9.4)
[Introduction à Udemy Python3 + Application] 67. Arguments de ligne de commande
[Introduction à l'application Udemy Python3 +] 9. Tout d'abord, imprimez avec print