Flask是一個使用python開發Web程序的框架。依賴於Werkzeug提供完整的WSGI支持,以及Jinja2提供templates支持。Flask的設計理念是提供Micro以及方便的框架。"Micro"是由於除了提供基本特性功能的實現外,其餘的功能(例如數據庫訪問)都是經過extension來完成。方便的特色是由於提供了簡單易用的必要特性和功能,提供的功能包含:python
Flask使用jinja2做爲templates引擎。jinjia2的默認的語法設定以下:sql
Flask經過test_client提供了很是簡單的方式來建立測試的上下文環境(Local Context)。這樣能夠經過各類方式來完成單元測試,最基本的方式是經過python自帶的unittest來完成集成的測試用例。數據庫
使用unittest的Flask單元測試的框架以下:express
import os import xxxx import unittest import tempfile class XxxxTestCase(unittest.TestCase): def setUp(self): self.db_fd, xxxx.app.config['DATABASE'] = tempfile.mkstemp() xxxx.app.config['TESTING'] = True self.app = xxxx.app.test_client() xxxx.init_db() def tearDown(self): os.close(self.db_fd) os.unlink(xxxx.app.config['DATABASE']) if __name__ == '__main__': unittest.main()
在上述例子裏面:flask
在tearDown函數裏面,關閉了數據庫文件並刪除。
在unittest中測試用例的函數必須喲以test單詞開始,例如testFunc1
,這樣測試框架能夠將此函數做爲測試用例執行。執行測試用例以前先執行setUp函數進行初始化,以後執行tearDown進行資源釋放。基本的測試用例以下:安全
def testemptydb(self):
rv = self.app.get('/')
assert 'No entries here so far' in rv.data服務器
unittest框架經過setUp建立了testclient以及須要的上下文環境,而且在tearDown函數裏面進行銷燬。一樣可使用testclient在任意代碼中完成驗證測試。由於test_client建立了一個臨時的上下文環境,在任何區域中均可以經過with語句是此context在範圍內有效,所以在這個範圍內能夠驗證request以及session的信息。
驗證request信息的簡單例子:網絡
with app.test_client() as c: rv = c.get('/?number=42') assert request.args['number'] == '42'
驗證session信息的簡單例子:session
with app.test_client() as c: rv = c.get('/') assert flask.session['foo'] == 42
若是須要修改testclient建立的臨時context中的session信息,能夠經過sessiontranscation來獲取session對象進行修改。以下簡單實例:app
with app.test_client() as c: with c.session_transcation() as sess: sess['a_key'] = 'a value'
在程序中,錯誤永遠沒法避免,錯誤有多是代碼邏輯問題,服務器問題,網絡問題或者是硬件問題,環境問題等等。Flask提供了兩種方式定位問題,其一能夠打開程序的調試模式,經過調試器(debugger)跟蹤程序的執行信息;另外就是Flask提供了完善的日誌系統,記錄程序的運行信息。
Flask經過必要的參數設置,來肯定是否使用Debug模式以及是否使用自帶的調試器。這些參數包含:
若是使用第三方相似於Aptana/Eclipse等調試器,須要設置debug爲True,usedebugger和usereloader爲False。
經過內置的debugger,當程序出現exception時,在錯誤界面提供一個交互式的界面,並且在這個界面裏面能夠執行任意的代碼進行程序調試。這樣存在着巨大的安全隱患,所以永遠不要在產品服務器上開啓調試模式。
Flask附帶的Logger依賴於Python內置的日誌系統,經過默認Logging庫設置日誌的處理Handler,日誌Format以及處理的Level。程序中經過Flask的Logger所寫的Log經過系統自帶的日誌系統進行過濾和格式化,而後輸出到所設置的Handler中。
handler能夠是文件也能夠是郵件,通常狀況下的應用場景是,將大部分的日誌信息保存到文件中,將重點須要關注的日誌信息發送到郵件中。
文件Handler。文件Handler包含四種:
郵件Handler。一般使用smtphandler進行郵件發送。
Handler的簡單示例以下:
if not app.debug:
import logging
from logging.handler import SMTPHandler, FileHandler
file_handler = FileHandler(/var/test/flask.log) file_handler.setLevel(logging.WARNING) email_handler = SMTPHandler('127.0.0.1', 'server-error@example.com' ADMINS, 'Your Application Failed!!!') app.logger.addHandler(file_handler) app.logger.addHandler(email_handler)
Formatter是Python自帶的日誌系統提供的,能夠對Handler進行設置須要保存的信息格式。通常狀況下,在郵件Handler中保存詳細的多行文本信息;在文件Handler裏面保存單行重要信息。Log的格式參數以下:
Email日誌格式設置的簡單示例:
from logging import Formatter mail_handler.setFormatter(Formatter(''' Message type: %(levelname)s Location: %(pathname)s:%(lineno)d Module: %(module)s Function: %(funcName)s Time: %(asctime)s Message: %(message)s '''))
文件日誌格式設置的簡單示例:
from logging import Formatter file_handler.setFormatter(Formatter( '%(asctime)s %(levelname)s: %(message)s ' '[in %(pathname)s:%(lineno)d]' ))
Flask中使用的第三庫都有本身的日誌策略,一樣可使用getlogger獲取每一個依賴庫的logger設置統一的Handler。以下示例:
from logging import getLogger loggers = [app.logger, getLogger('sqlalchemy'), getLogger('otherlibrary')] for logger in loggers: logger.addHandler(mail_handler) logger.addHandler(file_handler)