Flask 函式庫
Flask 函式庫 ( 模組 ) 是一個輕量級的 Web 應用框架,提供了包括路由 ( Routes )、樣板 ( templates ) 和權限 ( authorization) 等功能,只需要簡單的幾行程式碼,就能輕鬆架設網站或建構網路服務,許多 Python 所實現的聊天機器人應用 ( 例如 LINE BOT ),都會使用 Flask 來完成。
快速導覽:
安裝 Flask 函式庫
如果是使用 Colab 或 Anaconda,預設已經安裝了 requests 函式庫,不用額外安裝,如果是本機環境,輸入下列指令,就能安裝 requests 函式庫 ( 依據每個人的作業環境不同,可使用 pip 或 pip3 或 pipenv )。
由於使用 Flask 會啟動本機環境網頁伺服器,若要使用 Google Colab 必須搭配 ngrok 實作 ( 參考:Google Colab 使用 ngrok ),建議第一次先使用 Anaconda Jupyter 進行操作 ( 參考:使用 Anaconda )。
pip install Flask
import Flask
要使用 Flask 必須先 import Flask 函式庫,或使用 from 的方式,單獨 import 特定的類型。
from flask import Flask
建立第一個網頁服務
下方的程式碼執行後,會建立一個基本的網頁服務。
注意,如果使用 Colab 或 Anaconda Jupyter,同一個程式啟用網頁服務後,該程式裡其他片段的程式碼將會無法啟動 ( 按下執行紐啟動 )。
from flask import Flask # 載入 Flask
app = Flask(__name__) # 建立 app 變數為 Flask 物件,__name__ 表示目前執行的程式
@app.route("/") # 使用函式裝飾器,建立一個路由 ( Routes ),可針對主網域 / 發出請求
def home(): # 發出請求後會執行 home() 的函式
return "<h1>hello world</h1>" # 執行函式後會回傳特定的網頁內容
app.run() # 執行
網頁服務建立後,在開發畫面裡可以看到已經啟動 127.0.0.1:5000 的網頁服務,其中 127.0.0.1 表示本機環境的伺服器 ip,5000 則是埠號 port。
服務建立完成後,點擊產生的網址,或直接在瀏覽器的網址列輸入網址,就能看到網頁上出現 hello world 的文字。
設定 GET 與 POST 方法
使用 @app.route 建立路由時,預設採用「GET」的方法,可透過 method 參數設定 GET 或 POST。
如何簡單的區分 GET 和 POST?GET 方法可以透過網址進行溝通,以也就是透過網址列傳送所有的參數內容,POST 方法則是將資料放在 message-body 進行傳送,無法單純透過網址列傳送。
下方的程式碼會啟用一個主網域為 POST 方法的網頁服務。
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=['POST'])
def home():
return "<h1>hello world</h1>"
app.run()
如果透過瀏覽器輸入網址,就會得到 Method Not Allowed 的錯誤訊息。
如果改用 requests 函式庫的 post 方法,就能順利讀取並印出內容 ( 參考:Requests 函式庫 )。
import requests
web = requests.post('http://127.0.0.1:5000/') # 使用 post 方法
print(web.text) # 讀取並印出 text 屬性
設定連線埠號 port
使用 app.run 執行時,可以設定 port 參數來指定埠號 port,或設定 host 為 0.0.0.0 就能採用本機實際分配到的 IP 作為網址,下方的程式執行後,會產生 192.168.XXX.XXX:5555 的網址。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "<h1>hello world</h1>"
app.run(host="0.0.0.0", port=5555)
變數規則
使用 @app.route 可以指定特定的網址路徑,當使用者針對特定的網址發送請求後,就會執行對應的行為,下方的程式碼執行後,開啟三個網址會出現三種不同的結果。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "<h1>hello world</h1>"
@app.route("/ok")
def ok():
return "<h1>ok</h1>"
@app.route("/yes")
def yes():
return "<h1>yes</h1>"
app.run()
如果要讓程式更有彈性,則需要加入「變數」輔助,下方的程式執行後,就會在網頁中顯示根目錄後方的文字。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "<h1>hello world</h1>"
@app.route("/<msg>") # 加入 <msg> 讀取網址
def ok(msg): # 加入參數
return f"<h1>{msg}</h1>" # 使用變數
app.run()
在設定變數時,可以使用 Flask 提供的轉換器功能,指定內容的類型,Flask 提供了五種轉換方式:
類型 | 說明 |
---|---|
string | 預設值,表示不包含斜線的文字。 |
int | 正整數。 |
float | 正浮點數。 |
path | 路徑,類似 string,但可以包含斜線。 |
uuid | UUID 字串。 |
下方的程式執行後,會在網頁顯示根目錄後方的網址內容。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "<h1>hello world</h1>"
@app.route("/<path:msg>") # 加入 path: 轉換成「路徑」的類型
def ok(msg):
return f"<h1>{msg}</h1>"
app.run()
讀取參數
實作網頁應用時,常常會使用網址的參數 ( GET ) 或 message-body ( POST ) 進行訊息的溝通,透過 Flask 提供的 request 方法,就能讀取傳遞的參數內容。
當服務使用 GET 方法時,request.args 會將網址的參數讀取為 tuple 格式,tuple 第一個項目為參數,第二個項目為值。
網址參數由網址後方加上 ? 開始,不同參數以 & 區隔,例如
127.0.0.1:5000?name=oxxo&age=18
,就具有 name 和 age 兩個參數。
from flask import Flask, request # 載入了 request
app = Flask(__name__)
@app.route("/")
def home():
print(request.args) # 使用 request.args
return "<h1>hello world</h1>"
app.run()
當服務使用 POST 方法時,request.form 會將 message-body 讀取為 tuple 格式,tuple 第一個項目為參數,第二個項目為值。
from flask import Flask, request
app = Flask(__name__)
@app.route("/",methods=['POST'])
def home():
print(request.form) # 使用 request.form
return "<h1>hello world</h1>"
app.run()
當另外一組程式發送 POST 方法的請求時,就可以從後台看到執行的結果。
import requests
data = {'name': 'oxxo', 'age': '18'}
web = requests.post('http://127.0.0.1:5000/', data=data) # 發送 POST 請求
print(web.text)
不論是使用 request.args 或 request.form,都能繼續透過的 get 方法取得指定參數的值,下方的程式會取得 name 和 age 的值,接著將其顯示在網頁中。
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/')
def home():
name = request.args.get('name')
return render_template('test.html', name=name)
app.run()
使用網頁樣板
呼叫 Flask 所建立的網頁服務後,除了可以在網頁上顯示特定的文字,只要額外載入 render_template 方法,就能顯示位於「同一層的 templates 文件夾」裡的網頁樣板,下方為一個基本的網頁樣板,可以讀取並顯示 name 參數的內容 ( 使用 Jinja2 樣板語法 )。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
</body>
</html>
網頁樣板完成後,執行下方的程式,只要網址具有 name 的參數,就會透過網頁樣板顯示在網頁中。
from flask import Flask, request, render_template # 載入 render_template
app = Flask(__name__)
@app.route('/')
def home():
name = request.args.get('name')
return render_template('test.html', name=name) # 使用網頁樣板,並傳入參數
app.run()
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~