Search code examples
pythonexec

Remove Exec Command After Execution Or Run in Local Thread


I've created a function in python to execute generic script via exec(). It works perfectly but it creates functions globally. I need to create them locally and run them then I need to remove them.

My example script:

def demo_handler(request):
    ...
    return None

My executor function is:

def execute(body: ExecutorCommand):
    try:
        exec(body.script, globals())
        result = demo_handler(body.request)
        return {"success": True, "data": result}
    except Exception as ex:
        return {"success": False, "error": {"type": type(ex).__name__, "message": repr(ex)}}

When I send a first-request with script, it works like expected. Then even if I don't send a script, I can reach previous executed functions. But I don't want it. Is there a way to remove previous executed-functions?


Solution

  • Solved like:

    def execute(body: Command):
        fun_name = _generate_unique_function_name()
        try:
            handler_script = body.handler_script.replace("demo_handler", fun_name)
            exec(handler_script, globals())
    
            ...
            result = globals()[fun_name](**params)
            return {"success": True, "data": result}
        except Exception as ex:
            logging.error("Unexpected exception on execute command: %s", repr(ex))
            return {"success": False, "error": {"type": type(ex).__name__, "message": repr(ex)}}
        finally:
            if fun_name in globals():
                del globals()[fun_name]
            else:
                return {"success": False, "error": {"type": "Unknown Function", "message": "Couldn't found demo_handler function in script"}}
    
    
    def _generate_unique_function_name():
        return "handler_" + str(uuid.uuid4()).replace("-", "_")
    

    Or Alternative solution (Thanks to @Olivier and @Muslimbek Abduganiev):

    def execute(body: Command):
        fun_name = "demo_handler"
        try:
            global_vars = {}
            exec(body.handler_script, global_vars)
    
            ...
            result = global_vars[fun_name](**params)
            return {"success": True, "data": result}
        except Exception as ex:
            logging.error("Unexpected exception on execute command: %s", repr(ex))
            return {"success": False, "error": {"type": type(ex).__name__, "message": repr(ex)}}