setta 0.0.14.dev5__tar.gz → 0.0.14.dev7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of setta might be problematic. Click here for more details.

Files changed (269) hide show
  1. {setta-0.0.14.dev5/backend/setta.egg-info → setta-0.0.14.dev7}/PKG-INFO +1 -1
  2. setta-0.0.14.dev7/backend/setta/__init__.py +1 -0
  3. setta-0.0.14.dev7/backend/setta/tasks/task_runner.py +29 -0
  4. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/tasks.py +62 -64
  5. setta-0.0.14.dev7/backend/setta/tasks/utils.py +292 -0
  6. {setta-0.0.14.dev5 → setta-0.0.14.dev7/backend/setta.egg-info}/PKG-INFO +1 -1
  7. setta-0.0.14.dev5/backend/setta/__init__.py +0 -1
  8. setta-0.0.14.dev5/backend/setta/tasks/task_runner.py +0 -41
  9. setta-0.0.14.dev5/backend/setta/tasks/utils.py +0 -449
  10. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/LICENSE +0 -0
  11. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/MANIFEST.in +0 -0
  12. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/README.md +0 -0
  13. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/__init__.py +0 -0
  14. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/connect.py +0 -0
  15. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/logger.py +0 -0
  16. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/__init__.py +0 -0
  17. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/create_runnable_scripts.py +0 -0
  18. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/export_selected.py +0 -0
  19. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/find_placeholders.py +0 -0
  20. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/__init__.py +0 -0
  21. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/ast_utils.py +0 -0
  22. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/check_scope.py +0 -0
  23. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/generate_code.py +0 -0
  24. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/make_parseable.py +0 -0
  25. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/position_line_col.py +0 -0
  26. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/validate_imports.py +0 -0
  27. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/utils.py +0 -0
  28. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/__init__.py +0 -0
  29. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/generate_yaml.py +0 -0
  30. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/section_dict.py +0 -0
  31. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/__init__.py +0 -0
  32. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/backup.py +0 -0
  33. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/__init__.py +0 -0
  34. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/__init__.py +0 -0
  35. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/load.py +0 -0
  36. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/save.py +0 -0
  37. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/save_or_create.py +0 -0
  38. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/utils.py +0 -0
  39. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/__init__.py +0 -0
  40. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/copy.py +0 -0
  41. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/load.py +0 -0
  42. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/save.py +0 -0
  43. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/utils.py +0 -0
  44. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/__init__.py +0 -0
  45. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/load.py +0 -0
  46. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/save.py +0 -0
  47. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/__init__.py +0 -0
  48. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/copy.py +0 -0
  49. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/delete.py +0 -0
  50. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/load.py +0 -0
  51. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/save.py +0 -0
  52. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/saveAs.py +0 -0
  53. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/utils.py +0 -0
  54. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/__init__.py +0 -0
  55. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/copy.py +0 -0
  56. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/load.py +0 -0
  57. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/save.py +0 -0
  58. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/utils.py +0 -0
  59. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/__init__.py +0 -0
  60. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/copy.py +0 -0
  61. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/jsonSource.py +0 -0
  62. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/load.py +0 -0
  63. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/save.py +0 -0
  64. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/utils.py +0 -0
  65. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/__init__.py +0 -0
  66. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/copy.py +0 -0
  67. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/load.py +0 -0
  68. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/save.py +0 -0
  69. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/utils.py +0 -0
  70. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db_init.py +0 -0
  71. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db_objs.py +0 -0
  72. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/__init__.py +0 -0
  73. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_db.py +0 -0
  74. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_raw.py +0 -0
  75. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_readable.py +0 -0
  76. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/utils.py +0 -0
  77. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/import_db.py +0 -0
  78. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/seed.py +0 -0
  79. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/settings_file.py +0 -0
  80. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/utils.py +0 -0
  81. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/__init__.py +0 -0
  82. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/file_watcher.py +0 -0
  83. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader.py +0 -0
  84. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/__init__.py +0 -0
  85. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/completion.py +0 -0
  86. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/definition.py +0 -0
  87. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/diagnostics.py +0 -0
  88. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/documentHighlight.py +0 -0
  89. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/references.py +0 -0
  90. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/signatureHelp.py +0 -0
  91. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/server.py +0 -0
  92. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/specific_file_watcher.py +0 -0
  93. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/utils.py +0 -0
  94. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/writer.py +0 -0
  95. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/__init__.py +0 -0
  96. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/artifact.py +0 -0
  97. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/code_info.py +0 -0
  98. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/dependencies.py +0 -0
  99. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/in_memory_fn_stdout_websocket.py +0 -0
  100. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/interactive.py +0 -0
  101. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/lsp.py +0 -0
  102. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/projects.py +0 -0
  103. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/reference_renaming.py +0 -0
  104. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/sections.py +0 -0
  105. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/settings.py +0 -0
  106. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/terminals.py +0 -0
  107. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/websocket.py +0 -0
  108. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/server.py +0 -0
  109. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/start.py +0 -0
  110. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/BaseUITypes.json +0 -0
  111. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/Settings.json +0 -0
  112. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/constants.json +0 -0
  113. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/db_init.sql +0 -0
  114. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/defaultValues.json +0 -0
  115. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/settingsProject.json +0 -0
  116. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/android-chrome-192x192.png +0 -0
  117. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/android-chrome-512x512.png +0 -0
  118. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/apple-touch-icon.png +0 -0
  119. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  120. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  121. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  122. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  123. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  124. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  125. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  126. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  127. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  128. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  129. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  130. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  131. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  132. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  133. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  134. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  135. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  136. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  137. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  138. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  139. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  140. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  141. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  142. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  143. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  144. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  145. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  146. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  147. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  148. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  149. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  150. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  151. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  152. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  153. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  154. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  155. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  156. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  157. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  158. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  159. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  160. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  161. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  162. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  163. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  164. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  165. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  166. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  167. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  168. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  169. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  170. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  171. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  172. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  173. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  174. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  175. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  176. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  177. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  178. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-all-700-italic-D-4m7eF5.woff +0 -0
  179. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-C21vCyEA.woff2 +0 -0
  180. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-cyrillic-ext-700-italic-gsr366qd.woff2 +0 -0
  181. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-latin-700-italic-BQbwEFjx.woff2 +0 -0
  182. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-DnnS5iSC.woff2 +0 -0
  183. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-2_nTgjbG.woff2 +0 -0
  184. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/index-B8656WgG.js +0 -0
  185. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/index-DQjclEVk.css +0 -0
  186. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-400-normal-ByZ5TkcW.woff +0 -0
  187. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-600-normal-BQl_S1BW.woff +0 -0
  188. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-800-normal-BdAoPad8.woff +0 -0
  189. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-400-normal-BdCE3qi6.woff2 +0 -0
  190. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-600-normal-7XOpjHIA.woff2 +0 -0
  191. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-800-normal-DGhuWe7d.woff2 +0 -0
  192. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-ext-400-normal-BWPw_Wqo.woff2 +0 -0
  193. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-ext-600-normal-ejcnWb4M.woff2 +0 -0
  194. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-ext-800-normal-DBv1a6vS.woff2 +0 -0
  195. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-400-normal-B1y6FevT.woff2 +0 -0
  196. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-600-normal-C2fO7_LG.woff2 +0 -0
  197. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-800-normal-Cmzsyk9X.woff2 +0 -0
  198. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-ext-400-normal-CDYjSWzV.woff2 +0 -0
  199. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-ext-600-normal-aFl-DVOe.woff2 +0 -0
  200. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-ext-800-normal-BDfRYppl.woff2 +0 -0
  201. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-400-normal-C0b7ZYuD.woff2 +0 -0
  202. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-600-normal-Do_HpvrI.woff2 +0 -0
  203. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-800-normal-4xo3UuPr.woff2 +0 -0
  204. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-400-normal-CoAAiu5e.woff2 +0 -0
  205. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-600-normal-Dc00Iig3.woff2 +0 -0
  206. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-800-normal-MtSFSlwC.woff2 +0 -0
  207. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/logo/logo.svg +0 -0
  208. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-all-500-normal-r3XLtphf.woff +0 -0
  209. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-cyrillic-500-normal-CY1ydVwz.woff2 +0 -0
  210. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-cyrillic-ext-500-normal-CfYAfiCF.woff2 +0 -0
  211. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-greek-500-normal-CAXYj0Fh.woff2 +0 -0
  212. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-latin-500-normal-D9gpC5Cq.woff2 +0 -0
  213. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/source-code-pro-latin-ext-500-normal-CRAmHsi-.woff2 +0 -0
  214. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-400-normal-DjvUmtn7.woff +0 -0
  215. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-500-normal-xIKbAjND.woff +0 -0
  216. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-600-normal-G3qI_FYS.woff +0 -0
  217. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-700-normal-DDAKfh8R.woff +0 -0
  218. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-400-normal-DiMJuv0g.woff2 +0 -0
  219. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-500-normal-Bj5Gxvqh.woff2 +0 -0
  220. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-600-normal-DqkZaPuW.woff2 +0 -0
  221. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-700-normal-DrOaUiEE.woff2 +0 -0
  222. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-ext-400-normal-DVtzt6WA.woff2 +0 -0
  223. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-ext-500-normal-Ci3LVpiW.woff2 +0 -0
  224. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-ext-600-normal-BROvLH43.woff2 +0 -0
  225. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-ext-700-normal-qcgZR4tS.woff2 +0 -0
  226. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/browserconfig.xml +0 -0
  227. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon-16x16.png +0 -0
  228. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon-32x32.png +0 -0
  229. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon.ico +0 -0
  230. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/index.html +0 -0
  231. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/manifest.json +0 -0
  232. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-144x144.png +0 -0
  233. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-150x150.png +0 -0
  234. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-310x150.png +0 -0
  235. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-310x310.png +0 -0
  236. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-70x70.png +0 -0
  237. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/robots.txt +0 -0
  238. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/safari-pinned-tab.svg +0 -0
  239. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/site.webmanifest +0 -0
  240. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/seed/.DS_Store +0 -0
  241. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/seed/examples/.DS_Store +0 -0
  242. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/__init__.py +0 -0
  243. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/__init__.py +0 -0
  244. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaAutocomplete.py +0 -0
  245. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaFindTemplateVars.py +0 -0
  246. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaInitializeCode.py +0 -0
  247. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/findEVRefs.py +0 -0
  248. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/parametersRequest.py +0 -0
  249. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/textFieldAutocomplete.py +0 -0
  250. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/textFieldInitializeCode.py +0 -0
  251. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/typeCheck.py +0 -0
  252. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/utils.py +0 -0
  253. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/__init__.py +0 -0
  254. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/terminals.py +0 -0
  255. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/utils.py +0 -0
  256. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/__init__.py +0 -0
  257. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/constants.py +0 -0
  258. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/generate_memorable_string.py +0 -0
  259. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/generate_new_filename.py +0 -0
  260. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/section_contents.py +0 -0
  261. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/utils.py +0 -0
  262. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/websocket_manager.py +0 -0
  263. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/SOURCES.txt +0 -0
  264. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/dependency_links.txt +0 -0
  265. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/entry_points.txt +0 -0
  266. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/requires.txt +0 -0
  267. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/top_level.txt +0 -0
  268. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/pyproject.toml +0 -0
  269. {setta-0.0.14.dev5 → setta-0.0.14.dev7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: setta
3
- Version: 0.0.14.dev5
3
+ Version: 0.0.14.dev7
4
4
  Summary: Python without the donkeywork.
5
5
  Home-page: https://setta.dev
6
6
  Author: Kevin Musgrave, Jeff Musgrave
@@ -0,0 +1 @@
1
+ __version__ = "0.0.14.dev7"
@@ -0,0 +1,29 @@
1
+ import asyncio
2
+ import inspect
3
+ from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
4
+ from enum import Enum
5
+
6
+
7
+ class RunType(Enum):
8
+ SUBPROCESS = "SUBPROCESS"
9
+ THREAD = "THREAD"
10
+ NONE = "NONE"
11
+
12
+
13
+ class TaskRunner:
14
+ def __init__(self):
15
+ self.thread_executor = ThreadPoolExecutor(max_workers=2)
16
+ self.process_executor = ProcessPoolExecutor(max_workers=2)
17
+
18
+ async def run(self, fn, fn_args, run_as):
19
+ if inspect.iscoroutinefunction(fn):
20
+ return await fn(*fn_args)
21
+
22
+ if run_as == RunType.NONE:
23
+ return fn(*fn_args)
24
+ elif run_as == RunType.THREAD:
25
+ executor = self.thread_executor
26
+ elif run_as == RunType.SUBPROCESS:
27
+ executor = self.process_executor
28
+
29
+ return await asyncio.get_running_loop().run_in_executor(executor, fn, *fn_args)
@@ -3,7 +3,6 @@ import copy
3
3
  import json
4
4
  import logging
5
5
  import time
6
- import traceback
7
6
  from typing import Dict
8
7
 
9
8
  from setta.database.utils import create_new_id
@@ -72,56 +71,53 @@ class Tasks:
72
71
  call_type="call",
73
72
  other_data=None,
74
73
  ):
75
- # Create a list of tasks to run concurrently
76
- tasks = []
77
- results = []
78
74
  message.content = {tuple(json.loads(k)): v for k, v in message.content.items()}
79
75
 
76
+ # Group tasks by subprocess to ensure sequential processing per subprocess
77
+ subprocess_tasks = {}
78
+ results = []
79
+
80
+ # First, identify all relevant subprocesses and their functions to call
80
81
  for sp_key, sp_info in self.in_memory_subprocesses.items():
81
82
  if (subprocess_key and sp_key != subprocess_key) or (
82
83
  not match_subprocess_key(sp_key, project_config_id, section_id, idx)
83
84
  ):
84
85
  continue
86
+
87
+ # For each matching subprocess, collect all functions that need to be called
88
+ fns_to_call = []
85
89
  for fn_name, fnInfo in sp_info["fnInfo"].items():
86
90
  if (
87
91
  call_all
88
92
  or None in fnInfo["dependencies"]
89
93
  or any(k in fnInfo["dependencies"] for k in message.content.keys())
90
94
  ):
91
- logger.debug(
92
- f"Sending message to subprocess {sp_key}, function {fn_name}, message type: {call_type}"
93
- )
94
- try:
95
- # Send message to subprocess
96
- sp_info["subprocess"].parent_conn.send(
97
- {
98
- "type": call_type,
99
- "fn_name": fn_name,
100
- "message": message,
101
- "other_data": other_data,
102
- }
103
- )
104
- except Exception as e:
105
- logger.error(
106
- f"Error sending message to subprocess {sp_key}: {str(e)}"
107
- )
108
- traceback.print_exc()
109
- continue # Skip to next function if we can't send
110
-
111
- # Create task for receiving response
112
- task = asyncio.create_task(
113
- self._handle_subprocess_response(
114
- sp_key,
115
- fn_name,
116
- message.id,
117
- sp_info["subprocess"].parent_conn.recv,
118
- websocket_manager,
119
- results,
120
- )
121
- )
122
- tasks.append(task)
95
+ fns_to_call.append(fn_name)
123
96
 
124
- # Wait for all tasks to complete concurrently
97
+ if fns_to_call:
98
+ subprocess_tasks[sp_key] = {
99
+ "subprocess": sp_info["subprocess"],
100
+ "functions": fns_to_call,
101
+ }
102
+
103
+ # Create tasks to process each subprocess sequentially
104
+ tasks = []
105
+ for sp_key, sp_data in subprocess_tasks.items():
106
+ task = asyncio.create_task(
107
+ self._process_subprocess_sequentially(
108
+ sp_key,
109
+ sp_data["subprocess"],
110
+ sp_data["functions"],
111
+ message,
112
+ call_type,
113
+ other_data,
114
+ websocket_manager,
115
+ results,
116
+ )
117
+ )
118
+ tasks.append(task)
119
+
120
+ # Wait for all subprocess tasks to complete (each subprocess processed sequentially)
125
121
  if tasks:
126
122
  await asyncio.gather(*tasks)
127
123
 
@@ -134,47 +130,51 @@ class Tasks:
134
130
  content.extend(r["content"])
135
131
  return {"content": content, "messageType": C.WS_IN_MEMORY_FN_RETURN}
136
132
 
137
- async def _handle_subprocess_response(
138
- self, subprocess_key, fn_name, msg_id, recv_fn, websocket_manager, results
133
+ async def _process_subprocess_sequentially(
134
+ self,
135
+ subprocess_key,
136
+ subprocess,
137
+ fn_names,
138
+ message,
139
+ call_type,
140
+ other_data,
141
+ websocket_manager,
142
+ results,
139
143
  ):
140
- # Run the receive function in a thread
141
- logger.debug(
142
- f"Waiting for response from subprocess {subprocess_key}, function {fn_name}"
143
- )
144
- start_time = time.perf_counter()
145
- try:
146
- result = await self.task_runner.run(recv_fn, [], RunType.THREAD)
147
- logger.debug(
148
- f"Received response from subprocess {subprocess_key}, function {fn_name}: status={result.get('status', 'unknown')}"
144
+ # Process each function sequentially for this subprocess
145
+ for fn_name in fn_names:
146
+ # Send message to subprocess
147
+ subprocess.parent_conn.send(
148
+ {
149
+ "type": call_type,
150
+ "fn_name": fn_name,
151
+ "message": message,
152
+ "other_data": other_data,
153
+ }
149
154
  )
150
155
 
156
+ # Wait for and handle the response before sending the next message
157
+ start_time = time.perf_counter()
158
+ result = await self.task_runner.run(
159
+ subprocess.parent_conn.recv, [], RunType.THREAD
160
+ )
151
161
  elapsed_time = time.perf_counter() - start_time
162
+
152
163
  if result["status"] == "success":
153
164
  self.update_average_subprocess_fn_time(
154
165
  subprocess_key, fn_name, elapsed_time
155
166
  )
167
+
156
168
  if websocket_manager is not None:
157
169
  if result["content"]:
158
170
  await websocket_manager.send_message_to_requester(
159
- msg_id, result["content"], result["messageType"]
171
+ message.id, result["content"], result["messageType"]
160
172
  )
161
173
  await self.maybe_send_latest_run_time_info(
162
- subprocess_key, fn_name, msg_id, websocket_manager
174
+ subprocess_key, fn_name, message.id, websocket_manager
163
175
  )
164
176
  else:
165
177
  results.append(result)
166
- except EOFError:
167
- logger.error(
168
- f"EOF error when receiving response from subprocess {subprocess_key}, function {fn_name}"
169
- )
170
- # Add stack trace to see where exactly the error occurs
171
- traceback.print_exc()
172
- # Consider adding a placeholder result or raising to caller
173
- except Exception as e:
174
- logger.error(
175
- f"Error receiving response from subprocess {subprocess_key}, function {fn_name}: {str(e)}"
176
- )
177
- traceback.print_exc()
178
178
 
179
179
  async def add_custom_fns(self, code_graph, exporter_obj):
180
180
  for c in code_graph:
@@ -182,8 +182,6 @@ class Tasks:
182
182
  sp = self.in_memory_subprocesses.get(subprocess_key, {}).get("subprocess")
183
183
  if sp:
184
184
  sp.close()
185
- del self.in_memory_subprocesses[subprocess_key]
186
-
187
185
  sp = SettaInMemoryFnSubprocess(
188
186
  self.stop_event, self.websockets, c["subprocessStartMethod"]
189
187
  )
@@ -0,0 +1,292 @@
1
+ import asyncio
2
+ import importlib.util
3
+ import logging
4
+ import multiprocessing
5
+ import queue
6
+ import sys
7
+ import threading
8
+ import traceback
9
+ import uuid
10
+
11
+ from setta.tasks.fns.utils import TaskDefinition
12
+ from setta.utils.constants import CWD
13
+ from setta.utils.utils import nested_access
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ def import_code_from_string(code_string, module_name=None, add_to_sys_modules=True):
19
+ # Generate a unique module name if one isn't provided
20
+ if module_name is None:
21
+ module_name = f"setta_dynamic_module_{uuid.uuid4().hex}"
22
+
23
+ # Add current directory to sys.path if it's not already there
24
+ current_dir = str(CWD)
25
+ if current_dir not in sys.path:
26
+ sys.path.insert(0, current_dir)
27
+
28
+ spec = importlib.util.spec_from_loader(module_name, loader=None)
29
+
30
+ # Create a new module based on the spec
31
+ module = importlib.util.module_from_spec(spec)
32
+
33
+ # Optionally add the module to sys.modules
34
+ if add_to_sys_modules:
35
+ print(f"adding {module_name} to sys.modules", flush=True)
36
+ sys.modules[module_name] = module
37
+
38
+ # Compile the code string
39
+ code_object = compile(code_string, module_name, "exec")
40
+
41
+ # Execute the compiled code object in the module's namespace
42
+ exec(code_object, module.__dict__)
43
+
44
+ return module
45
+
46
+
47
+ class SettaInMemoryFnSubprocess:
48
+ def __init__(self, stop_event, websockets, start_method):
49
+ logger.debug(
50
+ f"Creating SettaInMemoryFnSubprocess using {start_method} start_method"
51
+ )
52
+ ctx = multiprocessing.get_context(start_method)
53
+ self.parent_conn, self.child_conn = ctx.Pipe()
54
+ self.process = ctx.Process(target=self._subprocess_main)
55
+ self.stdout_parent_conn, self.stdout_child_conn = ctx.Pipe()
56
+ self.process.daemon = True # Ensure process dies with parent
57
+ self.process.start()
58
+
59
+ self.stop_event = asyncio.Event()
60
+ self.tasks_stop_event = stop_event
61
+ self.websockets = websockets
62
+ self.stdout_queue = queue.Queue()
63
+ self.stdout_processor_task = None
64
+ self.stdout_thread = threading.Thread(target=self.stdout_listener, daemon=True)
65
+ self.stdout_thread.start()
66
+
67
+ if len(self.websockets) > 0:
68
+ self.start_stdout_processor_task()
69
+
70
+ def _subprocess_main(self):
71
+ """Main loop in subprocess that handles all requests"""
72
+ # Initialize store for imported modules
73
+ fns_dict = {}
74
+ cache = {}
75
+
76
+ class OutputCapture:
77
+ def __init__(self, stdout_pipe):
78
+ self.stdout_pipe = stdout_pipe
79
+
80
+ def write(self, text):
81
+ self.stdout_pipe.send(text)
82
+
83
+ def flush(self):
84
+ pass
85
+
86
+ # Redirect stdout as soon as subprocess starts
87
+ output_capture = OutputCapture(self.stdout_child_conn)
88
+ sys.stdout = output_capture
89
+ sys.stderr = output_capture
90
+
91
+ while True:
92
+ msg = self.child_conn.recv() # Wait for requests
93
+ msg_type = msg["type"]
94
+ return_message_type = None
95
+
96
+ if msg_type == "shutdown":
97
+ break
98
+
99
+ try:
100
+ if msg_type == "import":
101
+ dependencies = {}
102
+ for to_import in msg["imports"]:
103
+ code = to_import["code"]
104
+ module_name = to_import["module_name"]
105
+ # Import and store module
106
+ module = import_code_from_string(code, module_name)
107
+ added_fn_names = add_fns_from_module(
108
+ fns_dict, module, module_name
109
+ )
110
+ for k in added_fn_names:
111
+ cache[k] = msg["exporter_obj"]
112
+ dependencies[k] = get_task_metadata(fns_dict[k], cache[k])
113
+
114
+ self.child_conn.send(
115
+ {
116
+ "status": "success",
117
+ "content": dependencies,
118
+ }
119
+ )
120
+
121
+ elif msg_type == "call":
122
+ result, return_message_type = self.call_imported_fn(
123
+ msg, fns_dict, cache
124
+ )
125
+ self.child_conn.send(
126
+ {
127
+ "status": "success",
128
+ "content": result,
129
+ "messageType": return_message_type,
130
+ }
131
+ )
132
+
133
+ elif msg_type == "call_with_new_exporter_obj":
134
+ # replace old exporter_obj
135
+ cache[msg["fn_name"]] = msg["other_data"]["exporter_obj"]
136
+ result, return_message_type = self.call_imported_fn(
137
+ msg, fns_dict, cache
138
+ )
139
+ self.child_conn.send(
140
+ {
141
+ "status": "success",
142
+ "content": result,
143
+ "messageType": return_message_type,
144
+ }
145
+ )
146
+
147
+ except Exception as e:
148
+ traceback.print_exc()
149
+ self.child_conn.send(
150
+ {
151
+ "status": "error",
152
+ "error": str(e),
153
+ "messageType": return_message_type,
154
+ }
155
+ )
156
+
157
+ def call_imported_fn(self, msg, fns_dict, cache):
158
+ fn_name = msg["fn_name"]
159
+ message = self.process_message(fn_name, msg["message"], cache)
160
+ fn = fns_dict[fn_name]
161
+ result = fn.fn(message)
162
+ return_message_type = fn.return_message_type
163
+ return result, return_message_type
164
+
165
+ def close(self):
166
+ try:
167
+ logger.debug("Initiating shutdown sequence")
168
+ self.parent_conn.send({"type": "shutdown"})
169
+ self.process.join(timeout=2) # Add timeout to process join
170
+
171
+ if self.process.is_alive():
172
+ logger.debug("Process still alive after timeout, forcing termination")
173
+ self.process.terminate()
174
+ self.process.join(timeout=1)
175
+ except Exception as e:
176
+ logger.debug(f"Error during process shutdown: {e}")
177
+
178
+ # Set stop event before closing pipes
179
+ self.stop_event.set()
180
+
181
+ # Close all connections
182
+ for conn in [
183
+ self.parent_conn,
184
+ self.child_conn,
185
+ self.stdout_parent_conn,
186
+ self.stdout_child_conn,
187
+ ]:
188
+ conn.close()
189
+
190
+ self.stdout_thread.join(timeout=2) # Add timeout to thread join
191
+
192
+ if self.stdout_thread.is_alive():
193
+ logger.debug("Stdout thread failed to terminate within timeout")
194
+
195
+ if self.stdout_processor_task:
196
+ self.stdout_processor_task.cancel()
197
+
198
+ def process_message(self, fn_name, message, cache):
199
+ if fn_name in cache:
200
+ exporter_obj = cache[fn_name]
201
+ for k, v in message.content.items():
202
+ nice_str = exporter_obj.var_name_mapping.get(k)
203
+ if not nice_str:
204
+ continue
205
+ p_dict, key = nested_access(exporter_obj.output, nice_str)
206
+ p_dict[key] = v
207
+ message.content = exporter_obj.output
208
+ return message.content
209
+
210
+ def start_stdout_processor_task(self):
211
+ if self.stdout_processor_task is None or self.stdout_processor_task.done():
212
+ self.stdout_processor_task = asyncio.create_task(
213
+ self.process_stdout_queue()
214
+ )
215
+
216
+ async def stop_stdout_processor_task(self):
217
+ if self.stdout_processor_task and not self.stdout_processor_task.done():
218
+ self.stdout_processor_task.cancel()
219
+ try:
220
+ await self.stdout_processor_task
221
+ except asyncio.CancelledError:
222
+ pass
223
+ self.stdout_processor_task = None
224
+
225
+ async def process_stdout_queue(self):
226
+ while not self.should_stop():
227
+ try:
228
+ if self.should_stop():
229
+ break
230
+ if len(self.websockets) > 0:
231
+ stdout_data = self.stdout_queue.get_nowait()
232
+ stdout_data = stdout_data.replace("\n", "\r\n")
233
+ for w in self.websockets:
234
+ await w.send_text(stdout_data)
235
+ self.stdout_queue.task_done()
236
+ except queue.Empty:
237
+ await asyncio.sleep(0.1) # Check for connection every 100ms
238
+ except asyncio.CancelledError:
239
+ break
240
+ except Exception as e:
241
+ if self.should_stop():
242
+ break
243
+ logger.debug(f"Error processing stdout: {e}")
244
+
245
+ def stdout_listener(self):
246
+ while not self.should_stop():
247
+ if self.stdout_parent_conn.poll(0.1): # Check for data with timeout
248
+ try:
249
+ stdout_data = self.stdout_parent_conn.recv()
250
+ self.stdout_queue.put(stdout_data)
251
+ except EOFError: # Pipe was closed
252
+ break
253
+ except Exception as e:
254
+ logger.debug(f"Error in stdout listener: {e}")
255
+ if self.should_stop():
256
+ break
257
+ else: # No data available within timeout
258
+ if self.should_stop():
259
+ break
260
+
261
+ def should_stop(self):
262
+ return self.stop_event.is_set() or self.tasks_stop_event.is_set()
263
+
264
+
265
+ def add_fns_from_module(fns_dict, module, module_name=None):
266
+ count = 1
267
+ added_fn_names = []
268
+ for attr in vars(module).values():
269
+ if isinstance(attr, TaskDefinition):
270
+ if not attr.name:
271
+ if not module_name:
272
+ raise ValueError(
273
+ "Either TaskDefinition must be initialized with a name, or task_name must be specified"
274
+ )
275
+ attr.name = f"{module_name}-{count}"
276
+ count += 1
277
+ fns_dict[attr.name] = attr
278
+ added_fn_names.append(attr.name)
279
+ return added_fn_names
280
+
281
+
282
+ def get_task_metadata(in_memory_fn, exporter_obj):
283
+ # None means run the task on every change
284
+ if in_memory_fn.dependencies is None:
285
+ dependencies = set([None])
286
+ # Empty array means only run when the task imported.
287
+ # Non-empty array means run when specified dependencies update.
288
+ else:
289
+ dependencies = set(
290
+ exporter_obj.var_name_reverse_mapping[d] for d in in_memory_fn.dependencies
291
+ )
292
+ return dependencies
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: setta
3
- Version: 0.0.14.dev5
3
+ Version: 0.0.14.dev7
4
4
  Summary: Python without the donkeywork.
5
5
  Home-page: https://setta.dev
6
6
  Author: Kevin Musgrave, Jeff Musgrave
@@ -1 +0,0 @@
1
- __version__ = "0.0.14.dev5"
@@ -1,41 +0,0 @@
1
- import asyncio
2
- import inspect
3
- import logging
4
- import traceback
5
- from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
6
- from enum import Enum
7
-
8
- logger = logging.getLogger(__name__)
9
-
10
-
11
- class RunType(Enum):
12
- SUBPROCESS = "SUBPROCESS"
13
- THREAD = "THREAD"
14
- NONE = "NONE"
15
-
16
-
17
- class TaskRunner:
18
- def __init__(self):
19
- self.thread_executor = ThreadPoolExecutor(max_workers=2)
20
- self.process_executor = ProcessPoolExecutor(max_workers=2)
21
-
22
- async def run(self, fn, fn_args, run_as):
23
- logger.debug(f"TaskRunner running function {fn.__name__} with run_as={run_as}")
24
- try:
25
- if inspect.iscoroutinefunction(fn):
26
- return await fn(*fn_args)
27
-
28
- if run_as == RunType.NONE:
29
- return fn(*fn_args)
30
- elif run_as == RunType.THREAD:
31
- executor = self.thread_executor
32
- elif run_as == RunType.SUBPROCESS:
33
- executor = self.process_executor
34
-
35
- return await asyncio.get_running_loop().run_in_executor(
36
- executor, fn, *fn_args
37
- )
38
- except Exception as e:
39
- logger.error(f"Error in TaskRunner.run: {str(e)}")
40
- traceback.print_exc()
41
- raise