概要描述
Sophon中上线api服务的方式有nbcovert和gateway两种。
从2.5版本开始,python3/octave的kernel对应的脚本文件还可以支持gateway方式部署成api,该模式要求用户遵循一定的规则完成代码文件的编写,支持多线程发布,响应速度快,适用于对性能有要求的部署任务。
本篇文章主要讲述使用gateway的方式部署api。
详细说明
gateway服务的逻辑
打开notebook,每个cell可以视为一个完整api请求的整体,第一行以“#”开头,空格再加api类型,空格加api请求名称,定义了一个api请求,后续的内容为服务端收到请求后所执行的内容。返回给客户端的信息都是print中的内容。
因为服务发布在容器中,需要确认服务是否正常运行,因此必须建立/api/ping的GET请求,返回'{"status":"running"}’,作为服务的健康指标。
注意:以下这两个cell 是必须存在的!!!
import json
# GET /api/ping
a = {"status":"running"}
print(json.dumps(a))
GET请求示例
通过notebook打开一个python3的kernel,新建文件,将下述代码放在同一个cell中 :
# GET /hello
print("hello world!")
第一行定义了名为“hello”的GET请求,执行的内容只有一行print语句,返回的值即print中的内容。
如果文件中再新增一个cell,代码如下:
# GET /hello2
a = 1+2+3+4
print("hello world!", a)
一个ipynb文件可能会有多个cell,服务启动时会依次从头至尾执行每个cell内容,当收到相应的请求时,服务只会再次执行对应请求的cell中的内容,通过这样的方式提升了性能。举例如下:
sum=0
for i in range(1,5,1):
for j in range(1,5,1):
for k in range(1,5,1):
if(i!=j&j!=k):
sum=sum+1;
# GET /sum
print("sum is :",sum)
当服务初始化时,就已经计算了sum的值,当用户发起/sum的请求时,直接返回sum的计算值36即可。
POST 请求示例
当我们发起请求中带有结构体数据时,应当使用POST请求,下面给出简单样例,同样的,这4行代码需要写在同一个cell里
# POST /num
req = json.loads(REQUEST)
args = req['body']
num = args['num']
print(num)
解释
- 第一行定义了名为"num"的POST请求。
- 第二行的REQUEST不需要定义,通过json.loads获得整个传入request的信息,其中"body"对象即用户传入的结构体信息。注意:这里使用了json方法,需要在这个cell之前的cell里执行“import json”。
- 第四行从args里取出"num"对象的值,第五行予以返回。
notebook代码中运行时会报错:
NameError: name 'REQUEST' is not defined
直接忽略即可, 在部署时不会报错。
上架模型
新建模型成功后,点进版本管理, 上架模型服务版本
gateway方式,接口设置页面仅做展示用,供用户确认代码无误。
点击【上架】即可完成代码模型的上架操作
注意
1.用户基于python3的镜像创建实例,完成代码并成功执行,过程中不需要安装新的依赖,那么创建api任务时,选择python3的镜像,与本次完成的代码,进行部署。
2.用户基于python3的镜像创建实例,同时安装了当前环境没有的python包,完成代码并成功执行,代码中依赖新安装的python包;那么需要先将该实例固化成新的镜像,可命名为test1;后续创建api任务时,选择test1的镜像并选择依赖第三方lib包与本次的代码进行部署,
sophon功能spark镜像不支持作为api发布的基础镜像,因此,如果一个脚本只能在该镜像中执行成功,那么也不支持将其发布为api。
3.父文件:需要依赖的文件和代码在notebook放到一个文件夹里面,上架的时候选择依赖父文件,就会把代码所在的文件夹中的文件都放到镜像里面, 代码里面引用使用相对路径,例如代码和引用的父文件hello.txt
都放在test目录下,代码中路径直接写引用的文件就可以, 不需要加路径。父文件不宜过大,否则会超时。
上线
上线的 详细步骤查看教程文档的 服务管理 章节,
需要确保 连接状态 和 连接状态 都是成功的。
测试结果
使用sophon的测试页面
在sophon中使用测试功能时,请使用POST请求,并将传入参数按json结构处理,在上述num方法案例中的args即传入参数,传入时需是json结构,服务文件编写过程中也需要按json结构从args里读取信息。
测试页面只能测试post 请求
– api接口是上线的时候定义的名字: http://jiujiu-tdh-70:8003/{上线时自定义的名字}
– 需要在API接口后面加上代码中定义的请求名,例如代码中定义的post请求名为/num, 即改成 http://jiujiu-tdh-70:8003/gatewaytestv1/num
网页打开URL 将get请求返回结果
api接口后面需要加上代码中定义的请求名
示例中:
- 上线时的api接口: http://jiujiu-tdh-70:8003/gatewaytestv1
- 代码中定义的请求:/hello 、/hello2
使用curl返回结果
一、使用测试页面的ip和端口
post请求
可以直接复制测试界面的调用示例,在命令行执行
[root@jiujiu-tdh-71 ~]# curl -k -X POST http://jiujiu-tdh-70:8003/gatewaytestv1/num -H "Content-type: application/json" -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VybmFtZSI6Inp5cSIsInJvbGVzIjoiW1wiU09QSE9OX0FETUlOXCIsXCJwdWJsaWNcIixcImFkbWluXCJdIiwiZXhwIjo0NzYyOTQ0NTQ3LCJpYXQiOjE2MDkzNDQ1NDd9.Mj71LW0gsjGLhzdiDQuTIZY6fQf9ZXK1r26TwXBQFInuIwuWz1BfuX23eRudimIAszoYDV9jbkkbagScY_vyQA' -d '{"num":4}'
4
[root@jiujiu-tdh-71 ~]#
get请求
[root@jiujiu-tdh-71 ~]# curl http://jiujiu-tdh-70:8003/gatewaytestv1/hello
hello world!
[root@jiujiu-tdh-71 ~]#
二、使用pod的ip和svc的端口
- 获取部署的服务的示例名称
- 复制前面部分获取svc的ip和port
[root@jiujiu-tdh-71 ~]# kubectl get svc -owide|grep deploy-8ddc7ae3-085f-4431
deploy-8ddc7ae3-085f-4431-a29c-bc9b0eeebcfc ClusterIP 10.10.10.216 45907/TCP 39m aip.kube.app.general.deploy=7761f941-cda5-43ff-9264-096e81f485c6,aip.kube.app.name=deploy-8ddc7ae3-085f-4431-a29c-bc9b0eeebcfc,aip.kube.app.service=000d4fe7-1e26-4e17-8753-c6523f10560e
[root@jiujiu-tdh-71 ~]#
- 在命令行执行curl命令, ip和port 在上两步获取,加上对应的请求和传参(传参可选项)
GET请求
[root@jiujiu-tdh-71 ~]# curl http://10.10.10.216:45907/hello
hello world!
[root@jiujiu-tdh-71 ~]#
[root@jiujiu-tdh-71 ~]# curl http://10.10.10.216:45907/hello2
hello world! 10
[root@jiujiu-tdh-71 ~]#
POST请求
[root@jiujiu-tdh-71 ~]# curl -k -X POST http://10.10.10.216:45907/num -H "Content-type: application/json" -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VybmFtZSI6Inp5cSIsInJvbGVzIjoiW1wiU09QSE9OX0FETUlOXCIsXCJwdWJsaWNcIixcImFkbWluXCJdIiwiZXhwIjo0NzYyOTQ0NTQ3LCJpYXQiOjE2MDkzNDQ1NDd9.Mj71LW0gsjGLhzdiDQuTIZY6fQf9ZXK1r26TwXBQFInuIwuWz1BfuX23eRudimIAszoYDV9jbkkbagScY_vyQA' -d '{"num":4}'
4
[root@jiujiu-tdh-71 ~]#