In che modo i framework web Python, WSGI e CGI si integrano


150

Ho un account Bluehost dove posso eseguire script Python come CGI. Immagino sia il CGI più semplice, perché per eseguirlo devo definire quanto segue in .htaccess:

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

Ora, ogni volta che cerco la programmazione web con Python, sento molto parlare di WSGI e di come la maggior parte dei framework lo usa. Ma non capisco come si adatta tutto, soprattutto quando viene fornito il mio server Web (Apache in esecuzione su una macchina host) e non qualcosa con cui posso davvero giocare (tranne definire i .htaccesscomandi).

Come sono collegati WSGI , CGI e i framework? Cosa devo sapere, installare e fare se voglio eseguire un framework Web (ad esempio web.py o CherryPy ) sulla mia configurazione CGI di base? Come installare il supporto WSGI?

Risposte:


242

Come sono collegati WSGI, CGI e i framework?

Apache è in ascolto sulla porta 80. Ottiene una richiesta HTTP. Analizza la richiesta per trovare un modo di rispondere. Apache ha MOLTE scelte per rispondere. Un modo di rispondere è utilizzare CGI per eseguire uno script. Un altro modo di rispondere è semplicemente di servire un file.

Nel caso di CGI, Apache prepara un ambiente e invoca lo script tramite il protocollo CGI. Questa è una situazione standard Unix Fork / Exec: il sottoprocesso CGI eredita un ambiente operativo compreso socket e stdout. Il sottoprocesso CGI scrive una risposta, che risale ad Apache; Apache invia questa risposta al browser.

CGI è primitivo e fastidioso. Soprattutto perché genera un sottoprocesso per ogni richiesta e il sottoprocesso deve uscire o chiudere stdout e stderr per indicare la fine della risposta.

WSGI è un'interfaccia basata sul modello di progettazione CGI. Non è necessariamente CGI - non deve eseguire il fork di un sottoprocesso per ogni richiesta. Può essere CGI, ma non deve essere.

WSGI aggiunge al modello di progettazione CGI in diversi modi importanti. Analizza le intestazioni delle richieste HTTP per te e le aggiunge all'ambiente. Fornisce qualsiasi input orientato al POST come oggetto simile a un file nell'ambiente. Ti fornisce anche una funzione che formulerà la risposta, salvandoti da molti dettagli di formattazione.

Cosa devo sapere / installare / fare se voglio eseguire un framework Web (ad esempio web.py o cherrypy) sulla mia configurazione CGI di base?

Ricordiamo che il fork di un sottoprocesso è costoso. Esistono due modi per aggirare questo.

  1. Incorporato mod_wsgi o mod_pythonincorpora Python all'interno di Apache; nessun processo è biforcuto. Apache esegue direttamente l'applicazione Django.

  2. Demone mod_wsgi o mod_fastcgiconsente ad Apache di interagire con un demone separato (o "processo a esecuzione prolungata"), utilizzando il protocollo WSGI. Inizi il tuo processo Django di lunga durata, quindi configuri mod_fastcgi di Apache per comunicare con questo processo.

Nota che mod_wsgipuò funzionare in entrambe le modalità: incorporato o demone.

Quando leggi su mod_fastcgi, vedrai che Django utilizza flup per creare un'interfaccia compatibile WSGI dalle informazioni fornite da mod_fastcgi. La pipeline funziona così.

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

Django ha diversi "django.core.handlers" per le varie interfacce.

Per mod_fastcgi, Django fornisce un manage.py runfcgiche integra FLUP e il gestore.

Per mod_wsgi, c'è un gestore principale per questo.

Come installare il supporto WSGI?

Segui queste istruzioni.

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

Per lo sfondo vedi questo

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


4
Non riesco a installare mod_wsgi perché sono su hosting condiviso. Tutto quello che ho è il supporto FCC. Come posso ancora eseguire le app WSGI attraverso di essa?
Eli Bendersky,

3
+1 Questa è un'ottima risposta e risponde a molte (ma non tutte) domande che ho in mente. Questa risposta non è ancora completa. Hai spiegato bene di CGI e WSGI ma qual è la relazione e le differenze tra FASTCGI e WSGI? Che è migliore? Come funzionano? Come è entrato in scena mod_python?
artigli il

14
S.Lott, invece di lamentarsi quando le persone chiedono quale sia "migliore", perché non semplicemente dichiarare "mod_wsgi è meglio di X, fastcgi è meglio di Y", e se l'OP ha domande più specifiche, si chiederanno.
Gregg Lind,

7
@Greg Lind: Perché non dire semplicemente "mod_wsgi è meglio di X, fastcgi è meglio di Y"? Perché non è molto facile da fare. Ci sono dozzine di fattori di qualità non funzionali che sono elementi degli insiemi X e Y. È difficile elencarli tutti. È molto, molto meglio per le persone porre domande specifiche sui fattori di qualità che sono rilevanti.
S.Lott

4
Solo per le note: l'opzione runfcgi è obsoleta dalla versione 1.7 e il supporto FastCGI è stato rimosso in Django 1.9.
OBu,

58

Penso che la risposta di Florian risponda alla parte della tua domanda su "cos'è WSGI", specialmente se leggi il PEP .

Per quanto riguarda le domande che poni verso la fine:

WSGI, CGI, FastCGI ecc. Sono tutti protocolli per l' esecuzione di codice da parte di un server Web e la consegna del contenuto dinamico prodotto. Confronta questo con il servizio web statico, in cui un semplice file HTML viene sostanzialmente consegnato così com'è al client.

CGI, FastCGI e SCGI sono agnostici del linguaggio. Puoi scrivere script CGI in Perl, Python, C, bash, qualunque cosa. CGI definisce quale eseguibile verrà chiamato, in base all'URL, e come verrà chiamato: gli argomenti e l'ambiente. Definisce inoltre come il valore restituito debba essere restituito al server Web al termine dell'eseguibile. Le variazioni sono sostanzialmente ottimizzazioni per essere in grado di gestire più richieste, ridurre la latenza e così via; il concetto di base è lo stesso.

WSGI è solo Python. Piuttosto che un protocollo agnostico di linguaggio, viene definita una firma di funzione standard:

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']

Questa è un'applicazione WSGI completa (se limitata). Un server Web con supporto WSGI (come Apache con mod_wsgi) può richiamare questa funzione ogni volta che arriva una richiesta.

La ragione per cui è così grande è che possiamo evitare il passaggio disordinato della conversione da HTTP GET / POST a CGI in Python, e di nuovo in uscita. È un collegamento molto più diretto, pulito ed efficiente.

Inoltre, rende molto più semplice avere framework di lunga durata in esecuzione dietro i server Web, se tutto ciò che deve essere fatto per una richiesta è una chiamata di funzione. Con CGI semplice, dovresti avviare l'intero framework per ogni singola richiesta.

Per avere il supporto WSGI, devi aver installato un modulo WSGI (come mod_wsgi ) o utilizzare un server web con WSGI inserito (come CherryPy ). Se nessuno dei due è possibile, è possibile utilizzare il bridge CGI-WSGI indicato nel PEP.


3
Di chi è stata questa stupida idea di non rendere agnostico il linguaggio WSGI? Qual è il punto allora? Potrebbe anche spedire l'intero Python come modulo Apache.
Salman von Abbas,

2
@SalmanPK Penso che sia solo un compromesso. Sicuramente non è facile (se non impossibile) creare un protocollo indipendente dalla lingua che può essere utilizzato semplicemente implementando una funzione nella lingua scelta.
phunehehe,

21

È possibile eseguire WSGI su CGI come Pep333 dimostra come esempio. Tuttavia, ogni volta che c'è una richiesta, viene avviato un nuovo interprete Python e l'intero contesto (connessioni al database, ecc.) Deve essere creato, il che richiede tempo.

Il migliore se si desidera eseguire WSGI sarebbe se il proprio host installasse mod_wsgi e avesse creato una configurazione appropriata per rinviare il controllo a un'applicazione propria.

Flup è un altro modo di funzionare con WSGI per qualsiasi server web che può parlare FCGI , SCGI o AJP. Dalla mia esperienza, solo FCGI funziona davvero e può essere utilizzato in Apache tramite mod_fastcgi o se è possibile eseguire un demone Python separato con mod_proxy_fcgi .

WSGI è un protocollo molto simile a CGI, che definisce un insieme di regole su come interagire webserver e codice Python, è definito come Pep333 . Rende possibile che molti server Web diversi possano utilizzare molti framework e applicazioni diversi utilizzando lo stesso protocollo di applicazione. Questo è molto utile e lo rende così utile.


3
Eseguire WSGI su CGI a cosa serve "flup"? In che modo flup è collegato allo schema?
Eli Bendersky,

7

Se non sei chiaro su tutti i termini in questo spazio, e ammettiamolo, è un linguaggio confuso pieno di acronimi, c'è anche un buon lettore di background sotto forma di un HOWTO ufficiale in pitone che discute CGI vs FastCGI vs WSGI e così via su: http://docs.python.org/howto/webservers.html


2
L'URL è obsoleto, penso che sia aggiornato uno: docs.python.org/2.7/howto/webservers.html
Stefaan,

Ottimo materiale :) Si dovrebbe leggere questa introduzione ufficiale insieme alla risposta accettata.
Rick,

4

È un semplice livello di astrazione per Python, simile a quello che le specifiche Servlet sono per Java. Mentre il CGI è davvero di basso livello e scarica semplicemente le cose nell'ambiente di processo e lo standard in / out, le due specifiche sopra riportate modellano la richiesta e la risposta http come costrutti nel linguaggio. La mia impressione è tuttavia che in Python le persone non si siano ancora orientate sulle implementazioni di fatto, quindi hai un mix di implementazioni di riferimento e altre librerie di tipi di utilità che forniscono altre cose insieme al supporto WSGI (ad esempio Incolla). Ovviamente potrei sbagliarmi, sono un nuovo arrivato in Python. La community "web scripting" sta affrontando il problema da una direzione diversa (hosting condiviso, eredità CGI,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.