基于RESTful接口访问MindSpore Serving服务
概述
MindSpore Serving支持gPRC
和RESTful
两种请求方式。本章节介绍RESTful
类型请求。
RESTful
是一种基于HTTP
协议的网络应用程序的设计风格和开发方式,通过URI
实现对资源的管理及访问,具有扩展性强、结构清晰的特点。基于其轻量级以及通过HTTP
直接传输数据的特性,RESTful
已经成为最常见的Web
服务访问方式。用户通过RESTful
方式,能够简单直接的与服务进行交互。
部署Serving
参考快速入门 章节。
我们可以通过mindspore_serving.server.start_restful_server
接口启动RESTful
服务。
请求方式
当前仅支持POST
类型的RESTful请求,请求格式如下:
POST http://${HOST}:${PORT}/model/${MODLE_NAME}[/version/${VERSION}]:${METHOD_NAME}
其中:
${HOST}
:指定访问的IP地址;${PORT}
:指定访问的端口号;${MODLE_NAME}
:请求的模型名称;${VERSION}
:表示版本号。版本号是可选的,若未指定具体版本号,则默认使用模型的最新版本。${METHOD_NAME}
:表示请求模型的具体方法名称。
如果使用curl
工具,RESTful请求方式如下:
curl -X POST -d '${REQ_JSON_MESSAGE}' http://${HOST}:${PORT}/model/${MODLE_NAME}[/version/${VERSION}]:${METHOD_NAME}
例子:请求LeNet
模型的predict
方法进行数字图片的推理,请求如下:
curl -X POST -d '{"instances":{"image":{"b64":"babe64-encoded-string"}}}' http://127.0.0.1:1500/model/lenet/version/1:predict
其中:babe64-encoded-string
表示数字图片经过base64
编码之后的字符串。由于字符串比较长,不显式列出。
请求输入格式
RESTful支持Json
请求格式,key
固定为instances
,value
表示多个实例。
每个实例通过key-value
格式的Json
对象来表示。其中:
key
:表示输入名称,需要与请求模型提供的方法的输入参数名称一致,若不一致,则请求失败。value
:表示具体的值。当前支持的value
类型:标量:
str
、bytes
、int
、float
、bool
。bytes
:通过base64
编码方式支持。张量:
int
、float
、bool
组成的一级或多级数组。张量通过数组格式表示数据和维度信息。
Json
中支持的int
类型:是int32
表示的范围,float
类型:是float32
表示的范围。
请求格式:
{
"instances":[
{
"input_name1":<value>|<list>|<object>,
"input_name2":<value>|<list>|<object>,
...
},
{
"input_name1":<value>|<list>|<object>,
"input_name2":<value>|<list>|<object>,
...
}
...
]
}
例子:
{
"instances":[
{
"tag":"one",
"box":[[1,1],[2,3],[3,4]],
"image":{"b64":"iVBOR...ggg==="}
},
{
"tag":"two",
"box":[[2,2],[5,5],[6,6]],
"image":{"b64":"iVBOR...QmCC", "type":"bytes"}
}
]
}
其中:iVBOR...ggg===
是图片数字0
经过base64
编码之后的省略字符串。iVBOR...QmCC
是图片数字1
经过base64
编码之后的省略字符串。不同图片编码出来的字符串可能不同,上述是示意说明。
base64数据编码
bytes
类型需要通过base64
编码进行表示。base64
除了可以表示bytes
类型,也可以表示其他标量和张量数据,此时将标量和张量的二进制数据通过base64
进行编码,并额外通过type
指定数据类型,通过shape
指定维度信息:
type
:可选,如果不指定,默认为bytes
。支持
int8
、int16
、int32
、int64
、uint8
、uint16
、uint32
、uint64
、float16
(或fp16
)、float32
(或fp32
)、float64
(或fp64
)、bool
、str
、bytes
。shape
:可选,如果不指定,默认为[1]
。
例子:
如果要用base64
编码表示:int16
的数据类型,shape
为3*2,值是[[1,1],[2,3],[3,4]]
的张量,则表示如下:
{
"instances":[
{
"box":{"b64":"AQACAAIAAwADAAQA", "type":"int16", "shape":[3,2]}
}
]
}
其中AQACAAIAAwADAAQA
:是[[1,1],[2,3],[3,4]]
的二进制数据格式经过base64
编码后的字符串。
请求支持的类型总结如下:
支持的类型 |
例子 |
备注 |
---|---|---|
|
1,[1,2,3,4] |
默认 |
|
1.0,[[1.2, 2.3], [3.0, 4.5]] |
默认 |
|
true,false,[[true],[false]] |
|
|
“hello”或者 |
直接表示或者指定 |
|
{“b64”:”AQACAAIAAwADAAQA”} 或者 |
如果不填 |
|
{“b64”:”AQACAAIAAwADAAQA”, “type”:”int16”, “shape”:[3,2]} |
利用base64编码,表示指定type的数据 |
请求应答格式
应答格式与请求格式保持一致。返回Json
格式信息。应答格式如下:
{
"instances":[
{
"output_name1":<value>|<list>|<object>,
"output_name2":<value>|<list>|<object>,
...
},
{
"output_name1":<value>|<list>|<object>,
"output_name2":<value>|<list>|<object>,
...
}
...
]
}
多实例请求后,如果多实例全部成功处理,则响应格式如下:
例子:
LeNet
请求识别数字0
和数字1
。{ "instances":[ { "result":0 }, { "result":1 } ] }
如果部分实例出错,则响应格式如下:
例子:
lenet
请求识别数字0
和一个错误数字图片。{ "instances":[ { "result":0 }, { "error_msg":"Preprocess Failed" } ] }
如果请求全部失败,则响应格式如下:
例子:
lenet
请求识别两张错误数字图片为例。{ "instances":[ { "error_msg":"Preprocess Failed" }, { "error_msg":"Time out" } ] }
出现系统性或者其他解析等错误,则返回格式:
例子:
lenet
传入非法Json
字符串。{ "error_msg":"Parse request failed" }
应答数据表示如下:
Serving输出类型 |
RESTful json中数据类型 |
说明 |
举例 |
---|---|---|---|
|
json integer |
整型格式的数据表示为json整型 |
1,[1,2,3,4] |
|
json float |
浮点格式的数据表示为json浮点数 |
1.0,[[1.2, 2.3], [3.0, 4.5]] |
|
json bool |
bool类型数据表示为json bool |
true,false,[[true],[false]] |
|
json str |
字符串格式输出表示为json str |
“news_car” |
|
base64 object |
二进制格式输出转为base64对象 |
{“b64”:”AQACAAIAAwADAAQA”} |
访问开启SSL/TLS的RESTful服务
MindSpore Serving支持开启SSL/TLS
的RESTful
服务,下面以单向认证为例展示如何启动并访问开启SSL/TLS
的Restful
服务。
verify_client
设置为False
表示单向认证,开启SSL/TLS
需要把mindspore_serving.server.SSLConfig
对象传入start_restful_server
的ssl_config
参数。其他内容可以参考访问开启SSL/TLS的Serving服务。
import os
import sys
from mindspore_serving import server
def start():
servable_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
servable_config = server.ServableStartConfig(servable_directory=servable_dir, servable_name="add",
device_ids=(0, 1))
server.start_servables(servable_configs=servable_config)
ssl_config = server.SSLConfig(certificate="server.crt", private_key="server.key", custom_ca=None, verify_client=False)
server.start_restful_server(address="127.0.0.1:5500", ssl_config=ssl_config)
if __name__ == "__main__":
start()
我们可以使用curl
工具或python
的requests
库访问Serving
的开启SSL/TLS
的RESTful
服务。如果使用curl
工具访问,可以尝试使用下面的请求方式:
curl -X POST -d '${REQ_JSON_MESSAGE}' --cacert '${PATH_TO_CA_CERT_FILE}' https://${HOST}:${PORT}/model/${MODLE_NAME}/version/${VERSION}]:${METHOD_NAME}
例子:请求add
模型的add_common
方法,具体如下:
curl -X POST -d '{"instances":[{"x1":[[1.0, 2.0], [3.0, 4.0]], "x2":[[1.0, 2.0], [3.0, 4.0]]}]}' --cacert ca.crt https://localhost:5500/model/add/version/1:add_common
我们这里需要将协议设置为https
,设置选项--cacert
的值为CA证书文件ca.crt
的路径。
另外由于示例中使用了自签名的证书,也可以设置选项--insecure
表示忽略对服务器证书的验证,具体如下:
curl -X POST -d '{"instances":[{"x1":[[1.0, 2.0], [3.0, 4.0]], "x2":[[1.0, 2.0], [3.0, 4.0]]}]}' --insecure https://localhost:5500/model/add/version/1:add_common