Flask 是 python 中非常流行的一個 web 框架,容易學習。這篇文章主要通過 2 個實際案例講解 Flask 如何使用。第一個例子是實現一個呼叫公交車到站資訊的介面服務;第二個例子是通過介面展示所有的測試報告。
Flask 安裝
- 安裝 python
pip install flask
flask 安裝
Flask 啟動服務
from flask import Flask
app = Flask(__name__)
app.run()
通過 3 行程式碼,可以啟動一個 flask 的服務。
- 第一行,匯入
- 第二行,建立 Flask 程式例項
- 第三行,通過例項啟動服務
執行這個程式碼,可以在本地的 5000 埠訪問, 得到結果是 404 頁面無法找到:
flask running.gif
為 Flask 程式新增介面
此時,訪問 http://localhost:5000 看到 404 錯誤,是因為沒有定義介面。 一個 url 地址和一個處理函式對應,就可以形成一個介面。 通過下面的程式碼,可以在之前的程式碼基礎上新增一個介面:
@app.route('/')
def index():
return {
"msg": "success",
"data": "welcome to use flask."
}
介面新增完成後,再次訪問 http://localhost:5000, 就可以看到正常的響應資料了:
image.png
如果還需要定義另外的介面,只需要參照上面的例子繼續定義。 比如實現一個註冊介面:
@app.route('/user/<u_id>')
def user_info(u_id):
return {
"msg": "success",
"data": {
"id": u_id,
"username": 'yuz',
"age": 18
}
}
此時訪問 /user/3
將會得到 id 為 3 的使用者資訊:
image.png
Flask 實現公交資訊查詢服務
Flask 完全可以勝任中大型專案,但是這不是它的目標。如果想做一個完完全全的 web 專案,建議用 Django。Flask 更適合用在一些小型專案上,比如當你執行完一些計算任務,想通過 web 的形式為使用者提供資料服務或者是展示服務。 你不需要像 django 一樣,去維護太多的模組。
舉個例子。我現在寫了一個程式,計算接下來一段時間有哪些公交車會經過三元里這個站。計算得到的結果可以通過多種形式展現給別人看:
-
控制檯輸出
-
存到資料庫
-
展示到 api 上
-
展示到手機 app 上
-
展示到 web 網頁上
我現在可以通過 flask 建立一個 api , 為使用者展示這些資料。 但是要注意,展示資料只是一個小功能,核心程式應該是我怎樣計算出公交站的資訊,這些才是這個程式的真正價值所在,我可以通過上面的任意一種方式去展現,並不只有 web 開發一種形式。因為展示的邏輯非常簡單,並不需要使用 django 這樣的巨型框架。
真實的公交資訊計算程式是非常複雜的,這裡我通過一個簡單的程式模擬計算公交車資料的過程。這個程式會隨機生成 10 組公交車資料,存放到一個列表當中。
import random
def get_bus_info(station):
info = []
for random_bus in range(10):
bus_name = f"W{random.randint(1, 100)}"
bus_arrival_time = random.randint(1, 30)
bus_info = f"{bus_name} 還有 {bus_arrival_time} 分鐘到達 {station}"
info.append({bus_name: bus_info})
return info
可以直接呼叫這個函式獲取相關的公交車資料:
for bus in get_bus_info('三元里'):
print(bus)
可以在控制檯得到的輸出結果類似於這樣:
image.png
現在我可以用 flask 建立一個 api, 讓所有的使用者和其他想要我資料的服務商都可以拿到這些資料,
至於他們是直接讀取,還是用頁面展示出來,隨便吧,這不是我關心的。我只負責運算,然後提供資料,如果這個技術很厲害,我就可以通過這些資料收費,使用者就得為我提供的介面付費。
接下來我要建立一個 /bus/<station>
的介面, 當我往 url 輸入 station 公交站的名字,介面會給我返回這個公交站的公交資訊。
定義介面:
@app.route('/bus/<station>')
def bus_info(station):
import bus
info = bus.get_bus_info(station)
return {
"msg": "success",
"data": info
}
訪問 /bus/天安門
介面得到資料:
image.png
Flask 實現測試報告服務
上一個例子中,我通過 Flask 提供了一個 api 展示公交運營資料。接下來再通過一個展示測試報告的例子理解 flask 提供 api 的功能。
寫程式碼通常需要測試,測試完成以後生成的測試報告資料通常會存放在本地。存放的形式有多種:
- txt 文字
- xml 檔案
- html 檔案
- json 檔案
- yaml 檔案。
這裡以 html 檔案舉例。 先寫一個測試程式生成 html 測試報告:
import pytest
from datetime import datetime
def test_add():
assert 1 == 2
def gen_report_name():
prefix = '測試報告'
ts = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
return prefix + ts + '.html'
if __name__ == '__main__':
report_name = gen_report_name()
pytest.main([f'--html=output/{report_name}'])
每次執行測試用例程式以後會在 output 目錄下生成測試報告。這些報告以 測試報告
為字首,當前時間為檔名:
pytest-reports-fs8.png
現在我要設計一個 API, 地址為 /report/<filename>
。 當我輸入 report/測試報告2020-04-28-13-53-42.html
時,能夠檢視此次的測試報告內容:
flask check test report
要實現這個功能,只需要在 api.py 檔案中新增對應的程式。這個程式開啟在 output 目錄下的測試報告檔案,返回給前端:
@app.route('/report/<file_name>')
def get_report(file_name):
"""根據檔名獲取測試報告。"""
import pathlib
file_path = pathlib.Path(__file__).parent / 'output' / file_name
f = open(file_path, encoding='utf-8')
report = f.read()
f.close()
return Response(report)
Flask 檢視所有的測試報告連結
現在,雖然我能通過 API 檢視測試報告,但是我需要提前知道測試報告的名稱才能輸入對應 url。而如果要提供給別人使用,他們是不知道這些報告叫什麼名字的。
我現在可以設計另外的 API /reports
, 當使用者訪問這個介面時,能夠直接得到所有的測試報告地址。然後,複製這些地址就可以檢視每次的測試報告:
flask check reports
為了實現這個介面,首先我會寫一個函式自動收集 output 目錄下所有的測試報告,規則是以 .html
為字尾的檔案:
def discover_reports():
"""查詢所有的測試報告"""
import pathlib
report_dir = pathlib.Path(__file__).parent / 'output'
reports = [f.name for f in report_dir.iterdir() if f.suffix == '.html']
return reports
當我呼叫這個函式,返回 output 目錄下所有測試報告檔名:
接下來,我在 api.py 中新增對應的介面,呼叫這個 discover_report 函式就可以了:
@app.route('/reports')
def get_reports():
import test_helper
report_names = test_helper.discover_reports()
return {
"msg": "success",
"data": [f"http://localhost:5000/report/{name}"
for name in report_names
]
}
最後看一下檢視所有測試報告的執行效果:
flask check all reports
總結
Flask 是一個非常隨心的框架。如果你想使用 Flask, 你不需要去了解他的全部,要用的時候再去學習。在上面這個計算公交站資訊的程式中,web 展示的程式碼只有 7 行,而模擬公交資料的程式達到了 9 行。
我對 Flask 的理解是,web 只是展示資料的途徑,而不是目標。而在實際的生活中,有太多的公司或者開發者把 web 當成了生命中的全部。 這是設計理念上的區別。
如果你喜歡極簡主義,你真應該試試它。