快速上手python的簡單web框架flask
簡介
python可以做很多事情,雖然它的強(qiáng)項(xiàng)在于進(jìn)行向量運(yùn)算和機(jī)器學(xué)習(xí)、深度學(xué)習(xí)等方面。但是在某些時(shí)候,我們?nèi)匀恍枰褂胮ython對(duì)外提供web服務(wù)。
比如我們現(xiàn)在有一個(gè)用python寫好的模型算法,這個(gè)模型算法需要接收前端的輸入,然后進(jìn)行模擬運(yùn)算,最終得到最后的輸出。這個(gè)流程是一個(gè)典型的web服務(wù),與其我們使用java或者nodejs來搭建一個(gè)web服務(wù)器,不如我們就使用python自己的web框架來實(shí)現(xiàn)這一目標(biāo),減少技術(shù)棧的同時(shí),還可以實(shí)現(xiàn)代碼邏輯的統(tǒng)一,何樂而不為呢?
其實(shí)python的web框架也有很多種,比如django、flask等等。
這本系列的文章中,我們會(huì)介紹flask這個(gè)輕量級(jí)的web框架。
web框架的重要組成部分
相信大家都用過不少web框架吧,從java的spring MVC,到nodejs的express和koa,有功能復(fù)雜的,也有功能簡單的。
但是不管他們的功能如何,其最重要最基本的一個(gè)功能就是能夠提供web服務(wù),也就是說可以接收HTTP或者HTTPS的請(qǐng)求,然后返回對(duì)應(yīng)的數(shù)據(jù)。這個(gè)功能通常包含的是核心的路由跳轉(zhuǎn)功能。
有了這個(gè)核心的功能,web框架基本上就可以正常運(yùn)行了。配合上現(xiàn)在流行的前后端分離技術(shù),一切水到渠成。
如果不想用前后端分離,那么web框架還需要涉及到頁面的呈現(xiàn)技術(shù)。一般來說都會(huì)使用模板引擎作為前端頁面的呈現(xiàn)形式。
然后配合上對(duì)數(shù)據(jù)庫、緩存、消息隊(duì)列、靜態(tài)資源、日志、調(diào)試等附加的功能,一個(gè)完整的web框架就完成了。
flask雖然是一個(gè)輕量級(jí)web框架,但是該有的功能它全都有。
它的核心是提供了對(duì)web路由的支持,同時(shí)支持Jinja的模板語言。
快速上手flask
flask是一個(gè)非常簡單優(yōu)雅的web框架,flask需要Python 3.7及以上版本的支持。
為了區(qū)分python的不同開發(fā)環(huán)境,我們在使用flask的時(shí)候,可以使用python自帶的venv來創(chuàng)建不同的虛擬環(huán)境。venv跟conda的env很類似,都是用來創(chuàng)建虛擬環(huán)境,從而實(shí)現(xiàn)不同的環(huán)境進(jìn)行分離的作用。
使用venv非常簡單,如果你用的開發(fā)工具是pycharm,那么在創(chuàng)建python的flask項(xiàng)目的時(shí)候,會(huì)自動(dòng)選擇對(duì)應(yīng)的虛擬環(huán)境創(chuàng)建工具,這里我們選擇使用venv即可自動(dòng)創(chuàng)建。
當(dāng)然你也可以使用下面的命令來手動(dòng)創(chuàng)建venv:
$ mkdir learn-flask
$ cd learn-flask
$ python3 -m venv venv
創(chuàng)建好venv之后,使用下面的命令來激活這個(gè)env:
. venv/bin/activate
venv安裝完畢之后,我們可以使用下面的命令安裝flask:
pip install Flask
安裝完畢之后,你可以在python項(xiàng)目site-packages里面找到flask對(duì)應(yīng)的依賴包:
可以看到里面出了flask之外,還有其他的一些第三方依賴包,這些都是可以在后續(xù)的flask應(yīng)用中使用到的。
flask的第一個(gè)應(yīng)用
flask的依賴包都安裝好之后,我們就可以寫一個(gè)最最簡單的web應(yīng)用程序了,我們把這個(gè)應(yīng)用程序命名為first.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def first():
return "<p>這是我的第一個(gè)flask程序!</p>"
if __name__ == '__main__':
app.run()
和普通的python程序不同的是,這里我們先實(shí)例化了一個(gè)Flask對(duì)象,然后用類似注解的方式定義了一個(gè)route在fist這個(gè)方法上。
程序?qū)懞昧?,如果你在pycharm IDE中,那么可以右鍵運(yùn)行,可以得到下面的內(nèi)容:
FLASK_APP = first.py
FLASK_ENV = development
FLASK_DEBUG = 0
In folder /Users/data/git/ddean2009/learn-flask
/Users/data/git/ddean2009/learn-flask/venv/bin/python -m flask run
* Serving Flask app 'first.py'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
可以看到IDE為我們設(shè)置了幾個(gè)環(huán)境變量,分別是FLASK_APP:表示要運(yùn)行的app名稱。FLASK_ENV:表示現(xiàn)在的運(yùn)行環(huán)境是開發(fā)環(huán)境還是線上環(huán)境。FLASK_DEBUG表示是否是debug模式。
最終我們可以訪問默認(rèn)的http://127.0.0.1:5000,可以得到下面的內(nèi)容:
說明整個(gè)程序運(yùn)行成功了。
如果你想通過命令行來執(zhí)行flask的應(yīng)用,那么可以用下面的命令:
flask --app first run
注意,這里我們添加了–app這個(gè)參數(shù)來指定要運(yùn)行的app名稱。如果不指定的話,flask會(huì)去尋找名叫app.py或者wsgi.py的文件。如果你有這兩個(gè)文件,那么就可以直接使用flask run來運(yùn)行了。
這里的flask相當(dāng)于python -m flask。
默認(rèn)情況下flask的應(yīng)用程序只能通過本地的瀏覽器來訪問,如果你想通過遠(yuǎn)程來訪問的話,可以指定訪問的host,如下所示:
flask run --host=0.0.0.0
到此,我們的一個(gè)基本的最簡單的flask web應(yīng)用就完成了。
什么?你還要了解更多?別急,下面我們再詳細(xì)介紹一些web應(yīng)用程序所必須了解的知識(shí)。
flask中的路由
路由也叫Routing,它是web應(yīng)用程序中的靈魂,通過路由來定義各種URL和訪問路徑。
在flask中,可以使用@app.route來對(duì)路由進(jìn)行定義。@app.route類似于注解,可以放置在python的方法之上。
route中可以定義路由的名稱,路由的名稱可以跟方法的名稱不一樣:
@app.route('/test')
def test123():
return '我是一個(gè)測試'
路由的名稱還可以是動(dòng)態(tài)的,可以取一個(gè)跟注解方法中參數(shù)的名稱一樣的參數(shù)名作為路由的參數(shù)用一個(gè)尖括號(hào)括起來,如下所示:
from markupsafe import escape
@app.route('/student/<name>')
def what_is_your_name(name):
return f'你的名字是: {escape(name)}'
這里的方法體中我們調(diào)用了python的f函數(shù)來對(duì)字符串進(jìn)行格式化,在內(nèi)部為了防止web輸入端的惡意注入,這里引用了markupsafe的escape方法,可以對(duì)輸入的字符串進(jìn)行轉(zhuǎn)義,從而避免了惡意的攻擊。
除了在路徑中指定參數(shù)之外,我們還可以自行指定參數(shù)的類型,在flask中路徑參數(shù)可以設(shè)置為下面的幾種類型:
類型 說明
string
默認(rèn)類型,可以接收除了/之外的任何字符串
int
可以接收正整數(shù)
float
可以接收正的浮點(diǎn)數(shù)
path
和string類似,但是可以接收/
uuid
接收uuid字符串
比如我們想傳入一個(gè)路徑,那么可以將其定義為path類型:
@app.route('/path/<path:subpath>')
def what_is_your_path(subpath):
return f'你的路徑是: {escape(subpath)}'
上面我們提到了string和path的區(qū)別,就在于path可以接收/,而string不能。
那么在flask中/有什么特殊的含義嗎?
我們知道/是用做路徑分割的,在flask中包含/和不包含/還是有一定的區(qū)別的。以下面的代碼為例:
@app.route('/withslash/')
def with_slash():
return '這是帶slash的'
@app.route('/withoutslash')
def with_out_slash():
return '這是不帶slash的'
withslash的定義中帶了slash后綴,所以不管你訪問
/withslash
還是
/withslash/
, 都會(huì)被跳轉(zhuǎn)到
withslash/
。
但是因?yàn)閣ithoutslash沒有帶slash,所以你只能訪問
/withoutslash
,但是不能訪問
/withoutslash/
,否則你可能得到一個(gè)404 “Not Found”錯(cuò)誤。
不同的http方法
默認(rèn)情況下@app.route對(duì)外提供的是GET方法,如果你想對(duì)外提供一些不同的http方法,那么可以在@app.route中使用methods:
@app.route('/diffMethod', methods=['GET', 'POST'])
def diff_method():
if request.method == 'POST':
return '這是post'
else:
return '這是get'
當(dāng)然,你還可以使用@app.get或者@app.post把不同方法的請(qǐng)求分開:
@app.get('/getMethod')
def get_method():
return '這是get'
@app.post('/postMethod')
def post_method():
return '這是post'
靜態(tài)文件
web應(yīng)用中少不了的是一些靜態(tài)資源,比如圖片,js或者css等。這些靜態(tài)資源可以看做是一種特殊的路由規(guī)則。在flask中,可以通過創(chuàng)建特殊的static目錄來達(dá)到這一目的。如下所示:
url_for('static', filename='style.css')
這里面我們用到了url_for這個(gè)方法,這個(gè)方法實(shí)際上是用來構(gòu)建對(duì)應(yīng)方法的url的,可以舉下面的幾個(gè)例子來對(duì)url_for有個(gè)深入的了解。
urL_for的第一個(gè)參數(shù)是方法名,后面接的是url中定義的變量,如果url中并沒有這個(gè)變量,那么將會(huì)以參數(shù)的形式附加在url的后面:
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return f'{username}\'s profile'
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
輸出的內(nèi)容如下:
/
/login
/login?next=/
/user/John%20Doe
使用模板
如果我們只是用return來返回簡單的字符串或者變量,那么肯定滿足不了現(xiàn)代應(yīng)用的需求了。
為了實(shí)現(xiàn)復(fù)雜的頁面功能,我們通常會(huì)使用模板。flask使用的是Jinja2這個(gè)模板語言。
怎么使用模板呢?我們在返回的時(shí)候,可以使用render_template方法:
from flask import render_template
@app.route('/template/<name>')
def use_template(name=None):
return render_template('hello.html', name=name)
其中hello.html是模板文件的名字,name是模板文件中定義的變量。
總結(jié)
以上就是flask的基本使用了,掌握到這些內(nèi)容之后,相信大家已經(jīng)可以使用flask做出一個(gè)簡單的web應(yīng)用了。
作者:程序那些事
歡迎關(guān)注微信公眾號(hào) :程序那些事