0

I am working on a side projects which involves creating a separate process for flask server on demand.

I have already tried using dill function pickling but so far no luck and used al the techniques mentioned here AttributeError: Can't pickle local object in Multiprocessing

Here is the code for the same: ApiServer.py

import pickle

import ProcessBuilder as pb
import ServiceLogger as sl
import SystemRecovery as sr
from flask import Flask, Response
from waitress import serve
from flask_cors import CORS


class EndpointAction(object):

    def __init__(self, action):
        self.action = action
        self.logger = sl.ServiceLogger()
        self.response = Response(status=200, headers={})

    def __call__(self, *args):
        self.action()
        return self.response


class ApiServer:

    def __init__(self):
        self.server = None
        self.debug = sr.Recovery().debug
        self.port = sr.Recovery().api_port
        self.host = '127.0.0.1'
        self.logger = sl.ServiceLogger()
        self.app = Flask(__name__)
        CORS(self.app, resources={r"/api/*": {"origins": "*"}})
        self.register_endpoints()
        self.server = pb.ProcessBuilder().create_process(self.run, [self])

    def add_endpoint(self, endpoint=None, endpoint_name=None, handler=None):
        self.app.add_url_rule(endpoint, endpoint_name, EndpointAction(handler))

    def register_endpoints(self):
        return None

    def start(self):
        self.server.start()

    def run(self):
        print("heyy")
        #serve(self.app, port=self.port, host=self.host)

    def terminate(self):
        self.server.kill()
        return None


a = ApiServer()
a.start()
print("heyy")
a.terminate()
print("thread killed")

ProcessBuilder.py

from multiprocessing import Process
import random
import string
import dill

import ServiceLogger as sl


class DillProcess(Process):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._target = dill.dumps(self._target)  # Save the target function as bytes, using dill

    def run(self):
        if self._target:
            self._target = dill.loads(self._target)  # Unpickle the target function before executing
            self._target(*self._args, **self._kwargs)  # Execute the target function


class ProcessBuilder:

    def __init__(self):
        self.processes = []
        self.logger = sl.ServiceLogger()

    def create_process(self, method, args=[]):
        process = DillProcess(name=self.__generate_instance_name(), target=method, args=tuple(args))
        self.processes.append(process)
        return process

    def get_process_instance(self, process_name):
        for process in self.processes:
            if str(process.name) == process_name:
                return process
        return None

    def run_process(self, process):
        process.start()

    def kill_process(self, process):
        process.kill()

    def __generate_instance_name(self):
        # printing lowercase
        letters = string.ascii_lowercase
        randomString = ''.join(random.choice(letters) for i in range(3))

        # printing letters
        letters = string.digits
        randomDigits = ''.join(random.choice(letters) for i in range(5))

        return randomString + "" + randomDigits

Error:

Traceback (most recent call last):
  File "C:\Users\..", line 55, in <module>
    a.start()
  File "C:\Users\..", line 43, in start
    self.server.start()
  File "C:\Python\Lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
                  ^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\multiprocessing\context.py", line 336, in _Popen
    return Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\multiprocessing\popen_spawn_win32.py", line 94, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Python\Lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'Flask.__init__.<locals>.<lambda>'
SaM AroRa
  • 61
  • 1
  • 6

0 Answers0