Я пытаюсь написать простой веб-сервер, который бы брал путь к изображению в качестве параметра, определял лица на нем и возвращал информацию об обнаруженных лицах в формате JSON.
Работает нормально без потоков или разветвления, но не когда я использую ForkingMixIn для сервера, чтобы иметь возможность обрабатывать более одного запроса одновременно.
Вот код:
#!/usr/bin/python
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn, ForkingMixIn
import threading
import cv2
import numpy as np
import os
import sys
import getopt
import glob
import time
from PIL import Image
from io import BytesIO
import web
import logging
import urllib.parse as urlparse
import json
from matplotlib import pyplot
from mtcnn.mtcnn import MTCNN
class Handler(BaseHTTPRequestHandler):
def _set_response(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
self._set_response()
self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))
def do_POST(self):
res = {}
errors = []
self._set_response()
orig_image_path = "".encode("utf-8")
if self.rfile:
for key,value in dict(urlparse.parse_qs(self.rfile.read(int(self.headers['Content-Length'])))).items():
if key == "path".encode("utf-8"):
orig_image_path = value[0]
if not orig_image_path:
errors.append("image_file_not_defined")
else:
try:
with open(orig_image_path) as f:
n = 1
except IOError:
errors.append("image_file_not_found")
if len(errors) > 0:
res = {
"res": "error",
"errors": errors
}
self.wfile.write(json.dumps(res).encode("utf-8"))
return
res.update({"res": "ok"})
if orig_image_path:
image = cv2.imread(orig_image_path.decode("utf-8"))
faces = process_faces(image)
res.update({"faces": faces})
#Return result
self.wfile.write(json.dumps(res).encode("utf-8"))
def process_faces(image):
faces_list = []
faces = detector.detect_faces(image)
for face in faces:
face_obj = {
"mtcnn_data": face
}
faces_list.append(face_obj)
return faces_list
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
class ForkingHTTPServer(ForkingMixIn, HTTPServer):
pass
#This does not work (HTTP request halts)
def run(server_class=ForkingHTTPServer, handler_class=Handler, port=7000):
#This works as expected
#def run(server_class=HTTPServer, handler_class=Handler, port=7000):
logging.basicConfig(level=logging.INFO)
server_address = ('127.0.0.1', port)
httpd = server_class(server_address, handler_class)
logging.info('\n\nStarting httpd on port %s...\n', port)
try:
httpd.serve_forever()
except KeyboardInterrupt:
httpd.server_close()
logging.info('Stopping httpd...\n')
if __name__ == '__main__':
from sys import argv
#---FACE DETECTOR---
detector = MTCNN()
#---/FACE DETECTOR---
#Run server
run()
Любая идея о как с этим справиться?