1. 程式人生 > >一線Python運維開發帶你秒懂Flask框架

一線Python運維開發帶你秒懂Flask框架

相信曾經糾結過這個問題:怎樣才能徹底掌握flask?

Flask是一個使用 Python 編寫的輕量級 Web 應用框架。其 WSGI 工具箱採用 Werkzeug ,模板引擎則使用 Jinja2 。Flask使用 BSD 授權。

 

Flask也被稱為 “microframework” ,因為它使用簡單的核心,用 extension 增加其他功能。Flask沒有預設使用的資料庫、窗體驗證工具。

今天我們邀請到了多年從事Python開發的不動老師,讓他為我們帶來flask開發的一線實戰。

 

不動:馬哥教育Python實戰開發講師團特邀講師,多年python開發經驗,重度flask使用者,當前從事 O2Oweb商城後端開發和運維開發的工作。

 

分享開始

大家好,下面現在開始分享flask開發,先看下本次分享的內容:

1、Flask Web框架介紹

Flask是微型web框架,框架本身十分精簡,微型並不代表其功能弱,核心程式碼基於Werkzeug, Jinja 2 這兩個庫,它以外掛形式的進行功能擴充套件,且外掛易於安裝與使用,並且可以自行開發擴充套件外掛

與其他web框架類似,flask中請求(request),路由(route),響應(response)構成其完整的一個基本http流程。

 

2、作為入門flask框架非常易於使用

瞭解其基本結構後,可以迅速進行MVC開發,或者將其當作後端restfulApi來響應資料。

 

第一步我們先來用虛擬環境安裝flask

虛擬環境,將當前執行環境完全與系統的python環境進行隔離,這裡我們使用pyenv這個庫來進行構建環境

以centos系統為例安裝虛擬環境:

1、yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel
2、curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer 
| bash

配置環境變數, 在 ~/.bash_profile裡增加如下內容:

export PATH="~/.pyenv/bin:$PATH“
eval "$(pyenv init -)" 
eval "$(pyenv virtualenv-init -)“

第二步 :在生成虛擬環境 啟用此pyenv

 

1、系統中一般自帶的python版本是python2.7.10


2、我們自行下載一個python版本是2.7.12


3、使用sohu的映象源:http://mirrors.sohu.com/python/ 
找到python版本是2.7.12的包下載到本地

為何需要使用虛擬環境? 因為虛擬環境對於每一個python環境來說是獨立開來的,用虛擬環境可以在一臺機器上執行多個專案時,每個專案的環境是隔離,不產生依賴。

 

4、如需其他版本也可以下載對應的版本放到~/.pyenv/cache資料夾下面(cache資料夾假如不存在,自行建立)

 

5、然後執行 pyenv install 版本號 安裝對應的python版本: pyenv install 2.7.12

 

6、安裝2.7.12版本成功後,建立一個目錄為完全隔離的python虛擬環境:

pyenv virtualenv 2.7.12 venv27

mkdir -pv virtu

cd virtu pyenv local venv27 cd .. cd virtu 自動激活了venv27環境

第三步 安裝pip

Pip是一個用來安裝python第三方庫的工具

sudo yum -y install epel-release (安裝yum包擴充套件)

sudo yum –y install pip

使用阿里雲的python包加速pip安裝

Pip 配置阿里雲映象:
mkdir ~/.pip
vim ~/.pip/pip.conf, 輸入以下內容
[global] index-url=http://mirrors.aliyun.com/pypi/simple/ 
trusted-host=http://mirrors.aliyun.com 

第五步安裝flask:

cd vnvn27 (剛才構建的虛擬環境,切換到了一個完全虛擬環境)

Pip install flask

Pip freeze 列出當前安裝的第三方python庫以及版本

執行python終端,import flask,可以測試是否安裝flask成功

 

2.0:wsgi規範

Python使用wsgi閘道器進行Web開發,flask基於wsgi閘道器,flask中例項的app,也稱之為一個wsgi 應用
Wsgi是python中定義的一種閘道器協議規範,pep333對此的相關解釋: https://www.python.org/dev/peps/pep-0333/

from wsgiref.simple_server import make_server

wsgiref包是實現了wsgi標準的一個參考,我們可以用它來進行除錯,此包一般用於測試環境,不建議生產環境中使用。
simple_server實現了一個簡易的http伺服器,我們可以用它來執行一個wsgi應用

 

2.1:wsgi規範2

下面示例我們可以用wsgiref這個包實現一個簡單的wsgi web框架來理解其工作流程:

 

 

2.2:wsgi規範3

上面的程式碼中,我們使用了wsgiref包簡易的實現了一個wsgiweb框架,其中我們依據傳入的env中獲取到url字尾來匹配router字典中對應的處理函式

Env引數是包含了客戶端請求的資訊和服務端的環境資訊,可以將其打印出來,看下其中包含的變數。

Start_response函式作為引數傳入runserver應用中,必須要start_response(status,header)來進行響應,它是由閘道器介面定義的函式。
在上述中可以看出,wsgi的作用是在web伺服器和web應用之間的橋樑,web伺服器監聽將客戶端請求轉發給實現wsgi規範介面處理,wsgi接將請求進行中轉給上層的web應用處理,web應用處理完成並生成響應返回給wsgi介面,然後web伺服器將收到的響應返回給客戶端。

 

2.3:一個最基本應用

Flask框架也是依據上面的規範實現的web框架,我們可以看下flask原始碼中對於上述的封裝,不過它做了更高層次的抽象

 

 

可以看到flask原始碼中使用wsgi_app和魔術方法__call__對 上述start_respones做了封裝。

接下里用flask執行一個hello wordl

 

2.4:一個最基本應用分析

/usr/bin/env python 
from Flask import flask
app = Flask(__name__)

@app.route('/') 
def index(): 
return ‘<h1>Hello World!</h1>‘
if __name__ == '__main__': 
app.run()
python hello.py

 

2.5:最基本應用

app = Flask(__name__) 程式碼使用Flask類生成一個應用例項
@app.route('/') 
def index():
return ‘<h1>hello world</h1>’
一個http過程中請求來自客戶端,http伺服器(nginx,Apache)再次將請求轉發給flask應用例項app,@app.route(‘/)中映射了url連結與一個python函式的對應關係,我們將index函式稱之為檢視函式。
比如訪問192.168.1.19 

---》app.route(‘/’)
訪問192.168.1.19/blog 

---》app.route(‘/blog’)

 

2.6:可變url

在一般業務中,url都是動態可變的,在flask中我們這樣設定可變url

@app.route(‘/hello/<name>’)

def hello(name):

return ‘<h1>hello {}’.format(name)

示例:

訪問192.168.1.19/hello/jack

訪問192.168.1.19/hello/rose

<name> 被尖括號抱起來的部分代表url中與python處理函式中對應的可變部分.

常用的有以下3種,定義可變的型別

<string:name>、<int:uid>、<path:prefix>

 

2.7:可變url自定義裝換器

定義可變url,除了上述的string之外,還有以下幾種int、float、path這三種,另外flask還可以通過werkzeug中的BaseConverter類,自定義轉換器。

這裡自定義一個轉換器

 

fromwerkzeug.routing import BaseConverter

classListConverter(BaseConverter):

def to_python(self, value):

return value.split('+')

def to_url(self, values):

return'+'.join(BaseConverter.to_url(value) for value in values)

將自定義轉換器加入到app應用url_map中,當客戶端輸入引數時,可以以,我們自行設定的分隔符做轉換
app.url_map.converters['list'] = ListConverter
@app.route('/home/<list:subs>')
def home(subs):
# 使用自定義型別
htm = ''
for sub in subs:
htm += '<h1>{}</h1>'.format(sub)
return htm

在生產環境中客戶端到服務端,使用python開發應用的一般流程是如下圖所示:

 

 

flask中的請求,請求是web開發中最重要特性之一

 

3.0 Flask入門:請求

from flask import request
@app.route(‘/hi’)
def hi():
name = request.args.get(‘name’)
return ‘<h1>hi {}</h1>’.format(name)
訪問:
192.168.1.19/hi?name=mike 

flask中request物件封裝了客戶端的請求引數
我們可以嘗試將print(request.__dict__)檢視請求上下文環境變數

request請求物件是flask內部封裝的一個全域性物件,這個物件是執行緒隔離的,必須執行在當前請求中的上下文,直接執行會報錯,它通過werkzeug模組中localproxy在localstack這種資料結構尋找當前請求
常見的request客戶端變數
request.args 獲取從客戶端url傳輸過來的查詢字串
request.form 獲取從客戶端表單提交過來的資訊
request.json 獲取從客戶端從請求body獲取的json字串
request.method 獲取客戶端使用的請求方法 
Request.files 獲取從客戶端請求過來的檔案

 

3.1 Flask入門:響應與會話

from flask import make_respones

flask中封裝了make_response作為客戶端響應,返回http頭資訊、狀態碼等,resp = make_respone(‘hello’.encode()),resp.set_cookie(‘name’, ‘jack’) ,將resp作為返回,可以手動靈活的增加了cookie

會話分為客戶端和服務端2種形式,from flask importsession 中封裝了基於客戶端的cookies,示例如下:

 

 

在app.config物件中儲存了flask的預設配置以及我們專案中寫入的配置變數,通常情況下flask中的一些配置如下

 

 

 

 

4.1 flask中的讀入配置

app = Flask(__name__) app.config.from_object(‘yourapplication.default_settings’) app.config.from_pyfile(’config.cfg’)
上面兩種都可以將配置檔案加入到app應用當中,其中app.config.from_object()方法會尋找配置檔案為類的配置

 

 

用函式封裝配置檔案寫入app,這樣可以依據引數來區分開發環境與生產環境的配置檔案。

 

 

4.2工廠方法建立app

什麼是工廠方法?工廠方法是一種設計模式,這裡使用可以簡單理解為通過一個函式來批量建立一個flask app物件,依據不同的引數來生成不同的app

 

 

4.3為何需要工廠方法建立app?

當需要執行app的時候,可以通過工廠方法傳遞引數來生成不同的app物件,方便的進行測試不同的app,並且生成多個app的時候可以進行分別進行請求處理,流量負載等,通過以下示例說明

 

 

5.0鉤子函式

flask中鉤子函式作用是將被裝飾的函式註冊到app當中,在不同階段執行。

app.first_request: 在第一次請求之前執行

app.before_request: 在每次請求之前執行,可以用它來封裝中間鍵,效果類似於django middleware

app.after_request: 在每次請求之後執行

app.teardown_appcontext: 不管是否有異常出現,都會在每次請求之後執行

app.errorhandler:接受狀態碼,並且自定義返回錯誤處理資訊頁面

 

5.1鉤子函式before_request

 

 

5.2鉤子函式errorhandler

 

 

5.3藍圖

藍圖將應用進行模組化,能夠很方便的將不同的功能和路由區分開,並且易於維護,藍圖基於相同的url字首來作區分。

功能類似的檢視函式組合在一起作為藍圖的元件,將應用進行分割,極大簡化了大型應用的複雜度,藍圖要註冊到app物件中,藍圖的使用方式與app的使用方式很像

藍圖提供模板過濾器、靜態檔案、模板和其它功能

5.4藍圖生成

將user這些相似的功能分成一個藍圖模組,注意藍圖檔案不能和藍圖物件同名,否則會衝突報錯

 

 

5.5藍圖註冊

v 當以上user例項化時,必須將此註冊到app應用中,藍圖才能生效,url_prefix為自定義新增的url字尾

 

 

6.0flask擴充套件使用

v flask以外掛形式開發擴充套件功能,其中許多優秀第三方外掛可以直接使用,提升開發效率,常見專案開發用到的外掛有flask_sqlachemy、flask_redis、flask_login、flask_admin等等

v 外掛安裝一般使用 pip install <外掛名>,即可安裝

v 以下示例flask_sqlachemy使用,flask_sqlachemy是sqlalchemy的flask外掛,sqlalchemy是python界有名的工業級orm框架

 

6.1flask_sqlalchemy

v 例項化flask_sqlalchemy,生成db物件後續初始化到app中

 

 

6.2flask外掛初始化

v 由於db物件需要讀取app應用中配置,並且依賴app上下文工作,所以將上述db物件等擴充套件外掛初始化app,在每次app啟動之前完成繫結

 

 

6.3 flask_sqlalchemy定義model

使用上述db物件,model欄位繼承db.Model,在mvc中此表示model層,用來進行資料庫表字段對映關聯以及資料寫入儲存等.

 

 

6.4 flask_sqlalchemy進行使用者驗證

 

 

以上介紹了flask中入門開發常見的問題以及模組使用,歡迎大家拍磚。

 

使用flask可以輕鬆開發應用,每一種web框架都有其自身利弊,對於現代web開發的需求來說,微框架很適合快速迭代式開發,最好的理解的方法是實踐,可以依據以上對flask有一個大體理解之後進行一個簡單的應用開