欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Tornado路由與Application的實現(xiàn)

 更新時間:2023年05月16日 09:47:19   作者:tracy小貓  
本文主要介紹了Tornado路由與Application的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

路由原理

在Tornado框架中,路由是指將請求的URL映射到對應(yīng)的處理函數(shù)上,這個過程需要通過正則表達(dá)式來實現(xiàn)。Tornado使用了一種叫做Application的類來封裝整個Web應(yīng)用程序.我們定制一個Applicaiton繼承tornado的Application

from tornado.web import Application as tornadoApp
class Application(tornadoApp):
? ? """ 定制 Tornado Application 集成日志、sqlalchemy 等功能 """
? ? def __init__(self):
? ? ? ? self.ops_mongo = None ?# ops mongo
? ? ? ? self.redis_cluster = None ?# redis基礎(chǔ)session
? ? ? ? self.redis_manager = None ?# redis_manager session
? ? ? ? self.redis = None
? ? ? ? tornado_settings = {
? ? ? ? ? ? 'autoreload': settings.service.server.autoreload,
? ? ? ? ? ? 'debug': settings.service.server.debug,
? ? ? ? ? ? "default_handler_class": DefaultHandler,
? ? ? ? }
? ? ? ? route = getRoutes(settings)
? ? ? ? self.prepare()
? ? ? ? super(Application, self).__init__(handlers=route, **tornado_settings)
? ? def prepare(self):
? ? ? ? self.redis_cluster = asyncio.get_event_loop().run_until_complete(
? ? ? ? ? ? init_cluster()
? ? ? ? )
? ? ? ? self.ops_mongo = asyncio.get_event_loop().run_until_complete(
? ? ? ? ? ? init_ops_mongodb()
? ? ? ? )
? ? ? ? loop = asyncio.get_event_loop()
? ? ? ? self.redis = RedisPool(loop=loop).get_conn()
? ? ? ? self.redis_manager = RedisManager(self.redis)
? ? ? ? asyncio.get_event_loop().run_until_complete(
? ? ? ? ? ? create_all_indexes()
? ? ? ? )
? ? async def on_close(self, server_conn: object) -> None:
? ? ? ? await self.redis_manager.close()
? ? ? ? logger.info("close redis")
? ? ? ? self.ops_mongo.close()
? ? ? ? logger.info("close mongo")

這段代碼定義了一個繼承自 Tornado Application 的自定義 Application 類,并在初始化中進(jìn)行了一些準(zhǔn)備工作。

首先,定義了幾個實例變量,包括 ops_mongo(mongoDB 數(shù)據(jù)庫連接)、redis_cluster(基于 redis 的 session)、redis_manager(管理 redis 連接)和 redis(redis 數(shù)據(jù)庫連接)。

然后,根據(jù)配置文件中的設(shè)置,設(shè)定了 Tornado Application 的一些參數(shù),并根據(jù)路由設(shè)置得到路由列表。

接下來,調(diào)用了 prepare 方法,該方法中通過異步方法初始化了 ops_mongo(mongoDB 數(shù)據(jù)庫連接)、redis_cluster(基于 redis 的 session)和 redis(redis 數(shù)據(jù)庫連接),并創(chuàng)建了 redis_manager 實例管理 redis 連接。最后,調(diào)用了異步方法 create_all_indexes,創(chuàng)建了所有的索引。
最后,定義了一個異步方法 on_close,在 Web 服務(wù)關(guān)閉時關(guān)閉了 redis_manager 實例和 ops_mongo 實例。同時加入了一些對于關(guān)閉的日志信息。

class DefaultHandler(tornado.web.RequestHandler):
? ? def get(self):
? ? ? ? raise tornado.web.HTTPError(
? ? ? ? ? ? status_code=404,
? ? ? ? ? ? reason="Not Found"
? ? ? ? )
? ? def write_error(self, status_code, exc_info=None, **kwargs):
? ? ? ? self.finish({"error": self._reason})
def getRoutes(setting):
? ? Routes = [
? ? ? ? (r"/redis", home.TestRedisHandler),
? ? ]
? ? return Routes

該代碼是使用 Tornado 框架定義一個繼承自 tornado.web.RequestHandler 的 DefaultHandler 類,包含兩個方法 get 和 write_error。

  • get 方法會拋出一個 HTTPError,表示請求的頁面不存在或其他錯誤,會返回一個 404 的狀態(tài)碼和 Not Found 的原因。
  • write_error 方法會在遇到未處理的異常時自動調(diào)用,可以自定義錯誤響應(yīng)的方式。這里定義的行為是結(jié)束響應(yīng)并返回一個包含錯誤信息的 JSON 對象

另外,getRoutes 方法定義了一個以元組形式表示的 URL 路由表,將 /redis 映射到名為 TestRedisHandler 的類。

RequestHandler的功能

在Tornado中,RequestHandler是處理每個HTTP請求的基礎(chǔ)類,所有的請求處理類都應(yīng)該繼承自它。RequestHandler有如下幾個常用的方法:

  • initialize():初始化方法,在請求處理類實例化時自動調(diào)用,用于設(shè)置一些參數(shù)或進(jìn)行一些初始化操作。
  • prepare():在處理請求前調(diào)用,用于進(jìn)行一些安全檢查、身份驗證等操作,并且可以自定義錯誤頁面。
  • get()、post()等:根據(jù)HTTP請求方式的不同,提供相應(yīng)的get()、post()等方法來處理請求,并返回相應(yīng)的HTTP響應(yīng)。
  • write()、finish():用于返回響應(yīng)數(shù)據(jù),并結(jié)束請求處理。
  • redirect()、set_header()等:提供一些常用的HTTP響應(yīng)輔助方法。
class BaseHandler(RequestHandler, ABC):
????traceid = None
????start_time = None
????# 普通返回
????response_dict = {'code': 0, 'message': "", 'tid': "", 'data': None}
????# 分頁返回
????response_page_dict = {'code': 0, 'message': "", 'tid': "", 'data': None, "pagination":
????????{"pagesize": 0, "pages": 0, "items": 0, "pageno": 0}
??????????????????????????}
????@classmethod
????def return_response(cls):
????????resp = AttrDict(cls.response_dict)
????????return resp
????@classmethod
????def return_page_response(cls):
????????resp = AttrDict(cls.response_page_dict)
????????return resp
????@classmethod
????def create_page(cls, response: AttrDict, total=None, pagesize=0, pageno=None):
????????response.pagination["items"] = total
????????response.pagination["pagesize"] = pagesize
????????response.pagination["pages"] = total // pagesize if total % pagesize == 0 else total // pagesize + 1
????????response.pagination["pageno"] = pageno
????????return response
????def get_request(self):
????????request_body = None
????????if self.request.body:
????????????request_body = tornado.escape.json_decode(self.request.body)
????????return request_body
????def return_json(self, response):
????????*"""*
**返回統(tǒng)一的*json*格式結(jié)果
*****:param*** *response:*
*"""*
** ?
**self.set_header("Content-Type", "application/json; charset=UTF-8")
????????self.response_dict = json.dumps(response, default=json_util.default)
????????self.write(self.response_dict)
????def prepare(self):
????????trace_id = self.request.headers.get("tid", None)
????????self.__class__.start_time = datetime.datetime.now()
????????if not trace_id:
????????????trace_id = str(uuid.uuid4())
????????????self.request.headers["tid"] = trace_id
????????self.__class__.traceid = trace_id
????def write_error(self, status_code, exc_info=None, api_code=None, **kwargs):
????????resp = self.return_response()
????????resp.code = status_code
????????resp.tid = self.traceid
????????ex = exc_info[1]
????????if isinstance(ex, Exception):
????????????err_msg = str(ex)
????????????resp.message = err_msg
????????if isinstance(ex, tornado.web.HTTPError):
????????????err_msg = str(ex)
????????????resp.message = err_msg
????????if isinstance(ex, tornado.web.HTTPError) and ex.log_message:
????????????err_msg = str(ex.log_message)
????????????resp.message = err_msg
????????self.response_dict = json.dumps(resp, default=json_util.default)
????????self.finish(resp)
????def on_finish(self):
????????# 處理完請求后輸出日志,將請求頭信息和響應(yīng)結(jié)果json化
????????end_time = datetime.datetime.now()
????????request_data = {
????????????"tid": self.request.headers.get("tid", None),
????????????"url": self.request.uri,
????????????"method": self.request.method,
????????????"remote_ip": self.request.remote_ip,
????????????"user_agent": self.request.headers["User-Agent"],
????????????"request_body": json.loads(self.request.body) if self.request.body else ""
????????}
????????response_data = {
????????????"status": self.get_status(),
????????????"response_body": json.loads(self.response_dict) if not isinstance(self.response_dict,
??????????????????????????????????????????????????????????????????????????????dict) else self.response_dict,
????????????"response_time": (end_time - self.start_time).microseconds / 1000
????????}
????????logger = get_logger("access")
????????logger.bind(**request_data).bind(**response_data).info("request success")

BaseHandler 的類,它繼承了 tornado.web.RequestHandler 和 abc.ABC 兩個類。該類提供了一些基礎(chǔ)方法,可以被繼承使用來構(gòu)建業(yè)務(wù)處理類。

這個類定義了兩種返回方式:普通返回和分頁返回。普通返回返回的數(shù)據(jù)格式有 code、message、tid 和 data 四個字段,其中 code 表示請求狀態(tài)碼,message 表示請求狀態(tài)消息,tid 表示請求追蹤 id,data 表示響應(yīng)數(shù)據(jù)。分頁返回在普通返回的基礎(chǔ)上加入了分頁參數(shù)信息,即 pageSize、pages、items 和 pageNo。

該類實現(xiàn)了三個類方法:return_response、return_page_response 和 create_page。return_response 返回普通返回的響應(yīng)對象,return_page_response 返回分頁返回的響應(yīng)對象,create_page 用于創(chuàng)建分頁響應(yīng)。

該類實現(xiàn)了三個實例方法:get_request、return_json 和 write_error。get_request 方法用于獲取請求體的 json 數(shù)據(jù),return_json 方法用于返回 json 格式的響應(yīng),write_error 方法用于處理請求出錯時返回的響應(yīng)。

該類實現(xiàn)了兩個鉤子函數(shù):prepare 和 on_finish。prepare 在請求進(jìn)入處理前被調(diào)用,可以用來獲取請求頭信息等,on_finish 在請求處理完后被調(diào)用,用于記錄日志等操作。

處理錯誤

在Tornado中,異常處理同樣也是一個非常重要的問題,異常處理可以讓我們在遇到錯誤時能夠有更好的反應(yīng)和處理。可以通過使用@tornado.web.appadvice()裝飾器或者重寫write_error()方法來進(jìn)行自定義錯誤處理。

import tornado.web
class CustomErrorHandler(tornado.web.RequestHandler):
????def write_error(self, status_code, **kwargs):
????????if self.settings.get("serve_traceback"):
????????????self.write('Some Exception occurs: {}'.format(kwargs['exc_info'][1]))
????????else:
????????????self.write('Some Exception occurs. We are on it!')
????????self.set_status(status_code)
class ErrorExample(tornado.web.RequestHandler):
????def get(self, error_printer):
????????if error_printer == "raise":
????????????raise Exception("An unknown error occurred.")
????????elif error_printer == "syntax":
????????????raise SyntaxError("There is a syntax error in your code.")
????????else:
????????????self.write("This is normal operation!")

上述代碼中,使用write_error()重寫了RequestHandler的默認(rèn)錯誤處理方式。當(dāng)我們訪問http://localhost:8888/err?error=syntax 時,會輸出 Some Exception occurs: There is a syntax error in your code

處理完成

tornado的RequestHandler是用于請求處理的基本類,其中on_finish是RequestHandler的一個方法,可以在請求處理完成后被調(diào)用。當(dāng)客戶端請求處理完成時,可以使用此方法進(jìn)行一些清理工作或日志記錄等操作,并將tornado 對象釋放回底層IOLoop。在on_finish方法內(nèi)可以進(jìn)行資源釋放、統(tǒng)計請求處理時間等工作。此外,在建立連接之前初始化某些對象或資源,也可以在on_finish方法中完成清理。

以下是RequestHandler的on_finish方法的聲明:

def on_finish(self) -> None:
????????"""
????????Finish this response, ending the HTTP request.
????????"""
????????pass

Tornado提供了很多的錯誤處理接口來幫助我們進(jìn)行異常處理。為了使Web程序更加的健壯,我們需要盡可能的考慮到各種可能出現(xiàn)的錯誤情況,并對異常情況進(jìn)行適當(dāng)?shù)奶幚怼?/p>

到此這篇關(guān)于Tornado路由與Application的實現(xiàn)的文章就介紹到這了,更多相關(guān)Tornado路由與Application內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python實現(xiàn)sublime3的less編譯插件示例

    python實現(xiàn)sublime3的less編譯插件示例

    這篇文章主要介紹了python實現(xiàn)sublime3的less編譯插件示例的相關(guān)資料
    2014-04-04
  • 在arcgis使用python腳本進(jìn)行字段計算時是如何解決中文問題的

    在arcgis使用python腳本進(jìn)行字段計算時是如何解決中文問題的

    這篇文章主要介紹了在arcgis使用python腳本進(jìn)行字段計算時是如何解決中文問題的,需要的朋友可以參考下
    2015-10-10
  • 控制Python浮點數(shù)輸出位數(shù)的操作方法

    控制Python浮點數(shù)輸出位數(shù)的操作方法

    在python的輸出結(jié)果中,尤其是浮點數(shù)的輸出,當(dāng)我們需要寫入文本文件時,最好是采用統(tǒng)一的輸出格式,這樣也能夠增強結(jié)果的可讀性,這篇文章主要介紹了控制Python浮點數(shù)輸出位數(shù)的方法,需要的朋友可以參考下
    2022-04-04
  • Python實現(xiàn)合成多張圖片到PDF格式

    Python實現(xiàn)合成多張圖片到PDF格式

    在日常生活中,經(jīng)常會遇到需要提交身份證正反面證明資料的情況,而且這些網(wǎng)站大部分只接受pdf格式,這時候我們就需要把身份證正反面兩張圖片合成為一個pdf文件。本文將為大家提供用Python實現(xiàn)這一要求的方法,需要的可以參考一下
    2022-02-02
  • python實現(xiàn)與redis交互操作詳解

    python實現(xiàn)與redis交互操作詳解

    這篇文章主要介紹了python實現(xiàn)與redis交互操作,結(jié)合實例形式分析了Python Redis模塊的安裝、導(dǎo)入、連接與簡單操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2020-04-04
  • Python中使用bidict模塊雙向字典結(jié)構(gòu)的奇技淫巧

    Python中使用bidict模塊雙向字典結(jié)構(gòu)的奇技淫巧

    bidict模塊通過一對一映射結(jié)構(gòu)的處理為Pyhton帶來雙向字典,能夠更加利用Python的切片功能,這里我們就來學(xué)習(xí)Python中使用bidict模塊雙向字典結(jié)構(gòu)的奇技淫巧:
    2016-07-07
  • Python 通過分隔符分割文件后按特定次序重新組合的操作

    Python 通過分隔符分割文件后按特定次序重新組合的操作

    這篇文章主要介紹了Python 通過分隔符分割文件后按特定次序重新組合的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Windows 平臺做 Python 開發(fā)的最佳組合(推薦)

    Windows 平臺做 Python 開發(fā)的最佳組合(推薦)

    在 Windows 上如何做 Python 開發(fā)呢?相信大神們都會有自己的解決方案,但本文希望介紹微軟官方發(fā)布的 Terminal 和 Visual Studio Code,希望它們能構(gòu)建更流暢的 Windows 開發(fā)體驗,感興趣的朋友跟隨小編一起看看吧
    2020-07-07
  • Pandas加速代碼之避免使用for循環(huán)

    Pandas加速代碼之避免使用for循環(huán)

    如果你使用Python和Pandas進(jìn)行數(shù)據(jù)分析,循環(huán)是不可避免要使用的。這篇文章主要給大家介紹了關(guān)于Pandas加速代碼之避免使用for循環(huán)的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • python?離散點圖畫法的實現(xiàn)

    python?離散點圖畫法的實現(xiàn)

    本文主要介紹了python?離散點圖畫法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評論