custom_code.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import modules.scripts as scripts
  2. import gradio as gr
  3. import ast
  4. import copy
  5. from modules.processing import Processed
  6. from modules.shared import cmd_opts
  7. def convertExpr2Expression(expr):
  8. expr.lineno = 0
  9. expr.col_offset = 0
  10. result = ast.Expression(expr.value, lineno=0, col_offset = 0)
  11. return result
  12. def exec_with_return(code, module):
  13. """
  14. like exec() but can return values
  15. https://stackoverflow.com/a/52361938/5862977
  16. """
  17. code_ast = ast.parse(code)
  18. init_ast = copy.deepcopy(code_ast)
  19. init_ast.body = code_ast.body[:-1]
  20. last_ast = copy.deepcopy(code_ast)
  21. last_ast.body = code_ast.body[-1:]
  22. exec(compile(init_ast, "<ast>", "exec"), module.__dict__)
  23. if type(last_ast.body[0]) == ast.Expr:
  24. return eval(compile(convertExpr2Expression(last_ast.body[0]), "<ast>", "eval"), module.__dict__)
  25. else:
  26. exec(compile(last_ast, "<ast>", "exec"), module.__dict__)
  27. class Script(scripts.Script):
  28. def title(self):
  29. return "Custom code"
  30. def show(self, is_img2img):
  31. return cmd_opts.allow_code
  32. def ui(self, is_img2img):
  33. example = """from modules.processing import process_images
  34. p.width = 768
  35. p.height = 768
  36. p.batch_size = 2
  37. p.steps = 10
  38. return process_images(p)
  39. """
  40. code = gr.Code(value=example, language="python", label="Python code", elem_id=self.elem_id("code"))
  41. indent_level = gr.Number(label='Indent level', value=2, precision=0, elem_id=self.elem_id("indent_level"))
  42. return [code, indent_level]
  43. def run(self, p, code, indent_level):
  44. assert cmd_opts.allow_code, '--allow-code option must be enabled'
  45. display_result_data = [[], -1, ""]
  46. def display(imgs, s=display_result_data[1], i=display_result_data[2]):
  47. display_result_data[0] = imgs
  48. display_result_data[1] = s
  49. display_result_data[2] = i
  50. from types import ModuleType
  51. module = ModuleType("testmodule")
  52. module.__dict__.update(globals())
  53. module.p = p
  54. module.display = display
  55. indent = " " * indent_level
  56. indented = code.replace('\n', f"\n{indent}")
  57. body = f"""def __webuitemp__():
  58. {indent}{indented}
  59. __webuitemp__()"""
  60. result = exec_with_return(body, module)
  61. if isinstance(result, Processed):
  62. return result
  63. return Processed(p, *display_result_data)