用一个例子说明怎么使用Swagger和connexion、Docker构建深度学习服务

因为鄙人大创的需要,需要将深度学习模型打包成服务,所以这里写一个教程说明如何搭建服务。因为此刻我们的模型还没有训练好,所以就写一个简单的demo,实现的步骤都是一样的。自己对于connexion包用得不多,且YAML语言也是简单了解了一下,所以如果有错,请指正。

工具解释

Swagger

Swagger是一个强大的工具,就我掌握的而言,它是一个集文档生成、前后端代码生成功能的强大工具,能够根据YAML语言的API描述生成Android、python代码(可能需要修改某一些地方才能运行)、Web版文档。它编写的规则是基于OpenAPI规范的,OpenAPI是API描述规范,具体可以参考github上的链接OpenAPI Specification。API一般使用YAML语言进行描述,YAML语言可以与JSON进行转换,既然能相互转换,也就是说在Swagger里面可以按照OpenAPI规范使用JSON语言或YAML语言对API进行描述,很多地方一般都是使用YAML语言的。Swagger分为Swagger-codegen、Swagger-ui和Swagger-editor三个模块,关于这三个模块的详细介绍可以参看这一篇文档Swagger从入门到精通。其实Swagger提供了在线版Swagger
这里推荐一篇写得还不错的OpenAPI规范OpenAPI

connexion包

这个包使用较少,网上资料也很少,其实文档里面使用方法说得非常得清楚,参见PyPI文档connexion包

Docker

Docker真的小,我本以为一个容器或几个容器的运行,一般笔记本遭不住,结果很不错吧,看看一个容器占得内存,这个容器挂了一个服务
用一个例子说明怎么使用Swagger和connexion、Docker构建深度学习服务
仅仅18M,超乎想象。这里给自己留一个坑去学一学Docker的内部机制架构。关于Docker入门网上有很多资料,我参考的是Docker入门-菜鸟教程,关于各种命令的使用以及Dockerfile的使用可以自行看看别人的博客。其中这里记录一下,在使用过程中踩的坑,就是CMD命令,这个命令我的理解是镜像的一个属性,当使用镜像创建一个容器时如果在执行docker run命令时没有指定其他的命令,那么使用Dockerfile中定义的CMD命令,这个CMD命令也是容器的一个属性,容器的CMD属性与其镜像的CMD属性一致,当将容器转为镜像的时候,这个属性是会传递给镜像的,这个命令是在容器启动时就会执行(每一次启动),包括命令docker start、docker run(创建一个新的容器),如果启动的命令即CMD包括/bin/bash那么可以在docker start -i来与容器进行交互,如果CMD没有这个那么使用docker start -i也不能启动交互,直接就退出来了。这里注意下最好将dockerfile文件放到一个空文件夹下,不然发送到Docker daemon 的数据很大,他会将所有与dockerfile在同一目录下的文件全部发送到Docker daemon,这是占磁盘空间的。

搭建

这里给出简单的加法运算,搭建REST API服务
dockerfile:

FROM fedora:28
MAINTAINER Tanglj <邮箱>

RUN pip3 install connexion -i http://mirrors.aliyun.com/pypi/simple/  --trusted-host mirrors.aliyun.com

ADD ./ /test_docker
EXPOSE 5000

WORKDIR /test_docker

CMD python3 ConnexionTest.py

Connexion文件:

import connexion

app = connexion.App(__name__, specification_dir='./')

app.add_api('addtest.yml')

if __name__ == '__main__':
    app.run(debug=True)

API描述文件:

swagger: "2.0"
info:
  description: "test add op"
  title: "Add"
  version: "1.0"
consumes:
  - "application/json"
produces:
  - "application/json"
basePath: /
paths:
  /add:
    post:
      summary: "add op"
      operationId: "Add.add"  #文件名.函数名
      tags:
        - add
      parameters:
        - name: a #与函数中的参数名一致
          in: query  
          type: integer
        - name: b
          in: query
          type: integer
      responses:
        '200':
          description: "success"
        
      

Add python代码:

def add(a,b):
    return a+b

接下来我们使用

docker build -t 标签 . 

创建镜像,build命令会去当前路径找Dockerfile。然后使用如下命令创建容器并做主机与虚拟机的端口映射

docker run -it -p 5000:5000 标签 /bin/bash

为什么我们要使用新的CMD命令呢,因为如果不使用的化,根据Dockerfile中的CMD那么容器直接会执行python的命令然后就结束了,而我们还需要配置swagger-ui模块,所以需要进入交互模式,所以修改CMD命令为/bin/bash。其中的-it不能少,表示交互,如果没有-it参数那么也不会进入交互模式。
接下来我们进入了容器命令行界面
用一个例子说明怎么使用Swagger和connexion、Docker构建深度学习服务

这样只需运行python Connexion文件即可,你会发现程序提示错误,根据错误提示,我们需要安装Swagger-ui模块,我自己手动安装了一遍发现一堆错误,所以只好用另一种方法了,就是运行

 pip3 install connexion[swagger-ui]

估计connexion对swagger-ui做了集成。
接下来登录http://localhost:5000/ui/即可,效果:
用一个例子说明怎么使用Swagger和connexion、Docker构建深度学习服务