
踩在巨人的肩膀上。
weizetao @ 2012-01-05
最近工作不忙,一直做后臺(tái)的開發(fā),但對(duì)前端技術(shù)也很有興趣,正好朋友讓我?guī)退阋粋€(gè)小網(wǎng)站,遂開始了我的web開發(fā)之旅。我工作中基本都是linux下的C/C++,但我非常熱衷于Python,喜歡Python的Simple is power!再對(duì)Python下幾個(gè)web開發(fā)框架做了些了解,我相中了web.py這個(gè)輕量級(jí)的開發(fā)框架,它的自由、簡(jiǎn)單足以吸引任一個(gè)程序員。經(jīng)過兩周松松散散的時(shí)間,網(wǎng)站做的差不多了,在此還要非常感謝豆瓣上@davidx,因?yàn)閷W(xué)習(xí)他的開源blog程序讓我進(jìn)步迅速。
因?yàn)閣eb.py還不算一個(gè)流行的框架,資料也僅限于官網(wǎng)的cookbook,開發(fā)和部署的時(shí)候經(jīng)常遇到一些問題或是特殊業(yè)務(wù),這時(shí)就能展示web.py的優(yōu)點(diǎn)了所在了,因?yàn)檩p量級(jí),所以我們可以自己對(duì)源碼做些修改來適應(yīng)我們的需求。呵呵,下面是我對(duì)webpy的理解與認(rèn)識(shí),本文主要是研究webpy的程序架構(gòu)及數(shù)據(jù)流走向,因?yàn)榱私饬诉@些,就可以對(duì)自己的需求進(jìn)行有的放矢,整理如下:
一、源代碼目錄
application.py
應(yīng)用層,web程序的啟動(dòng)入口,對(duì)urls映射與環(huán)境變量做初始化,添加請(qǐng)求預(yù)處理函數(shù)add_processer,這里實(shí)現(xiàn)了http請(qǐng)求處理的主回調(diào)函數(shù)wsgifunc(),分析url映射到對(duì)應(yīng)的處理類并返回應(yīng)答。
template.py
應(yīng)用層,webpy中的模板功能。
from.py
應(yīng)用層,webpy實(shí)現(xiàn)的表單功能。
session.py
應(yīng)用層,實(shí)現(xiàn)session的管理,session是由cookies機(jī)制實(shí)現(xiàn)的,這里當(dāng)然也不例外,具體的實(shí)現(xiàn)有機(jī)會(huì)再去研究。。。但在這里可以看到可供配置的session選項(xiàng):
db.py
應(yīng)用層,提供訪問數(shù)據(jù)庫的操作,其實(shí)它就是對(duì)mysqldb進(jìn)行的封裝。我的程序中沒有用到它,而是用的是sqlalchemy,操作起來更方便。
webapi.py
應(yīng)用層,實(shí)現(xiàn)了操作config,header,input,cookies,HTTPERROR,Redirect的接口,還有服務(wù)器生成特定應(yīng)答的接口,比如生成NOT found,404等錯(cuò)誤的應(yīng)答報(bào)文。
wsgi.py
中間層,應(yīng)用層調(diào)用apprun的時(shí)候會(huì)進(jìn)入到這里,說它是中間層,因?yàn)檫\(yùn)行模式的選擇就在這里,它與上面的應(yīng)用層和下面的網(wǎng)絡(luò)層起到中間的紐帶關(guān)系。運(yùn)行模式就是runfcgi,runscgi,runsimple等,不同的方式,對(duì)應(yīng)著不同的網(wǎng)絡(luò)層實(shí)現(xiàn)。
httpserver.py
網(wǎng)絡(luò)層,運(yùn)行方式為cgi形式的網(wǎng)絡(luò)層實(shí)現(xiàn),它是基于Python已有的SimpleHTTPServer和BaseHTTPServer實(shí)現(xiàn)的。當(dāng)請(qǐng)求/static/時(shí)直接返回文件內(nèi)容,其它請(qǐng)求則調(diào)用指向application中wsgifunc()的handler。
wsgiserver/目錄下
網(wǎng)絡(luò)層,運(yùn)行方式為獨(dú)立程序時(shí)的網(wǎng)絡(luò)層實(shí)現(xiàn),wsgiserver.CherryPyWSGIServer是進(jìn)入到這里的入口,CherryPyWSGIServer包括線程池的初始化,工作線程初始化socket并開始監(jiān)聽等操作。
wserver = wsgiserver.CherryPyWSGIServer(server_address,wsgi_app, server_name="localhost")
sgi_app即時(shí)指向應(yīng)用層的handler,用于處理接收到的請(qǐng)求。
其它
utils.py
這個(gè)文件里實(shí)現(xiàn)了很多強(qiáng)大的功能,比如提供一些特殊數(shù)據(jù)結(jié)構(gòu),對(duì)字符串進(jìn)行特殊操作等,暫且就叫它“基礎(chǔ)元”吧。
net.py
提供測(cè)試ip,port是否可用,解決html/url等引用及安全編碼問題。
http.py
提供判斷網(wǎng)頁過期、是否存在更新,對(duì)網(wǎng)頁url前綴、query的一些操作。。。
二、程序結(jié)構(gòu)與數(shù)據(jù)流程
1.webpy程序結(jié)構(gòu)
webpy程序結(jié)構(gòu)我分為了四個(gè)大部分:
開發(fā)者:開發(fā)者站在所有層的最上面,調(diào)用webpy提供的一些功能接口,實(shí)現(xiàn)自己的web站點(diǎn)。
應(yīng)用層:對(duì)基于http協(xié)議的request進(jìn)行解析,并實(shí)現(xiàn)了一些基本警告、error的應(yīng)答格式,比如NOTFOUND,500應(yīng)答報(bào)文,提供了session,form,template,db等http服務(wù)器基本功能的接口等。
中間層:這里負(fù)責(zé)運(yùn)行模式的選擇,也就是根據(jù)WSGI公共接口選擇不同的底層實(shí)現(xiàn),只在啟動(dòng)服務(wù)的時(shí)候用到。
網(wǎng)絡(luò)層:接收發(fā)送數(shù)據(jù),將數(shù)據(jù)送給應(yīng)用層處理,再將應(yīng)答發(fā)送給請(qǐng)求者。
如下是我對(duì)webpy程序理解的框圖:
2.webpy數(shù)據(jù)流程
參見上圖可以很清晰的看書webpy的數(shù)據(jù)流走向,當(dāng)程序啟動(dòng)完畢,有新的request請(qǐng)求到來,首先接收網(wǎng)絡(luò)socket數(shù)據(jù),對(duì)request進(jìn)行初步分析,調(diào)用wsgi_app指向的func,就是application中的wsgigunc()進(jìn)行主要的業(yè)務(wù)處理,給出result后,再從上到下將data順序返回,最后通過socket發(fā)送出去。
其中有很多細(xì)節(jié)處理,我也沒有仔細(xì)看,特別是網(wǎng)絡(luò)層的代碼,應(yīng)用層中比較特殊的比如request的是/static/…路徑下,則直接去讀取該路徑下的文件并返回,若沒有該文件則返回NOTFOUND。在application的wsgifunc函數(shù)中,首先先執(zhí)行注冊(cè)在processers列表中的回調(diào)函數(shù),然后再根據(jù)URL映射關(guān)系匹配到對(duì)應(yīng)的類去執(zhí)行,具體處理類的操作就是開發(fā)者自己要干的事了。比如連接db,解析from、利用template、運(yùn)用session等。
愛華網(wǎng)


