写点什么

快速上手 python 的简单 web 框架 flask

作者:程序那些事
  • 2023-02-06
    广东
  • 本文字数:3585 字

    阅读完需:约 12 分钟

简介

python 可以做很多事情,虽然它的强项在于进行向量运算和机器学习、深度学习等方面。但是在某些时候,我们仍然需要使用 python 对外提供 web 服务。


比如我们现在有一个用 python 写好的模型算法,这个模型算法需要接收前端的输入,然后进行模拟运算,最终得到最后的输出。这个流程是一个典型的 web 服务,与其我们使用 java 或者 nodejs 来搭建一个 web 服务器,不如我们就使用 python 自己的 web 框架来实现这一目标,减少技术栈的同时,还可以实现代码逻辑的统一,何乐而不为呢?


其实 python 的 web 框架也有很多种,比如 django、flask 等等。


这本系列的文章中,我们会介绍 flask 这个轻量级的 web 框架。

web 框架的重要组成部分

相信大家都用过不少 web 框架吧,从 java 的 spring MVC,到 nodejs 的 express 和 koa,有功能复杂的,也有功能简单的。


但是不管他们的功能如何,其最重要最基本的一个功能就是能够提供 web 服务,也就是说可以接收 HTTP 或者 HTTPS 的请求,然后返回对应的数据。这个功能通常包含的是核心的路由跳转功能。


有了这个核心的功能,web 框架基本上就可以正常运行了。配合上现在流行的前后端分离技术,一切水到渠成。


如果不想用前后端分离,那么 web 框架还需要涉及到页面的呈现技术。一般来说都会使用模板引擎作为前端页面的呈现形式。


然后配合上对数据库、缓存、消息队列、静态资源、日志、调试等附加的功能,一个完整的 web 框架就完成了。


flask 虽然是一个轻量级 web 框架,但是该有的功能它全都有。


它的核心是提供了对 web 路由的支持,同时支持 Jinja 的模板语言。

快速上手 flask

flask 是一个非常简单优雅的 web 框架,flask 需要 Python 3.7 及以上版本的支持。


为了区分 python 的不同开发环境,我们在使用 flask 的时候,可以使用 python 自带的 venv 来创建不同的虚拟环境。venv 跟 conda 的 env 很类似,都是用来创建虚拟环境,从而实现不同的环境进行分离的作用。


使用 venv 非常简单,如果你用的开发工具是 pycharm,那么在创建 python 的 flask 项目的时候,会自动选择对应的虚拟环境创建工具,这里我们选择使用 venv 即可自动创建。



当然你也可以使用下面的命令来手动创建 venv:


$ mkdir learn-flask$ cd learn-flask$ python3 -m venv venv
复制代码


创建好 venv 之后,使用下面的命令来激活这个 env:


. venv/bin/activate
复制代码


venv 安装完毕之后,我们可以使用下面的命令安装 flask:


pip install Flask
复制代码


安装完毕之后,你可以在 python 项目 site-packages 里面找到 flask 对应的依赖包:



可以看到里面出了 flask 之外,还有其他的一些第三方依赖包,这些都是可以在后续的 flask 应用中使用到的。

flask 的第一个应用

flask 的依赖包都安装好之后,我们就可以写一个最最简单的 web 应用程序了,我们把这个应用程序命名为 first.py:


from flask import Flask
app = Flask(__name__)
@app.route('/')def first(): return "<p>这是我的第一个flask程序!</p>"
if __name__ == '__main__': app.run()
复制代码


和普通的 python 程序不同的是,这里我们先实例化了一个 Flask 对象,然后用类似注解的方式定义了一个 route 在 fist 这个方法上。


程序写好了,如果你在 pycharm IDE 中,那么可以右键运行,可以得到下面的内容:


FLASK_APP = first.pyFLASK_ENV = developmentFLASK_DEBUG = 0In folder /Users/data/git/ddean2009/learn-flask/Users/data/git/ddean2009/learn-flask/venv/bin/python -m flask run  * Serving Flask app 'first.py' * Debug mode: offWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000
复制代码


可以看到 IDE 为我们设置了几个环境变量,分别是 FLASK_APP:表示要运行的 app 名称。FLASK_ENV:表示现在的运行环境是开发环境还是线上环境。FLASK_DEBUG 表示是否是 debug 模式。


最终我们可以访问默认的http://127.0.0.1:5000,可以得到下面的内容:



说明整个程序运行成功了。


如果你想通过命令行来执行 flask 的应用,那么可以用下面的命令:


flask --app first run
复制代码


注意,这里我们添加了--app 这个参数来指定要运行的 app 名称。如果不指定的话,flask 会去寻找名叫 app.py 或者 wsgi.py 的文件。如果你有这两个文件,那么就可以直接使用 flask run 来运行了。


这里的 flask 相当于 python -m flask。


默认情况下 flask 的应用程序只能通过本地的浏览器来访问,如果你想通过远程来访问的话,可以指定访问的 host,如下所示:


flask run --host=0.0.0.0
复制代码


到此,我们的一个基本的最简单的 flask web 应用就完成了。


什么?你还要了解更多?别急,下面我们再详细介绍一些 web 应用程序所必须了解的知识。

flask 中的路由

路由也叫 Routing,它是 web 应用程序中的灵魂,通过路由来定义各种 URL 和访问路径。


在 flask 中,可以使用 @app.route 来对路由进行定义。@app.route 类似于注解,可以放置在 python 的方法之上。


route 中可以定义路由的名称,路由的名称可以跟方法的名称不一样:


@app.route('/test')def test123():    return '我是一个测试'
复制代码


路由的名称还可以是动态的,可以取一个跟注解方法中参数的名称一样的参数名作为路由的参数用一个尖括号括起来,如下所示:


from markupsafe import escape
@app.route('/student/<name>')def what_is_your_name(name): return f'你的名字是: {escape(name)}'
复制代码


这里的方法体中我们调用了 python 的 f 函数来对字符串进行格式化,在内部为了防止 web 输入端的恶意注入,这里引用了 markupsafe 的 escape 方法,可以对输入的字符串进行转义,从而避免了恶意的攻击。


除了在路径中指定参数之外,我们还可以自行指定参数的类型,在 flask 中路径参数可以设置为下面的几种类型:



比如我们想传入一个路径,那么可以将其定义为 path 类型:


@app.route('/path/<path:subpath>')def what_is_your_path(subpath):    return f'你的路径是: {escape(subpath)}'
复制代码


上面我们提到了 string 和 path 的区别,就在于 path 可以接收/,而 string 不能。


那么在 flask 中/有什么特殊的含义吗?


我们知道/是用做路径分割的,在 flask 中包含/和不包含/还是有一定的区别的。以下面的代码为例:


@app.route('/withslash/')def with_slash():    return '这是带slash的'
@app.route('/withoutslash')def with_out_slash(): return '这是不带slash的'
复制代码


withslash 的定义中带了 slash 后缀,所以不管你访问/withslash还是/withslash/, 都会被跳转到withslash/


但是因为 withoutslash 没有带 slash,所以你只能访问/withoutslash,但是不能访问/withoutslash/,否则你可能得到一个 404 “Not Found”错误。

不同的 http 方法

默认情况下 @app.route 对外提供的是 GET 方法,如果你想对外提供一些不同的 http 方法,那么可以在 @app.route 中使用 methods:


@app.route('/diffMethod', methods=['GET', 'POST'])def diff_method():    if request.method == 'POST':        return '这是post'    else:        return '这是get'
复制代码


当然,你还可以使用 @app.get 或者 @app.post 把不同方法的请求分开:


@app.get('/getMethod')def get_method():     return '这是get'
@app.post('/postMethod')def post_method(): return '这是post'
复制代码

静态文件

web 应用中少不了的是一些静态资源,比如图片,js 或者 css 等。这些静态资源可以看做是一种特殊的路由规则。在 flask 中,可以通过创建特殊的 static 目录来达到这一目的。如下所示:


url_for('static', filename='style.css')
复制代码


这里面我们用到了 url_for 这个方法,这个方法实际上是用来构建对应方法的 url 的,可以举下面的几个例子来对 url_for 有个深入的了解。


urL_for 的第一个参数是方法名,后面接的是 url 中定义的变量,如果 url 中并没有这个变量,那么将会以参数的形式附加在 url 的后面:


@app.route('/')def index():    return 'index'
@app.route('/login')def login(): return 'login'
@app.route('/user/<username>')def profile(username): return f'{username}\'s profile'
with app.test_request_context(): print(url_for('index')) print(url_for('login')) print(url_for('login', next='/')) print(url_for('profile', username='John Doe'))
复制代码


输出的内容如下:


//login/login?next=//user/John%20Doe
复制代码

使用模板

如果我们只是用 return 来返回简单的字符串或者变量,那么肯定满足不了现代应用的需求了。


为了实现复杂的页面功能,我们通常会使用模板。flask 使用的是 Jinja2 这个模板语言。


怎么使用模板呢?我们在返回的时候,可以使用 render_template 方法:


from flask import render_template
@app.route('/template/<name>')def use_template(name=None): return render_template('hello.html', name=name)
复制代码


其中 hello.html 是模板文件的名字,name 是模板文件中定义的变量。

总结

以上就是 flask 的基本使用了,掌握到这些内容之后,相信大家已经可以使用 flask 做出一个简单的 web 应用了。

发布于: 22 小时前阅读数: 17
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020-06-07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
快速上手python的简单web框架flask_Python_程序那些事_InfoQ写作社区