Python集成tornado搭建web基礎框架

一、綜述

基於興趣嘗試使用Python開發語言搭建一個基礎的web框架,本次採用的方案是集成tornado方式。項目源碼

二、開發環境

系統需要具備以下開發環境:

三、python下載tornado庫

如果當前的環境裏沒有tornado依賴庫,使用以下命令安裝

	pip install tornado

四、基於Python3.x搭建web框架

需具備上述開發環境後,方可進入以下搭建流程。推薦使用PyCharm開發工具,也可以使用其他的開發工具替代。

1. 項目目錄介紹

config.py:項目環境的基礎配置文件
application.py:自定義tornado Application啓動類,自定義相關的配置等
server.py:項目的啓動類
views:項目的路由定義及相關業務處理的目錄,類似SpringBoot中的controller
static:該目錄爲項目的靜態資源目錄,用於存放js/css/img等靜態資源
templates:該目錄爲項目的模板頁面資源文件,用於渲染相關的顯示頁面
upfile:該目錄爲項目的文件上傳基礎目錄

2.項目配置文件config.py

該文件統一管理項目的配置文件,包含啓動的端口,tornado支持的一些web啓動配置參數,項目的請求路由註冊等。

import os

"""
#config
    配置參數
"""
options = {
    "port": 8080
}

"""
#config
配置文件,相當於django裏面的setting
配置application應用程序路由,即文件地址路徑
BASE_DIRS = os.path.dirname(__file__)
當前file文件路徑
##os.path.join(BASE_DIRS,"static")
拼接路徑:如(BASE_DIRS/static),當然BASE_DIRS=當前文件的父類的文件路徑
"""
BASE_DIRS = os.path.dirname(__file__)
print("******config******")
print("BASE_DIRS",BASE_DIRS)

"""
    靜態路由配置
"""
STATIC_ROUTERS_CONFIGS = {
    "STATIC_PATH":os.path.join(BASE_DIRS,"static"),
    "CSS_URL": os.path.join(BASE_DIRS,"static","css"),
    "JS_URL":os.path.join(BASE_DIRS,"static","js"),
    "IMG_URL":os.path.join(BASE_DIRS,"static","img")
}

"""
    tornado配置
"""
settings = {
    "static_path": os.path.join(BASE_DIRS, "static"),  # 靜態文件
    # "static_url_prefix": "/static",
    "template_path": os.path.join(BASE_DIRS, "templates"),  # 視圖
    "compiled_template_cache":True,
    "autoescape":None,
    "debug": True,
    "cookie_secret": "OrGWKG+lTja4QD6jkt0YQJtk+yIUe0VTiy1KaGBIuks",
    "xsrf_cookies": True,
    "login_url": "/login"
}

3.項目自定義Web Application

  • (1)創建MainApplication繼承tornado.web.Application,自定義相關的靜態資源路由配置。
  • (2)**all_router_configs()**方法爲抽取的views目錄下定義的路由接口,這樣可以按模塊定義相應的路由和處理的Handler,下面會詳細說到。
import tornado.web
import os
import config
from views import *
from config import settings
from tornado.web import StaticFileHandler,URLSpec

"""
    創建Application
"""
class MainApplication(tornado.web.Application):
    def __init__(self):
        # BASE HANDLERS
        handlers = [
            # 靜態文件
            URLSpec(r"/static/(.*)", StaticFileHandler, {"path": config.STATIC_ROUTERS_CONFIGS["STATIC_PATH"]}),
            URLSpec(r"/css/(.*)", StaticFileHandler, {"path": config.STATIC_ROUTERS_CONFIGS["CSS_URL"]}),
            URLSpec(r"/js/(.*)", StaticFileHandler, {"path": config.STATIC_ROUTERS_CONFIGS["JS_URL"]}),
            URLSpec(r"/img/(.*)", StaticFileHandler, {"path": config.STATIC_ROUTERS_CONFIGS["IMG_URL"]}),
        ]
        # SERVICE HANDLERS
        handlers.extend(all_router_configs())
        super().__init__(handlers=handlers, **settings)
        print("******tornado web application configs******")
        print("handlers", handlers)
        print("setting", config.settings)

4.項目啓動類server.py

項目的啓動入庫類server.py,啓動命令:python server.py

import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options
import config           #導入自定義配合的py文件
import application      #導入自定義的應用程序模塊

"""
    server服務配置
"""
if __name__ == "__main__":
    app = application.MainApplication()
    httpServer = tornado.httpserver.HTTPServer(app)
    httpServer.bind(config.options["port"])
    httpServer.start(1)
    print("server success start, port:",config.options["port"])
    tornado.ioloop.IOLoop.current().start()

5. views下路由定義介紹

views目錄爲項目所有的路由定義的地方及相關業務處理的模塊,建議按業務模塊化的方式管理。

5.1 自定義路由接口ViewRouterInterface

接口統一定義獲取註冊路由方法,便於獲取每個handler註冊的路由配置。

"""
    統一定義路由配置URL
"""
from abc import ABCMeta,abstractmethod

"""
    定義公共的路由方法
"""
class ViewRouterInterface(metaclass=ABCMeta):
    """
        配置路由,要求返回數組行駛
    """
    @abstractmethod
    def configRouter(self):
        raise NotImplementedError

5.2 views package默認的初始化文件__init__.py

  • (1)python中每當導入一個package時會默認先執行相關的__init__.py文件,可以藉此時機獲取項目裏所有註冊的handler。
  • (2)ALL_HANDLERS爲項目裏註冊的業務處理Handler,應爲RequestHandler的子類
  • (3)all_router_configs方法爲views包下的全局方法,用於獲取每個ALL_HANDLERS裏配置的相關路由和請求處理器。
"""
    請求路由定義及相關的業務處理
    Handler相當於Web中的Controller
    ViewRouterInterface定義了獲取路由配置的統一接口
        即configRouter方法返回路由配置數組
"""
print("******start to import view Request Handler packages******")
from views.test.TestHandlerKit import TestHandler
from views.index.index import IndexHandler,LoginHandler
from views.upload.UploadUtilsHandlerKit import UploadFileHandler

# 定義所有的RequestHandler
ALL_HANDLERS = [
    TestHandler,IndexHandler,LoginHandler,UploadFileHandler
]

"""
    獲取所有的路由
"""
def all_router_configs():
    allRouters = []
    for viewRouterInterface in ALL_HANDLERS:
        routerConfigs = viewRouterInterface.configRouter(viewRouterInterface)
        if routerConfigs is None:
            continue
        allRouters.extend(routerConfigs)
    print("ALL ROUTER CONFIGS",allRouters)
    return allRouters

5.3 自定義TestHandler

  • (1)按照模塊化管理的思想,在views目錄下創建test文件夾,創建TestHandler.py文件。
  • (2)TestHandler繼承ViewRouterInterface和RequestHandler類。
  • (3)繼承ViewRouterInterface是爲了自定義相關的路由及處理Handler。
  • (4)繼承RequestHandler,實現其中的get和post方法用於處理Http的GET請求和POST請求,類似SpringBoot中的Controller。
from tornado.web import RequestHandler
from views.ViewRouterInterface import ViewRouterInterface

"""
    Test view
"""
class TestHandler(ViewRouterInterface,RequestHandler):
    # 配置路由
    def configRouter(self):
        return [
            (r"/test",TestHandler)
        ]

    # Get方法
    def get(self):
        items = ["item1", "item2", "item3"]
        items2 = ["item1", "item2"]
        def checked(item):
            return 'checked=checked' if item in items2 else ''
        self.render("test/test.html", items=items, add=add, items2=items2, checked=checked)

"""
    Html Page Function
"""
def add(x, y):
    return (x+y)

5.4自定義test.html模板頁面

  • (1)按照模板化管理的思想,建議模板頁面同樣使用模塊化文件夾管理的方式,在templates目錄下創建test目錄。
  • (2)創建test.html文件,簡單demo顯示Handler返回的結果及調用Handler裏自定義的函數。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test1 HTML</title>
</head>
<body>
        {% for item in items %}
		        <li>{{ escape(item) }}</li>
		        <li>
		             <input  value={{item}} name={{item}}  type="checkbox"
		             {{checked(item)}}
		             /> {{item}}
		       </li>
		{% end %}
		add func test: 2+2={{ add(2,2) }}
</body>
</html>

6.啓動項目

啓動方式:

python server.py

在這裏插入圖片描述

7.訪問請求

http://localhost:8080/test
在這裏插入圖片描述

五、總結

工作之餘學習瞭解下如何基於python開發語言實現一個web開發框架,若有不足或者錯誤之處,請多多指教!!!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章