Exemple Python: Code serveur Python (server.py) – Bien choisir son serveur d impression

Author: Titanfall —

Short summary: Cette section fournit le code du serveur Python décrit dans Exemple Python (client HTML5 et Python                                        Serveur). "" " Exemple d'application Python 2.7 + / 3.3 + Cette application se compose d'un serveur HTTP 1.1 utilisant le transfert HTTP fragmenté codage (https://tools.ietf.org/html/rfc2616#section-3.6.1) et un HTML5 minimal interface utilisateur qui interagit avec elle. Le but de […]

Quick overview

Site
Tutos GameServer
Canonical URL
https://tutos-gameserver.fr/2020/03/30/exemple-python-code-serveur-python-server-py-bien-choisir-son-serveur-d-impression/
LLM HTML version
https://tutos-gameserver.fr/2020/03/30/exemple-python-code-serveur-python-server-py-bien-choisir-son-serveur-d-impression/llm
LLM JSON version
https://tutos-gameserver.fr/2020/03/30/exemple-python-code-serveur-python-server-py-bien-choisir-son-serveur-d-impression/llm.json
Manifest
https://tutos-gameserver.fr/llm-endpoints-manifest.json
Estimated reading time
9 minutes (498 seconds)
Word count
1658

Key points

Structured content

Cette section fournit le code du serveur Python décrit dans Exemple Python (client HTML5 et Python                                        Serveur). "" " Exemple d'application Python 2.7 + / 3.3 +

Cette application se compose d'un serveur HTTP 1.1 utilisant le transfert HTTP fragmenté codage (https://tools.ietf.org/html/rfc2616#section-3.6.1) et un HTML5 minimal interface utilisateur qui interagit avec elle.

Le but de cet exemple est de commencer à diffuser le discours vers le client (le Interface Web HTML5) dès que le premier morceau de discours consommable est renvoyé dans afin de commencer à lire l'audio dès que possible. Pour les cas d'utilisation où une faible latence et réactivité sont des exigences fortes, c'est l'approche recommandée.

La documentation du service contient des exemples de cas d'utilisation sans streaming où attendre la fin de la synthèse vocale et récupérer tout le flux audio sont à la fois une option.

Pour tester l'application, exécutez 'python server.py' puis ouvrez l'URL affiché dans le terminal dans un navigateur Web (voir index.html pour une liste des navigateurs pris en charge). L'adresse et le port du serveur peuvent être transmis comme paramètres à server.py. Pour plus d'informations, exécutez: 'python server.py -h' "" " depuis argparse import ArgumentParser à partir des collections importées namedtuple de la fermeture de l'import contextlib depuis io import BytesIO depuis les vidages d'importation json en tant que json_encode importer os importer sys

si sys.version_info> = (3, 0):     depuis http.server import BaseHTTPRequestHandler, HTTPServer     depuis socketserver importation ThreadingMixIn     depuis urllib.parse importez parse_qs autre:     depuis BaseHTTPServer, importez BaseHTTPRequestHandler, HTTPServer     depuis SocketServer importation ThreadingMixIn     depuis urlparse import parse_qs

de la session d'importation boto3 à partir de botocore.exceptions, importez BotoCoreError, ClientError

ResponseStatus = namedtuple ("HTTPStatus", ["code", "message"])

ResponseData = namedtuple ("ResponseData", ["status", "content_type", "data_stream"])

# Mappage du format de sortie utilisé dans le client au type de contenu pour le # réponse AUDIO_FORMATS = "ogg_vorbis": "audio / ogg",                  "mp3": "audio / mpeg",                  "pcm": "audio / onde; codecs = 1" CHUNK_SIZE = 1024 HTTP_STATUS = "OK": ResponseStatus (code = 200, message = "OK"),                "BAD_REQUEST": ResponseStatus (code = 400, message = "Bad request"),                "NOT_FOUND": ResponseStatus (code = 404, message = "Not found"),                "INTERNAL_SERVER_ERROR": ResponseStatus (code = 500, message = "Erreur de serveur interne") PROTOCOL = "http" ROUTE_INDEX = "/index.html" ROUTE_VOICES = "/ voices" ROUTE_READ = "/ lire"

# Créez un client en utilisant les informations d'identification et la région définies dans l'administrateur # section des informations d'identification AWS et des fichiers de configuration session = Session (profile_name = "adminuser") polly = session.client ("polly")

classe HTTPStatusError (Exception):     "" "Exception encapsulant une valeur de http.server.HTTPStatus" ""

    def __init __ (auto, état, description = Aucun):         "" "         Construit une instance d'erreur à partir d'un tuple de         (code, message, description), voir http.server.HTTPStatus         "" "         super (HTTPStatusError, self) .__ init __ ()         self.code = status.code         self.message = status.message         self.explain = description

classe ThreadedHTTPServer (ThreadingMixIn, HTTPServer):     "" "Un serveur HTTP qui gère chaque demande dans un nouveau thread" ""     daemon_threads = True

classe ChunkedHTTPRequestHandler (BaseHTTPRequestHandler):     "" "" HTTP 1.1 Gestionnaire de demande de codage en morceaux "" "     # Utiliser HTTP 1.1 car 1.0 ne prend pas en charge le codage en morceaux     protocol_version = "HTTP / 1.1"

    def query_get (self, queryData, key, default = ""):         "" "Aide pour obtenir des valeurs à partir d'une chaîne de requête pré-analysée" ""         return queryData.get (clé, [default])[0]

def do_GET (auto):         "" "Gère les requêtes GET" ""

        # Extraire des valeurs de la chaîne de requête         path, _, query_string = self.path.partition ('?')         query = parse_qs (query_string)

        réponse = Aucune

        imprimer (u "[START]: GET reçu pour% s avec requête:% s "% (chemin, requête))

        essayer:             # Gérer les chemins de requête possibles             si chemin == ROUTE_INDEX:                 response = self.route_index (chemin, requête)             chemin elif == ROUTE_VOICES:                 response = self.route_voices (chemin, requête)             chemin elif == ROUTE_READ:                 response = self.route_read (chemin, requête)             autre:                 response = self.route_not_found (chemin, requête)

            self.send_headers (response.status, response.content_type)             self.stream_data (response.data_stream)

        sauf HTTPStatusError comme err:             # Répondre avec une erreur et déboguer le journal             # information             si sys.version_info> = (3, 0):                 self.send_error (err.code, err.message, err.explain)             autre:                 self.send_error (err.code, err.message)

            self.log_error (u "% s% s% s - [%d] % s ", self.client_address[0],                            self.command, self.path, err.code, err.explain)

        impression("[END]")

    def route_not_found (auto, chemin, requête):         "" "Gère le routage pour les chemins inattendus" ""         lever HTTPStatusError (HTTP_STATUS["NOT_FOUND"], "Page non trouvée")

    def route_index (auto, chemin, requête):         "" "Gère le routage pour le point d'entrée de l'application" "" "         essayer:             return ResponseData (status = HTTP_STATUS["OK"], content_type = "text_html",                                 # Ouvrir un flux binaire pour lire l'index                                 # Fichier HTML                                 data_stream = open (os.path.join (sys.path[0],                                                               chemin[1:]), "rb"))         sauf IOError comme err:             # Impossible d'ouvrir le flux             lever HTTPStatusError (HTTP_STATUS["INTERNAL_SERVER_ERROR"],                                   str (err))

    def route_voices (auto, chemin, requête):         "" "Gère le routage pour répertorier les voix disponibles" ""         params =         voix = []

tandis que True:             essayer:                 # Demander la liste des voix disponibles, si un jeton de continuation                 # a été retourné par l'appel précédent, puis utilisez-le pour continuer                 # référencement                 response = polly.describe_voices (** params)             sauf (BotoCoreError, ClientError) comme err:                 # Le service a renvoyé une erreur                 lever HTTPStatusError (HTTP_STATUS["INTERNAL_SERVER_ERROR"],                                       str (err))

            # Recueillez toutes les voix             voices.extend (response.get ("Voices", []))

            # Si un jeton de continuation a été renvoyé continuez, arrêtez d'itérer             # autrement             si "NextToken" en réponse:                 params = "NextToken": réponse["NextToken"]             autre:                 Pause

        json_data = json_encode (voix)         bytes_data = octets (json_data, "utf-8") si sys.version_info> = (3, 0)             sinon octets (json_data)

        return ResponseData (status = HTTP_STATUS["OK"],                             content_type = "application / json",                             # Créer un flux binaire pour les données JSON                             data_stream = BytesIO (bytes_data))

    def route_read (auto, chemin, requête):         "" "Gère le routage pour la lecture de texte (synthèse vocale)" ""         # Récupère les paramètres de la chaîne de requête         text = self.query_get (requête, "texte")         voiceId = self.query_get (requête, "voiceId")         outputFormat = self.query_get (requête, "outputFormat")

        # Validez les paramètres, définissez le drapeau d'erreur en cas d'inattendu         # valeurs         si len (texte) == 0 ou len (voiceId) == 0 ou                 outputFormat pas dans AUDIO_FORMATS:             lever HTTPStatusError (HTTP_STATUS["BAD_REQUEST"],                                   "Paramètres incorrects")         autre:             essayer:                 # Demander la synthèse vocale                 response = polly.synthesize_speech (Text = text,                                                     VoiceId = voiceId,                                                     OutputFormat = outputFormat)             sauf (BotoCoreError, ClientError) comme err:                 # Le service a renvoyé une erreur                 lever HTTPStatusError (HTTP_STATUS["INTERNAL_SERVER_ERROR"],                                       str (err))

            return ResponseData (status = HTTP_STATUS["OK"],                                 content_type = AUDIO_FORMATS[outputFormat],                                 # Accéder au flux audio dans la réponse                                 data_stream = response.get ("AudioStream"))

    def send_headers (self, status, content_type):         "" "Envoyer le groupe d'en-têtes pour une demande réussie" ""         # Envoyer des en-têtes HTTP         self.send_response (status.code, status.message)         self.send_header ('Content-type', content_type)         self.send_header ('Transfer-Encoding', 'chunked')         self.send_header ('Connexion', 'fermer')         self.end_headers ()

    def stream_data (self, stream):         "" "Consomme un flux en morceaux pour produire la sortie de la réponse" "" "         print ("Le streaming a commencé ...")

        si flux:             # Remarque: la fermeture du flux est importante car le service se réduit             # le nombre de connexions parallèles. Ici, nous utilisons             # contextlib.closing pour garantir la méthode close de l'objet stream             # sera appelé automatiquement à la fin de l'instruction with             # portée.             avec fermeture (flux) en tant que flux géré:                 # Poussez le contenu du flux en morceaux                 tandis que True:                     data = managed_stream.read (CHUNK_SIZE)                     self.wfile.write (b "% X r n% s r n"% (len (data), data))

                    # S'il n'y a plus de données à lire, arrêtez la diffusion                     sinon données:                         Pause

                # Assurez-vous que toute sortie en mémoire tampon a été transmise et fermez                 # stream                 self.wfile.flush ()

            imprimer ("Streaming terminé.")         autre:             # Le flux transmis est vide             self.wfile.write (b "0 r n r n")             print ("Rien à diffuser.")

# Définir et analyser les arguments de la ligne de commande cli = ArgumentParser (description = 'Exemple d'application Python') cli.add_argument (     "-p", "--port", type = int, metavar = "PORT", dest = "port", par défaut = 8000) cli.add_argument (     "--host", type = str, metavar = "HOST", dest = "host", default = "localhost") arguments = cli.parse_args ()

# Si le module est appelé directement, initialisez l'application si __name__ == '__main__':     # Créer et configurer l'instance de serveur HTTP     server = ThreadedHTTPServer ((arguments.host, arguments.port),                                 ChunkedHTTPRequestHandler)     print ("Démarrage du serveur, utilisez arrêter...")     imprimer (u "ouvert 0: //1:23 dans un navigateur Web. ". Format (PROTOCOLE,                                                             arguments.host,                                                             arguments.port,                                                             ROUTE_INDEX))

    essayer:         # Écoutez les demandes indéfiniment         server.serve_forever ()     sauf KeyboardInterrupt:         # Une demande de résiliation a été reçue, arrêtez le serveur         print (" nArrêt ...")         server.socket.close ()

Click to rate this post! [Total: 0 Average: 0]

Topics and keywords

Themes: Serveur d'impression

License & attribution

License: CC BY-ND 4.0.

Attribution required: yes.

Manifest: https://tutos-gameserver.fr/llm-endpoints-manifest.json

LLM Endpoints plugin version 1.1.2.