手把手教你用APIFlask做毕业设计后端—基本简介与Hello APIFlask!(一)
本文项目对应地存储库: https://github.com/Farmer-chong/HelloAPIFlask
最近正值毕业阶段,相信许多人的毕业设计都无不例外的选择了Web相关的内容,毕竟这个比较容易实现。我发现许多人都出于从众心理无不例外的使用了Spring全家桶,Spring有着很庞大的生态、久远的历史以及很丰富的社区资料,这使得它被许多从业者使用。但也正是这些优势导致它对新手或者快速上手开发变得十分不好,再加之国内的毒瘤技术社区等原因,使得一个小问题往往需要花费大量的时间来排除错误的答案。
相比于繁重、学习成本较高的Spring,Flask其简单的语法可以是我们快速的上手完成(应对)毕设这一类学业任务, 因此本文仅停留在 能用 阶段, 更多底层原理需要读者自行了解(这里推荐一下李大的狗书《Flask Web 开发实战 》) 另外出于为社区做贡献等情怀原因也是写这一系列的初衷。
系列文章
写在前面
本文默认使用Windows进行开发,Linux/macOS会特别说明
相比于传统的后端渲染模板架构,本文采用目前主流的前后端分离结构
对于前后端分离,服务端只需要提供API接口来处理请求。简单的来说就是前端不再局限于浏览器,还可以是app、小程序亦或者是爬虫程序。对后端而言,我们不再渲染html返回给前端,而是与前端共同约定一个数据格式进行交互。
如果读者的思想还停留在具体的浏览器中,那需要读者打开思维的局限来理解。无论是传统的后端渲染还是前后端分离,其本质都是操作 HTTP报文 。
许多人此时会有个疑问:为什么一会儿Flask一会APIFlask的,这两者有什么关系?
先来简单的说一下,Flask
是一个十分流行的 Python Web 框架。而APIFlask
则是基于Flask
框架针对 Web API开发的特点二次开发的框架,这是一个针对API而生的框架(或者具体点前后端分离)。如果读者有Java
开发经验,可以理解类似于Spring
与Spring Boot
的关系。
扩展阅读:
因为APIFlask是一个Flask的扩展补充框架,因此它大部分都是与Flask保持一致的,你甚至可以把APIFlask当成Flask来写(当然这并不推荐)。因此对Flask有经验的读者许多内容是可以跳过阅读的,我甚至更推荐你去阅读 APIFlask的官方文档。
初识APIFlask(Hello APIFlask)
废话放在后面说,作为快速上手教程,理所应当地先来个Hello World感受一下Flask
的魅力,作为一篇保姆级教程下面就让从pip
这个包管理器开始安装一下APIFlask
吧(默认安装好python及其包管理器)
快速开始
小白的话就直接运行下面这条命令即可
1 | pip install apiflask # Linux环境用pip3 |
当然本人还是强烈建议使用虚拟环境哈。细节就不多赘述了,下面开始写一个Hello World吧:
1 | from apiflask import APIFlask |
哪怕你没有开发经验,单纯的看单词也许已经猜到它是做什么了,下面就来一步步的分解这个程序。
创建应用实例(application 对象)
我们使用pip
安装apiflask,其实也就是下载了一个叫apiflask的包。因此我们可以通过apiflask包的构造文件导入开发的类和函数。我们一开始从apiflask包导入APIFlask类,实例化这个类,就得到了我们的程序实例app
:
1 | from apiflask import APIFlask |
传入apiflask的第一个参数是模块或者包名词,这里使用Python的特殊变量__name__
。
注册路由
首先对于很多初学者来说都会有这么一个问题:路由是什么?
回答这个问题之前我们先来看看一个传统的Web应用,客户端和服务器上的程序是如何交互的:
- 用户在浏览器输入URL访问某个资源
- APIFlask接收用户请求并分析请求的URL
- APIFlask为这个URL找到对应的处理函数
- 执行函数并生成响应,然后返回给浏览器
- 浏览器接收并解析响应
而我们现在要做前后端分离,整个流程和上面是一致的,但客户端具体的对象则从浏览器变成了一段发起 http 请求的代码,以网页前后端分离为例稍微完善一下如下:
- 前端使用AJAX向后端发起请求
- APIFlask接收请求并分析请求的URL
- APIFlask为这个URL找到对应的处理函数
- 执行函数并生成 HTTP 响应
- AJAX接收响应
- 根据后续的业务代码进行页面的修改
⚠⚠注意⚠⚠ 这里的 AJAX 是指 Asynchronous JavaScript + XML(异步JavaScript和XML) 这是一个技术名词,读者需要注意与较多人熟知的
jQuery
库的ajax
方法进行区分!!!
简单的来讲,jQuery
的ajax
是 AJAX 技术的一个实现,有着许多同类的替代品,比如axios
。由于笔者见过太多的人将两者混淆,故在此着重强调。
这些步骤中,大部分都是由APIFlask完成,我们只需要将处理函数与URL对应起来。只需在函数添加app.route()
装饰器,并传入URL规则作为参数,就可以让URL与函数建立关系。这个过程我们称为注册路由(route),路由复制管理URL和函数之间的映射,而这个函数则被称为视图函数(view function)。
1. 绑定多个URL
一个视图函数可以绑定多个URL,具体就像下面这段代码:
1 |
|
2. 动态URL
我们还可以在URL规则中添加变量部分, 使用<变量名>
的形式表示。APIFlask处理请求时会把变量传入视图函数,代码如下:
1 |
|
如果URL变量中包含变量,但如果又要适配没有变量的情况,比如与多个URL配合起来使用,那么我们可以给一个默认值:
1 |
|
启动开发服务器
Flask内置了一个开发服务器(由依赖包Werkzeug)提供,足够在开发和测试阶段使用,而APIFlask是基于Flask二次开发的,因此我们一样可以使用。
在生产环境需要使用性能够好的生产服务器,以提升安全和性能,具体更多内容移步到《Flask Web 开发实战 》
在项目的根目录下,输入下面这条命令:
1 | flask run |
然后我们会看到如下输出:
1 | * Tip: There are .env or .flaskenv files present. Do "pip install python-dotenv" to use them. |
这时候我们在浏览器访问这个URL,会看到这样显示:
同理,其他URL自行替换即可得到相应的结果。但由于我们开发的是前后端分离架构,后端只负责提供API进行访问,除了基本的GET
请求外还有大量其他请求报文。因为浏览器的调试无疑是不够的,为此APIFlask
提供了交互式API文档(基于Swagger UI and Redoc)
要进入这个交互式API文档,默认的方式是访问/docs
路由,为此我们重新在浏览器访问: http://127.0.0.1:5000/docs,即可看到下面的这个页面:
后续都会基于该API文档进行演示,当然你也可以访问: http://127.0.0.1:5000/redoc 查看基于Redoc生成的API文档。
需要注意,网上许多教程都是通过
app.run()
形式来运行开发服务器的,这种方式其实是旧的启动方式,已经过时了目前已不推荐使用(deprecated)。
Flask通过依赖包Click内置了一个CLI(Command Line Interface, 命令行交互界面)系统。当我们安装Flask后,会自动添加一个flask命令脚本,我们可以通过flask命令执行内置命令、扩展插件的命令与我们自定义的命令。其中,flask run
命令用来启动开发服务器。
此外,你还可以执行flask --help
查看所有命令,这些命令都需要在项目的根目录执行。
自动发现程序实例
上面启动开发服务器我们使用了flask run
来启动,这就不禁让人好奇,Flask是如何找到程序的?
其实这个问题是因为Flask会自动探测程序实例,一般来说,在执行flask run
命令运行程序前,我们需要提供程序实例所在模块的位置,而自动探测是按照下面这些规则:
- 从当前目录寻找
app.py
和wsgi.py
模块,并从中寻找名为app
或application
的程序实例 - 从环境变量FLASK_APP对应的模块名/导入路径寻找名为
app
或application
的程序实例
因为我们上面的程序代码文件名为app.py
,所以flask run
命令会自动在其中寻找应用实例。如果你的程序文件名是其他名称,比如hello_apiflask.py
,那么需要设置环境变量FLASK_APP,将包含程序实例的模块名赋值给这个变量。命令如下:
1 | set FLASK_APP=hello_apiflask |
Linux或macOS系统使用export
命令:
1 | export FLASK_APP=hello_apiflask |
管理环境变量
FLASK的自动发现程序实例机制还有第三条规则: 如果安装了python-dotenv,那么在使用flask run
或其他命令时会自动使用它从.flaskenv
文件和.env
文件中加载环境变量。
安装python-dotenv包命令如下:
1 | pip install python-dotenv # Linux环境用pip3 |
除了管理自动发现程序实例外,我们还可以用来管理程序需要的环境变量。我们在项目根目录下分别创建两个文件:.env
和.flaskenv
,其中.flaskenv
用来管理和Flask相关的公开环境变量。而.env
文件则用来管理包含敏感信息的环境变量。
.env
包含敏感信息,除非是私有项目,否则绝对不能提交到Git仓库中
扩展阅读
为什么写扩展阅读,扩展阅读的作用?
扩展阅读模块主要是对上面的内容进行补充,内容并非必读内容并不会影响程序的运行,更多是补充开发相关各方面的知识内容。
配置热更新(重载器)
开发环境(development environment)和生产环境(production environment)。根据运行环境的不同,Flask程序、扩展以及其他程序会改变相应的行为和设置。为了区分运行环境,Flask提供了一个FLASK_ENV环境变量用来设置环境,默认为production
(生产)。在开发时我们可以将其设置为development
,这会开启所有支持开发的特性,为了方便管理我们还可以将其写入到.flaskenv
文件中:
1 | FLASK_ENV=development |
现在启动程序,你会看到下面的输出提示:
1 | (env) E:\Github\HelloAPIFlask\demos\hello>flask run |
在开发环境下,调试模式(Debug Mode)将被开启,这时执行flask run
启动程序会自动激活Werkzeug内置的调试器(debugger)和重载器(reloader),他们会为开发带来很大的帮助。
如果你想单独控制调试模式开关,可以通过FLASK_DEBUG环境变量来设置,设为1为开启,设为0则关闭,不过通常不推荐手动设置这个值
创建虚拟环境
在 Python 中,虚拟环境(virtual enviroment)就是隔离的 Python 解释器环境。通过创建虚拟环境,你可以拥有一个独立的 Python 解释器环境。这样做的好处是可以为每一个项目创建独立的 Python 解释器环境,因为不同的项目经常会依赖不同版本的库或Python版本。使用虚拟环境可以保持全局 Python 解释器环境的干净,避免包和版本的混乱,并且可以方便地区分和记录每个项目的依赖,以便在新环境下复现依赖环境。
虚拟环境通常使用Virtualenv来创建,除此之外还有Pipenv、PDM等诸多环境管理工具。简单起见,我们使用Python3自带的工具来创建虚拟环境,首先确保我们当前工作目录在项目的根目录,然后使用python3 -m venv env
命令为当前项目创建虚拟环境:
1 | python -m venv env |
1 | python3 -m venv env |
提示: Windows用户可直接复制,但Linux系统大多存在python2与python3,Linux用户需要注意这点
这会在当前目录创建一个名为env的文件夹(命令最后一个选项为文件夹名),其中包含隔离的Python解释器环境。
激活虚拟环境
在创建虚拟环境后,我们还需要载入(激活)这个环境,接下来使用.\env\Script\active
来激活虚拟环境:
1 | E:\Github\HelloAPIFlask>.\env\Scripts\activate |
Linux环境使用source
命令来激活:
1 | farmer@farmer-ubuntu:~/HelloAPIFlask$ source ./env/bin/activate |
可以看到虚拟环境激活后命令行前面多了一个虚拟环境的标识,这就表示虚拟环境激活啦!使用pip list
我们可以看到该环境是一个全新的环境。
更多启动项
- 使服务器外部可见
我们上面启动的Web服务器默认是对外不可见的,我们可以通过--host
选项将主机地址改为0.0.0.0
使其对外部可见:1
flask run --host=0.0.0.0
需要注意这里的外部是指你计算机外部,并不是指公网。一般个人的电脑是没有公网IP(公有地址),所以此时你的程序只能被局域网内的其他用户通过你电脑的IP(内网)进行访问。
- 改变默认端口
Flask提供的Web服务器默认监听5000端口,你可以通过--port
选项进行更改:
1 | flask run --port=2333 |
此时会监听来自2333端口的请求,对应的程序网址也变成了 http://127.0.0.1:2333/。
彩蛋
这一切开始于2010年4月1日,Armin Ronacher在网上发布了一篇关于”下一代 Python 微框架”的介绍文章,文章里称这个 Denied 框架不依赖 Python 标准库,只需要复制一份
deny.py
放到你的项目文件夹就可以开始编程。随着一本正经的介绍、名人推荐语、示例代码和演示视频,这个”虚假“的项目让不少人信以为真。5天后 Flask 就从这么一个愚人节玩笑诞生了。
同样的,APIFlask这个框架开始于 2021年4月1日,不知道是机缘巧合还是Grey Li有意为之的一个小玩笑,APIFlask与Flask均诞生于4月1日这一天。🎉🚀✨
在与Grey Li求证后得知两者选择同一天发布是有意为之的!!😄