这篇文档展示了Python如何融入到web中。它介绍了几种Python结合web服务器的方法,以及开发网站的一些常规做法。
译文:
http://www.cnblogs.com/rainfd/p/howto_webservers.html
全文约 14524 字,读完可能需要 22 分钟。
原文:
HOWTO Use Python in the Web
"Web 2.0"是指由用户主导网站内容的创作。自从这个概念兴起以来,网络编程就成为了一个热门话题。一直以来,用Python创建网站是相当繁琐的,所以也很少有人这么做。因此人们创建了许多框架和辅助工具来帮助开发者创建更快更可靠的网站。这篇HOWTO介绍了几种Python结合web服务器创建动态内容的方法。当然,因为这个话题涉及的内容太广,很难在单独的一篇文档里进行详细的描述。所以这里就只对一些当前流行的库作简要的概述。
参见
:这篇HOWTO试图对Python的Web开发作一个概览,但不能总是按预期及时地更新。Python的Web开发正在迅速发展,所以wiki上的
Web Programming
可能与近期的发展更为接近。
底层视角
当一个用户访问网站时,他们的浏览器会与网站的服务器进行连接(这称为
请求
)。服务器在文件系统中寻找文件,并将其发送回用户的浏览器(这称为
响应
)。这就是底层HTTP协议的大致工作原理。动态网站不是基于文件系统中的文件,而是以程序为基础。当请求到来,运行在服务器上的程序就会生成相应内容并发送回用户。它们可以处理用户的各种数据,例如列出公告板上的帖子,显示你的邮件,配置软件,或者只是显示当前时间。这些程序能用服务器支持的任意语言完成。自从大部分的服务器开始支持Python,用Python创建动态网站就变得十分简单了。
大多数的HTTP服务器是用C或者C++写的,它们不能直接执行Python代码,所以服务器和程序之间就需要有一座桥。网桥,或者更确切地称为接口,决定了程序如何与服务器进行交互。
为了创建尽可能好的接口,人们作出了无数尝试,但只有少数的几个值得关注。
不是每一个服务器都支持所有的接口。许多服务器只支持老的,现在已经过时的接口。然而,它们经常可以通过第三方模块扩展来支持新的接口。
常用网关接口
这个接口,通常被称为"CGI",是最古老的,几乎被所有web服务器很好地支持着。在处理单个请求时,程序由服务器启动,通过CGI与服务器进行通讯。因而每个请求来临时都要花一定时间去启动新的Python解释器。这就使得整个接口在低负载状态的时候才能正常使用。
CGI的优点在于它很简单----用CGI写一个Python程序大概就是三行代码的事情。这种简易性造成了一种误解:它对开发者的帮助聊胜于无。
虽然还有可能用CGI写程序,但已经不建议这么做了。通过使用本文稍后提到的WSGI,就能模仿CGI的方式写程序,而且在迫不得已的时候,它们也能作为CGI运行。
参见
:Python标准库包含了一些模块来帮助创建简单的CGI程序:
Python的wiki有专门描述CGI脚本的页面,里面有关于CGI在Python中的一些额外信息。
测试CGI的简单脚本
你可以用这个简短的CGI程序来测试你的服务器是否支持CGI。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# enable debugging
import cgitb
cgitb.enable()
print("Content-Type: text/plain;charset=utf-8")
print()
print("Hello World!")
根据你服务器的配置,你可能需要使用用
.
py
或者
.
cgi
扩展名来保存此代码。出于对安全的考虑,此文件也可能需要放置在
cgi
-
bin
目录中。
也许你想知道
cgitb
那行代码有什么作用。这行代码显示良好的错误回溯,而不仅仅是崩溃时在用户的浏览器上显示"服务器内部错误"。这有利于进行debug,但存在一定的风险暴露某些机密的数据给用户。基于这个原因,你不应该在生产环境中使用
cgitb
模块。还有,终端用户不会喜欢在浏览器上看到"服务器内部错误"这样不伦不类的信息,所以你应该捕获所有异常,并显示合适的错误页面。
在你自己的服务器上安装配置CGI
如果你没有自己的服务器,这就不适用于你。你可以检查服务器是否如常工作,如果不是,你就可能需要联系你网站的管理员。如果它是一个庞大的主机,你可以尝试提交问题请求Python支持。
如果你就是自己的管理员,或者基于测试的目的想在自己的电脑上安装CGI,你就必须自己进行配置。因为每个服务器的配置选项都不用,所以配置CGI没有通用的方法。现在使用最广的免费服务器是
Apache HTTPd
,或者简称Apache。通过系统的包管理工具,Apache可以轻易地安装到几乎所有的系统。
lighttpd
则是另一个选项,据说有着更好的性能。在许多系统中,可以使用包管理工具来安装这个服务器,所以不再需要手动来编译它。
关于cgi脚本的常见问题
在运行CGI脚本的时候,时常会出现一些小的烦人的问题。有时看起来似乎正确的脚本不会像预期那样工作,原因是某些小的隐藏问题很难被发现。
以下是一些潜在的问题:
-
Python脚本没有被标记为可执行的。当CGI脚本不能被执行时,大部分服务器不会运行它并发送结果给用户,反而是让用户来下载它。在类Unix系统中,要正确运行CGI脚本,需要设置
+
x
位(修改执行权限)。使用
chmod a
+
x your_script
.
py
可能会解决问题。
-
在类Unix系统中,编程文件行结束必须是Unix风格的。这相当重要,因为服务器会检查脚本文件的第一行(称为shebang),并尝试运行那里指定的程序。如果是Windows的行结束(回车和换行Carriage Return&Line Feed, 所以称为CRLF),服务器就很容易混淆。因而你要将文件转为Unix的行结束(只有换行Line Feed,LF)。在通过FTP上传文件时,选择文本模式而非二进制模式,转换就可以自动完成。但更好的方式是在编辑器中用Unix风格的行结束保存文件。目前大多数的编辑器都支持这一选项。
-
你的Web服务器必须能够读取文件,还要保证相关权限的正确。在类Unix系统中,服务器常在用户和用户组为
www
-
data
的状态下运行。所以可以试着去修改文件的所有权,或者用
chmod a
+
r your_script
.
py
命令将文件改为可读状态。
-
在类Unix系统中,shebang(#!/usr/bin/env python)中解释器的路径必须正确。这行代码在
/usr/
bin
/
python
中寻找Python,但如果该目录不存在或者路径不正确,查找都会失败。你如果知道你的Python安装在哪里,可以使用绝对路径。命令
whereis python
和
type
-
p python
都能帮助你找到它的安装位置。一旦你知道了正确的路径,你就可以相应地修改shebang:
#!/usr/bin/python
。
-
文件中不能包含BOM(Byte Order Mark)。使用BOM意味着使用UTF-16或UTF-32编码,但有的编辑器也将这些内容写进UTF-8编码的文件。BOM干扰了shebang一行,所以要确保你的编辑器不要将BOM写到文件中。
-
如果Web服务器在使用
mod_python
,
mod_python
可能会有问题。
mod_python
能够自己处理CGI脚本,但也能成为问题的源头。
mod_python
从PHP来的人经常很难抓住用Python进行Web开发的要领。他们第一时间想到的通常是
mod_python
,因为他们想
mod_python
等价于
mod_php
。事实上,它们之间有很多不同。
mod_python
做的是将解释器嵌入到Apache的进程里,这样就不用再为每个请求各启动一个解释器,从而加快了运行速度。另一方面,PHP经常混合着HTML,但Python不是。实际上,在Python中与之相当的是模板引擎。比起
mod_php
,
mod_python
本身要强大得多,它提供了更多的权限来访问Apache的内部。在一个Python混合HTML的"Python服务器页面"模式(与JSP相似)下,它可以模拟CGI工作。它还有一个"发布者",可以指定一个文件来接收所有请求并决定接下来如何处理它们。
mod_python
确实有很多问题。不同于PHP解释器,Python解释器在运行文件时是使用缓存的,所以修改文件时需要重启服务器。另一个问题是关于Apache的工作原理 --- Apache启动子进程来处理请求,即使用不到Python,每个子进程依然要加载整个Python解释器。这让整个服务器运行得更慢了。另一个问题则是,如果不重新编译
mod_python
,它就不能切换版本(例如从2.4升级到2.5),理由是
mod_python
依赖于一个特定版本的
libpython
。还有,
mod_python
是绑定到Apache上的,所以用
mod_python
写的程序不能轻易移植到在其他Web服务器上。
已经有很多原因解释了应该避免用
mod_python
写新的程序。在特定情况下,使用
mod_python
进行开发还是不错的,但自从WSGI出现后,我们就可以在
mod_python
下运行WSGI程序了。
FastCGI和SCGI
FastCGI和SCGI尝试以另一种方式解决CGI的性能问题。取代了在Web服务器中嵌入解释器的做法,它们使用了一个长时间运行的后台进程。这还是一个能让服务器与后台进程"说话"的模块。既然后台进程独立于服务器,它就可以用包括Python在内的任何语言来完成。使用的语言只需要一个能处理与Web服务器通信的库。
正如SCGI本质上就是一个"简单的FastCGI",FastCGI和SCGI之间的差距非常小。因为仅有少数的服务器支持SCGI,大多数人使用工作方式相似的FastCGI。几乎所有能应用于SCGI的也能应用于FastCGI,所以我们只讨论后者。
如今,FastCGI不再被直接使用。就像
mod_python
,它只在WSGI的应用开发中使用。
安装配置FastCGI
每个Web服务器都需要一个特定的模块。
一旦你将模块安装配置完成,就可以用下面的WSGI应用进行测试:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys, os
from html import escape
from flup.server