Python Web框架,WSGI和CGI如何组合在一起

我有一个Bluehost帐户,我可以在CGI上运行Python脚本。 我想这是最简单的CGI,因为要运行我必须在.htaccess定义以下内容:

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

现在,每当我用Python查看网页编程时,我都会听到很多关于WSGI以及大多数框架如何使用它的信息。 但是我只是不明白它是如何组合在一起的,尤其是当我的web服务器(Apache运行在主机的机器上),而不是我真的可以玩的(除了定义.htaccess命令)。

WSGI ,CGI和框架如何连接? 如果我想在我的基本CGIconfiguration上运行Web框架(比如说web.py或CherryPy ),我需要知道什么,安装和做什么? 如何安装WSGI支持?

WSGI,CGI和框架如何连接?

Apache在端口80上侦听。它得到一个HTTP请求。 它分析请求以find响应的方式。 Apache有很多回应的select。 一种方法是使用CGI来运行脚本。 另一种反应方式是简单地提供一个文件。

在CGI的情况下,Apache准备一个环境并通过CGI协议调用脚本。 这是一个标准的Unix Fork / Exec情况 – CGIsubprocessinheritance了包括套接字和标准输出的操作系统环境。 CGIsubprocess写回应Apache, Apache将这个响应发送给浏览器。

CGI是原始的和烦人的。 主要是因为它为每个请求分派一个subprocess,并且subprocess必须退出或closuresstdout和stderr才能表示响应结束。

WSGI是一个基于CGIdevise模式的接口。 它不一定是CGI – 它不必为每个请求分派一个subprocess。 它可以是CGI,但不一定是。

WSGI在几个重要方面增加了CGIdevise模式。 它为您parsingHTTP请求标题并将其添加到环境中。 它在环境中提供任何面向POST的input作为类文件对象。 它也提供了一个函数来制定响应,从很多格式化的细节中拯救你。

如果我想在我的基本CGIconfiguration上运行Web框架(比如web.py或cherrypy),我需要知道/安装/做什么?

回想一下,分叉subprocess是昂贵的。 有两种方法可以解决这个问题。

  1. embedded式 mod_wsgimod_python将Pythonembedded到Apache中; 没有过程分叉。 Apache直接运行Django应用程序。

  2. 守护程序 mod_wsgimod_fastcgi允许Apache使用WSGI协议与单独的守护程序(或“长时间运行的进程”)进行交互。 你开始你长时间运行的Django进程,然后你configurationApache的mod_fastcgi与这个进程通信。

请注意, mod_wsgi可以在任何模式下工作:embedded式或守护进程。

当你读到mod_fastcgi时,你会发现Django使用flup从mod_fastcgi提供的信息创build一个兼容WSGI的接口。 pipe道是这样工作的。

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

Django为各种接口提供了几个“django.core.handlers”。

对于mod_fastcgi,Django提供了一个集成了FLUP和处理程序的manage.py runfcgi

对于mod_wsgi,这里有一个核心处理程序。

如何安装WSGI支持?

按照这些说明。

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

为了背景看这个

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

我想弗洛里安的答案回答了关于“什么是WSGI”的问题,特别是如果您阅读PEP 。

至于你最后提出的问题:

WSGI,CGI,FastCGI等都是Web服务器运行代码的协议,并提供生成的dynamic内容。 将此与静态Web服务相比较,其中纯HTML文件基本上按原样传递给客户端。

CGI,FastCGI和SCGI是语言不可知的。 你可以用Perl,Python,C,bash等编写CGI脚本。 CGI根据URL定义将调用哪个可执行文件,以及如何调用它:参数和环境。 它还定义了一旦你的可执行文件完成后,返回值应该如何传递回Web服务器。 这些变化基本上是能够处理更多请求,减less延迟等的优化。 基本的概念是一样的。

WSGI只是Python。 定义标准函数签名而不是语言不可知协议:

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

这是一个完整的(如果有限的话)WSGI应用程序。 WSGI支持的Web服务器(例如Apache和mod_wsgi)可以在请求到达的时候调用这个函数。

之所以如此伟大,是因为我们可以避免从HTTP GET / POST转换为CGI到Python的混乱步骤,并且可以避免出错。 这是一个更直接,清洁和有效的联系。

如果一个请求需要完成的只是一个函数调用,那么在Web服务器后面运行长时间运行的框架也会更容易。 用简单的CGI,你必须为每个单独的请求启动你的整个框架 。

为了支持WSGI,你需要安装一个WSGI模块(比如mod_wsgi ),或者使用一个带有WSGI的Web服务器(比如CherryPy )。 如果两者都不可行,那么可以使用PEP中给出的CGI-WSGI桥。

您可以像Pep333演示的那样通过CGI运行WSGI 。 然而,每次有请求时,都会启动一个新的Python解释器,并且需要构build整个上下文(数据库连接等),这都需要时间。

如果你想要运行WSGI,最好的办法是,如果你的主机安装了mod_wsgi并且做了一个合适的configuration来把控制权推迟到你的应用程序。

Flup是运行WSGI的另一种方式,可用于任何可以说FCGI , SCGI或AJP的Web服务器。 根据我的经验,只有FCGI可以工作,可以通过mod_fastcgi在Apache中使用,也可以使用mod_proxy_fcgi运行单独的Python守护进程。

WSGI是一个非常类似CGI的协议,它定义了一组规则,webserver和Python代码如何交互,定义为Pep333 。 这使得许多不同的Web服务器可以使用相同的应用程序协议来使用许多不同的框架和应用程序。 这是非常有益的,并使其非常有用。

如果你对这个领域的所有术语都不清楚,让它面对,它是一个令人困惑的首字母缩略词,还有一个很好的背景阅读器,以官方的Python HOWTO的forms讨论CGI与FastCGI与WSGI等在: http : //docs.python.org/howto/webservers.html

这是一个简单的Python抽象层,类似于Java的Servlet规范。 而CGI真的是低层次的,只是把东西放到stream程环境和标准的input/输出中,上述两个规范把http请求和响应build模成语言结构。 然而,我的印象是,在Python中人们还没有完全确定事实上的实现,所以你有混合的参考实现,以及其他实用程序types的库,提供其他事情以及WSGI支持(例如粘贴)。 当然,我可能是错的,我是Python的新手。 “Web脚本”社区正在从一个不同的方向(共享主机,CGI传统,特权分离问题)出现问题,而不是Java开始的奢侈(在专用环境中运行单个企业容器,以防静态编译和部署码)。