abstra 3.23.3__py3-none-any.whl → 3.23.4__py3-none-any.whl
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.
- {abstra-3.23.3.dist-info → abstra-3.23.4.dist-info}/METADATA +1 -1
- {abstra-3.23.3.dist-info → abstra-3.23.4.dist-info}/RECORD +187 -188
- abstra_internals/controllers/execution/consumer.py +27 -39
- abstra_internals/controllers/execution/execution.py +7 -4
- abstra_internals/controllers/execution/execution_client.py +2 -11
- abstra_internals/controllers/execution/execution_client_form.py +10 -11
- abstra_internals/controllers/execution/execution_client_hook.py +3 -9
- abstra_internals/controllers/execution/execution_stdio.py +3 -14
- abstra_internals/controllers/execution/execution_test.py +5 -9
- abstra_internals/controllers/execution/worker_process.py +8 -33
- abstra_internals/controllers/main.py +18 -26
- abstra_internals/entities/execution_context.py +1 -0
- abstra_internals/entities/execution_test.py +6 -3
- abstra_internals/interface/cli/editor.py +6 -3
- abstra_internals/interface/sdk/forms/deprecated/page_test.py +6 -8
- abstra_internals/interface/sdk/tables/api_test.py +1 -7
- abstra_internals/logs_watcher.py +13 -6
- abstra_internals/repositories/consumer.py +1 -3
- abstra_internals/repositories/factory.py +7 -6
- abstra_internals/repositories/producer.py +7 -41
- abstra_internals/repositories/project/project_test.py +1 -6
- abstra_internals/repositories/tasks.py +8 -4
- abstra_internals/server/blueprints/player.py +39 -24
- abstra_internals/server/guards/role_guard_test.py +1 -6
- abstra_internals/server/routes/forms.py +10 -3
- abstra_internals/server/routes/stdio.py +3 -3
- abstra_internals/stdio_patcher.py +4 -4
- abstra_internals/tasks_watcher.py +59 -0
- abstra_internals/utils/ai.py +4 -9
- abstra_statics/dist/assets/{AbstraButton.vue_vue_type_script_setup_true_lang.c714d609.js → AbstraButton.vue_vue_type_script_setup_true_lang.86a761e5.js} +2 -2
- abstra_statics/dist/assets/AbstraLogo.vue_vue_type_script_setup_true_lang.d02ffa6d.js +2 -0
- abstra_statics/dist/assets/ApiKeys.e132de0a.js +2 -0
- abstra_statics/dist/assets/App.9aa34c4e.js +2 -0
- abstra_statics/dist/assets/App.vue_vue_type_style_index_0_lang.9dc1f7e7.js +2 -0
- abstra_statics/dist/assets/BaseLayout.d41dae76.js +2 -0
- abstra_statics/dist/assets/Billing.04224d7b.js +2 -0
- abstra_statics/dist/assets/{Breadcrumb.1d42c80c.js → Breadcrumb.00a432b7.js} +2 -2
- abstra_statics/dist/assets/{Builds.4641dcf9.js → Builds.329c2faa.js} +2 -2
- abstra_statics/dist/assets/{Card.774e5d67.js → Card.d8993609.js} +2 -2
- abstra_statics/dist/assets/{CircularLoading.02fd7b7b.js → CircularLoading.e0819e0b.js} +2 -2
- abstra_statics/dist/assets/CloseCircleOutlined.ae1e7621.js +2 -0
- abstra_statics/dist/assets/{ConnectorsView.746c7417.js → ConnectorsView.4c23ea88.js} +2 -2
- abstra_statics/dist/assets/ConsoleOmniChat.vue_vue_type_script_setup_true_lang.f2c53fd6.js +2 -0
- abstra_statics/dist/assets/{ContentLayout.4fc85c66.js → ContentLayout.9774740e.js} +2 -2
- abstra_statics/dist/assets/{CrudView.7f2cbde4.js → CrudView.01e6ed04.js} +2 -2
- abstra_statics/dist/assets/{DocsButton.vue_vue_type_script_setup_true_lang.0b26fb89.js → DocsButton.vue_vue_type_script_setup_true_lang.3efd2188.js} +2 -2
- abstra_statics/dist/assets/{EditorLogin.45764526.js → EditorLogin.b9477432.js} +2 -2
- abstra_statics/dist/assets/{EditorsView.e9452d34.js → EditorsView.ec2e0465.js} +2 -2
- abstra_statics/dist/assets/EnvVars.72e8a906.js +2 -0
- abstra_statics/dist/assets/Error.75789fcd.js +2 -0
- abstra_statics/dist/assets/ExclamationCircleOutlined.443f1727.js +2 -0
- abstra_statics/dist/assets/{Files.8bcd4d1f.js → Files.598e1924.js} +2 -2
- abstra_statics/dist/assets/Form.dcd328f9.js +2 -0
- abstra_statics/dist/assets/{FormRunner.f721431d.js → FormRunner.22c166b3.js} +2 -2
- abstra_statics/dist/assets/Home.29af870e.js +2 -0
- abstra_statics/dist/assets/Home.5a193adf.js +2 -0
- abstra_statics/dist/assets/{Live.2bbd1666.js → Live.47f1d55b.js} +2 -2
- abstra_statics/dist/assets/LoadingContainer.4d7a6e83.js +2 -0
- abstra_statics/dist/assets/LoadingOutlined.688afd1b.js +2 -0
- abstra_statics/dist/assets/Login.543da72d.js +2 -0
- abstra_statics/dist/assets/{Login.186f24a9.js → Login.d4ed4415.js} +2 -2
- abstra_statics/dist/assets/{Login.vue_vue_type_script_setup_true_lang.fab46c0c.js → Login.vue_vue_type_script_setup_true_lang.7a0b5cb9.js} +2 -2
- abstra_statics/dist/assets/Logo.a483cebb.js +2 -0
- abstra_statics/dist/assets/Logs.93696d9a.js +2 -0
- abstra_statics/dist/assets/LogsController.051e4c97.js +2 -0
- abstra_statics/dist/assets/Main.e6271958.js +2 -0
- abstra_statics/dist/assets/{MockForm.9b6a244c.js → MockForm.60f0a0c9.js} +2 -2
- abstra_statics/dist/assets/Navbar.6beb23a2.js +2 -0
- abstra_statics/dist/assets/{NewEditor.1d7ddf86.js → NewEditor.a3f0cf6f.js} +5 -5
- abstra_statics/dist/assets/OidcLoginCallback.5d621b1e.js +2 -0
- abstra_statics/dist/assets/OidcLogoutCallback.726fd77b.js +2 -0
- abstra_statics/dist/assets/{OmniChat.5e68be1c.js → OmniChat.65218812.js} +2 -2
- abstra_statics/dist/assets/{OnboardingView.8733d184.js → OnboardingView.7b28e3d9.js} +2 -2
- abstra_statics/dist/assets/{Organization.bcb76b94.js → Organization.4d764c53.js} +2 -2
- abstra_statics/dist/assets/{Organizations.3dbd99e1.js → Organizations.99154f7f.js} +2 -2
- abstra_statics/dist/assets/{PhArrowCounterClockwise.vue.d273955f.js → PhArrowCounterClockwise.vue.731eb94b.js} +2 -2
- abstra_statics/dist/assets/{PhArrowSquareOut.vue.0d20b8e9.js → PhArrowSquareOut.vue.da6ece6b.js} +2 -2
- abstra_statics/dist/assets/{PhBookBookmark.vue.8611e54f.js → PhBookBookmark.vue.129658c0.js} +2 -2
- abstra_statics/dist/assets/{PhChats.vue.3dd1c2d7.js → PhChats.vue.3eae87f1.js} +2 -2
- abstra_statics/dist/assets/{PhClockCounterClockwise.vue.853bd5ec.js → PhClockCounterClockwise.vue.83a88fd2.js} +2 -2
- abstra_statics/dist/assets/{PhCopy.vue.b1c2f21f.js → PhCopy.vue.889171d4.js} +2 -2
- abstra_statics/dist/assets/{PhCopySimple.vue.ffc7ec94.js → PhCopySimple.vue.fa1be768.js} +2 -2
- abstra_statics/dist/assets/{PhCube.vue.b5e79047.js → PhCube.vue.c868f288.js} +2 -2
- abstra_statics/dist/assets/{PhDotsThreeVertical.vue.89b627bd.js → PhDotsThreeVertical.vue.82ed05fc.js} +2 -2
- abstra_statics/dist/assets/{PhDownloadSimple.vue.2c2eeb2c.js → PhDownloadSimple.vue.32b4f321.js} +2 -2
- abstra_statics/dist/assets/{PhFolderPlus.vue.e199ba17.js → PhFolderPlus.vue.9b394b08.js} +2 -2
- abstra_statics/dist/assets/{PhGear.vue.fbac4098.js → PhGear.vue.bd7172cf.js} +2 -2
- abstra_statics/dist/assets/{PhKey.vue.1850e466.js → PhKey.vue.e1681937.js} +2 -2
- abstra_statics/dist/assets/{PhPencil.vue.c3c70f7d.js → PhPencil.vue.6abcb050.js} +2 -2
- abstra_statics/dist/assets/{PhPencilSimple.vue.ee9d03fc.js → PhPencilSimple.vue.9dc4c516.js} +2 -2
- abstra_statics/dist/assets/{PhPencilSimpleLine.vue.6eedd1e6.js → PhPencilSimpleLine.vue.516b8dd0.js} +2 -2
- abstra_statics/dist/assets/{PhRocket.vue.56a9b767.js → PhRocket.vue.6310b8e2.js} +2 -2
- abstra_statics/dist/assets/{PhSignOut.vue.ee548b4c.js → PhSignOut.vue.33352908.js} +2 -2
- abstra_statics/dist/assets/{PhSparkle.vue.dc906cc7.js → PhSparkle.vue.aaea2035.js} +2 -2
- abstra_statics/dist/assets/{PhUserList.vue.6d0e7bc8.js → PhUserList.vue.66442c99.js} +2 -2
- abstra_statics/dist/assets/{PhUsersThree.vue.528ec19f.js → PhUsersThree.vue.dd3dd5e5.js} +2 -2
- abstra_statics/dist/assets/{PhWebhooksLogo.vue.49b66d69.js → PhWebhooksLogo.vue.3159b8c2.js} +2 -2
- abstra_statics/dist/assets/{PlayerConfigProvider.ead35c7b.js → PlayerConfigProvider.608f994d.js} +2 -2
- abstra_statics/dist/assets/{PlayerNavbar.523eb145.js → PlayerNavbar.db2b0cc0.js} +2 -2
- abstra_statics/dist/assets/{Project.d667be48.js → Project.b5f0a540.js} +2 -2
- abstra_statics/dist/assets/ProjectLogin.ca80209f.js +2 -0
- abstra_statics/dist/assets/{ProjectSettings.78ebb6ae.js → ProjectSettings.c69dc60b.js} +2 -2
- abstra_statics/dist/assets/{ProjectsView.0a9b802f.js → ProjectsView.7ea6a476.js} +2 -2
- abstra_statics/dist/assets/{SaveButton.7c95c711.js → SaveButton.45360af6.js} +2 -2
- abstra_statics/dist/assets/{Sidebar.88ff0297.js → Sidebar.5b02858f.js} +2 -2
- abstra_statics/dist/assets/Sql.f80e393a.js +5 -0
- abstra_statics/dist/assets/Steps.2a44bd5a.js +2 -0
- abstra_statics/dist/assets/{TableEditor.8166dbd3.js → TableEditor.9f5307b3.js} +2 -2
- abstra_statics/dist/assets/{Tables.0da330b6.js → Tables.c8410571.js} +2 -2
- abstra_statics/dist/assets/{TablesDiagram.67a07e98.js → TablesDiagram.174bf25c.js} +2 -2
- abstra_statics/dist/assets/TablesTabs.vue_vue_type_script_setup_true_lang.d32d5407.js +2 -0
- abstra_statics/dist/assets/{Tasks.d7e74b8f.js → Tasks.6bf6e3ab.js} +2 -2
- abstra_statics/dist/assets/{UploadOutlined.6515c426.js → UploadOutlined.17748ead.js} +2 -2
- abstra_statics/dist/assets/{View.2cf966b9.js → View.fc004ade.js} +2 -2
- abstra_statics/dist/assets/{View.vue_vue_type_script_setup_true_lang.17304c45.js → View.vue_vue_type_script_setup_true_lang.b156d2b4.js} +2 -2
- abstra_statics/dist/assets/{Watermark.4b6da85c.js → Watermark.3f4c77a5.js} +2 -2
- abstra_statics/dist/assets/{WebEditor.969d0862.js → WebEditor.1b4c1d6e.js} +2 -2
- abstra_statics/dist/assets/WidgetPreview.b3a57be6.js +2 -0
- abstra_statics/dist/assets/{ant-design.771baa34.js → ant-design.4dde64bb.js} +2 -2
- abstra_statics/dist/assets/apiKey.2481730b.js +2 -0
- abstra_statics/dist/assets/{asyncComputed.0f036eae.js → asyncComputed.24fa122c.js} +2 -2
- abstra_statics/dist/assets/{build.c819a477.js → build.5e49b52b.js} +2 -2
- abstra_statics/dist/assets/colorHelpers.a41e45a3.js +2 -0
- abstra_statics/dist/assets/{console.072f10aa.js → console.d4555e1e.js} +2 -2
- abstra_statics/dist/assets/constants.4f491067.js +2 -0
- abstra_statics/dist/assets/{cssMode.b24669f0.js → cssMode.94fba5f4.js} +2 -2
- abstra_statics/dist/assets/datetime.215ab936.js +2 -0
- abstra_statics/dist/assets/dayjs.cad6407e.js +2 -0
- abstra_statics/dist/assets/editor.68f10cac.js +2 -0
- abstra_statics/dist/assets/editor.main.d5278805.js +2 -0
- abstra_statics/dist/assets/fetch.b229b6c0.js +2 -0
- abstra_statics/dist/assets/{files.ff551888.js → files.2d03f0a6.js} +2 -2
- abstra_statics/dist/assets/{folder.92a70293.js → folder.c0b92096.js} +2 -2
- abstra_statics/dist/assets/{freemarker2.c3563cfb.js → freemarker2.a8ae0e5a.js} +2 -2
- abstra_statics/dist/assets/{handlebars.bedd8360.js → handlebars.3529fc9d.js} +3 -3
- abstra_statics/dist/assets/{html.3cfc37f8.js → html.193c548a.js} +3 -3
- abstra_statics/dist/assets/{htmlMode.f9c29f9d.js → htmlMode.5669aea7.js} +2 -2
- abstra_statics/dist/assets/{index.138ad220.js → index.17c59820.js} +2 -2
- abstra_statics/dist/assets/{index.9028af84.js → index.17c9890b.js} +2 -2
- abstra_statics/dist/assets/{index.5429e60c.js → index.2f9d5f42.js} +2 -2
- abstra_statics/dist/assets/{index.dfc9f500.js → index.341d2d78.js} +2 -2
- abstra_statics/dist/assets/{index.e6b397aa.js → index.590aa576.js} +3 -3
- abstra_statics/dist/assets/{index.b69b3146.js → index.84a81069.js} +2 -2
- abstra_statics/dist/assets/index.9d0d77b2.js +2 -0
- abstra_statics/dist/assets/{index.dccc1696.js → index.c3ea2813.js} +2 -2
- abstra_statics/dist/assets/{index.26a34a52.js → index.ee7c5f13.js} +2 -2
- abstra_statics/dist/assets/{index.a9e83a57.js → index.fd173cc0.js} +2 -2
- abstra_statics/dist/assets/{javascript.a4a24e63.js → javascript.ff046b2c.js} +3 -3
- abstra_statics/dist/assets/{jsonMode.4df0cb48.js → jsonMode.c051f145.js} +2 -2
- abstra_statics/dist/assets/{jwt-decode.esm.b204fb7d.js → jwt-decode.esm.f18c394f.js} +7 -7
- abstra_statics/dist/assets/{linters.5b679742.js → linters.e4e7bac9.js} +2 -2
- abstra_statics/dist/assets/{liquid.6539d262.js → liquid.98fcb8a3.js} +3 -3
- abstra_statics/dist/assets/member.d0ead44d.js +2 -0
- abstra_statics/dist/assets/{metadata.e6e36ac2.js → metadata.218ef86b.js} +2 -2
- abstra_statics/dist/assets/{omniChatStore.0470e5b1.js → omniChatStore.405dd08d.js} +2 -2
- abstra_statics/dist/assets/{organization.04cff158.js → organization.c20116a5.js} +2 -2
- abstra_statics/dist/assets/player.30fb0733.js +2 -0
- abstra_statics/dist/assets/{plotly.min.e185d882.js → plotly.min.b26aecc2.js} +2 -2
- abstra_statics/dist/assets/polling.775bd07d.js +2 -0
- abstra_statics/dist/assets/{project.c198d794.js → project.d26f784f.js} +2 -2
- abstra_statics/dist/assets/{python.5c45007e.js → python.6f801519.js} +2 -2
- abstra_statics/dist/assets/{razor.dbd79c37.js → razor.80957baf.js} +2 -2
- abstra_statics/dist/assets/{record.316e025a.js → record.f0e74f25.js} +2 -2
- abstra_statics/dist/assets/redirect.47662fd9.js +2 -0
- abstra_statics/dist/assets/{repository.ae6e826f.js → repository.75210ebd.js} +2 -2
- abstra_statics/dist/assets/repository.d2158c5f.js +2 -0
- abstra_statics/dist/assets/{router.29d47df0.js → router.9924fce0.js} +3 -3
- abstra_statics/dist/assets/string.c4805024.js +2 -0
- abstra_statics/dist/assets/{tables.e80a0328.js → tables.4cd227ff.js} +2 -2
- abstra_statics/dist/assets/{tasksController.307be8dc.js → tasksController.f0830c77.js} +3 -3
- abstra_statics/dist/assets/{toggleHighContrast.4184537f.js → toggleHighContrast.d8b2c912.js} +7 -7
- abstra_statics/dist/assets/{tsMode.12c94eed.js → tsMode.7de6acfd.js} +2 -2
- abstra_statics/dist/assets/{typescript.e087b68e.js → typescript.78bce6b9.js} +2 -2
- abstra_statics/dist/assets/url.f54a173c.js +2 -0
- abstra_statics/dist/assets/userStore.1345e655.js +2 -0
- abstra_statics/dist/assets/uuid.2e8600ec.js +2 -0
- abstra_statics/dist/assets/{vue-flow-background.402b0a32.js → vue-flow-background.57038ee0.js} +2 -2
- abstra_statics/dist/assets/{vue-quill.esm-bundler.10d49c97.js → vue-quill.esm-bundler.130627ea.js} +2 -2
- abstra_statics/dist/assets/workspaceStore.29138ee5.js +2 -0
- abstra_statics/dist/assets/{xml.c4ef7130.js → xml.46fa5b06.js} +3 -3
- abstra_statics/dist/assets/{yaml.5eb27541.js → yaml.775c20d7.js} +2 -2
- abstra_statics/dist/console.html +15 -15
- abstra_statics/dist/editor.html +11 -11
- abstra_statics/dist/player.html +9 -9
- abstra_internals/utils/threading.py +0 -24
- abstra_internals/utils/websockets.py +0 -79
- abstra_statics/dist/assets/AbstraLogo.vue_vue_type_script_setup_true_lang.37e7ad5b.js +0 -2
- abstra_statics/dist/assets/ApiKeys.94113392.js +0 -2
- abstra_statics/dist/assets/App.6c102d26.js +0 -2
- abstra_statics/dist/assets/App.vue_vue_type_style_index_0_lang.26121baf.js +0 -2
- abstra_statics/dist/assets/BaseLayout.670b8441.js +0 -2
- abstra_statics/dist/assets/Billing.80a50079.js +0 -2
- abstra_statics/dist/assets/CloseCircleOutlined.7ac8e1e8.js +0 -2
- abstra_statics/dist/assets/ConsoleOmniChat.vue_vue_type_script_setup_true_lang.b85f86d8.js +0 -2
- abstra_statics/dist/assets/EnvVars.ccc24231.js +0 -2
- abstra_statics/dist/assets/Error.1bf571a6.js +0 -2
- abstra_statics/dist/assets/ExclamationCircleOutlined.f71fa58b.js +0 -2
- abstra_statics/dist/assets/Form.288a7191.js +0 -2
- abstra_statics/dist/assets/Home.23f0cff8.js +0 -2
- abstra_statics/dist/assets/Home.5ce6aade.js +0 -2
- abstra_statics/dist/assets/LoadingContainer.3ea9ec8d.js +0 -2
- abstra_statics/dist/assets/LoadingOutlined.11688830.js +0 -2
- abstra_statics/dist/assets/Login.2a4c7e48.js +0 -2
- abstra_statics/dist/assets/Logo.cc2d4a95.js +0 -2
- abstra_statics/dist/assets/Logs.f57284a4.js +0 -2
- abstra_statics/dist/assets/LogsController.353f0002.js +0 -2
- abstra_statics/dist/assets/Main.635e443c.js +0 -2
- abstra_statics/dist/assets/Navbar.dacca218.js +0 -2
- abstra_statics/dist/assets/OidcLoginCallback.0dff6320.js +0 -2
- abstra_statics/dist/assets/OidcLogoutCallback.1f077fbb.js +0 -2
- abstra_statics/dist/assets/ProjectLogin.ed25cb39.js +0 -2
- abstra_statics/dist/assets/Sql.cbcb65af.js +0 -5
- abstra_statics/dist/assets/Steps.4c7bc2b0.js +0 -2
- abstra_statics/dist/assets/TablesTabs.vue_vue_type_script_setup_true_lang.2d88acf3.js +0 -2
- abstra_statics/dist/assets/WidgetPreview.6cc6a025.js +0 -2
- abstra_statics/dist/assets/apiKey.8e591cfc.js +0 -2
- abstra_statics/dist/assets/colorHelpers.c4e8851c.js +0 -2
- abstra_statics/dist/assets/constants.6f822a9d.js +0 -2
- abstra_statics/dist/assets/datetime.7d5f4744.js +0 -2
- abstra_statics/dist/assets/dayjs.19defe89.js +0 -2
- abstra_statics/dist/assets/editor.6fa2da52.js +0 -2
- abstra_statics/dist/assets/editor.main.91c25311.js +0 -2
- abstra_statics/dist/assets/fetch.41281c28.js +0 -2
- abstra_statics/dist/assets/index.e7bc0e19.js +0 -2
- abstra_statics/dist/assets/member.c5283d66.js +0 -2
- abstra_statics/dist/assets/player.c715ca22.js +0 -2
- abstra_statics/dist/assets/polling.5f85e241.js +0 -2
- abstra_statics/dist/assets/redirect.d1904049.js +0 -2
- abstra_statics/dist/assets/repository.babdc912.js +0 -2
- abstra_statics/dist/assets/string.4a80abd5.js +0 -2
- abstra_statics/dist/assets/url.371275cf.js +0 -2
- abstra_statics/dist/assets/userStore.26658284.js +0 -2
- abstra_statics/dist/assets/uuid.ffd92735.js +0 -2
- abstra_statics/dist/assets/workspaceStore.9caf566c.js +0 -2
- {abstra-3.23.3.dist-info → abstra-3.23.4.dist-info}/WHEEL +0 -0
- {abstra-3.23.3.dist-info → abstra-3.23.4.dist-info}/entry_points.txt +0 -0
- {abstra-3.23.3.dist-info → abstra-3.23.4.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,6 @@ import io
|
|
|
2
2
|
import unittest
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from multiprocessing import Pipe
|
|
6
5
|
from typing import List
|
|
7
6
|
from uuid import UUID
|
|
8
7
|
|
|
@@ -26,7 +25,6 @@ from abstra_internals.interface.sdk.tables.api import (
|
|
|
26
25
|
serialize,
|
|
27
26
|
)
|
|
28
27
|
from abstra_internals.repositories.tables import TablesRepository
|
|
29
|
-
from abstra_internals.utils.websockets import MockWS, bind_ws_with_connection
|
|
30
28
|
from tests.fixtures import BaseTest
|
|
31
29
|
|
|
32
30
|
|
|
@@ -56,11 +54,8 @@ class TestTables(BaseTest):
|
|
|
56
54
|
context = FormContext(
|
|
57
55
|
request=Request(body="", query_params={}, headers={}, method="GET"),
|
|
58
56
|
)
|
|
59
|
-
|
|
60
|
-
self.parent_conn, child_conn = Pipe()
|
|
61
|
-
bind_ws_with_connection(MockWS(), self.parent_conn, block=False)
|
|
62
57
|
self.client = FormClient(
|
|
63
|
-
|
|
58
|
+
ws=None, # type: ignore
|
|
64
59
|
context=context,
|
|
65
60
|
production_mode=False,
|
|
66
61
|
)
|
|
@@ -72,7 +67,6 @@ class TestTables(BaseTest):
|
|
|
72
67
|
|
|
73
68
|
def tearDown(self) -> None:
|
|
74
69
|
self.context.__exit__(None, None, None)
|
|
75
|
-
self.parent_conn.close()
|
|
76
70
|
super().tearDown()
|
|
77
71
|
|
|
78
72
|
def test_select(self):
|
abstra_internals/logs_watcher.py
CHANGED
|
@@ -14,7 +14,8 @@ from watchdog.events import (
|
|
|
14
14
|
from watchdog.observers import Observer
|
|
15
15
|
|
|
16
16
|
from abstra_internals.consts.filepaths import LOCAL_LOGS_DIR_PATH
|
|
17
|
-
from abstra_internals.controllers.execution.execution_stdio import
|
|
17
|
+
from abstra_internals.controllers.execution.execution_stdio import BroadcastController
|
|
18
|
+
from abstra_internals.utils import serialize
|
|
18
19
|
|
|
19
20
|
LogUpdateHandler = Callable[[str, str, str], None] # execution_id, stage_id, content
|
|
20
21
|
|
|
@@ -85,9 +86,15 @@ class LogsWatcher(FileSystemEventHandler):
|
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
def on_logs_update(execution_id: str, stage_id: str, log_content: str):
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
msg = serialize(
|
|
90
|
+
dict(
|
|
91
|
+
type="stdio",
|
|
92
|
+
payload=dict(
|
|
93
|
+
type="stdout",
|
|
94
|
+
log=log_content,
|
|
95
|
+
execution_id=execution_id,
|
|
96
|
+
stage_id=stage_id,
|
|
97
|
+
),
|
|
98
|
+
)
|
|
93
99
|
)
|
|
100
|
+
BroadcastController.broadcast(msg=msg)
|
|
@@ -97,9 +97,7 @@ class RabbitConsumer(Consumer):
|
|
|
97
97
|
continue
|
|
98
98
|
|
|
99
99
|
yield QueueMessage(
|
|
100
|
-
preexecution=PreExecution.
|
|
101
|
-
deserialize(body.decode("utf-8"))
|
|
102
|
-
),
|
|
100
|
+
preexecution=PreExecution(**deserialize(body.decode("utf-8"))),
|
|
103
101
|
delivery_tag=method.delivery_tag,
|
|
104
102
|
)
|
|
105
103
|
|
|
@@ -15,8 +15,12 @@ from abstra_internals.repositories.ai import (
|
|
|
15
15
|
LocalAIRepository,
|
|
16
16
|
ProductionAIRepository,
|
|
17
17
|
)
|
|
18
|
-
from abstra_internals.repositories.connectors import
|
|
19
|
-
|
|
18
|
+
from abstra_internals.repositories.connectors import (
|
|
19
|
+
ConnectorsRepository,
|
|
20
|
+
)
|
|
21
|
+
from abstra_internals.repositories.email import (
|
|
22
|
+
EmailRepository,
|
|
23
|
+
)
|
|
20
24
|
from abstra_internals.repositories.execution import (
|
|
21
25
|
ExecutionRepository,
|
|
22
26
|
LocalExecutionRepository,
|
|
@@ -106,15 +110,12 @@ class Repositories:
|
|
|
106
110
|
def build_editor_repositories(local_queue: Optional[Queue] = None):
|
|
107
111
|
mp_context = SpawnContextReposity()
|
|
108
112
|
|
|
109
|
-
# If no queue is provided, create one using the same context
|
|
110
|
-
if local_queue is None:
|
|
111
|
-
local_queue = mp_context.get_context().Queue()
|
|
112
|
-
|
|
113
113
|
http_client = HTTPClient(
|
|
114
114
|
base_url=CLOUD_API_CLI_URL, base_headers_resolver=resolve_headers_raise
|
|
115
115
|
)
|
|
116
116
|
|
|
117
117
|
linter = LocalLinterRepository()
|
|
118
|
+
local_queue = local_queue or mp_context.get_context().Queue()
|
|
118
119
|
|
|
119
120
|
return Repositories(
|
|
120
121
|
project=LocalProjectRepository(),
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import socket
|
|
2
1
|
from abc import ABC, abstractmethod
|
|
3
2
|
from dataclasses import dataclass
|
|
4
3
|
from multiprocessing import Queue
|
|
5
|
-
from
|
|
6
|
-
from uuid import uuid4
|
|
4
|
+
from typing import Optional
|
|
7
5
|
|
|
8
6
|
import pika
|
|
9
7
|
|
|
@@ -17,9 +15,7 @@ from abstra_internals.utils.serializable import Serializable
|
|
|
17
15
|
|
|
18
16
|
class PreExecution(Serializable):
|
|
19
17
|
stage_id: str
|
|
20
|
-
|
|
21
|
-
connection_auth_key: str
|
|
22
|
-
context: ClientContext
|
|
18
|
+
context: Optional[ClientContext] = None
|
|
23
19
|
|
|
24
20
|
|
|
25
21
|
@dataclass
|
|
@@ -30,7 +26,7 @@ class QueueMessage:
|
|
|
30
26
|
|
|
31
27
|
class ProducerRepository(ABC):
|
|
32
28
|
@abstractmethod
|
|
33
|
-
def enqueue(self, stage_id: str, context: ClientContext) ->
|
|
29
|
+
def enqueue(self, stage_id: str, context: Optional[ClientContext] = None) -> None:
|
|
34
30
|
raise NotImplementedError()
|
|
35
31
|
|
|
36
32
|
|
|
@@ -38,31 +34,14 @@ class LocalProducerRepository(ProducerRepository):
|
|
|
38
34
|
def __init__(self, local_queue: Queue):
|
|
39
35
|
self.queue = local_queue
|
|
40
36
|
|
|
41
|
-
def enqueue(self, stage_id: str, context: ClientContext) ->
|
|
42
|
-
|
|
43
|
-
listener = Listener(("0.0.0.0", 0), authkey=auth_key.encode())
|
|
44
|
-
preexecution = PreExecution(
|
|
45
|
-
stage_id=stage_id,
|
|
46
|
-
context=context,
|
|
47
|
-
connection_port=int(listener.address[1]),
|
|
48
|
-
connection_auth_key=auth_key,
|
|
49
|
-
)
|
|
37
|
+
def enqueue(self, stage_id: str, context: Optional[ClientContext] = None) -> None:
|
|
38
|
+
preexecution = PreExecution(stage_id=stage_id, context=context)
|
|
50
39
|
self.queue.put(
|
|
51
40
|
QueueMessage(
|
|
52
41
|
preexecution=preexecution,
|
|
53
42
|
delivery_tag=0,
|
|
54
43
|
),
|
|
55
44
|
)
|
|
56
|
-
listener._listener._socket.settimeout(5) # type: ignore
|
|
57
|
-
try:
|
|
58
|
-
connection = listener.accept()
|
|
59
|
-
return connection
|
|
60
|
-
except socket.timeout:
|
|
61
|
-
raise Exception(
|
|
62
|
-
"Timeout waiting for worker to connect. Are you sure the consumers are set?"
|
|
63
|
-
)
|
|
64
|
-
finally:
|
|
65
|
-
listener.close()
|
|
66
45
|
|
|
67
46
|
|
|
68
47
|
class ProductionProducerRepository(ProducerRepository):
|
|
@@ -80,15 +59,8 @@ class ProductionProducerRepository(ProducerRepository):
|
|
|
80
59
|
content_type="application/json",
|
|
81
60
|
)
|
|
82
61
|
|
|
83
|
-
def enqueue(self, stage_id: str, context: ClientContext) ->
|
|
84
|
-
|
|
85
|
-
listener = Listener(("0.0.0.0", 0), authkey=auth_key.encode())
|
|
86
|
-
preexecution = PreExecution(
|
|
87
|
-
stage_id=stage_id,
|
|
88
|
-
context=context,
|
|
89
|
-
connection_port=int(listener.address[1]),
|
|
90
|
-
connection_auth_key=auth_key,
|
|
91
|
-
)
|
|
62
|
+
def enqueue(self, stage_id: str, context: Optional[ClientContext] = None) -> None:
|
|
63
|
+
preexecution = PreExecution(stage_id=stage_id, context=context)
|
|
92
64
|
with pika.BlockingConnection(self.conn_params) as connection:
|
|
93
65
|
with connection.channel() as channel:
|
|
94
66
|
channel.queue_declare(queue=RABBITMQ_EXECUTION_QUEUE, durable=True)
|
|
@@ -98,9 +70,3 @@ class ProductionProducerRepository(ProducerRepository):
|
|
|
98
70
|
exchange=RABBITMQ_DEFAUT_EXCHANGE,
|
|
99
71
|
properties=self.props,
|
|
100
72
|
)
|
|
101
|
-
|
|
102
|
-
listener._listener._socket.settimeout(5) # type: ignore
|
|
103
|
-
try:
|
|
104
|
-
return listener.accept()
|
|
105
|
-
except socket.timeout:
|
|
106
|
-
raise Exception("Timeout waiting for worker to connect")
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from multiprocessing import Queue
|
|
2
1
|
from unittest import TestCase
|
|
3
2
|
|
|
4
|
-
from abstra_internals.repositories.consumer import EditorConsumer
|
|
5
3
|
from abstra_internals.repositories.factory import build_editor_repositories
|
|
6
4
|
from abstra_internals.repositories.project.project import (
|
|
7
5
|
FormStage,
|
|
@@ -16,10 +14,7 @@ from tests.fixtures import clear_dir, init_dir
|
|
|
16
14
|
class ProjectTests(TestCase):
|
|
17
15
|
def setUp(self):
|
|
18
16
|
self.root = init_dir()
|
|
19
|
-
self.
|
|
20
|
-
repos = build_editor_repositories(self.queue)
|
|
21
|
-
self.project_repository = repos.project
|
|
22
|
-
self.consumer = EditorConsumer(self.queue)
|
|
17
|
+
self.project_repository = build_editor_repositories().project
|
|
23
18
|
|
|
24
19
|
def tearDown(self) -> None:
|
|
25
20
|
clear_dir(self.root)
|
|
@@ -210,7 +210,9 @@ class LocalTasksRepository(TasksRepository):
|
|
|
210
210
|
and task.status == "pending"
|
|
211
211
|
and self._where_matches(task, where)
|
|
212
212
|
]
|
|
213
|
-
pending_tasks = sorted(
|
|
213
|
+
pending_tasks = sorted(
|
|
214
|
+
pending_tasks, key=lambda task: task.created.at, reverse=True
|
|
215
|
+
)
|
|
214
216
|
|
|
215
217
|
if limit is None:
|
|
216
218
|
return pending_tasks[offset:]
|
|
@@ -225,7 +227,7 @@ class LocalTasksRepository(TasksRepository):
|
|
|
225
227
|
for task in all_tasks
|
|
226
228
|
if task.created.by_stage_id == stage_id and self._where_matches(task, where)
|
|
227
229
|
]
|
|
228
|
-
sent_tasks = sorted(sent_tasks, key=lambda task: task.created.at)
|
|
230
|
+
sent_tasks = sorted(sent_tasks, key=lambda task: task.created.at, reverse=True)
|
|
229
231
|
|
|
230
232
|
if limit is None:
|
|
231
233
|
return sent_tasks[offset:]
|
|
@@ -233,13 +235,15 @@ class LocalTasksRepository(TasksRepository):
|
|
|
233
235
|
|
|
234
236
|
def get_stage_tasks(self, stage_id: str) -> List[TaskDTO]:
|
|
235
237
|
all_tasks = self.fs_storage.load_all()
|
|
236
|
-
|
|
238
|
+
stage_tasks = [task for task in all_tasks if task.target_stage_id == stage_id]
|
|
239
|
+
return sorted(stage_tasks, key=lambda task: task.created.at, reverse=True)
|
|
237
240
|
|
|
238
241
|
def get_by_id(self, task_id: str) -> TaskDTO:
|
|
239
242
|
return self.get(task_id)
|
|
240
243
|
|
|
241
244
|
def get_all_tasks(self) -> List[TaskDTO]:
|
|
242
|
-
|
|
245
|
+
all_tasks = self.fs_storage.load_all()
|
|
246
|
+
return sorted(all_tasks, key=lambda task: task.created.at, reverse=True)
|
|
243
247
|
|
|
244
248
|
def get_execution_sent_tasks(self, execution_id: str) -> List[TaskDTO]:
|
|
245
249
|
all_tasks = self.fs_storage.load_all()
|
|
@@ -4,12 +4,17 @@ import flask
|
|
|
4
4
|
import flask_sock
|
|
5
5
|
|
|
6
6
|
from abstra_internals.constants import get_public_dir
|
|
7
|
+
from abstra_internals.controllers.execution.execution import ExecutionController
|
|
8
|
+
from abstra_internals.controllers.execution.execution_client_form import FormClient
|
|
9
|
+
from abstra_internals.controllers.execution.execution_client_hook import (
|
|
10
|
+
HookClient,
|
|
11
|
+
Response,
|
|
12
|
+
)
|
|
7
13
|
from abstra_internals.controllers.main import MainController
|
|
8
14
|
from abstra_internals.entities.execution_context import (
|
|
9
15
|
FormContext,
|
|
10
16
|
HookContext,
|
|
11
17
|
JobContext,
|
|
12
|
-
Response,
|
|
13
18
|
extract_flask_request,
|
|
14
19
|
)
|
|
15
20
|
from abstra_internals.environment import (
|
|
@@ -37,7 +42,6 @@ from abstra_internals.settings import Settings
|
|
|
37
42
|
from abstra_internals.usage import player_usage
|
|
38
43
|
from abstra_internals.utils import check_is_url
|
|
39
44
|
from abstra_internals.utils.file import get_tmp_upload_dir, path2module, upload_file
|
|
40
|
-
from abstra_internals.utils.websockets import bind_ws_with_connection
|
|
41
45
|
|
|
42
46
|
|
|
43
47
|
def get_player_bp(controller: MainController):
|
|
@@ -114,8 +118,18 @@ def get_player_bp(controller: MainController):
|
|
|
114
118
|
if not form:
|
|
115
119
|
return
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
client = FormClient(
|
|
122
|
+
context=context,
|
|
123
|
+
production_mode=True,
|
|
124
|
+
ws=ws,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
ExecutionController(
|
|
128
|
+
repositories=controller.repositories,
|
|
129
|
+
stage=form,
|
|
130
|
+
client=client,
|
|
131
|
+
context=context,
|
|
132
|
+
).run()
|
|
119
133
|
except Exception as e:
|
|
120
134
|
AbstraLogger.capture_exception(e)
|
|
121
135
|
finally:
|
|
@@ -175,10 +189,6 @@ def get_player_bp(controller: MainController):
|
|
|
175
189
|
|
|
176
190
|
return send_from_dist(background_path, dist_folder=Settings.root_path)
|
|
177
191
|
|
|
178
|
-
@bp.route("/_hooks", methods=["POST", "GET", "PUT", "DELETE", "PATCH"])
|
|
179
|
-
def root_hook_runner():
|
|
180
|
-
return hook_runner("")
|
|
181
|
-
|
|
182
192
|
@bp.route("/_hooks/<path:path>", methods=["POST", "GET", "PUT", "DELETE", "PATCH"])
|
|
183
193
|
def hook_runner(path):
|
|
184
194
|
hook = controller.get_hook_by_path(path)
|
|
@@ -191,29 +201,34 @@ def get_player_bp(controller: MainController):
|
|
|
191
201
|
|
|
192
202
|
context = HookContext(
|
|
193
203
|
request=extract_flask_request(flask.request),
|
|
204
|
+
response=Response(
|
|
205
|
+
status=200,
|
|
206
|
+
body="",
|
|
207
|
+
headers={},
|
|
208
|
+
),
|
|
194
209
|
)
|
|
195
210
|
|
|
196
|
-
|
|
211
|
+
client = HookClient(context)
|
|
197
212
|
|
|
198
|
-
|
|
199
|
-
|
|
213
|
+
ExecutionController(
|
|
214
|
+
repositories=controller.repositories,
|
|
215
|
+
stage=hook,
|
|
216
|
+
client=client,
|
|
217
|
+
context=context,
|
|
218
|
+
).run()
|
|
200
219
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if not response:
|
|
204
|
-
flask.abort(500)
|
|
205
|
-
finally:
|
|
206
|
-
connection.close()
|
|
220
|
+
if not context.response or not client.context.response:
|
|
221
|
+
flask.abort(500)
|
|
207
222
|
|
|
208
|
-
|
|
209
|
-
status=response.status,
|
|
210
|
-
response=response.body,
|
|
211
|
-
headers=response.headers,
|
|
223
|
+
return flask.Response(
|
|
224
|
+
status=context.response.status,
|
|
225
|
+
response=client.context.response.body,
|
|
226
|
+
headers=context.response.headers,
|
|
212
227
|
)
|
|
213
228
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return
|
|
229
|
+
@bp.route("/_hooks", methods=["POST", "GET", "PUT", "DELETE", "PATCH"])
|
|
230
|
+
def root_hook_runner():
|
|
231
|
+
return hook_runner("")
|
|
217
232
|
|
|
218
233
|
@bp.get("/_jobs")
|
|
219
234
|
def list_jobs():
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from multiprocessing import Queue
|
|
2
1
|
from typing import Optional
|
|
3
2
|
from unittest import TestCase
|
|
4
3
|
|
|
5
4
|
from flask import Blueprint, Flask
|
|
6
5
|
|
|
7
|
-
from abstra_internals.repositories.consumer import EditorConsumer
|
|
8
6
|
from abstra_internals.repositories.project.project import (
|
|
9
7
|
AccessSettings,
|
|
10
8
|
FormStage,
|
|
@@ -25,10 +23,7 @@ from tests.fixtures import build_editor_repositories, clear_dir, init_dir
|
|
|
25
23
|
class TestRequirementsApi(TestCase):
|
|
26
24
|
def setUp(self) -> None:
|
|
27
25
|
self.root = init_dir()
|
|
28
|
-
self.
|
|
29
|
-
repos = build_editor_repositories(self.queue)
|
|
30
|
-
self.project_repository = repos.project
|
|
31
|
-
self.consumer = EditorConsumer(self.queue)
|
|
26
|
+
self.project_repository = build_editor_repositories().project
|
|
32
27
|
|
|
33
28
|
def tearDown(self) -> None:
|
|
34
29
|
clear_dir(self.root)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import flask
|
|
2
2
|
import flask_sock
|
|
3
3
|
|
|
4
|
+
from abstra_internals.controllers.execution.execution import ExecutionController
|
|
5
|
+
from abstra_internals.controllers.execution.execution_client_form import FormClient
|
|
4
6
|
from abstra_internals.controllers.main import MainController
|
|
5
7
|
from abstra_internals.entities.execution_context import (
|
|
6
8
|
FormContext,
|
|
@@ -10,7 +12,6 @@ from abstra_internals.logger import AbstraLogger
|
|
|
10
12
|
from abstra_internals.repositories.project.project import FormStage
|
|
11
13
|
from abstra_internals.usage import editor_usage
|
|
12
14
|
from abstra_internals.utils import is_it_true
|
|
13
|
-
from abstra_internals.utils.websockets import bind_ws_with_connection
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def get_editor_bp(controller: MainController):
|
|
@@ -32,9 +33,15 @@ def get_editor_bp(controller: MainController):
|
|
|
32
33
|
if not form:
|
|
33
34
|
return
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
client = FormClient(ws=ws, context=context, production_mode=False)
|
|
37
|
+
|
|
38
|
+
ExecutionController(
|
|
39
|
+
repositories=controller.repositories,
|
|
40
|
+
stage=form,
|
|
41
|
+
client=client,
|
|
42
|
+
context=context,
|
|
43
|
+
).run()
|
|
36
44
|
|
|
37
|
-
bind_ws_with_connection(ws, connection, block=True)
|
|
38
45
|
except Exception as e:
|
|
39
46
|
AbstraLogger.capture_exception(e)
|
|
40
47
|
finally:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import flask
|
|
2
2
|
import flask_sock
|
|
3
3
|
|
|
4
|
-
from abstra_internals.controllers.execution.execution_stdio import
|
|
4
|
+
from abstra_internals.controllers.execution.execution_stdio import BroadcastController
|
|
5
5
|
from abstra_internals.logger import AbstraLogger
|
|
6
6
|
|
|
7
7
|
|
|
@@ -13,11 +13,11 @@ def get_editor_bp(_):
|
|
|
13
13
|
def _websocket(ws: flask_sock.Server):
|
|
14
14
|
try:
|
|
15
15
|
ws.thread.name = "StdioWebSocket"
|
|
16
|
-
|
|
16
|
+
BroadcastController.register(ws)
|
|
17
17
|
ws.event.wait()
|
|
18
18
|
except Exception as e:
|
|
19
19
|
AbstraLogger.capture_exception(e)
|
|
20
20
|
finally:
|
|
21
|
-
|
|
21
|
+
BroadcastController.unregister(ws)
|
|
22
22
|
|
|
23
23
|
return bp
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
|
|
3
|
-
from abstra_internals.controllers.execution.execution_stdio import
|
|
3
|
+
from abstra_internals.controllers.execution.execution_stdio import BroadcastController
|
|
4
4
|
from abstra_internals.controllers.main import MainController
|
|
5
5
|
from abstra_internals.environment import DISABLE_STDIO_PATCH
|
|
6
6
|
|
|
@@ -14,14 +14,14 @@ class StdioPatcher:
|
|
|
14
14
|
if DISABLE_STDIO_PATCH:
|
|
15
15
|
return
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
broadcast_controller = BroadcastController(
|
|
18
18
|
sys_stderr_write=cls.original_sys_stderr_write,
|
|
19
19
|
sys_stdout_write=cls.original_sys_stdout_write,
|
|
20
20
|
main_controller=main_controller,
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
sys.stdout.write =
|
|
24
|
-
sys.stderr.write =
|
|
23
|
+
sys.stdout.write = broadcast_controller.patched_stdout_write
|
|
24
|
+
sys.stderr.write = broadcast_controller.patched_stderr_write
|
|
25
25
|
|
|
26
26
|
@classmethod
|
|
27
27
|
def reset(cls):
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Callable, List
|
|
6
|
+
|
|
7
|
+
from watchdog.events import (
|
|
8
|
+
FileCreatedEvent,
|
|
9
|
+
FileModifiedEvent,
|
|
10
|
+
FileSystemEvent,
|
|
11
|
+
FileSystemEventHandler,
|
|
12
|
+
)
|
|
13
|
+
from watchdog.observers import Observer
|
|
14
|
+
|
|
15
|
+
from abstra_internals.consts.filepaths import TASKS_DIR_PATH
|
|
16
|
+
from abstra_internals.controllers.execution.execution_stdio import BroadcastController
|
|
17
|
+
from abstra_internals.repositories.tasks import TaskDTO
|
|
18
|
+
from abstra_internals.utils import serialize
|
|
19
|
+
|
|
20
|
+
TaskUpdateHandler = Callable[[TaskDTO], None]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TasksWatcher(FileSystemEventHandler):
|
|
24
|
+
def __init__(self, handlers: List[TaskUpdateHandler]):
|
|
25
|
+
super().__init__()
|
|
26
|
+
self.handlers: List[TaskUpdateHandler] = handlers
|
|
27
|
+
self._last_offsets: dict[str, int] = {}
|
|
28
|
+
|
|
29
|
+
def start(self):
|
|
30
|
+
Path(TASKS_DIR_PATH).mkdir(parents=True, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
observer = Observer()
|
|
33
|
+
observer.schedule(self, path=str(TASKS_DIR_PATH), recursive=False)
|
|
34
|
+
observer.start()
|
|
35
|
+
self._observer = observer
|
|
36
|
+
|
|
37
|
+
def dispatch(self, event: FileSystemEvent):
|
|
38
|
+
if not isinstance(event, (FileCreatedEvent, FileModifiedEvent)):
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
filepath = Path(event.src_path)
|
|
42
|
+
if filepath.suffix != ".json" or not filepath.parent.samefile(TASKS_DIR_PATH):
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
self._handle_file_event(filepath)
|
|
46
|
+
|
|
47
|
+
def _handle_file_event(self, filepath: Path):
|
|
48
|
+
time.sleep(0.01)
|
|
49
|
+
|
|
50
|
+
raw_task = filepath.read_text(encoding="utf-8")
|
|
51
|
+
task = TaskDTO(**json.loads(raw_task))
|
|
52
|
+
|
|
53
|
+
for handler in self.handlers:
|
|
54
|
+
threading.Thread(target=handler, args=(task,)).start()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def on_tasks_update(task: TaskDTO):
|
|
58
|
+
msg = serialize(dict(type="task", payload=task.dump()))
|
|
59
|
+
BroadcastController.broadcast(msg=msg)
|
abstra_internals/utils/ai.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Dict
|
|
3
3
|
|
|
4
4
|
from abstra_internals.contracts_generated import (
|
|
5
5
|
CloudApiCliAiV2PromptPostRequestMessages,
|
|
@@ -7,11 +7,9 @@ from abstra_internals.contracts_generated import (
|
|
|
7
7
|
CloudApiCliAiV2PromptPostRequestMessagesItemContentItemText,
|
|
8
8
|
CloudApiCliAiV2PromptPostRequestToolsItemFunction,
|
|
9
9
|
)
|
|
10
|
+
from abstra_internals.repositories.factory import Repositories
|
|
10
11
|
from abstra_internals.utils.string import to_snake_case
|
|
11
12
|
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from abstra_internals.repositories.factory import Repositories
|
|
14
|
-
|
|
15
13
|
|
|
16
14
|
def build_function_tool_call(
|
|
17
15
|
format: Dict[str, object],
|
|
@@ -31,13 +29,13 @@ def build_function_tool_call(
|
|
|
31
29
|
|
|
32
30
|
class AiWs:
|
|
33
31
|
seq: int
|
|
34
|
-
repos:
|
|
32
|
+
repos: Repositories
|
|
35
33
|
messages: CloudApiCliAiV2PromptPostRequestMessages = []
|
|
36
34
|
url_params: Dict[str, str]
|
|
37
35
|
prompt: str
|
|
38
36
|
|
|
39
37
|
def __init__(
|
|
40
|
-
self, repos:
|
|
38
|
+
self, repos: Repositories, prompt_text: str, url_params: Dict[str, str]
|
|
41
39
|
) -> None:
|
|
42
40
|
self.repos = repos
|
|
43
41
|
self.prompt = prompt_text
|
|
@@ -105,6 +103,3 @@ class AiWs:
|
|
|
105
103
|
)
|
|
106
104
|
self.seq += 1
|
|
107
105
|
return json.dumps({**ans, "seq": self.seq})
|
|
108
|
-
|
|
109
|
-
def close(self):
|
|
110
|
-
self.messages.clear()
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{d as
|
|
2
|
-
//# sourceMappingURL=AbstraButton.vue_vue_type_script_setup_true_lang.
|
|
1
|
+
import{d as c,c as b,o as r,a as d,b as a,f as l,u as n,de as i,a7 as p,h as u,ez as f,eA as g,bR as y,aV as m,e6 as _}from"./jwt-decode.esm.f18c394f.js";(function(){try{var t=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},e=new Error().stack;e&&(t._sentryDebugIds=t._sentryDebugIds||{},t._sentryDebugIds[e]="b9332890-365b-4ad6-81d3-838ac1f88e57",t._sentryDebugIdIdentifier="sentry-dbid-b9332890-365b-4ad6-81d3-838ac1f88e57")}catch{}})();const h=c({__name:"AbstraButton",props:{disabledTooltip:{},tooltip:{},prefixCls:{},type:{},htmlType:{},shape:{},size:{},loading:{type:[Boolean,Object]},disabled:{type:Boolean},ghost:{type:Boolean},block:{type:Boolean},danger:{type:Boolean},icon:{},href:{},target:{},title:{},onClick:{type:[Function,Array]},onMousedown:{type:[Function,Array]}},setup(t){const e=t,s=b(()=>e.disabledTooltip&&e.disabled?e.disabledTooltip:e.tooltip);return(o,k)=>s.value?(r(),d(n(m),{key:0,title:s.value},{default:a(()=>[l(n(y),f(g(o.$props)),{default:a(()=>[l(n(i),{style:{display:"flex","align-items":"center","justify-content":"center",gap:"5px"}},{default:a(()=>[o.loading?u("",!0):p(o.$slots,"default",{key:0})]),_:3})]),_:3},16)]),_:3},8,["title"])):(r(),d(n(y),f(_({key:1},o.$props)),{default:a(()=>[l(n(i),{style:{display:"flex","align-items":"center","justify-content":"center",gap:"5px"}},{default:a(()=>[o.loading?u("",!0):p(o.$slots,"default",{key:0})]),_:3})]),_:3},16))}});export{h as _};
|
|
2
|
+
//# sourceMappingURL=AbstraButton.vue_vue_type_script_setup_true_lang.86a761e5.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{L as t}from"./Logo.a483cebb.js";import{d as n,o as r,a as d,u as i}from"./jwt-decode.esm.f18c394f.js";(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},s=new Error().stack;s&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[s]="1464add3-6466-4255-9773-5b7b5fa4d62b",e._sentryDebugIdIdentifier="sentry-dbid-1464add3-6466-4255-9773-5b7b5fa4d62b")}catch{}})();const f="/assets/logo.0faadfa2.svg",u=n({__name:"AbstraLogo",props:{hideText:{type:Boolean},size:{}},setup(e){return(s,a)=>{var o;return r(),d(t,{"image-url":i(f),"brand-name":"Abstra","hide-text":s.hideText,size:(o=s.size)!=null?o:"small"},null,8,["image-url","hide-text","size"])}}});export{u as _};
|
|
2
|
+
//# sourceMappingURL=AbstraLogo.vue_vue_type_script_setup_true_lang.d02ffa6d.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{C as w}from"./CrudView.01e6ed04.js";import{d as _,r as k,eb as x,c as v,a5 as C,f as l,u as i,b as d,aR as P,o as h,d9 as D,g as y,da as M,ed as j,M as N,ee as K,ep as T}from"./jwt-decode.esm.f18c394f.js";import{a as V}from"./asyncComputed.24fa122c.js";import{A as c}from"./apiKey.2481730b.js";import"./router.9924fce0.js";import{M as B}from"./member.d0ead44d.js";import{a as E}from"./project.d26f784f.js";import"./tables.4cd227ff.js";import"./DocsButton.vue_vue_type_script_setup_true_lang.3efd2188.js";import"./constants.4f491067.js";import"./url.f54a173c.js";import"./PhDotsThreeVertical.vue.82ed05fc.js";import"./index.9d0d77b2.js";import"./index.ee7c5f13.js";import"./record.f0e74f25.js";import"./string.c4805024.js";(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},a=new Error().stack;a&&(n._sentryDebugIds=n._sentryDebugIds||{},n._sentryDebugIds[a]="bc49802f-3b9e-4074-9103-e8f1f63731ea",n._sentryDebugIdIdentifier="sentry-dbid-bc49802f-3b9e-4074-9103-e8f1f63731ea")}catch{}})();const ee=_({__name:"ApiKeys",setup(n){const a=k(null),p=[{key:"name",label:"API key name"}],s=x().params.projectId,f=new B,{loading:g,result:b,refetch:u}=V(async()=>Promise.all([c.list(s),E.get(s).then(e=>f.list(e.organizationId))]).then(([e,t])=>e.map(o=>({apiKey:o,member:t.find(r=>r.authorId===o.ownerId)})))),I=async e=>{const t=await c.create({projectId:s,name:e.name});u(),a.value=t.value},A=v(()=>{var e,t;return{columns:[{title:"Name"},{title:"Creation date"},{title:"Owner"},{title:"",align:"right"}],rows:(t=(e=b.value)==null?void 0:e.map(({apiKey:o,member:r})=>{var m;return{key:o.id,cells:[{type:"text",text:o.name},{type:"text",text:K(o.createdAt)},{type:"text",text:(m=r==null?void 0:r.email)!=null?m:"Unknown"},{type:"actions",actions:[{label:"Delete",icon:T,dangerous:!0,onClick:async()=>{await c.delete(s,o.id),u()}}]}]}}))!=null?t:[]}});return(e,t)=>(h(),C(P,null,[l(w,{"entity-name":"API key","create-button-text":"Create API Key",loading:i(g),title:"API Keys",description:"API Keys are used to deploy your project from the local editor.","empty-title":"No API keys here yet",table:A.value,fields:p,create:I},null,8,["loading","table"]),l(i(N),{open:!!a.value,title:"Api key generated",onCancel:t[0]||(t[0]=o=>a.value=null)},{footer:d(()=>[]),default:d(()=>[l(i(D),null,{default:d(()=>[y("Your API key was successfully generated. Use this code to login on your local development environment or deploy using CI")]),_:1}),l(i(M),{code:"",copyable:""},{default:d(()=>[y(j(a.value),1)]),_:1})]),_:1},8,["open"])],64))}});export{ee as default};
|
|
2
|
+
//# sourceMappingURL=ApiKeys.e132de0a.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"./App.vue_vue_type_style_index_0_lang.9dc1f7e7.js";import{_ as m}from"./App.vue_vue_type_style_index_0_lang.9dc1f7e7.js";import"./userStore.1345e655.js";import"./jwt-decode.esm.f18c394f.js";import"./PlayerConfigProvider.608f994d.js";import"./colorHelpers.a41e45a3.js";import"./workspaceStore.29138ee5.js";import"./url.f54a173c.js";(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},t=new Error().stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="ce721ac9-1dbf-407b-acbf-056f63d3cb82",e._sentryDebugIdIdentifier="sentry-dbid-ce721ac9-1dbf-407b-acbf-056f63d3cb82")}catch{}})();export{m as default};
|
|
2
|
+
//# sourceMappingURL=App.9aa34c4e.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as r}from"./userStore.1345e655.js";import{W as n}from"./PlayerConfigProvider.608f994d.js";import{u as c}from"./workspaceStore.29138ee5.js";import{d as f,w as i,m as p,u as o,a as u,b as d,h as l,o as m,f as _}from"./jwt-decode.esm.f18c394f.js";(function(){try{var t=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},a=new Error().stack;a&&(t._sentryDebugIds=t._sentryDebugIds||{},t._sentryDebugIds[a]="57e1579c-ccfa-42fc-a5e7-82b3124cee01",t._sentryDebugIdIdentifier="sentry-dbid-57e1579c-ccfa-42fc-a5e7-82b3124cee01")}catch{}})();const v=f({__name:"App",setup(t){const a=r(),e=c();return e.actions.fetch(),i(()=>a.jwt,e.actions.fetch),(w,y)=>{const s=p("RouterView");return o(e).state.workspace?(m(),u(n,{key:0,"main-color":o(e).state.workspace.mainColor,background:o(e).state.workspace.theme,"font-family":o(e).state.workspace.fontFamily,locale:o(e).state.workspace.language},{default:d(()=>[_(s,{style:{height:"100vh",width:"100%"}})]),_:1},8,["main-color","background","font-family","locale"])):l("",!0)}}});export{v as _};
|
|
2
|
+
//# sourceMappingURL=App.vue_vue_type_style_index_0_lang.9dc1f7e7.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{_ as c,o,a5 as n,a7 as s,e as d,h as a}from"./jwt-decode.esm.f18c394f.js";(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},t=new Error().stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="b879e53c-8b51-4f2e-9cb4-33a0c4919f71",e._sentryDebugIdIdentifier="sentry-dbid-b879e53c-8b51-4f2e-9cb4-33a0c4919f71")}catch{}})();const r={},i={class:"base-layout"},_={class:"base-middle"},f={class:"content"},l={class:"left"},u={key:0,class:"base-footer"},b={key:0};function y(e,t){return o(),n("div",i,[s(e.$slots,"sidebar",{},void 0,!0),d("section",_,[s(e.$slots,"navbar",{},void 0,!0),d("section",f,[d("section",l,[s(e.$slots,"content",{},void 0,!0),e.$slots.footer?(o(),n("section",u,[s(e.$slots,"footer",{},void 0,!0)])):a("",!0)]),e.$slots.chat?(o(),n("section",b,[s(e.$slots,"chat",{},void 0,!0)])):a("",!0)])])])}const g=c(r,[["render",y],["__scopeId","data-v-da85ecdc"]]);export{g as B};
|
|
2
|
+
//# sourceMappingURL=BaseLayout.d41dae76.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as _}from"./asyncComputed.24fa122c.js";import{d as w,eb as b,k as h,u as e,a as d,a5 as k,f as o,b as t,h as I,o as n,A as f,g as c,ed as C,bR as x,de as l,e as N}from"./jwt-decode.esm.f18c394f.js";import{l as g,c as v}from"./router.9924fce0.js";import{a as z}from"./organization.c20116a5.js";import"./tables.4cd227ff.js";import{L as B}from"./LoadingContainer.4d7a6e83.js";import"./index.ee7c5f13.js";import"./record.f0e74f25.js";import"./string.c4805024.js";(function(){try{var a=typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},s=new Error().stack;s&&(a._sentryDebugIds=a._sentryDebugIds||{},a._sentryDebugIds[s]="e450c0c7-a08f-4f11-97d4-04eb384cdcc3",a._sentryDebugIdIdentifier="sentry-dbid-e450c0c7-a08f-4f11-97d4-04eb384cdcc3")}catch{}})();const D={key:1},U=["src"],O=w({__name:"Billing",setup(a){const u=b().params.organizationId,{loading:m,result:r}=_(async()=>{const i=await z.get(u),p=await i.getUsageReportUrl();return{organization:i,reportUrl:p}});h(()=>{location.search.includes("upgrade")&&g.showNewMessage("I want to upgrade my plan")});const y=()=>g.showNewMessage("I want to upgrade my plan");return(i,p)=>e(m)?(n(),d(B,{key:0})):e(r)?(n(),k("div",D,[o(e(l),{justify:"space-between",align:"center"},{default:t(()=>[o(e(f),{level:3},{default:t(()=>[c("Current plan: "+C(e(r).organization.coalescedPlan),1)]),_:1}),o(e(x),{type:"primary",onClick:y},{default:t(()=>[c("Upgrade")]),_:1})]),_:1}),o(e(v),{style:{"margin-top":"0"}}),e(r).organization.hasUsageReport?(n(),d(e(l),{key:0,align:"center",justify:"center"},{default:t(()=>[N("iframe",{src:e(r).reportUrl,frameborder:"0",style:{width:"1000px",height:"1700px"}},null,8,U)]),_:1})):(n(),d(e(l),{key:1,align:"center",justify:"center"},{default:t(()=>[o(e(f),{level:4},{default:t(()=>[c("No usage report available")]),_:1})]),_:1}))])):I("",!0)}});export{O as default};
|
|
2
|
+
//# sourceMappingURL=Billing.04224d7b.js.map
|