1. 简介
使用flask封装,简单来讲就是将python文件引入flask。这样的结果就是在网页上输入一个url就能得到结果。下面就讲如何进行实现。
2. 任务1:求两数之和
2.1 代码讲解
新建一个server.py的文件,文件中代码如下所示:
from flask import Flask
from flask import request
from flask import jsonify
def get_sum(x, y):
result = x + y
return result
app = Flask(__name__)
@app.route('/',methods=['POST','GET','PUT'])
def get_result():
x = request.args.get('first')
y = request.args.get('second')
res = get_sum(x, y)
return str(res)
if __name__ == '__main__':
app.config['JSON_AS_ASCII'] = False
app.run()
最上面导包和python一样,不再赘述。
导包和app = Flask(__name__)
之间的内容(本例中就是get_sum函数)为执行python server.py加入内存的东西。假如我们现在不仅需要计算一次两数之和,而是给了100组数,每组数都要计算两数之和,那么我们需要不断加载get_sum函数,然后求和(如果换成一个机器学习的例子可能更好理解。比如我们已经训练好一个模型,现在要实时预测,即来一条数据加载一次模型,然后预测。再来一条数据,重复上述过程。每次来数据,我们都加载模型,会很浪费时间,尤其是模型很大时,这时把load模型的代码放到get_sum的位置,在命令窗口执行python server.py后,模型就永久加载到内存了,不需要每次来一条数据都要加载一次模型,第3章的例子可能会帮助理解, 可详看第三章)
app = Flask(__name__)
个人觉得写法比较固定,可不用理会
@app.route('/',methods=['POST','GET','PUT'])
斜杠/貌似也比较固定,可先不用管,有的例子也做了调整,可见链接:http://www.pythondoc.com/flask-restful/first.html。methods是http请求的方法,目前有8种请求方法:
具体详见博客:https://www.cnblogs.com/weibanggang/p/9454581.html。在实际应用中发现,如果想要新建一个excel文件,并保存代码的结果,必须加put才有结果,否则得到的excel文件是空的。具体原理涉及http请求,本人不太懂。
接下来get_result函数具体作用大致有两个:一个是从url中获得相应的参数值。本例中要求两数之和,因此必须得到两个数x和y的值,那么 x = request.args.get(‘first’)
y = request.args.get(‘second’)就是从url解析出first和second参数,并把两个参数的值分别赋给x和y,不过赋值前需要先转化成int,因为从url中解析到的参数值是str类型,url长什么样子下面会讲。第二个作用就是从内存中(就是本例上面所讲的get_sum函数)调用相应函数以获得最终结果。特别需要注明的是get_result函数必须有return,不能省略或者写成return None,否则在网页使用url打开时会报错,且返回的类型不能是int,只能是str或者json。
if __name__ == '__main__':
和python中用法一样
app.config['JSON_AS_ASCII'] = False
固定用法暂时不管
app.run()
这个就是运行整个程序,run有两个参数,可写成app.run(host="192.168.199.166", port=5000)
。我们知道在浏览器中输入ip地址或者域名都可以打开网页,那么host就指定了打开哪个网页,port指定了端口。不写的话默认是本地地址,发现无论是自己的window电脑还是linux电脑,默认ip都是127.0.0.1,端口都是5000。
2.2 执行讲解
上面我们在server.py文件中写好代码后,就可以打开命令窗口执行python server.py了,如下图所示:
此时get_sum函数已经加载到内存。
然后打开自己的浏览器,输入http://127.0.0.1:5000/?first=3&second=4
- http://127.0.0.1:5000就是我们app.run中指定的host和port
- /?:固定写法,记住吧,应该是http的知识
- first=3:即
x = request.args.get('first')
中的first,因此x现在是3,注意这时3是str类型(即使没有引号,默认都是str类型),要计算和需要转换成int - second=4:同上
- &:多个参数之间用&符号连接
最终页面返回结果如下:
3. 任务2:机器学习任务用于线上部署
任务:预测url中是否含有xss攻击,现已经训练好一个决策树模型。
- 本地新建一个server.py文件
import numpy as np
from flask import Flask
from flask import request
from flask import jsonify
import joblib
import re
import urllib
import base64
import string
dt_model = joblib.load('DT-module.m') # 决策树模型
std_model = joblib.load('DT-std-module.m') # 数据标准化模型
# 提取url的特征
def get_feature(url):
# url的长度
处于保密性,省略该函数的代码,此函数的目的就是根据url提取特征数据
app = Flask(__name__)
@app.route('/',methods=['POST','GET'])
def output_data():
text=request.args.get('inputdata') # inputdata为需要检测的url
if text:
url_feature = get_feature(url)
url_feature = np.array(url_feature).reshape(1, -1)
std_feature = std_model.transform(url_feature)
pred = dt_model.predict(std_feature)
return jsonify(str(pred)) # 转化成json方式
if __name__ == '__main__':
app.config['JSON_AS_ASCII'] = False
app.run(host='127.0.0.1',port=6666) # 127.0.0.1 #指的是本地ip
- 打开命令窗扣
执行python server.py
- 本地新建一个client.py文件
import requests
import time
from sklearn.metrics import accuracy_score
import pandas as pd
time_list = [] # 记录时间
pred = [] # 用于记录一个个url的结果
with open('test.csv', 'rb') as f: # test.csv中有用于检测的url
for line in f:
time_start = time.time()
base = 'http://127.0.0.1:6666/?inputdata=%s'%line # url
response = requests.get(base) # 类似于第2章从网页打开了url
answer = response.json() # 获得网页返回的结果
print('预测结果',answer)
time_end = time.time()
one_time = time_end - time_start
time_list.append(one_time)
answer = answer[1] # 返回的结果是一个str,str里面是list,list里只有一个元素0或者1,代表是否是xss攻击。为了取出0或者1,需要本代码
pred.append(int(answer))
mean_time = sum(time_list) / len(time_list)
result = pd.DataFrame({'real_label':label, 'pred':pred})
- 打开命令窗扣
执行python client.py
这样就完成了机器学习模型的线上部署