likes
comments
collection
share

Python中使用Flask:Docker发布Flask API

作者站长头像
站长
· 阅读数 9

Python中使用Flask

机器学习离不开Python,那么必不可少的的我们回用到Python中的一些web api框架,Python中的web框架很多,使用量大,轻量级的那么flask当之无愧(随便搜了一下,大家都说它好,就用了)。 在从零点一开始机器学习之HDF5模型发布到tensorflow/serving中,我们也发布了我们的模型,那么如果将模型更好的给第三方人员使用呢?在进行验证的时候,如果要做一定的前期处理又在哪个模块中进行呢?那么我们就看本文就好了。


系列文章目录

前言

本文主要是基于docker 运行flaskapi,主要是对外提供二次图像分类接口,进行图像预处理,flask 后台调用基于TensorFlow Serving的分类模型API ==环境说明 环境和版本很重要,大量的博客没有环境说明和版本介绍,对新人很不友好== 开发环境: 系统版本:Win7 Python版本:Python3.6 tensorflow版本:tensorflow-cpu 2.6.0 发布环境: 系统版本:CentOS Linux release 7.8.2003 (Core) tensorflow/serving版本:最新cpu版本(latest版本) docker版本:Docker version 19.03.12, build 48a66213fe


一、flask项目架构

1.整体项目架构

Python中使用Flask:Docker发布Flask API 很多小伙伴刚接触这个flask框架很多地方都不熟悉,绕来绕去的,成功发版踩坑很多,本来就是几个简单的接口。结果弄一大堆大学,实力劝退! 图中架构包含了fask基本框架,蓝图使用,gunicorn的简单配置等

wwxcwebcopy:.
│  1.txt  
│  dockerfile    
│  gunicorn.conf.py  #gunicorn配置文件
│  requirements.txt  #安装依赖文件
│  requirements__.txt #系统导出的全部安装依赖文件,即命令pip freeze > requirements.txt 生成后的文件
│  start.py  #gunicorn启动文件
│  start_local.py #本地启动文件  Python命令中 start_local.py可以启动
│  
├─.vscode
│      launch.json #flask debug文件
│      settings.json #系统设置文件
│      
├─wwxcweb
│  │  fileupload.py  #上传模块 就是暴露一个api
│  │  returnhtml.py  #返回静态文件
│  │  __init__.py    #初始文件
│  │  
│  ├─model 模型存放文件
│  ├─static
│  │  │  index.html #静态页面
│  │  │  
│  │  └─uploads
│  └─__pycache__ 
└─__pycache__

==注意==,一定不要使用上一篇博客或者flask中文网中大型应用作为一个包 中的项目框架,这样会产生循环调用,在启动docker时报错!大坑(第一次见官方文档挂一个错误的使用方式来方便大家理解和入门的)而且还在问中明确的描述出这个错误。还说不影响使用!我信你个鬼! Python中使用Flask:Docker发布Flask API

二、承载服务

greenlet是一个轻量级的协程库。gevent是基于greenlet的网络库。 guincorn是支持wsgi协议的http server,gevent只是它支持的模式之一 ,是为了解决django、flask这些web框架自带wsgi server性能低下的问题。它的特点是与各个web框架结合紧密,部署特别方便。 总结理解一下就是guincorn是一个性能好一点的web服务壳子,支持以gevent方式进行工作,我们不直接 发布flask,而是用guincorn来承载flaskapp。

1.安装gunicorn 和gevent

pip install gunicorn gevent

安装完成后 pip list查看效果,果然安装了依赖库greenlet Python中使用Flask:Docker发布Flask API

2.创建gunicorn配置

在项目根目录创建 /gunicorn.conf.py

workers = 17    # 定义同时开启的处理请求的进程数量,每个worker都是一个加载python应用程序的UNIX进程 worker之间没有共享内存 建议workers 数量是 (2*CPU) + 1
worker_class = "gevent"   # 采用gevent库,支持异步处理请求,提高吞吐量
bind = "0.0.0.0:7077"   #端口随便写,但是注意是否已经被占用。查看所有端口 netstap -lntp

我们可以使用gunicorn命令来测试是否可以正确运行,打开网址127.0.0.1:7077,将会打开我们的网站。

gunicorn start:app -c gunicorn.conf.py

==注意== Windows下运行会报错! 报错为No module named 'fcntl',新建一个 fcntl. py.文件,将其存放 Python的安装目录 Python36/Lib下 接下来还会报错缺少No module named 'pwd' ,到这个地方为止吧,等会直接干掉服务器上去,有bug慢慢来在解决,反正项目代码很少,应该没有bug吧!

二、docker环境准备

根目录下创建dockerfile文件

# 1、第一行必须指定   基础镜像信息
FROM python:3.6   
# 指定工作目录
WORKDIR /var/wf/  
#  安装依赖
COPY requirements.txt ./
# RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
# RUN apt-get clean
# RUN apt-get update && apt-get install -y libgl1-mesa-glx
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
#copy依赖库
COPY . .
# 端口
EXPOSE 7077
 
CMD ["gunicorn", "start:app", "-c", "./gunicorn.conf.py"]  #用于指定默认的容器主进程的启动命令

三、开始发布

才home/llp/目录下 新建wf文件夹,将步骤1中wwxcwebcopy目录下的全部文件copy到wf中

[root@ecs-photo ~]# cd /home/llp/wf/
[root@ecs-photo wf]# ls
1.txt  dockerfile  gunicorn.conf.py  __pycache__  requirements__.txt  requirements.txt  start_local.py  start.py  wwxcweb

在该文件中构建镜像 ==注意有个点==

docker build -t "wf" .

构建成功后,在docker中启动一个对应的容器。构建过程部分截图 Python中使用Flask:Docker发布Flask API 启动容器命令 配置文件挂载可以按照需要省略

docker run -di --name=wbc9511 -v /home/llpcode/wb9511docker/config.ini:/var/wf/flaskweb/config.ini -p 9511:7077 wf &

docker ps查看结果,容器运行成功Python中使用Flask:Docker发布Flask API postman测试一下 Python中使用Flask:Docker发布Flask API 收工!

四、BUG处理

1.docker启动flask容器报错: ImportError: cannot import name app

不要在flask代码中产生循环依赖否则会报错,此处建议使用蓝图解决 ==注意==,一定不要使用上一篇博客或者flask中文网中大型应用作为一个包中的代码结构!入门劝退型文档!

2.Centos 容器启动 ImportError: libGL.so.1: cannot open shared object file: No such file or dir报错,含有opencv依赖

网上搜索出来的方案大部分都是ubuntu16.04下的解决方案,apt-get install -y libgl1-mesa-glx apt安装对应的库,但是在centos中个人感觉姿势不对,尝试了很久,不能成功,在安装更新过程中总是卡死。后来了解到是requirements.txt中引用了opencv-python依赖包的原因,需要将opencv-python替换为opencv-python-headless即可解决,也就是说只需要一个opencv-python-headless就ok了,其他的OpenCV相关包都不需要。

3.docker启动flask容器报错: ImportError: cannot import name app

不要在flask代码中产生循环依赖否则会报错,此处建议使用蓝图解决 ==注意==,一定不要使用上一篇博客或者flask中文网中大型应用作为一个包中的代码结构!入门劝退型文档!

4.Address already in use

在容器启动日志中可以看到有一个http://127.0.0.1:5000启动成功的日志,原来是启动了2次,falsk本身启动了一次,gunicorn又启动了一次. start.py文件中去掉 app.run(threaded=True)代码

5.gunicorn HaltServer: 「HaltServer ‘Worker failed to boot.‘ 3」

在start.py中添加gunicorn,gevent依赖

install_requires=[
    "Flask",
    "gevent",
    "gunicorn",
],

6.蓝图不能返回静态文件

蓝图的第三个参数是 static_folder 。这个参数用以指定蓝图的静态文件所在的 文件夹,它可以是一个绝对路径也可以是相对路径。:也就是需要手动指定静态文件夹 admin = Blueprint('admin', name, static_folder='static')

5代码

阿里云盘测试 www.aliyundrive.com/s/6ncBymvm8…

总结

文中发布方式为最基础的发布方式,没有继承持续构建和自动化构建。镜像也没有上传到容器仓库。如果需要进一步优化发布流程,参考博主[docker专栏]