Python: Forking HTTP-сервер (ForkingMixIn) останавливается на любом запросе при использовании с MTCNN - PullRequest
1 голос
/ 10 февраля 2020

Я пытаюсь написать простой веб-сервер, который бы брал путь к изображению в качестве параметра, определял лица на нем и возвращал информацию об обнаруженных лицах в формате 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()

Любая идея о как с этим справиться?

...