web-dev-qa-db-fra.com

Comment Python, WSGI et CGI s'assemblent

J'ai un compte Bluehost où je peux exécuter des scripts Python en tant que CGI. Je suppose que c'est le CGI le plus simple, car pour exécuter, je dois définir ce qui suit dans .htaccess:

Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py

Maintenant, chaque fois que je recherche de la programmation Web avec Python, j'entends beaucoup parler de WSGI et de la façon dont la plupart des frameworks l'utilisent. Mais je ne comprends tout simplement pas comment tout cela s'imbrique, en particulier lorsque mon serveur Web est fourni (Apache fonctionnant sur la machine d'un hôte) et pas quelque chose avec quoi je peux vraiment jouer (sauf définir .htaccess commandes).

Comment WSGI , CGI et les frameworks sont-ils tous connectés? Que dois-je savoir, installer et faire si je veux exécuter un framework web (disons web.py ou CherryPy ) sur ma configuration CGI de base? Comment installer le support WSGI?

148
Eli Bendersky

Comment WSGI, CGI et les frameworks sont-ils tous connectés?

Apache écoute sur le port 80. Il obtient une requête HTTP. Il analyse la demande pour trouver un moyen de répondre. Apache a BEAUCOUP de choix pour répondre. Une façon de répondre consiste à utiliser CGI pour exécuter un script. Une autre façon de répondre est de simplement signifier un fichier.

Dans le cas de CGI, Apache prépare un environnement et appelle le script via le protocole CGI. Il s'agit d'une situation standard Unix Fork/Exec - le sous-processus CGI hérite d'un environnement de système d'exploitation comprenant le socket et la sortie standard. Le sous-processus CGI écrit une réponse, qui revient à Apache; Apache envoie cette réponse au navigateur.

CGI est primitif et ennuyeux. Principalement parce qu'il bifurque un sous-processus pour chaque demande, et le sous-processus doit quitter ou fermer stdout et stderr pour signifier la fin de la réponse.

WSGI est une interface basée sur le modèle de conception CGI. Ce n'est pas nécessairement CGI - il n'a pas besoin de bifurquer un sous-processus pour chaque requête. Il peut s'agir de CGI, mais ce n'est pas obligatoire.

WSGI ajoute au modèle de conception CGI de plusieurs manières importantes. Il analyse les en-têtes de demande HTTP pour vous et les ajoute à l'environnement. Il fournit toute entrée orientée POST en tant qu'objet de type fichier dans l'environnement. Il vous fournit également une fonction qui formulera la réponse, vous épargnant de nombreux détails de mise en forme.

Que dois-je savoir/installer/faire si je veux exécuter un framework web (par exemple web.py ou cherrypy) sur ma configuration CGI de base?

Rappelons que bifurquer un sous-processus coûte cher. Il existe deux façons de contourner ce problème.

  1. Intégré mod_wsgi ou mod_python embarque Python dans Apache; aucun processus n'est bifurqué. Apache exécute directement l'application Django.

  2. Démon mod_wsgi ou mod_fastcgi permet à Apache d'interagir avec un démon distinct (ou "processus de longue durée"), en utilisant le protocole WSGI. Vous démarrez votre long processus Django, puis vous configurez mod_fastcgi d'Apache pour communiquer avec ce processus.

Notez que mod_wsgi peut fonctionner dans les deux modes: embarqué ou démon.

Lorsque vous lirez sur mod_fastcgi, vous verrez que Django utilise flup pour créer une interface compatible WSGI à partir des informations fournies par mod_fastcgi. Le pipeline fonctionne comme ceci .

Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)

Django a plusieurs "Django.core.handlers" pour les différentes interfaces.

Pour mod_fastcgi, Django fournit un manage.py runfcgi qui intègre FLUP et le gestionnaire.

Pour mod_wsgi, il existe un gestionnaire de base pour cela.

Comment installer le support WSGI?

Suivez ces instructions.

https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki

Pour le fond voir ceci

http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index

237
S.Lott

Je pense que la réponse de Florian répond à la partie de votre question sur "qu'est-ce que WSGI", surtout si vous lisez le PEP .

Quant aux questions que vous posez vers la fin:

WSGI, CGI, FastCGI etc. sont tous des protocoles permettant à un serveur Web de exécuter du code, et de fournir le contenu dynamique qui est produit. Comparez cela à un service Web statique, où un fichier HTML brut est essentiellement livré tel quel au client.

CGI, FastCGI et SCGI sont indépendants du langage. Vous pouvez écrire des scripts CGI en Perl, Python, C, bash, peu importe. CGI définit lequel l'exécutable sera appelé, basé sur l'URL, et comment il sera appelé: les arguments et l'environnement. Il définit également comment la valeur de retour doit être renvoyée au serveur Web une fois que votre exécutable est terminé. Les variations sont essentiellement des optimisations pour pouvoir gérer plus de demandes, réduire la latence, etc. le concept de base est le même.

WSGI est Python uniquement. Plutôt qu'un protocole indépendant du langage, une signature de fonction standard est définie:

def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']

Il s'agit d'une application WSGI complète (si limitée). Un serveur Web prenant en charge WSGI (comme Apache avec mod_wsgi) peut appeler cette fonction chaque fois qu'une demande arrive.

La raison pour laquelle cela est si important est que nous pouvons éviter l'étape compliquée de conversion d'un HTTP GET/POST en CGI en Python, et revenir en arrière. C'est une liaison beaucoup plus directe, propre et efficace.

Il est également beaucoup plus facile d'avoir des cadres de longue durée exécutés derrière des serveurs Web, si tout ce qui doit être fait pour une demande est un appel de fonction. Avec un simple CGI, vous devrez démarrer votre framework entier pour chaque demande individuelle.

Pour prendre en charge WSGI, vous devez avoir installé un module WSGI (comme mod_wsgi ), ou utiliser un serveur Web avec WSGI intégré (comme CherryPy ). Si aucun de ceux-ci n'est possible, vous pourrait utiliser le pont CGI-WSGI donné dans le PEP.

56
James Brady

Vous pouvez exécuter WSGI sur CGI comme le montre Pep3 comme exemple. Cependant, chaque fois qu'il y a une demande, un nouvel interpréteur Python est démarré et tout le contexte (connexions à la base de données, etc.) doit être construit, ce qui prend du temps.

Le mieux si vous voulez exécuter WSGI serait que votre hôte installe mod_wsgi et fasse une configuration appropriée pour reporter le contrôle à une de vos applications.

Flup est une autre façon de fonctionner avec WSGI pour tout serveur Web qui peut parler FCGI , SCGI ou AJP. D'après mon expérience, seul FCGI fonctionne vraiment, et il peut être utilisé dans Apache via mod_fastcgi ou si vous pouvez exécuter un démon séparé Python avec mod_proxy_fcgi .

WSGI est un protocole similaire à CGI, qui définit un ensemble de règles sur la façon dont le serveur Web et Python peut interagir, c'est défini comme Pep3 . Il permet à de nombreux serveurs Web différents d'utiliser de nombreux frameworks et applications différents en utilisant le même protocole d'application. Ceci est très bénéfique et le rend si utile.

21
Florian Bösch

Si vous n'êtes pas clair sur tous les termes de cet espace, et avouons-le, c'est un acronyme déroutant, il y a aussi un bon lecteur de fond sous la forme d'un officiel python HOWTO qui discute CGI vs FastCGI vs WSGI et ainsi de suite: http://docs.python.org/howto/webservers.html

7
Richard Boardman

C'est une simple couche d'abstraction pour Python, semblable à ce que la spécification Servlet est pour Java. Alors que CGI est vraiment de bas niveau et ne fait que vider des éléments dans l'environnement de processus et les entrées/sorties standard, les deux spécifications ci-dessus modélisent la demande et la réponse http en tant que constructions dans le langage. Mon impression est cependant qu'en Python n'ont pas tout à fait choisi les implémentations de facto, vous avez donc un mélange d'implémentations de référence et d'autres bibliothèques de type utilitaire qui fournissent d'autres choses avec le support WSGI ( par exemple Paste). Bien sûr, je pourrais me tromper, je suis un nouveau venu sur Python. La communauté de "web scripting" pose le problème dans une direction différente (hébergement partagé, héritage CGI, problèmes de séparation des privilèges) que Java les gens avaient le luxe de commencer par (exécuter un seul conteneur d'entreprise dans un environnement dédié contre du code compilé et déployé statiquement).

4
aaron