目录
一、环境准备
1、Flask
Flask 是一个微型的 Python 开发的 Web 框架,基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用BSD授权。 Flask也被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。
Flask学习参考:Flask教程 Flask官方文档学习
2、Postman
Postman是一款接口测试工具,postman适用于不同的操作系统,Postman Mac、Windows X32、Windows X64、Linux系统,还支持postman 浏览器扩展程序、postman chrome应用程序等,官网下载地址:Postman | Download Postman App
Postman基础功能如下:
请求区域介绍如下:
- Authorization:身份验证,主要用来填写用户名密码,以及一些验签字段,postman有一个helpers可以帮助我们简化一些重复和复杂的任务。当前的一套helpers可以帮助你解决一些authentication protocols的问题。;
- Headers:请求的头部信息
- Body:post请求时必须要带的参数,里面放一些key-value键值对
- Pre-requerst Script:可以让你在 请求之前自定义请求数据,这个运行在请求之前,语法使用JavaScript语句。
- tests:tests标签功能比较强大,通常用来写测试,它是运行在请求之后。支持JavaScript语法。postman每次执行request的时候,会执行tests。测试结果会在tests的tab上面显示一个通过的数量以及对错情况。这个后面会进行详解,它也可以用来设计用例,比如要测试返回结果是否含有某一字符串
- form-data:,它将表单数据处理为一条消息,以标签为单元,用分隔符分开。既可以单独上传键值对,也可以直接上传文件(当上传字段是文件时,会有Content-Type来说明文件类型,但该文件不会作为历史保存,只能在每次需要发送请求的时候,重新添加文件。);post请求里较常用的一种
- x-www-form-urlencoded:对应信息头-application/x-www-from-urlencoded,会将表单内的数据转换为键值对;
- raw:可以上传任意类型的文本,比如text、json、xml等,所有填写的text都会随着请求发送;
- binary:对应信息头-Content-Type:application/octet-stream,只能上传二进制文件,且没有键值对,一次只能上传一个文件, 也不能保存历史,每次选择文件,提交。
二、Flask接口开发
from flask import Flask,request,jsonify
import json
import time
from yolo_json import YOLO
from PIL import Image
# 获取图像检测结果
def result(img_url):
try:
image = Image.open(img_url) # 打开图像
except:
return 'Open Error! Try again!'
else:
yolo = YOLO()
result_data = yolo.detect_image_result(image) #获得图像的检测结果
return result_data #返回字典格式的检测结果
app = Flask(__name__)
@app.route('/detect', methods=['POST']) #只接受POST方法访问
def check():
_head ={
"applicationCode": None,
"operationTime": " ",
"status": "S",
"code": "-000000",
"msg": "成功"
}
_body = {
"VehicleNum": " ",
"VehicleInfo":[]
}
operation_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 获取现在时间
_head["operationTime"] = str(operation_time)
result_dict={"head":_head,"body":_body} # 默认结果
# 获取传入的参数,传入的参数为bytes类型,需要转化成json
request_data = json.loads(request.get_data())
img=request_data["ImageInfo"] #获得图像路径
result_body=result(img) #图像检测结果
#判断是否成功
if result_body=='Open Error! Try again!':
_head['status']='F'
_head['code']='DC000001'
_head['msg']='图像错误或不存在,请重试!'
result_dict['head']=_head
result_dict['body']={}
return json.dumps(result_dict, ensure_ascii=False)
else:
result_dict["body"] = result_body
return jsonify(result_dict)
# 启动web服务器
if __name__=='__main__':
# host = 服务IP, port = 端口, debug = 是否debug模式,默认是Fasle
app.run(host='0.0.0.0',port=1000,debug=False)
- app = Flask(__name__):初始化,创建一个该类的实例,第一个参数是应用模块或者包的名称
- @app.route('/detect', methods=['POST']):通过使用route()装饰器的方法定义一个路由地址,/detect是接口的uri,使用 route() 装饰器告诉 Flask 什么样的URL能触发我们的函数,这个函数的名字也在生成 URL 时被特定的函数采用,这个函数返回我们想要显示在用户浏览器中的信息;methods=['POST']表示只接受POST方法访问,methods=['GET']表示只接受GET方法访问,methods=['POST', 'GET']表示两种方法都接受。
- app.run(host='0.0.0.0', port=1000,debug=True):用 run() 函数来让应用运行在本地服务器上。其中host为要监听的主机名, 默认为127.0.0.1(localhost),设置为“0.0.0.0”以使服务器在外部可用,port是设置的端口号,port不填的话默认5000,debug默认为false,如果设置为true,则提供调试信息;若是在docker中使用,记得docker要把对应的端口映射到主机;
python和flask中返回JSON数据的方法如下:
- 字典转化为JSON的数据格式:return json.dumps(result_dict,ensure_ascii=False) #result_dict为字典数据,使用json转换的在前端显示的数据为JSON字符串;
- 使用flask的jsonify转换后,在前台显示的为JSON对象:return jsonify(result_dict)
三、接口测试
1、使用postman进行接口测试
执行该接口脚本启动服务显示:Running on http://0.0.0.0:1000/ (Press CTRL+C to quit),可以看到提示服务启动位于http://0.0.0.0:1000/
使用postman工具发送(send)请求到接口地址 http://0.0.0.0:1000/detect
结果如下:
2、服务器及容器中进行接口测试
(1)该测试是在服务器中容器无法与外网链接的条件下进行的
首先,进入容器查看容器的IP地址:cat /etc/hosts;
然后,修改容器中对应接口脚本的app.run(host='0.0.0.0',port=1000) 中的host,有两种方法:第一仍可以使用host='0.0.0.0',第二可以将host修改为容器IP,即host='172.17.0.12'。
最后,编写测试脚本(代码为Python2.7版本下)在服务器中模拟Postman进行测试
# -*- coding: utf-8 -*-
import requests
import json
import time
import base64
host = "172.17.0.12:1000"
endpoint=r"/detect"
url = ''.join([host,endpoint])
headers = \
{
"applicationCode": "detection",
"operationTime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) ,
"Content-Type": "application/json;charset=UTF-8"
}
body = \
{
"ImageInfo": "/root/data/test.jpg" #测试图片路径
}
r = requests.post(url,headers=headers,json=body)
print r.headers
print r.text
print r.url
(2)通过K8s进入容器进行接口测试
该测试是在服务器中通过K8s进入容器与外网链接的条件下使用Postman进行的测试
接口脚本不变,运行服务后,在Postman中进行测试结果如下:
注意:此处IP为服务器的IP地址,端口号为K8s通过yaml文件创建资源时设定的端口号。
3、注意事项
(1)错误解决:OSError: [Errno 98] Address already in use -- flask
该错误是由于服务进程运行的情况下或非正常关闭的情况下,再次运行接口脚本启动服务造成的,解决方法如下:
首先,运行以下命令:ps -fA | grep python 显示所有进行及对应的ID号
然后,运行以下命令:kill 14949 根据ID号关掉对应的进程即可