Maison >Périphériques technologiques >Industrie informatique >Applications Web Python: les bases de WSGI

Applications Web Python: les bases de WSGI

Joseph Gordon-Levitt
Joseph Gordon-Levittoriginal
2025-02-18 11:40:08580parcourir

Applications Web Python: les bases de WSGI

Les plats clés

  • WSGI, ou interface de passerelle de serveur Web, sous-tend tous les frameworks Web Python, fournissant une spécification courante pour les serveurs Web qui permet une interaction entre différents serveurs Web et frameworks d'application.
  • Une application WSGI est un python callable qui doit accepter deux arguments, l'environnement (un dict python contenant des données de demande) et start_fn (un appelable). L'application doit appeler start_fn avec deux arguments: le code d'état et une liste des en-têtes, et renvoyer une itérable contenant les octets dans l'organisme de réponse.
  • Le middleware peut être utilisé pour étendre les fonctionnalités des applications WSGI, le middleware et le gestionnaire n'ont pas besoin de se connaître ou de se soucier les uns des autres. Cela facilite l'ajout de fonctionnalités comme la journalisation ou la gestion des erreurs.
  • Les applications WSGI peuvent être servies de diverses manières, Gunicorn et Uwsgi étant deux options populaires. Il est recommandé de configurer quelque chose comme Nginx devant ceux-ci pour servir les actifs statiques.
Applications Web Python: les bases de WSGI

Sous Django, Flask, Bottle et tous les autres framework Web Python, se trouve l'interface de passerelle du serveur Web, ou WSGI pour faire court. WSGI consiste à python ce que sont les servlets à Java - une spécification courante pour les serveurs Web qui permet à différents serveurs Web et cadres d'application d'interagir en fonction d'une API commune. Cependant, comme pour la plupart des choses, la version Python est considérablement plus simple.

WSGI est défini dans PEP 3333, que je vous encourage à lire comme référence si vous voulez plus d'informations après cette intro.

Cet article vous présentera les spécifications WSGI du point de vue d'un développeur d'applications et vous montrera comment travailler directement avec WSGI pour créer des applications (si vous le souhaitez).

Votre première application WSGI

Voici l'application Web Python la plus élémentaire possible:

<span>def app(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>

c'est tout! Le fichier entier. Appelez-le app.py et exécutez-le avec n'importe quel serveur compatible WSGI et vous obtiendrez une réponse Hello World avec un statut de 200. Vous pouvez utiliser Gunicorn pour cela; Installez-le simplement via PIP (PIP install Gunicorn) et exécutez-le avec Gunicorn App: App. Cette commande indique à Gunicorn d'obtenir le WSGI appelé à partir de la variable d'application dans le module d'application.

En ce moment, vous devriez être très excité. Juste 3 lignes pour une application en cours d'exécution? Cela doit être une sorte d'enregistrement (sauf PHP, car mod_php triche). Je parie que tu es juste impatient d'en savoir plus.

Alors, quelles sont les parties essentielles d'une application WSGI?

  • Une application WSGI est un python callable , comme une fonction, une classe ou une instance de classe avec une méthode __Call__
  • L'application appelant à accepter deux arguments: l'environnement, qui est un dict python contenant les données de demande, et start_fn, lui-même un appelable.
  • L'application doit appeler le start_fn avec deux arguments: le code d'état (comme une chaîne), et une liste d'en-têtes exprimée en 2 tuples.
  • L'application renvoie une itérable contenant les octets dans le corps de réponse dans des morceaux pratiques et diffusables - dans ce cas, une liste de chaînes contenant juste "Hello, World!". (Si l'application est une classe, cela peut être accompli dans la méthode __iter__.)

À titre d'exemple, ces deux exemples suivants sont équivalents au premier:

<span>def app(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>
<span>class app(object):
</span>
    <span>def __init__(self, environ, start_fn):
</span>        self<span>.environ = environ
</span>        self<span>.start_fn = start_fn
</span>
    <span>def __iter__(self):
</span>        self<span>.start_fn('200 OK', [('Content-Type', 'text/plain')])
</span>        <span>yield "Hello World!\n"
</span>

Vous envisagez peut-être déjà des moyens que vous puissiez utiliser ces informations, mais probablement la plus pertinente est d'écrire MiddleWares.

Jazzing It Up

Middlewares est un moyen facile d'étendre la fonctionnalité des applications WSGI. Étant donné que vous n'avez qu'à fournir un appelable, vous pouvez le conclure dans d'autres fonctions comme vous le souhaitez.

Par exemple, disons que nous voulons examiner le contenu de l'environnement. Nous pouvons facilement créer un middleware pour le faire, comme dans cet exemple:

<span>class Application(object):
</span>    <span>def __call__(self, environ, start_fn):
</span>        start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>        <span>yield "Hello World!\n"
</span>
app <span>= Application()
</span>

Ici, Log_environ est une fonction qui renvoie une fonction, qui imprime l'argument Environ avant de reporter au rappel d'origine.

L'avantage de l'écriture de Middlewares de cette façon est que le middleware et le gestionnaire n'ont pas à se connaître ou à se soucier les uns des autres. Vous pouvez facilement boulonner Log_environ sur une application Flask, par exemple, car les applications FLASK sont des applications WSGI.

Quelques autres idées middleware utiles:

<span>import pprint
</span>

<span>def handler(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>

<span>def log_environ(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        pprint<span>.pprint(environ)
</span>        <span>return handler(environ, start_fn)
</span>    <span>return _inner
</span>

app <span>= log_environ(handler)
</span>

Vous pouvez utiliser Réduction pour appliquer un tas de middleware à la fois si vous ne voulez pas faire une grosse pyramide un bas de votre fichier:

<span>import pprint
</span>

<span>def handle_error(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        <span>try:
</span>            <span>return handler(environ, start_fn)
</span>        <span>except Exception as e:
</span>            <span>print e  # Log error
</span>            start_fn<span>('500 Server Error', [('Content-Type', 'text/plain')])
</span>            <span>return ['500 Server Error']
</span>    <span>return _inner
</span>

<span>def wrap_query_params(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        qs <span>= environ.get('QUERY_STRING')
</span>        environ<span>['QUERY_PARAMS'] = urlparse.parse_qs(qs)
</span>        <span>return handler(environ, start_fn)
</span>    <span>return _inner
</span>

Vous pouvez également écrire du middleware qui modifie la réponse, en tirant parti de l'argument start_fn. Voici un middleware qui inverse la sortie si l'en-tête de type contenu est texte / simple:

<span># Applied from bottom to top on the way in, then top to bottom on the way out
</span>MIDDLEWARES <span>= [wrap_query_params,
</span>               log_environ<span>,
</span>               handle_error<span>]
</span>
app <span>= reduce(lambda h, m: m(h), MIDDLEWARES, handler)
</span>

C'est un peu plus emmêlé grâce à la séparation de start_fn et de réponse, mais toujours parfaitement réalisable.

Notez également que, pour être strictement conforme aux spécifications avec WSGI, nous devons vérifier une méthode Close sur la réponse et l'appeler si elle est présente. Les applications WSGI héritées peuvent également renvoyer une fonction écrire au lieu d'un gestionnaire d'appel itérable; Si vous souhaitez que votre middleware prenne en charge les applications plus anciennes, vous devrez peut-être gérer ce cas.

Une fois que vous commencez un peu à jouer avec RAW WSGI, vous commencez à comprendre pourquoi Python a littéralement des dizaines de frameworks Web. WSGI rend assez simple à construire quelque chose à partir de zéro. Par exemple, vous pourriez considérer le problème du routage:

<span>def reverser(handler):
</span>
    <span># A reverse function
</span>    rev <span>= lambda it: it[::-1]
</span>
    <span>def _inner(environ, start_fn):
</span>        do_reverse <span>= []  # Must be a reference type such as a list
</span>
        <span># Override start_fn to check the content type and set a flag
</span>        <span>def start_reverser(status, headers):
</span>            <span>for name, value in headers:
</span>                <span>if (name.lower() == 'content-type'
</span>                        <span>and value.lower() == 'text/plain'):
</span>                    do_reverse<span>.append(True)
</span>                    <span>break
</span>
            <span># Remember to call `start_fn`
</span>            start_fn<span>(status, headers)
</span>
        response <span>= handler(environ, start_reverser)
</span>
        <span>try:
</span>            <span>if do_reverse:
</span>                <span>return list(rev(map(rev, response)))
</span>
            <span>return response
</span>        <span>finally:
</span>            <span>if hasattr(response, 'close'):
</span>                response<span>.close()
</span>    <span>return _inner
</span>

Travailler directement avec WSGI peut être bien si vous appréciez la flexibilité de l'assemblage de bibliothèques sur

  • Bibliothèques de modèles: Déposez simplement dans n'importe quelle bibliothèque de modèles que vous aimez (par exemple Jinja2, Pystashe) et renvoyez le modèle rendu de votre gestionnaire!
  • Aidez votre routage avec une bibliothèque comme les itinéraires ou peut-être le routage de Werkzug. En fait, jetez un œil à Werkzug si vous souhaitez utiliser une abstraction toujours si légère sur WSGI.
  • Utilisez n'importe quelle base de données / bibliothèques de migration comme vous le feriez avec Flask ou similaire.

Bien sûr, pour les applications non spécialisées, vous voudrez probablement toujours utiliser un framework juste pour que les cas de bord soient correctement manipulés et quoi que ce soit.

Mais qu'en est-il des serveurs?

Il existe un tas de façons de servir les applications WSGI. Nous avons déjà parlé de Gunicorn, ce qui est une option décente. UWSGI est une autre excellente option. Assurez-vous simplement de configurer quelque chose comme Nginx devant ceux-ci pour servir des actifs statiques et vous devriez avoir un point de départ solide.

Et c'est tout ce qu'il y a!

Questions fréquemment posées (FAQ) sur les applications Web Python et WSGI

Quel est le rôle de WSGI dans les applications Web Python?

WSGI, ou interface de passerelle de serveur Web, est une interface standard entre les serveurs Web et les applications Web. Il joue un rôle crucial dans les applications Web Python car il permet à l'application et au serveur Web de communiquer et de se envoyer des demandes. WSGI agit comme un pont, permettant au serveur Web de transférer les demandes d'un client (comme un navigateur Web) à une application Web. L'application traite ensuite la demande et renvoie une réponse au client via le serveur Web.

Comment fonctionne WSGI dans une application Web Python?

WSGI fonctionne en définissant une interface commune qui permet Serveurs Web pour communiquer avec les applications Web. Lorsqu'un client envoie une demande à un serveur Web, le serveur utilise l'interface WSGI pour transmettre cette demande à l'application Web. L'application traite la demande et renvoie une réponse, que le serveur renvoie ensuite au client. Ce processus permet d'interagir un moyen cohérent et fiable pour les serveurs et les applications Web, indépendamment de leurs implémentations spécifiques.

Quels sont les serveurs WSGI populaires pour Python?

Il existe plusieurs serveurs WSGI populaires populaires Disponible pour Python, chacun avec ses propres forces et faiblesses. Certains des plus couramment utilisés incluent Gunicorn, UWSGI et MOD_WSGI. Gunicorn est connu pour sa simplicité et sa facilité d'utilisation, tandis que UWSGI est loué pour sa vitesse et son efficacité. MOD_WSGI, en revanche, est un module pour les serveurs Apache et est souvent utilisé dans les environnements d'entreprise.

Comment déployer une application Web Python à l'aide de WSGI?

Le déploiement d'une application Web Python à l'aide de WSGI implique plusieurs étapes. Tout d'abord, vous devez installer un serveur WSGI, comme Gunicorn ou UWSGI. Ensuite, vous devez configurer votre serveur Web pour utiliser le serveur WSGI comme proxy pour gérer les demandes à votre application. Cela implique de modifier le fichier de configuration de votre serveur pour inclure les paramètres WSGI nécessaires. Enfin, vous devez démarrer votre serveur WSGI et le pointer vers le fichier WSGI de votre application.

Puis-je utiliser WSGI avec Django?

Oui, vous pouvez utiliser WSGI avec Django. En fait, Django est livré avec une application WSGI intégrée que vous pouvez utiliser pour déployer vos projets Django. L'application Django WSGI agit comme un pont entre votre projet Django et le serveur Web, leur permettant de communiquer et d'échanger des demandes et des réponses.

Quelle est la différence entre WSGI et ASGI?

WSGI et Les ASGI sont tous deux des interfaces pour les applications Web Python, mais elles servent des objectifs différents. WSGI est une interface synchrone qui permet la communication entre un serveur Web et une application Web. ASGI, ou interface de passerelle de serveur asynchrone, est une extension de WSGI qui prend en charge les opérations asynchrones. Cela signifie qu'avec ASGI, votre application peut gérer plusieurs demandes en même temps sans blocage, ce qui la rend plus efficace pour les applications en temps réel.

Comment créer une application WSGI dans Python?

La création d'une application WSGI dans Python implique de définir une fonction qui accepte deux arguments: un dictionnaire environnemental et un start_response callable. Le dictionnaire environnemental contient des informations sur la demande entrante, tandis que le start_Response Calsable est utilisé pour démarrer la réponse à la demande. Votre fonction doit renvoyer un itérable qui produit le corps de la réponse.

Quels sont les avantages de l'utilisation des applications Web WSGI dans Python?

L'utilisation de WSGI dans les applications Web Python offre plusieurs avantages. Tout d'abord, il fournit une interface standard pour les serveurs Web et les applications, ce qui facilite le développement et le déploiement d'applications Web Python. Deuxièmement, il permet une plus grande flexibilité, comme vous pouvez choisir parmi une variété de serveurs et d'applications compatibles WSGI. Enfin, il favorise la réutilisabilité du code, car vous pouvez utiliser la même application WSGI avec différents serveurs et middleware.

Puis-je utiliser WSGI avec Flask?

Oui, vous pouvez utiliser WSGI avec Flask. En fait, les applications Flask sont par défaut des applications WSGI. Lorsque vous créez une application Flask, vous créez en fait une application WSGI que le framework Flask utilisera pour gérer les demandes entrantes et envoyer des réponses.

Qu'est-ce qu'un middleware WSGI?

Un middleware WSGI est un composant qui se trouve entre un serveur WSGI et une application WSGI. Il peut traiter les demandes avant d'atteindre l'application et les réponses avant d'être renvoyées au client. Le middleware peut être utilisé pour implémenter une variété de fonctionnalités, telles que la gestion des sessions, le routage d'URL et l'authentification.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn