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.
- {setta-0.0.14.dev5/backend/setta.egg-info → setta-0.0.14.dev7}/PKG-INFO +1 -1
- setta-0.0.14.dev7/backend/setta/__init__.py +1 -0
- setta-0.0.14.dev7/backend/setta/tasks/task_runner.py +29 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/tasks.py +62 -64
- setta-0.0.14.dev7/backend/setta/tasks/utils.py +292 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7/backend/setta.egg-info}/PKG-INFO +1 -1
- setta-0.0.14.dev5/backend/setta/__init__.py +0 -1
- setta-0.0.14.dev5/backend/setta/tasks/task_runner.py +0 -41
- setta-0.0.14.dev5/backend/setta/tasks/utils.py +0 -449
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/LICENSE +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/MANIFEST.in +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/README.md +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/connect.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/cli/logger.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/create_runnable_scripts.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/export_selected.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/find_placeholders.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/ast_utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/check_scope.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/generate_code.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/make_parseable.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/position_line_col.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/python/validate_imports.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/generate_yaml.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/code_gen/yaml/section_dict.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/backup.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/save_or_create.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/artifacts/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/copy.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/codeInfo/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/evRefs/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/copy.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/delete.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/saveAs.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/projects/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/copy.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sectionVariants/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/copy.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/jsonSource.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/sections/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/copy.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/load.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/save.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db/uiTypes/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db_init.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/db_objs.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_db.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_raw.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/export_readable.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/export_db/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/import_db.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/seed.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/settings_file.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/database/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/file_watcher.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/completion.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/definition.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/diagnostics.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/documentHighlight.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/references.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/reader_fns/signatureHelp.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/server.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/specific_file_watcher.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/lsp/writer.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/artifact.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/code_info.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/dependencies.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/in_memory_fn_stdout_websocket.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/interactive.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/lsp.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/projects.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/reference_renaming.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/sections.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/settings.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/terminals.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/routers/websocket.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/server.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/start.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/BaseUITypes.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/Settings.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/constants.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/db_init.sql +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/defaultValues.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/constants/settingsProject.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/android-chrome-192x192.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/android-chrome-512x512.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/apple-touch-icon.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-C21vCyEA.woff2 +0 -0
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/cormorant-garamond-latin-700-italic-BQbwEFjx.woff2 +0 -0
- {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
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/index-B8656WgG.js +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/index-DQjclEVk.css +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-400-normal-ByZ5TkcW.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-600-normal-BQl_S1BW.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-all-800-normal-BdAoPad8.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-400-normal-BdCE3qi6.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-600-normal-7XOpjHIA.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-800-normal-DGhuWe7d.woff2 +0 -0
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-ext-600-normal-ejcnWb4M.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-cyrillic-ext-800-normal-DBv1a6vS.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-400-normal-B1y6FevT.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-600-normal-C2fO7_LG.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-800-normal-Cmzsyk9X.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-ext-400-normal-CDYjSWzV.woff2 +0 -0
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-greek-ext-800-normal-BDfRYppl.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-400-normal-C0b7ZYuD.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-600-normal-Do_HpvrI.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-800-normal-4xo3UuPr.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-400-normal-CoAAiu5e.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-600-normal-Dc00Iig3.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/inter-latin-ext-800-normal-MtSFSlwC.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/logo/logo.svg +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-400-normal-DjvUmtn7.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-500-normal-xIKbAjND.woff +0 -0
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-all-700-normal-DDAKfh8R.woff +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-400-normal-DiMJuv0g.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-500-normal-Bj5Gxvqh.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-600-normal-DqkZaPuW.woff2 +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/assets/work-sans-latin-700-normal-DrOaUiEE.woff2 +0 -0
- {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
- {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
- {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
- {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
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/browserconfig.xml +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon-16x16.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon-32x32.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/favicon.ico +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/index.html +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/manifest.json +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-144x144.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-150x150.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-310x150.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-310x310.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/mstile-70x70.png +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/robots.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/safari-pinned-tab.svg +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/frontend/site.webmanifest +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/seed/.DS_Store +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/static/seed/examples/.DS_Store +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaAutocomplete.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaFindTemplateVars.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/codeAreaInitializeCode.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/findEVRefs.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/parametersRequest.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/textFieldAutocomplete.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/textFieldInitializeCode.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/typeCheck.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/tasks/fns/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/terminals.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/terminals/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/__init__.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/constants.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/generate_memorable_string.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/generate_new_filename.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/section_contents.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/utils.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta/utils/websocket_manager.py +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/SOURCES.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/dependency_links.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/entry_points.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/requires.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/backend/setta.egg-info/top_level.txt +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/pyproject.toml +0 -0
- {setta-0.0.14.dev5 → setta-0.0.14.dev7}/setup.cfg +0 -0
@@ -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
|
-
|
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
|
-
|
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
|
138
|
-
self,
|
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
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
171
|
+
message.id, result["content"], result["messageType"]
|
160
172
|
)
|
161
173
|
await self.maybe_send_latest_run_time_info(
|
162
|
-
subprocess_key, fn_name,
|
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 +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
|