Обработка post запроса на python webserver в docker toolbox
На python вебсервере хочу отловить post запрос, распарсить его и запустить скрипт с просто нейросетевой моделью. Полученный результат отдать в пост ответ.
Пока вебсервер отвечает на пост запросы текстом, который я задаю(проверил в Insomnia).
В Docker почему-то сервер не всегда запускается, хотя я вроде все библиотеки подгружаю правильно.
#!/usr/bin/python3
from http.server import BaseHTTPRequestHandler, HTTPServer
import socket
import subprocess
from io import BytesIO
from keras.models import Sequential
from keras.layers import Dense
import pandas as pd
import numpy as np
from urllib import request, parse
# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# GET
def do_GET(self):
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write(b'Hello, world!')
# Send message back to client
message = "<font size=+3>Hello world!(HTML)</font><p>"
self.wfile.write(bytes(message, "utf8"))
def do_POST(self):
content_length = int(self.headers['Content-Length']) # Gets the size of data
body = self.rfile.read(content_length) # - Gets the data itself
self.send_response(200)
self.end_headers()
response = BytesIO()
response.write(b'wto proishodit????. ')
response.write(b'This is POST request. ')
response.write(b'Received: ')
response.write(body)
self.wfile.write(response.getvalue())
def run():
print('starting server...')
# Server settings
# Choose port 8081, for port 80, which is normally used for a http server, you need root access
server_address = ('', 8888)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
class modelnn(object):
"""docstring"""
def __init__(self,data):
"""Constructor"""
self.data = data
def get_result(self):
train = pd.DataFrame([[0, 0, 1, 0],[1, 1, 1, 1], [1, 0, 1, 1], [0, 1, 1,0]])
train.columns = ['ohe1', 'ohe2','ohe3', 'output']
X_train = train[['ohe1', 'ohe2','ohe3']]
y_train = train['output']
batch_size = 2
epochs = 6
model = Sequential()
model.add(Dense(3, activation = 'relu', input_shape=(3,)))
model.add(Dense(1, activation = 'sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=0);
a = model.predict(self.data)
b =np.apply_along_axis(lambda x: round(x[0]), 1, a )
return b
X_test = pd.DataFrame([[0, 0, 1],[1, 1, 1], [1, 0, 1], [0, 1, 1],[1, 0, 0]])
X_test.columns = ['ohe1', 'ohe2','ohe3']
resultat = modelnn(X_test)
b = resultat.get_result()
run()
пробовал использовать json.loads(body), но ничего не получилось.
текст запроса в моем понимании будет примерно такой: json_data = '{"a": [2,2,2]}'.
В докере сначала создаю образ, затем запускаю:
docker build -t server .
docker run -t -p 8888:8888 server
Скорее всего, я что-то делаю не так в работе с докером.
https://github.com/dwfjwedk/webserver.git
Ответы (1 шт):
Проблема была в неправильном использовании пробелов и табуляции и текста json запроса.
#!/usr/bin/python3
from http.server import BaseHTTPRequestHandler, HTTPServer
from io import BytesIO
import json
from keras.models import Sequential
from keras.layers import Dense
import pandas as pd
import numpy as np
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
message = "<font size=+3>Hello world!</font><p>"
self.wfile.write(bytes(message, "utf8"))
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
self.send_response(200)
self.end_headers()
response = BytesIO()
response.write(b'This is POST request.\n')
response.write(b'Received as a test data: ')
response.write(body)
response.write(b'\nPredicted by nn model:')
X_test = pd.DataFrame(json.loads(body.decode('utf-8')).values())
resultat = modelnn(X_test)
b = resultat.get_result()
response.write(str(b).encode('UTF-8'))
self.wfile.write(response.getvalue())
def run():
print('starting server...')
server_address = ('', 8000)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
class modelnn(object):
def __init__(self,data):
self.data = data
def get_result(self):
train = pd.DataFrame([[0, 0, 1, 0],[1, 1, 1, 1], [1, 0, 1, 1], [0, 1, 1,0]])
train.columns = ['ohe1', 'ohe2','ohe3', 'output']
X_train = train[['ohe1', 'ohe2','ohe3']]
y_train = train['output']
batch_size = 2
epochs = 6
model = Sequential()
model.add(Dense(3, activation = 'relu', input_shape=(3,)))
model.add(Dense(1, activation = 'sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=0);
a = model.predict(self.data)
b =np.apply_along_axis(lambda x: round(x[0]), 1, a )
return b
run()