Como os frameworks web Python, WSGI e CGI se encaixam

150

Eu tenho uma conta Bluehost onde posso executar scripts Python como CGI. Eu acho que é o CGI mais simples, porque para executar, tenho que definir o seguinte em .htaccess:

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

Agora, sempre que procuro programação na Web com Python, ouço muito sobre o WSGI e como a maioria das estruturas o usa. Mas eu simplesmente não entendo como tudo se encaixa, especialmente quando meu servidor da Web é fornecido (o Apache rodando na máquina de um host) e não algo com o qual eu possa brincar (exceto a definição de .htaccesscomandos).

Como o WSGI , CGI e os frameworks estão todos conectados? O que preciso saber, instalar e fazer se quiser executar uma estrutura da Web (por exemplo, web.py ou CherryPy ) na minha configuração básica de CGI? Como instalar o suporte WSGI?

Eli Bendersky
fonte

Respostas:

242

Como WSGI, CGI e os frameworks estão todos conectados?

O Apache escuta na porta 80. Ele recebe uma solicitação HTTP. Ele analisa a solicitação para encontrar uma maneira de responder. O Apache tem muitas opções para responder. Uma maneira de responder é usar o CGI para executar um script. Outra maneira de responder é simplesmente servir um arquivo.

No caso de CGI, o Apache prepara um ambiente e chama o script por meio do protocolo CGI. Essa é uma situação padrão do Unix Fork / Exec - o subprocesso CGI herda um ambiente de SO, incluindo o soquete e o stdout. O subprocesso CGI grava uma resposta, que volta ao Apache; O Apache envia essa resposta ao navegador.

O CGI é primitivo e irritante. Principalmente porque ele bifurca um subprocesso para cada solicitação, e o subprocesso deve sair ou fechar stdout e stderr para significar o fim da resposta.

WSGI é uma interface baseada no padrão de design CGI. Não é necessariamente CGI - ele não precisa bifurcar um subprocesso para cada solicitação. Pode ser CGI, mas não precisa ser.

O WSGI adiciona ao padrão de design CGI de várias maneiras importantes. Ele analisa os cabeçalhos de solicitação HTTP para você e os adiciona ao ambiente. Ele fornece qualquer entrada orientada ao POST como um objeto semelhante a arquivo no ambiente. Também fornece uma função que formulará a resposta, poupando-lhe muitos detalhes de formatação.

O que preciso saber / instalar / fazer se quiser executar uma estrutura da web (por exemplo, web.py ou cherrypy) na minha configuração básica de CGI?

Lembre-se de que bifurcar um subprocesso é caro. Existem duas maneiras de contornar isso.

  1. Incorporado mod_wsgi ou mod_pythonincorporado o Python no Apache; nenhum processo é bifurcado. O Apache executa o aplicativo Django diretamente.

  2. Daemon mod_wsgi ou mod_fastcgipermite que o Apache interaja com um daemon separado (ou "processo de longa execução"), usando o protocolo WSGI. Você inicia o processo de execução do Django, depois configura o mod_fastcgi do Apache para se comunicar com esse processo.

Observe que mod_wsgi pode funcionar em qualquer um dos modos: incorporado ou daemon.

Quando você ler sobre mod_fastcgi, verá que o Django usa flup para criar uma interface compatível com WSGI a partir das informações fornecidas por mod_fastcgi. O pipeline funciona assim.

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

O Django possui vários "django.core.handlers" para as várias interfaces.

Para mod_fastcgi, o Django fornece um manage.py runfcgi que integra o FLUP e o manipulador.

Para mod_wsgi, há um manipulador principal para isso.

Como instalar o suporte WSGI?

Siga estas instruções.

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

Para mais informações, consulte

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

S.Lott
fonte
4
Não consigo instalar o mod_wsgi porque estou em hospedagem compartilhada. Tudo o que tenho é suporte fcgi. Como ainda posso executar aplicativos WSGI através dele?
Eli Bendersky
3
+1 Essa é uma excelente resposta e muitas perguntas (mas não todas) que tenho em mente. Esta resposta ainda não está completa. Você explicou bem sobre CGI e WSGI, mas qual é a relação e as diferenças entre FASTCGI e WSGI? Qual é melhor? Como eles funcionam? Como o mod_python entrou em cena?
garras
14
S.Lott, em vez de reclamar quando as pessoas perguntam o que é "melhor", por que não simplesmente declarar "mod_wsgi é melhor como X, fastcgi é melhor para Y" e, se o OP tiver perguntas mais específicas, elas perguntarão.
Gregg Lind
7
@ Greg Lind: Por que não simplesmente declarar "mod_wsgi é melhor que X, fastcgi é melhor para Y"? Porque não é muito fácil de fazer. Existem dezenas de fatores de qualidade não funcionais que são elementos dos conjuntos X e Y. É difícil enumerar todos eles. É muito, muito melhor para as pessoas fazerem perguntas específicas sobre os fatores de qualidade relevantes.
31510 S.Lott
4
Apenas para as notas: a opção runfcgi está obsoleta desde a versão 1.7 e o suporte ao FastCGI foi removido no Django 1.9.
OBu
58

Acho que a resposta de Florian responde à parte da sua pergunta sobre "o que é WSGI", especialmente se você ler o PEP .

Quanto às perguntas que você coloca no final:

WSGI, CGI, FastCGI etc. são todos protocolos para um servidor Web executar código e entregar o conteúdo dinâmico produzido. Compare isso ao serviço da Web estático, onde um arquivo HTML simples é basicamente entregue como está para o cliente.

CGI, FastCGI e SCGI são independentes de idioma. Você pode escrever scripts CGI em Perl, Python, C, bash, qualquer que seja. O CGI define qual executável será chamado, com base na URL e como será chamado: os argumentos e o ambiente. Ele também define como o valor de retorno deve ser passado de volta ao servidor da Web assim que o executável for concluído. As variações são basicamente otimizações para poder lidar com mais solicitações, reduzir a latência e assim por diante; o conceito básico é o mesmo.

WSGI é apenas Python. Em vez de um protocolo independente de idioma, uma assinatura de função padrão é definida:

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

Esse é um aplicativo WSGI completo (se limitado). Um servidor da web com suporte a WSGI (como Apache com mod_wsgi) pode chamar essa função sempre que uma solicitação chegar.

O motivo disso ser tão grande é que podemos evitar a etapa confusa da conversão de um HTTP GET / POST para CGI para Python e voltar novamente na saída. É uma ligação muito mais direta, limpa e eficiente.

Também facilita muito a execução de estruturas de execução longa atrás de servidores da Web, se tudo o que for necessário para uma solicitação for uma chamada de função. Com CGI simples, você teria que iniciar toda a estrutura para cada solicitação individual.

Para ter suporte ao WSGI, você precisará instalar um módulo WSGI (como mod_wsgi ) ou usar um servidor da Web com o WSGI instalado (como CherryPy ). Se nenhuma dessas opções for possível, você poderá usar a ponte CGI-WSGI fornecida no PEP.

James Brady
fonte
3
De quem foi a idéia estúpida de não tornar a linguagem WSGI agnóstica? Qual é o objetivo então? Poderia também enviar todo o Python como um módulo Apache.
Salman von Abbas
2
@SalmanPK Eu acho que é apenas uma troca. Certamente não é fácil (se não impossível) criar um protocolo independente de idioma que possa ser usado simplesmente implementando uma função no idioma escolhido.
phunehehe
21

Você pode executar o WSGI sobre CGI como o Pep333 demonstra como exemplo. No entanto, toda vez que há uma solicitação, um novo intérprete Python é iniciado e todo o contexto (conexões com o banco de dados, etc.) precisa ser construído, o que leva algum tempo.

O melhor se você deseja executar o WSGI seria se seu host instalasse o mod_wsgi e fizesse uma configuração apropriada para adiar o controle para um aplicativo seu.

O Flup é outra maneira de executar o WSGI para qualquer servidor da Web que possa falar FCGI , SCGI ou AJP. Pela minha experiência, apenas o FCGI realmente funciona, e pode ser usado no Apache via mod_fastcgi ou se você pode executar um daemon Python separado com mod_proxy_fcgi .

O WSGI é um protocolo muito parecido com o CGI, que define um conjunto de regras de como o servidor da web e o código Python podem interagir. Ele é definido como Pep333 . Torna possível que muitos servidores da Web diferentes possam usar estruturas e aplicativos diferentes usando o mesmo protocolo de aplicativo. Isso é muito benéfico e o torna muito útil.

Florian Bösch
fonte
3
Está executando o WSGI sobre CGI para que serve "flup"? Como o flup está conectado ao esquema?
Eli Bendersky
7

Se você não tem certeza de todos os termos deste espaço e, se for verdade, é um arquivo de acrônimos confuso, também existe um bom leitor de plano de fundo na forma de um python oficial HOWTO que discute CGI vs. FastCGI vs. WSGI e assim por diante. em: http://docs.python.org/howto/webservers.html

Richard Boardman
fonte
2
URL está desatualizado, penso que este é actualizado um: docs.python.org/2.7/howto/webservers.html
Stefaan
Ótimo material :) Deve-se ler esta introdução oficial, juntamente com a resposta aceita.
Rick
4

É uma camada de abstração simples para Python, semelhante à especificação do Servlet para Java. Enquanto o CGI é realmente de baixo nível e apenas despeja coisas no ambiente do processo e na entrada / saída padrão, as duas especificações acima modelam a solicitação e a resposta http como construções na linguagem. Minha impressão, no entanto, é que, em Python, as pessoas ainda não se decidiram pelas implementações de fato, então você tem uma mistura de implementações de referência e outras bibliotecas do tipo utilitário que fornecem outras coisas junto com o suporte WSGI (por exemplo, Colar). Claro que posso estar errado, sou novato no Python. A comunidade de "scripts da web" está enfrentando o problema de uma direção diferente (hospedagem compartilhada, legado CGI,

Aaron
fonte