2 个案例带你迅速入门 Python Flask 框架

1,556 阅读6分钟

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.gif
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
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
image.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.png
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
image.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.png
pytest-reports-fs8.png

现在我要设计一个 API, 地址为 /report/<filename>。 当我输入 report/测试报告2020-04-28-13-53-42.html时,能够查看此次的测试报告内容:

flask check test report
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
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 目录下所有测试报告文件名:

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 reports
flask check all reports

总结

Flask 是一个非常随心的框架。如果你想使用 Flask, 你不需要去了解他的全部,要用的时候再去学习。在上面这个计算公交站信息的程序中,web 展示的代码只有 7 行,而模拟公交数据的程序达到了 9 行。

我对 Flask 的理解是,web 只是展示数据的途径,而不是目标。而在实际的生活中,有太多的公司或者开发者把 web 当成了生命中的全部。 这是设计理念上的区别。

如果你喜欢极简主义,你真应该试试它。