Flask实现Web服务调用Python程序
通过Web服务调用Python写的手写数字识别算法模型,得到手写数字识别结果。
项目场景:
项目需求:将客户端的请求经由Web服务器转发给Flask程序实例。
示例:通过Web服务调用Python写的手写数字识别算法模型,得到手写数字识别结果。
环境准备:
- Python环境不多说了
- 安装
flask``````pip install flask
- 安装
waitress``````pip install waitress
代码:
main.py
from flask import Flask
from predictNumber import predict
app=Flask(__name__)@app.route('/predictNumber/', methods=['POST'])defpredict_number():
image = request.form["image"]# 非必须,本案例使用
result = predict(image)return{"result": result
}if __name__=='__main__':
app.debug=True
app.run(host='127.0.0.1',port=5000)
其中,手写数字识别的代码
predictNumber.py
赠送如下:
from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
from PIL import Image
import numpy as np
import base64
from io import BytesIO
classNet(nn.Module):def__init__(self):super(Net, self).__init__()
self.conv1 = nn.Conv2d(1,32,3,1)
self.conv2 = nn.Conv2d(32,64,3,1)
self.dropout1 = nn.Dropout(0.25)
self.dropout2 = nn.Dropout(0.5)
self.fc1 = nn.Linear(9216,128)
self.fc2 = nn.Linear(128,10)defforward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = self.conv2(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = self.dropout1(x)
x = torch.flatten(x,1)
x = self.fc1(x)
x = F.relu(x)
x = self.dropout2(x)
x = self.fc2(x)
output = F.log_softmax(x, dim=1)return output
defpredict(image):# load model
model = Net()
model.load_state_dict(torch.load("demo/model/mnist_cnn.pt"))
model.eval()# load test data
img = Image.open(image).convert('L')
img = img.resize((28,28))# 更改图片大小
npimg1 = np.array(img)# 转为numpy矩阵
flatten_img = npimg1.reshape(1,1,28,28)# 转为mnist1, 1, 28, 28二维张量# 以下意思是把白色背景转为黑色背景,因为训练的都是黑色背景
new_flatten_img =(255-flatten_img)/255.0
new_flatten_img = new_flatten_img.reshape(1,1,28,28)# -------- 该数据可直接被模型识别
test_kwargs ={'batch_size':1}
test_loader = torch.utils.data.DataLoader(new_flatten_img,**test_kwargs)for data in test_loader:
data = data.to(torch.float32)
output = model(data)
pred = output.argmax(dim=1, keepdim=True)print(pred)print(pred.item())return pred.item()
启动该服务有两种方式
方式一:
通过运行Python脚本启动服务,
run.py
代码如下:
from waitress import serve
import main
serve(main.app, host='127.0.0.1',port=5000)
直接运行
run.py
即可
python run.py
验证我们可通过postman发送请求,得到如下结果:
方式二:
通过 cmd 设置 mian.py 路径,我的
main.py
放在E:\pythonProject\下面,大家自行调整。
setFLASK_APP=E:\pythonProject\main.py
再通过以下指令启动服务:
flask run
效果如下:
以上便是简单版的完整流程。下面加更一些补充说明~
Flask程序必须创建一个程序实例。参见上面第一个代码
main.py
中
app = Flask(__name__)
即为实例。
Web服务器把接收到的所有客户端请求,转交给Web服务器网关接口对象处理。需要提供的参数只有一个,就是程序主模块或包的名字,一般就是Python的name变量。
客户端的请求经由Web服务器转发给Flask程序实例。程序实例需要URL到具体代码的映射关系。这个映射关系称为路由。
Flask中最简单的路由定义方式是app.route修饰器。
上面的路由定义,把根路径和predictNumber函数关联起来,如果部署程序的服务器域名是 http://127.0.0.1:5000/,那么浏览器中输入 http://127.0.0.1:5000/predictNumber/ 就会触发这个函数。
函数的返回值称为响应,是客户端接收到的内容。这样如果客户端是Web浏览器,响应就是给客户看的文档。
下面博文中有非常详细完整的介绍,以供参考。
一个简单的Flask Web服务器
实现多并发调用服务可参考:
Flask+gunicorn实现web服务并发调用Python程序,解决多线程/多进程问题
多并发调用Pytorch的坑:
Flask+gunicorn部署深度学习报错gunicorn: error: argument -b: invalid int value ‘0.0.0.0:8000‘
版权归原作者 小白白程序员 所有, 如有侵权,请联系我们删除。