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

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 程式添加介面

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

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

介面添加完成後,再次訪問 //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(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.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"//localhost:5000/report/{name}"
                 for name in report_names
                 ]
    }

最後看一下查看所有測試報告的執行效果:

flask check all reportsflask check all reports

總結

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

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

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

Tags: