Flask implements web services to call Python programs
The handwritten digit recognition algorithm model written in Python is called through the Web service to obtain the handwritten digit recognition results.
Project scenario:
Project requirements: Forward the client's request to the Flask program instance via the web server.
Example: Call the handwritten digit recognition algorithm model written in Python through the Web service to obtain the handwritten digit recognition results.
Environment preparation:
- Not much to say about the Python environment
- Install
flask
pip install flask
- Install
waitress
pip install waitress
Code:
main.py
from flask import Flask
from predictNumber import predict
app=Flask(__name__)
@app.route('/predictNumber/', methods=['POST'])
def predict_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)
Among them, the code for handwritten digit recognition predictNumber.py
is given as follows:
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
class Net(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)
def forward(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
def predict(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()
There are two ways to start the service
method one:
Start the service by running a Python script, run.py
the code is as follows:
from waitress import serve
import main
serve(main.app, host='127.0.0.1',port=5000)
run.py
Just run it directly
python run.py
Verify that we can send the request through postman and get the following results:
Method two:
Set the main.py path through cmd. Mine is main.py
placed under E:\pythonProject\. You can adjust it yourself.
set FLASK_APP=E:\pythonProject\main.py
Then start the service with the following command:
flask run
The effect is as follows:
The above is the complete process of the simple version. Here are some additional explanations~
The Flask program must create a program instance. See the first code above main.py
for app = Flask(__name__)
an example.
The web server transfers all client requests received to the web server gateway interface object for processing. There is only one parameter that needs to be provided, which is the name of the main module or package of the program, usually the name variable of Python.
The client's request is forwarded to the Flask program instance via the web server. Program instances require a mapping from URL to specific code. This mapping relationship is called routing.
The simplest way to define routes in Flask is the app.route decorator.
The above route definition associates the root path with the predictNumber function. If the server domain name of the deployment program is http://127.0.0.1:5000/, then enter http://127.0.0.1:5000/predictNumber/ in the browser. This function will be triggered.
The return value of the function is called the response and is what the client receives. In this way, if the client is a web browser, the response is the document shown to the client.
There is a very detailed and complete introduction in the following blog post for reference.
To implement multiple concurrent service calls, please refer to:
Pitfalls of multiple concurrent calls to Pytorch: