web.py

web.py

web.py 是一個輕量級Python web框架,它簡單而且功能強大。web.py是一個開源項目。該框架由已故美國作家、Reddit聯合創始人、RSS規格合作創造者、著名計算機黑客Aaron Swartz開發。web.py目前已被很多家大型網站所使用。 web.py簡單易學,只要有Python基礎,掌握web.py就非常容易。

安裝

解壓並拷貝 web 資料夾到你的應用程式目錄下。 或者,為了讓所有的應用程式都可以使用,運行:

python setup.py install

注意: 在某些類unix系統上你可能需要切換到root用戶或者運行:

sudo python setup.py install

查看 推薦設定.

另外一個選擇是使用Easy Install. Easy Install 使用如下:

easy_install web.py

或者 PIP

sudo pip install web.py

安裝完畢之後,就可以正式開始web.py 之旅…

URL 處理

對於一個站點來說,URL 的組織是最重要的一個部分,因為這是用戶看得到的部分,而且直接影響到站點是如何工作的,在著名的站點如:del.icio.us ,其URLs 甚至是網頁界面的一部分。而web.py 以簡單的方式就能夠構造出一個強大的URLs。

在每個web.py 套用,必須先import web 模組:

import web

現在,我們須要告訴web.py URL 如何組織,讓我們以一個簡單例子開始:

urls = (

'/', 'index' )

在上面的例子中,第一部分(‘/’)是一個匹配URL 的正則表達式,像/,/help/faq,/item/(\d+),等等;第二部分(‘index’)是一個類名,匹配的請求將會被傳送過去。

現在,我們需要編寫index 類。當大部人瀏覽網頁的時候,他們都沒有注意到,瀏覽器是通過HTTP 跟World Wide Web 通信的。通信的細節不太重要,但要明白一點,用戶是通過URLs(例如 / 或者 /foo?f=1)來請求web 伺服器完成一定請求的(例如 GET 或者POST)。

GET 是最普遍的方法,用來請求一個頁面。當我們在瀏覽器里輸入“harvard.edu” 的時候,實際上它是向Web 伺服器請求GET ”/“。另一個常見的方法是POST,常用於提交特定類型的表單,例如利用信用卡付費和處理一個訂單。注意,GET URLs 能夠被搜尋引擎索引得到(想像一下Google 嘗試購買你網站上的所用物品)。

在我們的web.py 代碼中。我們清晰區分這兩種方法:

class index:

def GET(self):

return "Hello, world!"

當接收到一個GET 請求時,上面的GET 方法將會被web.py 調用。

好的。現在,我們只需添加最後一行代碼,讓web.py 啟動網頁套用:

if __name__ == "__main__": web.run(urls, globals())

上面告訴web.py 如何配置URLs,以及找尋的類在檔案中的全局命名空間。

整個code.py 檔案的內容如下:

import web

urls = ('/', 'index')

app = web.application(urls, globals())

class index:

def GET(self):

return "Hello world!"

if __name__ == "__main__":

app.run()

注意到沒有,雖然我說了很多東西,但實際上web 套用的代碼就只得上面的幾行,而且這是一個完整的web.py 套用。在你的命令行下輸入:

$ python code.py

Launching server: http://0.0.0.0:8080/

現在,你的web.py 套用已經啟動了伺服器。通過瀏覽器訪問http://localhost:8080/ 的話,會見到”Hello, world!“。在啟動伺服器的時候,你可以在python code.py 後面添加IP 地址/連線埠 來控制web.py 啟動的伺服器。例如:python code.py 8888。

調試

web.py 本身也提供調試的工具。在最後的“if name …” 代碼前面添加:

web.webapi.internalerror = web.debugerror

並在最後的“if name …” 添加”web.reloader“:

if __name__ == "__main__": web.run(urls, globals(), web.reloader)

上面的代碼會使你在調試的階段得到更多有用的信息。web.reloader 其實是一個中間件,當你在運行時修改了code.py 檔案後,web.reloader 會重新載入code.py 檔案,讓你在瀏覽器上立刻可以看到變化。如何有多何變化的話,還是需要重新啟動伺服器。web.py 也提供web.profiler ,可以輸出有用的信息,有關每個頁面的每個函式調用的次數,這用助於你改善代碼。

web.py 的確相當的小巧,應當歸屬於輕量級的web 框架。但這並不影響web.py 的強大,而且使用起來很簡單、很直接。在實際套用上,web.py 更多的是學術上的價值,因為你可以看到更多web 套用的底層,這在當今“抽象得很好”的web 框架上是學不到的 :) 如果想了解更多web.py,可以訪問web.py 的官方文檔。

開發

web.py 內置了web伺服器。可以按照 tutorial 學習如何寫一個Web套用。 寫完後,將你的代碼放到 code.py 並如下面的方法來啟動伺服器:

python code.py

打開你的瀏覽器輸入 http://localhost:8080/ 查看頁面。 若要制定另外的連線埠,使用 python code.py 1234。

產品

現在所運行 web.py 程式的web伺服器是挺不錯的, 但絕大多數網站還是需要更加專業一些的web伺服器。web.py 實現了 WSGI 並能在任何兼容它的伺服器上運行。 WSGI 是一個web伺服器與應用程式之間的通用API, 就如Java 的 Servlet 接口。 你需要安裝 flup (download here) 使web.py 支持with CGI, FastCGI 或 SCGI, flup提供了這些API的WSGI接口。

對於所有的CGI變數, 添加以下到你的 code.py:

#!/usr/bin/env python

並運行 chmod +x code.py 添加可執行屬性。

LightTPD

使用 方法

在產品中通過FastCGI結合lighttpd是web.py使用的一種推薦方法。 reddit.com 通過該方法來處理百萬次的點擊。

lighttpd config設定參考如下:

server.modules = ("mod_fastcgi", "mod_rewrite")

server.document-root = "/path/to/root/"

fastcgi.server = ( "/code.py" =>

(( "socket" => "/tmp/fastcgi.socket",

"bin-path" => "/path/to/root/code.py",

"max-procs" => 1

))

)

url.rewrite-once = (

"^/favicon.ico$" => "/static/favicon.ico",

"^/static/(.*)$" => "/static/$1",

"^/(.*)$" => "/code.py/$1"

)

在某些版本的lighttpd中, 需要保證fastcgi.server選項下的"check-local"屬性設定為"false", 特別是當你的 code.py 不在文檔根目錄下。

如果你得到錯誤顯示不能夠導入flup, 請在命令行下輸入 "easy_install flup" 來安裝。

從修訂版本 145開始, 如果你的代碼使用了重定向,還需要在fastcgi選項下設定bin-environment變數。 如果你的代碼重定向到http://domain.com/ 而在url欄中你會看到 http://domain.com/code.py/, 你可以通過設定這個環境變數來阻止。 這樣你的fastcgi.server設定將會如下:

fastcgi.server = ( "/code.py" =>

((

"socket" => "/tmp/fastcgi.socket",

"bin-path" => "/path/to/root/code.py",

"max-procs" => 1,

"bin-environment" => (

"REAL_SCRIPT_NAME" => ""

),

"check-local" => "disable"

))

)

Apache

使用 CGI

添加以下到 httpd.conf 或 apache2.conf。

Alias /foo/static/ /path/to/static

ScriptAlias /foo/ /path/to/code.py

.. 使用 CGI .htaccess

CGI很容易配置, 但不適合高性能網站。 添加以下到你的 .htaccess:

Options +ExecCGI

AddHandler cgi-script .py

將你的瀏覽器指向 http://example.com/code.py/。 不要忘記最後的斜槓,否則你將會看到 not found 訊息 (因為在 urls 列表中你輸入的沒有被匹配到). 為了讓其運行的時候不需要添加 code.py, 啟用mod_rewrite 法則 (查看如下)。

注意: web.py 的實現破壞了 cgitb 模組,因為它截取了 stdout。 可以通過以下的方法來解決該問題:

import cgitb; cgitb.enable()

import sys

# ... import web etc here...

def cgidebugerror():

"""

""" _wrappedstdout = sys.stdout

sys.stdout = web._oldstdout

cgitb.handler()

sys.stdout = _wrappedstdout

web.internalerror = cgidebugerror

配置方法

FastCGI很容易配置,運行方式如同mod_python。

添加以下到 .htaccess:

<Files code.py> SetHandler fastcgi-script

</Files>

不幸的是, 不像lighttpd, Apache不能夠暗示你的web.py腳本以FastCGI 伺服器的形式工作,因此你需要明確的告訴web.py。 添加以下到 code.py的 if __name__ == "__main__": 行前:

web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)

將你的瀏覽器指向 http://example.com/code.py/。 不要忘記最後的斜槓,否則你將會看到 not found 訊息 (因為在 urls 列表中你輸入的沒有被匹配到). 為了讓其運行的時候不需要添加 code.py, 啟用mod_rewrite 法則 (查看如下)。

Walter 還有一些額外建議.

使用 SCGI

https://www.mems-exchange.org/software/scgi/ 從 http://www.mems-exchange.org/software/files/mod_scgi/ 下載 mod_scgi 代碼 windows apache 用戶: 編輯 httpd.conf:

LoadModule scgi_module Modules/mod_scgi.so

SCGIMount / 127.0.0.1:8080

重啟apache,並在命令行中如下方式啟動code.py:

python code.py 127.0.0.1:8080 scgi

打開你的瀏覽器,訪問127.0.0.1 It's ok!

.. 使用 mod_python

mod_python 運行方式如同FastCGI, 但不是那么方便配置。

對於 Python 2.5 按照如下:

cd /usr/lib/python2.5/wsgiref

# or in windows: cd /python2.5/lib/wsgiref

wget -O modpython_gateway.py http://projects.amor.org/misc/browser/modpython_gateway.py?format=raw

# or fetch the file from that address using your browser

對於 Python <2.5 按照如下:

cd /usr/lib/python2.4/site-packages

# or in windows: cd /python2.4/lib/site-packages

svn co svn://svn.eby-sarna.com/svnroot/wsgiref/wsgiref

cd wsgiref

wget -O modpython_gateway.py http://projects.amor.org/misc/browser/modpython_gateway.py?format=raw

# or fetch the file from that address using your browser

重命名 code.py 為 codep.py 或別的名字, 添加:

app = web.application(urls, globals())

main = app.wsgifunc()

在 .htaccess 中, 添加:

AddHandler python-program .py

PythonHandler wsgiref.modpython_gateway::handler

PythonOption wsgi.application codep::main

你應該希望添加 RewriteRule 將 / 指向 /codep.py/

確保訪問 /codep.py/ 的時候有添加最後的 /。 否則,你將會看到一條錯誤信息,比如 A server error occurred. Please contact the administrator.

.. 使用 mod_wsgi

mod_wsgi 是一個新的Apache模組 通常優於mod_python 用於架設WSGI套用,它非常容易配置。

在 code.py 的最後添加:

app = web.application(urls, globals(), autoreload=False)

application = app.wsgifunc()

mod_wsgi 提供 許多可行方法 來實現WSGI套用, 但一種簡單的方法是添加以下到 .htaccess:

<Files code.py>

SetHandler wsgi-script

Options ExecCGI FollowSymLinks

</Files>

如果在apache的 error.log 檔案中出現 "ImportError: No module named web", 在導入web之前,你可能需要在code.py中嘗試設定絕對路徑:

import sys, os

abspath = os.path.dirname(__file__)

sys.path.append(abspath)

os.chdir(abspath)

import web

同時, 你可能需要查看 WSGI套用的常見問題的 "Application Working Directory" 部分。

最終應該可以訪問 http://example.com/code.py/。

mod_rewrite 法則,Apache

如果希望 web.py 能夠通過 'http://example.com' 訪問,代替使用 'http://example.com/code.py/', 添加以下法則到 .htaccess 檔案:

<IfModule mod_rewrite.c>

RewriteEngine on

RewriteBase /

RewriteCond %{REQUEST_URI} !^/icons

RewriteCond %{REQUEST_URI} !^/favicon.ico$

RewriteCond %{REQUEST_URI} !^(/.*)+code.py/

RewriteRule ^(.*)$ code.py/$1 [PT]

</IfModule>

如果 code.py 在子目錄 myapp/中, 調整 RewriteBase 為 RewriteBase /myapp/。 如果還有一些靜態檔案如CSS檔案和圖片檔案, 複製這些並改成你需要的地址。

相關詞條

熱門詞條

聯絡我們