目录
- 🍀前言
- 🍀安装
- 🍀导入
- 🍀Hello World
- 1、flask项目文件目录
- 2、python文件内容示例
- 🍀路由处理
- 🍀配置
- 1、修改app文件名,文件夹路径
- 2、开启项目调试模式
- 3、设置app运行的端口并开启调试
- 🍀Request
- 1、处理GET请求
- 2、处理POST请求
- 3、处理表单数据
- 4、处理JSON数据
- 5、处理请求头参数
- 🍀 Response
- 1、返回JSON数据
- 2、设置请求头
- 🍀Cookie
- 🍀Session
- 🍀Token验证
- 1、安装并应用
- 2、生成token
- 3、验证token
- 4、使用token
- 🍀CORS跨域处理
- 🍀返回http状态码
- 🍀重定向
- 🍀Restful api
- Restful api 安装
- Restful api 示例
- 🍀Flask返回图片
🍀前言
官方文档:Flask Document
Flask可以搭建轻量服务api,而且使用python语言编写程序,非常方便。以前也使用过php做服务器后端,但是不喜欢php的$,而且我想多学学python,没想到Flask框架恰好能满足我的需求,简直是一个神器!特别适合我这种非计算机专业人士学习,能快速搭建api,为前端web、微信小程序等提供api服务,非常nice,爱了爱了
🍀安装
pip3 install Flask
🍀导入
from flask import Flask,request
🍀Hello World
1、flask项目文件目录
project/
app/ # 整个程序的包目录
static/ # 静态资源文件
js/ # JS脚本
css/ # 样式表
img/ # 图片
favicon.ico # 网站图标
templates/ # 模板文件
common/ # 通用模板
errors/ # 错误页面
user/ # 用户模板
posts/ # 帖子模板
email/ # 邮件发送
views/ # 视图文件
models/ # 数据模型
libs/ #工具类
framework/ #全局性的工具
utils/ #小工具
extensions/ # 各种扩展
forms/ # 表单文件
main.py # 邮件发送
migrations/ # 数据库迁移目录
tests/ # 测试单元
venv/ # 虚拟环境
requirements.txt # 依赖包的列表
config.py # 配置文件
manage.py # 项目启动控制文件
2、python文件内容示例
from flask import Flask
app = Flask(__name__) # 实例化类flask
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run() # 默认运行在5000端口
🍀路由处理
flask支持三种路由处理
一种就是如上所展示的@app.route('/')
里写路径,紧接着写函数,
还有一种使用flask.add_url_rule()
方法添加
def index():
...
app.add_url_rule("/", view_func=index)
第三种是把不同的URL映射到同一个函数里,就是在函数前用多个@app.route(' ')
🍀配置
1、修改app文件名,文件夹路径
在app实例化的时候设置
app = Flask("my-app", static_folder="path1", template_folder="path2")
2、开启项目调试模式
app.run(debug=True)
3、设置app运行的端口并开启调试
注意:如果在开发环境中debug,要在app.run前加上
app.env="development"
否则,会出现WARNING: This is a development server. Do not use it in a production deployment.
app.run(host='0.0.0.0', port=80, debug=True)
🍀Request
flask中的request类专门用于对请求的参数进行处理,比如获得get
请求参数,获得post
请求参数。
必须要导入flask的request,这里导入的是全局变量(全局变量写代码量少,快速方便)
from flask import request
常用属性:
属性 | 描述 |
method | 请求方法,比如POST、GET。值为字符串,有“GET”,“POST”等 |
form | 处理POST和PUT请求 |
args | 处理GET参数 |
cookies | 请求的cookies,类型是dict。 |
headers | 请求头,字典类型。 |
data | 包含了请求的数据,并转换为字符串,除非是一个Flask无法处理的mimetype。 |
files | MultiDict,带有通过POST或PUT请求上传的文件。 |
path | 获取请求文件路径:/myapplication/page.html |
url_root | 获取域名:http://www.baidu.com/ |
base_url | 获取基本url:http://www.baidu.com/myapplication/page.html |
url | 获取全部url:http://www.baidu.com/myapplication/page.html?id=1&edit=edit |
json | 如果mimetype是application/json,这个参数将会解析JSON数据,如果不是则返回None。 |
stream | 处理流 |
remote_addr | 获取请求ip |
1、处理GET请求
request.args.__str__()
:列出所有参数request.args.get('')
:取出指定参数的第一个参数(如果有好多的话)request.args.getlist('')
:取出指定参数列表
2、处理POST请求
request.form.get("")
3、处理表单数据
@app.route('/api',methods=['GET','POST'])
def api():
#以下两行是展示form中处理文件以外的所有item
# for item in request.form:
# print(item)
d1 = request.form.get("l1")
d2 = request.form.get("l2")
d3 = request.form.get("l3")
file = request.files.get('file')
print(file)
dict = {"code":"200","data":"处理完毕"}
return jsonify(dict)
4、处理JSON数据
request.json # 返回的是dict类型
5、处理请求头参数
request.headers可以返回请求头参数。但是注意这是werkzeug.datastructures.EnvironHeaders
对象。
想获取请求头的参数需要用get()
方法:
request.headers.get("Host")
🍀 Response
flask接收到请求(request
)后进行处理,处理完毕后会想客户端发送响应(response
)
flask的Response类是专门用于处理响应模块的。
使用导入两个:
from flask import make_response,Response
@app.route("/test")
def test():
response = Response("返回信息")
# 或者这样:response = make_response('返回信息', 200, {"header1": "header1_info"})
response.status_code = 200
return response
返回response最精简(懒人)模式:
return "index.html", 200, {"header1":"header1_info", "header2": "header2_info"}
# 第一个参数是返回的信息,第二个是状态码,第三个是设置请求头(字典形式)。后两个参数可以省略
补充:原则上我们返回(return
)都应该是返回Response对象,但是上面的方式也是可以的,flask智能地将他们转为了Response对象。
常用属性:
属性 | 描述 |
headers | 设置请求头信息 |
status | String类型的数据,格式为这种:“200 ok” |
status_code | int 类型,就是状态码,但是不能是自定义的状态码 |
data | 需要返回到前端的数据 |
set_cookie | 设置cookie 的值 |
del_cookie | 删除cookie ,不会立马删除cookie 值,会将过期时间设置为当前时间 |
构造函数: class flask.Response(response=None, status=None, headers=None, mimetype=None, content_type=None,direct_passthrough=False)
1、返回JSON数据
方案一 (返回JSON对象,并设置请求头)
from flask import Response
return Response(json.dumps(text), mimetype='application/json')
方案二(使用jsonify)
from flask import jsonify
return jsonify(text)
2、设置请求头
方案一:
@app.route("/test")
def test():
rp = Response("返回信息")
rp.headers['header1'] = "header1_info" # 设置响应头
rp.headers['header2'] = "header2_info" # 设置响应头
return rp
方案二:
return "返回信息", 200, {"header1":"header1_info", "header2": "header2_info"}
方案三
return "返回信息", 200, [("header1", "header1_info"), ("header2", "header2_info")] # 使用元组的方式设
🍀Cookie
读取cookie
name=request.cookies.get('Name')
return name
设置Cookie并返回
response.set_cookie('key','value',expires=None, path='/')
return response
expires设置时间,其中expires
的格式:[str, datetime.datetime, int, float]
🍀Session
session本质上还是cookie,但是时效短。flask会发送session-id给客户端(数据临时存储在服务端),客户端只要不关闭浏览器,打开多个页面浏览器会自动发送session-id,服务端能读取id来处理数据。
session能够运行在服务器端并存储交互状态。Flask中的Session与其他的Web框架不同,它使用了密钥签名的方式进行了加密。
配置SECRET_KEY:
app.config["SECRET_KEY"]='XXXXX' # 密钥是24位字符串。可以使用os.urandom(24)来生成随机字符串
session操作:
from flask import session
session["key"]= ... # 设置session,也可以不赋值来返回值,无值会异常
session.get("key") # 如果没有key值,会返回NONE
# 删除session
session.pop('key')
# 清除所有session
session.clear
🍀Token验证
token验证技术的其中一种解决方案是JSON Web Token。这是目前最常用的token认证解决方法。关于JWT的解释可以看这篇文章:基于 Token 的身份验证:JSON Web Token flask框架实现JWT token验证有好几个库,比如pyjwt,flask-jwt。我选择pyjwt,他的文档比较好。
1、安装并应用
pip install pyjwt
import jwt
2、生成token
auth = HTTPBasicAuth()
# 密钥,可随意修改
SECRET_KEY = 'abcdefghijklmm'
# 生成token, 有效时间为600min
encoded = jwt.encode({"some": "payload"}, SECRET_KEY, algorithm="HS256")
def createToken():
payload = {"id": "此token指向的用户id", "iss": “crayonxin”,"nbf": time.time(), "exp": time.time()+604800}
encoded = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
rp = Response(encoded)
rp.set_cookie("token", encoded, expires=time.time()+604800)
rp.headers["token"] = encoded
return rp
我设置了过期时间为604800秒(一周的时间)。
我把token放到了cookie和自定义请求头token中。我放到cookie中是为了做web时好自动存储,省事。
3、验证token
我自己封装了一个类,方便后期。
# 密钥,可随意修改
SECRET_KEY = 'abcdefghijklmm'
class Verify(object):
def __init__(self, key, headers: werkzeug.datastructures.EnvironHeaders): # hearders是请求头
self.headers = headers
self.key = key
def verifyToken(self):
encoded = self.headers.get("token")
try:
jwt.decode(encoded, self.key, issuer="crayonxin", algorithms="HS256")
except Exception as e:
return False
return True
# 有没有错误都会返回信息
def DecodeToken(self):
encoded = self.headers.get("token")
if encoded == None:
return "请求头没有token参数"
try:
dict = jwt.decode(encoded, self.key,issuer="crayonxin", algorithms="HS256")
except jwt.ExpiredSignatureError: # 时间到期错误
return "时间到期"
except jwt.InvalidSignatureError: # token验证失败
return "token验证失败"
except jwt.InvalidIssuerError: # 颁发者错误
return "颁发者错误"
return dict
4、使用token
def get():
verify = Verify(SECRET_KEY, request.headers)
if verify.verifyToken():
print("成功")
# 这里写验证成功的程序
pass
else:
# 这里写验证失败的程序
print("失败")
pass
dict = verify.DecodeToken()
return dict
🍀CORS跨域处理
from flask_cors import * # 没有库请安装
app = Flask("name")
CORS(app,methods=["GET","POST","PUT","PATCH","DELETE","OPTIONS"], supports_credentials=True,expose_headers=['Content-Disposition'],) # 解决跨域问题
CORS类的参数:
参数名 | 类型 | Head字段 | 解释 |
resources | 字典、迭代器或字符串 | 无 | 全局配置允许跨域的API接口 |
origins | 列表、字符串或正则表达式 | Access-Control-Allow-Origin | 配置允许跨域访问的源,*表示全部允许 |
methods | 列表、字符串 | Access-Control-Allow-Methods | 配置跨域支持的请求方式,如:GET、POST |
expose_headers | 列表、字符串 | Access-Control-Expose-Headers | 自定义请求响应的Head信息,设置值之后,前端js能获取到响应头 |
allow_headers | 列表、字符串或正则表达式 | Access-Control-Request-Headers | 配置允许跨域的请求头 |
supports_credentials | 布尔值 | Access-Control-Allow-Credentials | 是否允许请求发送cookie |
🍀返回http状态码
return “错误信息”,404
或者使用abort()
from flask import abort
abort(404)
🍀重定向
from flask import redirect
@app.route('')
def index():
return redirect(location='',code=302)
🍀Restful api
flask不用其他的扩展其实可以构建简单的api,但是写的多的时候,看起来很乱。
有一个非常好用的库叫flask_restful
,这可以非常简单的部署api服务。
restful api 不是技术,准确的说是一种规范。可以看这个介绍RESTful API接口设计标准及规范 一个链接代表一个资源,使用[GET]
、[POST]
、[PUT]
、[DELETE]
、[PATCH]
来对资源进行处理。
Restful api 安装
pip install flask-restful
Restful api 示例
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
def post(self):
return {'':''}
def delete(self, todo_id):
del todo_id
return '', 204
def put(self,param):
return {}
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True)
注意: 没有flask_restful
这个工具的话,以前发送JSON需要使用Reponse
类或者jsonify
,现在直接返回字典,自动转换成JSON格式返回,太方便了!!!
🍀Flask返回图片
flask如果想返回图片,通用的处理方式是使用Base64编码,web接收到信息,使用html的img
标签即可展示图片。
下面以使用matplot绘制图为例,展示flask返回图片
import base64
from io import BytesIO
from flask import Flask
from matplotlib.figure import Figure
app = Flask(__name__)
@app.route("/")
def hello():
# 建立图板,不要用pyplot,会造成内存溢出
fig = Figure()
ax = fig.subplots()
ax.plot([1, 2])
# matplot图保存在io流
buf = BytesIO()
fig.savefig(buf, format="png")
# io流转为base64编码的字符串
data = base64.b64encode(buf.getbuffer()).decode("ascii")
return f"data:image/png;base64,{data}" # 返回图片字符串,html中img标签可以直接引用该字符串。