編者注:咱們發現了有趣的系列文章《30天學習30種新技術》,正在翻譯,一天一篇更新,年終禮包。下面是第23天的內容。javascript
今天的《30天學習30種新技術》,我決定暫時放下 JavaScripts 的內容,而去學習一個叫作 Tornado 的 Web 框架。我決定去學 Tornado 的緣由是我這樣就能夠用 Python 去寫 Web 程序了。我只學過 Flask 框架,因此我以爲 Tornado 應該能增長我在 Python Web 開發方面的知識。咱們在這篇博文中描述的應用使用 Tornado 來做 REST 後端,MongoDB 做爲數據庫,AngularJS 做爲客戶端那邊的 JavaScripts MVC 框架,而後 OpenShift 做爲部署的平臺。
css
Tornado 是一個開源的 Python Web 框架,是一個非阻塞(non blocking)的的 Web 服務器, 最開始是在 FriendFeed開發的。在 FriendFeed 被收購以後,Facebook 維護並繼續發展 Tornado。因爲它的非阻塞網絡輸入輸出(non-blocking network I/O )特性,它有卓越的可擴展性,能同時支持一千多個鏈接。前端
在這篇博文中,咱們將會開發一個容許用戶發佈和分享連接的社交化書籤應用。你能夠在這裏看到真實在 OpenShift 上運行着的程序。這是咱們在 Day 22 開發過的應用,因此能夠參考那篇博文以便更好地理解這個應用案例。java
今天這個演示應用的代碼能夠在 GitHub 上獲得:day25-tornado-demo-app。python
在咱們開始 Tornado 以前,咱們須要在機器上安裝 Python 和 virtualenv。在這篇博文中,我使用的 Python 版本是 2.7git
這個應用使用 MongoDB 做爲數據存儲的軟件,因此請下載對應你所用操做系統的最新的 MongoDB 發行版。angularjs
咱們會使用 pip
安裝 Tornado。對於那些不熟悉 pip
的開發者,其實 pip
就是一個 Python 的包管理器。咱們能夠從官網安裝 pip
。打開終端,轉到任何一個在文件系統上方便的目錄,而後運行下面的命令:github
$ mkdir getbookmarks $ cd getbookmarks $ virtualenv venv --python=python2.7 $ . venv/bin/activate $ pip install tornado $ pip install pymongo
上面的命令會在本機上建立一個 getbookmarks 目錄,而後在 Python 2.7 下激活 virtualenv,而後安裝 tornado 包,最後安裝 pymongo。其中,pymongo 是官方 MongoDB 的 Python 驅動;咱們會使用它往 MongoDB 中寫入故事(stories)。web
在 getbookmarks 目錄下,建立一個名爲 getbookmarks.py 的文件:mongodb
$ touch getbookmarks.py
複製下面的代碼,而後粘貼到 getbookmarks.py 源文件中:
import os from tornado import ioloop,web from pymongo import MongoClient import json from bson import json_util from bson.objectid import ObjectId class IndexHandler(web.RequestHandler): def get(self): self.write("Hello World!!") settings = { "template_path": os.path.join(os.path.dirname(__file__), "templates"), "static_path": os.path.join(os.path.dirname(__file__), "static"), "debug" : True } application = web.Application([ (r'/', IndexHandler), (r'/index', IndexHandler), ],**settings) if __name__ == "__main__": application.listen(8888) ioloop.IOLoop.instance().start()
上面的代碼會執行下面的事情:
1. 咱們從導入須要的庫開始;
2. 下一步,咱們定義一個擴展類 web.RequestHandler 的新類:IndexHandler。一個 Tornado web 應用會把 URLs 或者 URL 模式對應到 web.RequestHandler 的子類。這些類定義了 get()
、post()
等方法去處理訪問這個 URL 的 HTTP GET 或者 POST 請求。當在地址 '/' 下收到一個 GET 請求時,IndexHandler 會返回一個 "Hello World!!"
3. 接着咱們定義了一些應用的設置。template_path
設置是告訴 Tornado 應用在 template
目錄尋找應用模板。static_path
設置告訴應用使用 static
目錄裏面的相似 css、圖像、javascript 文件等靜態文件。經過設置 debug
爲 True
,你對項目作了改變後,會自動重載,不用重啓查看效果。咱們會在應用開發過程當中,保持着調試器在後臺運行。這能提供高效的開發環境。
4. 接着,咱們建立一個Tornado 應用實例,把路由routes)和 settings
傳遞進去。
5. 最後,咱們使用 python getbookmarks.py
命令啓動服務器去運行這個應用
打開 http://localhost:8888 和 http://localhost:8888/index 看看是否看到 "Hello World!!"
在導入庫以後,增長下面的語句:
MONGODB_DB_URL = os.environ.get('OPENSHIFT_MONGODB_DB_URL') if os.environ.get('OPENSHIFT_MONGODB_DB_URL') else 'mongodb://localhost:27017/' MONGODB_DB_NAME = os.environ.get('OPENSHIFT_APP_NAME') if os.environ.get('OPENSHIFT_APP_NAME') else 'getbookmarks' client = MongoClient(MONGODB_DB_URL) db = client[MONGODB_DB_NAME]
咱們定義了 MongoDB 鏈接的路由和數據庫的名稱。若是應用是部署到 OpenShift 上,那麼 OpenShift 特定環境變量會先被使用,若是沒有,就會使用本機上的配置。
咱們建立了一個 MongoClient 實例,把鏈接的路由傳遞進去。這個鏈接路由是隻想運行着的 mongod 實例。接着咱們使用 MongoClient 實例使用數據庫
如今咱們要添加建立新的故事(stories)和列出全部故事(stories)的功能。咱們首先把路由加到下面的應用實例中:
application = web.Application([ (r'/', IndexHandler), (r'/index', IndexHandler), (r'/api/v1/stories',StoriesHandler), ],**settings)
接着,咱們定義一個把故事(stories)保存在 MongoDB 和在裏面查找全部故事(stories)的 StoriesHandler:
class StoriesHandler(web.RequestHandler): def get(self): stories = db.stories.find() self.set_header("Content-Type", "application/json") self.write(json.dumps(list(stories),default=json_util.default)) def post(self): story_data = json.loads(self.request.body) story_id = db.stories.insert(story_data) print('story created with id ' + str(story_id)) self.set_header("Content-Type", "application/json") self.set_status(201)
在上面的代碼中:
1. 當一個用戶發出一個 GET 請求到 /api/v1/stories
時,咱們會向 MongoDB 中發出一個 Find() 方法請求。因爲咱們沒有具體聲明是任何查詢,因此它會從 MongoDB 取出全部的故事。咱們把內容類型(content type)設置爲 application/json
,而後轉出(dump) json 迴應。
2. 當用戶發出一個 POST 請求到 /api/v1/stories
,而後咱們首先解碼 json 的內容到一個字典(dictionary),而後把數據寫入 MongoDB。咱們會把迴應狀態(response status)設爲 201(已建立)。
最後一個後端功能是查看單獨的故事,咱們首先指明路由:
application = web.Application([ (r'/', IndexHandler), (r'/index', IndexHandler), (r'/api/v1/stories',StoriesHandler), (r'/api/v1/stories/(.*)', StoryHandler) ],**settings)
咱們編寫 StoryHandler
class StoryHandler(web.RequestHandler): def get(self , story_id): story = db.stories.find_one({"_id":ObjectId(str(story_id))}) self.set_header("Content-Type", "application/json") self.write(json.dumps((story),default=json_util.default))
上面的代碼查找對應 story_id
的故事,而後轉出 json 迴應。
我決定重用我在 第 22 天 寫的前端。第 22 天的內容展現瞭如何以 Java Spring 框架做爲後端去使用 AngularJS。使用 JavaScripts MVC 架構的最好的地方就是你能夠重用前端的代碼,若是你的應用符合 REST 接口客戶端的要求。能夠閱讀第 22 天的內容瞭解更多。
你能夠在個人 GiHub 倉庫下載 AngularJS 前端。複製靜態文件和模板文件夾,粘貼到 getbookmarks.py 所在文件夾。
在構建應用以前,咱們須要作些設置:
註冊一個OpenShift帳號。註冊是徹底免費的,Red Hat給每一個用戶三枚免費的Gear,能夠用Gear運行你的應用。在寫做此文的時候,每一個用戶能無償使用總共 1.5 GB 內存和 3 GB 硬盤空間。
安裝 rhc客戶端工具。rhc
是ruby gem,所以你的機子上須要裝有 ruby 1.8.7以上版本。 只需輸入 sudo gem install rhc
便可安裝 rhc 。若是你已經安裝過了,確保是最新版。運行sudo gem update rhc
便可升級。關於配置rhc命令行工具的詳細信息,請參考: https://openshift.redhat.com/community/developers/rhc-client-tools-install
使用 rhc 的 setup 命令配置你的 OpenShift 帳號。這個命令會幫助你建立一個命名空間,同時將你的ssh公鑰上傳至 OpenShift 服務器。
輸入以下命令便可將應用部署到 OpenShift:
$ rhc create-app day25demo python-2.7 mongodb-2 --from-code https://github.com/shekhargulati/day25-tornado-demo-app.git
這個命令將建立應用,設置公開的DNS,建立私有git倉庫,最後利用你的Github倉庫中的代碼來部署應用。應用能夠經過 http://day25demo-shekhargulati.rhcloud.com/#/ 訪問。
今天就到這裏了,歡迎反饋意見。
原文 Day 25: Tornado--Combining Tornado, MongoDB, and AngularJS to Build an App
翻譯 SegmentFault