2 個案例帶你迅速入門 Python Flask 框架

和牛發表於2020-05-01

Flask 是 python 中非常流行的一個 web 框架,容易學習。這篇文章主要通過 2 個實際案例講解 Flask 如何使用。第一個例子是實現一個呼叫公交車到站資訊的介面服務;第二個例子是通過介面展示所有的測試報告。

Flask 安裝

  1. 安裝 python
  2. pip install flask

flask 安裝flask 安裝

Flask 啟動服務

from flask import Flask

app = Flask(__name__)

app.run()

通過 3 行程式碼,可以啟動一個 flask 的服務。

  1. 第一行,匯入
  2. 第二行,建立 Flask 程式例項
  3. 第三行,通過例項啟動服務

執行這個程式碼,可以在本地的 5000 埠訪問, 得到結果是 404 頁面無法找到:

flask running.gifflask running.gif

為 Flask 程式新增介面

此時,訪問 http://localhost:5000 看到 404 錯誤,是因為沒有定義介面。 一個 url 地址和一個處理函式對應,就可以形成一個介面。 通過下面的程式碼,可以在之前的程式碼基礎上新增一個介面:

@app.route('/')
def index():
    return {
        "msg""success",
        "data""welcome to use flask."
    }

介面新增完成後,再次訪問 http://localhost:5000, 就可以看到正常的響應資料了:

image.pngimage.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.pngimage.png

Flask 實現公交資訊查詢服務

Flask 完全可以勝任中大型專案,但是這不是它的目標。如果想做一個完完全全的 web 專案,建議用 Django。Flask 更適合用在一些小型專案上,比如當你執行完一些計算任務,想通過 web 的形式為使用者提供資料服務或者是展示服務。 你不需要像 django 一樣,去維護太多的模組。

舉個例子。我現在寫了一個程式,計算接下來一段時間有哪些公交車會經過三元里這個站。計算得到的結果可以通過多種形式展現給別人看:

  1. 控制檯輸出

  2. 存到資料庫

  3. 展示到 api 上

  4. 展示到手機 app 上

  5. 展示到 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(1100)}"
        bus_arrival_time = random.randint(130)
        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.pngimage.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.pngimage.png

Flask 實現測試報告服務

上一個例子中,我通過 Flask 提供了一個 api 展示公交運營資料。接下來再通過一個展示測試報告的例子理解 flask 提供 api 的功能。

寫程式碼通常需要測試,測試完成以後生成的測試報告資料通常會存放在本地。存放的形式有多種:

  1. txt 文字
  2. xml 檔案
  3. html 檔案
  4. json 檔案
  5. 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.pngpytest-reports-fs8.png

現在我要設計一個 API, 地址為 /report/<filename>。 當我輸入 report/測試報告2020-04-28-13-53-42.html時,能夠檢視此次的測試報告內容:

flask check test reportflask 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 reportsflask 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 目錄下所有測試報告檔名:

discover-reports

接下來,我在 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 reportsflask check all reports

總結

Flask 是一個非常隨心的框架。如果你想使用 Flask, 你不需要去了解他的全部,要用的時候再去學習。在上面這個計算公交站資訊的程式中,web 展示的程式碼只有 7 行,而模擬公交資料的程式達到了 9 行。

我對 Flask 的理解是,web 只是展示資料的途徑,而不是目標。而在實際的生活中,有太多的公司或者開發者把 web 當成了生命中的全部。 這是設計理念上的區別。

如果你喜歡極簡主義,你真應該試試它。

相關文章