Flowfile 0.4.1__py3-none-any.whl → 0.5.3__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.
- build_backends/main.py +25 -22
- build_backends/main_prd.py +10 -19
- flowfile/__init__.py +179 -73
- flowfile/__main__.py +10 -7
- flowfile/api.py +52 -59
- flowfile/web/__init__.py +14 -9
- flowfile/web/static/assets/AdminView-49392a9a.js +713 -0
- flowfile/web/static/assets/AdminView-f53bad23.css +129 -0
- flowfile/web/static/assets/CloudConnectionView-36bcd6df.css +72 -0
- flowfile/web/static/assets/{CloudConnectionManager-d3248f8d.js → CloudConnectionView-f13f202b.js} +11 -11
- flowfile/web/static/assets/{CloudStorageReader-d65bf041.js → CloudStorageReader-0023d4a5.js} +10 -8
- flowfile/web/static/assets/{CloudStorageReader-29d14fcc.css → CloudStorageReader-24c54524.css} +27 -27
- flowfile/web/static/assets/{CloudStorageWriter-b0ee067f.css → CloudStorageWriter-60547855.css} +26 -26
- flowfile/web/static/assets/{CloudStorageWriter-e83be3ed.js → CloudStorageWriter-8e781e11.js} +10 -8
- flowfile/web/static/assets/{ColumnSelector-47996a16.css → ColumnSelector-371637fb.css} +2 -2
- flowfile/web/static/assets/{ColumnSelector-cce661cf.js → ColumnSelector-8ad68ea9.js} +3 -5
- flowfile/web/static/assets/{ContextMenu-c13f91d0.css → ContextMenu-26d4dd27.css} +6 -6
- flowfile/web/static/assets/{ContextMenu-11a4652a.js → ContextMenu-31ee57f0.js} +3 -3
- flowfile/web/static/assets/{ContextMenu-160afb08.js → ContextMenu-69a74055.js} +3 -3
- flowfile/web/static/assets/{ContextMenu-cf18d2cc.js → ContextMenu-8e2051c6.js} +3 -3
- flowfile/web/static/assets/{ContextMenu-4c74eef1.css → ContextMenu-8ec1729e.css} +6 -6
- flowfile/web/static/assets/{ContextMenu-63cfa99b.css → ContextMenu-9b310c60.css} +6 -6
- flowfile/web/static/assets/{CrossJoin-d395d38c.js → CrossJoin-03df6938.js} +12 -10
- flowfile/web/static/assets/{CrossJoin-1119d18e.css → CrossJoin-71b4cc10.css} +20 -20
- flowfile/web/static/assets/CustomNode-59e99a86.css +32 -0
- flowfile/web/static/assets/{CustomNode-b812dc0b.js → CustomNode-8479239b.js} +36 -24
- flowfile/web/static/assets/{DatabaseConnectionSettings-7000bf2c.js → DatabaseConnectionSettings-869e3efd.js} +5 -4
- flowfile/web/static/assets/{DatabaseConnectionSettings-0c04b2e5.css → DatabaseConnectionSettings-e91df89a.css} +13 -13
- flowfile/web/static/assets/{DatabaseReader-ae61773c.css → DatabaseReader-36898a00.css} +24 -24
- flowfile/web/static/assets/{DatabaseReader-4f035d0c.js → DatabaseReader-c58b9552.js} +25 -15
- flowfile/web/static/assets/DatabaseView-6655afd6.css +57 -0
- flowfile/web/static/assets/{DatabaseManager-9662ec5b.js → DatabaseView-d26a9140.js} +11 -11
- flowfile/web/static/assets/{DatabaseWriter-2f570e53.css → DatabaseWriter-217a99f1.css} +19 -19
- flowfile/web/static/assets/{DatabaseWriter-f65dcd54.js → DatabaseWriter-4d05ddc7.js} +17 -10
- flowfile/web/static/assets/{designer-e3c150ec.css → DesignerView-a6d0ee84.css} +629 -538
- flowfile/web/static/assets/{designer-f3656d8c.js → DesignerView-e6f5c0e8.js} +1214 -3209
- flowfile/web/static/assets/{documentation-52b241e7.js → DocumentationView-2e78ef1b.js} +5 -5
- flowfile/web/static/assets/{documentation-12216a74.css → DocumentationView-fd46c656.css} +7 -7
- flowfile/web/static/assets/{ExploreData-2d0cf4db.css → ExploreData-10c5acc8.css} +13 -12
- flowfile/web/static/assets/{ExploreData-94c43dfc.js → ExploreData-7b54caca.js} +18 -9
- flowfile/web/static/assets/{ExternalSource-ac04b3cc.js → ExternalSource-3fa399b2.js} +9 -7
- flowfile/web/static/assets/{ExternalSource-e37b6275.css → ExternalSource-47ab05a3.css} +17 -17
- flowfile/web/static/assets/Filter-7494ea97.css +48 -0
- flowfile/web/static/assets/Filter-8cbbdbf3.js +287 -0
- flowfile/web/static/assets/{Formula-bb96803d.css → Formula-53d58c43.css} +7 -7
- flowfile/web/static/assets/{Formula-71472193.js → Formula-aac42b1e.js} +13 -11
- flowfile/web/static/assets/{FuzzyMatch-1010f966.css → FuzzyMatch-ad6361d6.css} +68 -69
- flowfile/web/static/assets/{FuzzyMatch-b317f631.js → FuzzyMatch-cd9bbfca.js} +12 -10
- flowfile/web/static/assets/{Pivot-cf333e3d.css → GraphSolver-c24dec17.css} +5 -5
- flowfile/web/static/assets/{GraphSolver-754a234f.js → GraphSolver-c7e6780e.js} +13 -11
- flowfile/web/static/assets/{GroupBy-6c6f9802.js → GroupBy-93c5d22b.js} +9 -7
- flowfile/web/static/assets/{GroupBy-b9505323.css → GroupBy-be7ac0bf.css} +10 -10
- flowfile/web/static/assets/{Join-fd79b451.css → Join-28b5e18f.css} +22 -22
- flowfile/web/static/assets/{Join-a1b800be.js → Join-a19b2de2.js} +13 -11
- flowfile/web/static/assets/LoginView-0df4ed0a.js +134 -0
- flowfile/web/static/assets/LoginView-d325d632.css +172 -0
- flowfile/web/static/assets/ManualInput-3702e677.css +293 -0
- flowfile/web/static/assets/{ManualInput-a9640276.js → ManualInput-8d3374b2.js} +170 -116
- flowfile/web/static/assets/{MultiSelect-97213888.js → MultiSelect-ad1b6243.js} +2 -2
- flowfile/web/static/assets/{MultiSelect.vue_vue_type_script_setup_true_lang-6ffe088a.js → MultiSelect.vue_vue_type_script_setup_true_lang-e278950d.js} +1 -1
- flowfile/web/static/assets/NodeDesigner-40b647c9.js +2610 -0
- flowfile/web/static/assets/NodeDesigner-5f53be3f.css +1429 -0
- flowfile/web/static/assets/{NumericInput-e638088a.js → NumericInput-7100234c.js} +2 -2
- flowfile/web/static/assets/{NumericInput.vue_vue_type_script_setup_true_lang-90eb2cba.js → NumericInput.vue_vue_type_script_setup_true_lang-5130219f.js} +5 -2
- flowfile/web/static/assets/{Output-ddc9079f.css → Output-35e97000.css} +6 -6
- flowfile/web/static/assets/{Output-76750610.js → Output-f5efd2aa.js} +60 -38
- flowfile/web/static/assets/{GraphSolver-f0cb7bfb.css → Pivot-0eda81b4.css} +5 -5
- flowfile/web/static/assets/{Pivot-7814803f.js → Pivot-d981d23c.js} +11 -9
- flowfile/web/static/assets/PivotValidation-0e905b1a.css +13 -0
- flowfile/web/static/assets/{PivotValidation-f92137d2.js → PivotValidation-39386e95.js} +3 -3
- flowfile/web/static/assets/PivotValidation-41b57ad6.css +13 -0
- flowfile/web/static/assets/{PivotValidation-76dd431a.js → PivotValidation-63de1f73.js} +3 -3
- flowfile/web/static/assets/{PolarsCode-650322d1.css → PolarsCode-2b1f1f23.css} +4 -4
- flowfile/web/static/assets/{PolarsCode-889c3008.js → PolarsCode-f9d69217.js} +18 -9
- flowfile/web/static/assets/PopOver-b22f049e.js +939 -0
- flowfile/web/static/assets/PopOver-d96599db.css +33 -0
- flowfile/web/static/assets/{Read-6b17491f.css → Read-36e7bd51.css} +12 -12
- flowfile/web/static/assets/{Read-637b72a7.js → Read-aec2e377.js} +83 -105
- flowfile/web/static/assets/{RecordCount-2b050c41.js → RecordCount-78ed6845.js} +6 -4
- flowfile/web/static/assets/{RecordId-81df7784.js → RecordId-2156e890.js} +8 -6
- flowfile/web/static/assets/{SQLQueryComponent-36cef432.css → SQLQueryComponent-1c2f26b4.css} +5 -5
- flowfile/web/static/assets/{SQLQueryComponent-88dcfe53.js → SQLQueryComponent-48c72f5b.js} +3 -3
- flowfile/web/static/assets/{Sample-258ad2a9.js → Sample-1352ca74.js} +6 -4
- flowfile/web/static/assets/SecretSelector-22b5ff89.js +113 -0
- flowfile/web/static/assets/SecretSelector-6329f743.css +43 -0
- flowfile/web/static/assets/{SecretManager-2a2cb7e2.js → SecretsView-17df66ee.js} +35 -36
- flowfile/web/static/assets/SecretsView-aa291340.css +38 -0
- flowfile/web/static/assets/{Select-850215fd.js → Select-0aee4c54.js} +9 -7
- flowfile/web/static/assets/{SettingsSection-55bae608.js → SettingsSection-0784e157.js} +3 -3
- flowfile/web/static/assets/{SettingsSection-71e6b7e3.css → SettingsSection-07fbbc39.css} +4 -4
- flowfile/web/static/assets/{SettingsSection-5c696bee.css → SettingsSection-26fe48d4.css} +4 -4
- flowfile/web/static/assets/{SettingsSection-2e4d03c4.css → SettingsSection-8f980839.css} +4 -4
- flowfile/web/static/assets/{SettingsSection-0e8d9123.js → SettingsSection-cd341bb6.js} +3 -3
- flowfile/web/static/assets/{SettingsSection-29b4fa6b.js → SettingsSection-f2002a6d.js} +3 -3
- flowfile/web/static/assets/{SingleSelect-bebd408b.js → SingleSelect-460cc0ea.js} +2 -2
- flowfile/web/static/assets/{SingleSelect.vue_vue_type_script_setup_true_lang-6093741c.js → SingleSelect.vue_vue_type_script_setup_true_lang-30741bb2.js} +1 -1
- flowfile/web/static/assets/{SliderInput-6a05ab61.js → SliderInput-5d926864.js} +7 -4
- flowfile/web/static/assets/SliderInput-f2e4f23c.css +4 -0
- flowfile/web/static/assets/{Sort-10ab48ed.js → Sort-3cdc971b.js} +9 -7
- flowfile/web/static/assets/{Unique-f9fb0809.css → Sort-8a871341.css} +10 -10
- flowfile/web/static/assets/{TextInput-df9d6259.js → TextInput-a2d0bfbd.js} +2 -2
- flowfile/web/static/assets/{TextInput.vue_vue_type_script_setup_true_lang-000e1178.js → TextInput.vue_vue_type_script_setup_true_lang-abad1ca2.js} +5 -2
- flowfile/web/static/assets/{TextToRows-5d2c1190.css → TextToRows-12afb4f4.css} +10 -10
- flowfile/web/static/assets/{TextToRows-6c2d93d8.js → TextToRows-918945f7.js} +11 -10
- flowfile/web/static/assets/{ToggleSwitch-0ff7ac52.js → ToggleSwitch-f0ef5196.js} +2 -2
- flowfile/web/static/assets/{ToggleSwitch.vue_vue_type_script_setup_true_lang-c6dc3029.js → ToggleSwitch.vue_vue_type_script_setup_true_lang-5605c793.js} +1 -1
- flowfile/web/static/assets/{UnavailableFields-5edd5322.css → UnavailableFields-54d2f518.css} +6 -6
- flowfile/web/static/assets/{UnavailableFields-1bab97cb.js → UnavailableFields-bdad6144.js} +4 -4
- flowfile/web/static/assets/{Union-af6c3d9b.css → Union-d6a8d7d5.css} +7 -7
- flowfile/web/static/assets/{Union-b563478a.js → Union-e8ab8c86.js} +8 -6
- flowfile/web/static/assets/{Unique-f90db5db.js → Unique-8cd4f976.js} +13 -22
- flowfile/web/static/assets/{Sort-3643d625.css → Unique-9fb2f567.css} +10 -10
- flowfile/web/static/assets/{Unpivot-1e422df3.css → Unpivot-710a2948.css} +7 -7
- flowfile/web/static/assets/{Unpivot-bcb0025f.js → Unpivot-8da14095.js} +10 -8
- flowfile/web/static/assets/{UnpivotValidation-c4e73b04.js → UnpivotValidation-6f7d89ff.js} +3 -3
- flowfile/web/static/assets/UnpivotValidation-d5ca3b7b.css +13 -0
- flowfile/web/static/assets/{VueGraphicWalker-bb8535e2.js → VueGraphicWalker-3fb312e1.js} +4 -4
- flowfile/web/static/assets/{VueGraphicWalker-ed5ab88b.css → VueGraphicWalker-430f0b86.css} +1 -1
- flowfile/web/static/assets/{api-4c8e3822.js → api-24483f0d.js} +1 -1
- flowfile/web/static/assets/{api-2d6adc4f.js → api-8b81fa73.js} +1 -1
- flowfile/web/static/assets/{dropDown-35135ba8.css → dropDown-3d8dc5fa.css} +40 -40
- flowfile/web/static/assets/{dropDown-1bca8a74.js → dropDown-ac0fda9d.js} +3 -3
- flowfile/web/static/assets/{fullEditor-2985687e.js → fullEditor-5497a84a.js} +11 -10
- flowfile/web/static/assets/{fullEditor-178376bb.css → fullEditor-a0be62b3.css} +74 -62
- flowfile/web/static/assets/{genericNodeSettings-924759c7.css → genericNodeSettings-3b2507ea.css} +10 -10
- flowfile/web/static/assets/{genericNodeSettings-0476ba4e.js → genericNodeSettings-99014e1d.js} +5 -5
- flowfile/web/static/assets/index-07dda503.js +38 -0
- flowfile/web/static/assets/index-3ba44389.js +2696 -0
- flowfile/web/static/assets/{index-50508d4d.css → index-e6289dd0.css} +1945 -569
- flowfile/web/static/assets/{index-246f201c.js → index-fb6493ae.js} +41626 -40869
- flowfile/web/static/assets/node.types-2c15bb7e.js +82 -0
- flowfile/web/static/assets/nodeInput-0eb13f1a.js +2 -0
- flowfile/web/static/assets/{outputCsv-d686eeaf.js → outputCsv-8f8ba42d.js} +3 -3
- flowfile/web/static/assets/outputCsv-b9a072af.css +2499 -0
- flowfile/web/static/assets/{outputExcel-8809ea2f.js → outputExcel-393f4fef.js} +3 -3
- flowfile/web/static/assets/{outputExcel-b41305c0.css → outputExcel-f5d272b2.css} +26 -26
- flowfile/web/static/assets/{outputParquet-53ba645a.js → outputParquet-07c81f65.js} +4 -4
- flowfile/web/static/assets/outputParquet-54597c3c.css +4 -0
- flowfile/web/static/assets/{readCsv-053bf97b.js → readCsv-07f6d9ad.js} +21 -20
- flowfile/web/static/assets/{readCsv-bca3ed53.css → readCsv-3bfac4c3.css} +15 -15
- flowfile/web/static/assets/{readExcel-e1b381ea.css → readExcel-3db6b763.css} +13 -13
- flowfile/web/static/assets/{readExcel-ad531eab.js → readExcel-ed69bc8f.js} +10 -12
- flowfile/web/static/assets/{readParquet-cee068e2.css → readParquet-c5244ad5.css} +4 -4
- flowfile/web/static/assets/{readParquet-58e899a1.js → readParquet-e3ed4528.js} +4 -7
- flowfile/web/static/assets/secrets.api-002e7d7e.js +65 -0
- flowfile/web/static/assets/{selectDynamic-b38de2ba.js → selectDynamic-80b92899.js} +5 -5
- flowfile/web/static/assets/{selectDynamic-aa913ff4.css → selectDynamic-f2fb394f.css} +21 -20
- flowfile/web/static/assets/{vue-codemirror.esm-db9b8936.js → vue-codemirror.esm-0965f39f.js} +31 -637
- flowfile/web/static/assets/{vue-content-loader.es-b5f3ac30.js → vue-content-loader.es-c506ad97.js} +1 -1
- flowfile/web/static/index.html +2 -2
- {flowfile-0.4.1.dist-info → flowfile-0.5.3.dist-info}/METADATA +4 -4
- flowfile-0.5.3.dist-info/RECORD +402 -0
- {flowfile-0.4.1.dist-info → flowfile-0.5.3.dist-info}/WHEEL +1 -1
- {flowfile-0.4.1.dist-info → flowfile-0.5.3.dist-info}/entry_points.txt +1 -0
- flowfile_core/__init__.py +13 -3
- flowfile_core/auth/jwt.py +51 -16
- flowfile_core/auth/models.py +32 -7
- flowfile_core/auth/password.py +89 -0
- flowfile_core/auth/secrets.py +8 -6
- flowfile_core/configs/__init__.py +9 -7
- flowfile_core/configs/flow_logger.py +15 -14
- flowfile_core/configs/node_store/__init__.py +72 -4
- flowfile_core/configs/node_store/nodes.py +155 -172
- flowfile_core/configs/node_store/user_defined_node_registry.py +108 -27
- flowfile_core/configs/settings.py +28 -15
- flowfile_core/database/connection.py +7 -6
- flowfile_core/database/init_db.py +96 -2
- flowfile_core/database/models.py +3 -1
- flowfile_core/fileExplorer/__init__.py +17 -0
- flowfile_core/fileExplorer/funcs.py +123 -57
- flowfile_core/fileExplorer/utils.py +10 -11
- flowfile_core/flowfile/_extensions/real_time_interface.py +10 -8
- flowfile_core/flowfile/analytics/analytics_processor.py +27 -24
- flowfile_core/flowfile/analytics/graphic_walker.py +11 -12
- flowfile_core/flowfile/analytics/utils.py +1 -1
- flowfile_core/flowfile/code_generator/code_generator.py +391 -279
- flowfile_core/flowfile/connection_manager/_connection_manager.py +6 -5
- flowfile_core/flowfile/connection_manager/models.py +1 -1
- flowfile_core/flowfile/database_connection_manager/db_connections.py +60 -44
- flowfile_core/flowfile/database_connection_manager/models.py +1 -1
- flowfile_core/flowfile/extensions.py +17 -12
- flowfile_core/flowfile/flow_data_engine/cloud_storage_reader.py +34 -32
- flowfile_core/flowfile/flow_data_engine/create/funcs.py +152 -103
- flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +526 -477
- flowfile_core/flowfile/flow_data_engine/flow_file_column/interface.py +2 -2
- flowfile_core/flowfile/flow_data_engine/flow_file_column/main.py +92 -52
- flowfile_core/flowfile/flow_data_engine/flow_file_column/polars_type.py +12 -11
- flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +6 -6
- flowfile_core/flowfile/flow_data_engine/flow_file_column/utils.py +26 -30
- flowfile_core/flowfile/flow_data_engine/fuzzy_matching/prepare_for_fuzzy_match.py +43 -32
- flowfile_core/flowfile/flow_data_engine/join/__init__.py +1 -1
- flowfile_core/flowfile/flow_data_engine/join/utils.py +11 -9
- flowfile_core/flowfile/flow_data_engine/join/verify_integrity.py +15 -11
- flowfile_core/flowfile/flow_data_engine/pivot_table.py +5 -7
- flowfile_core/flowfile/flow_data_engine/polars_code_parser.py +95 -82
- flowfile_core/flowfile/flow_data_engine/read_excel_tables.py +66 -65
- flowfile_core/flowfile/flow_data_engine/sample_data.py +27 -21
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/__init__.py +1 -1
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/models.py +13 -11
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +360 -191
- flowfile_core/flowfile/flow_data_engine/threaded_processes.py +8 -8
- flowfile_core/flowfile/flow_data_engine/utils.py +101 -67
- flowfile_core/flowfile/flow_graph.py +1011 -561
- flowfile_core/flowfile/flow_graph_utils.py +31 -49
- flowfile_core/flowfile/flow_node/flow_node.py +332 -232
- flowfile_core/flowfile/flow_node/models.py +54 -41
- flowfile_core/flowfile/flow_node/schema_callback.py +14 -19
- flowfile_core/flowfile/graph_tree/graph_tree.py +41 -41
- flowfile_core/flowfile/handler.py +82 -32
- flowfile_core/flowfile/manage/compatibility_enhancements.py +493 -47
- flowfile_core/flowfile/manage/io_flowfile.py +391 -0
- flowfile_core/flowfile/node_designer/__init__.py +15 -13
- flowfile_core/flowfile/node_designer/_type_registry.py +34 -37
- flowfile_core/flowfile/node_designer/custom_node.py +162 -36
- flowfile_core/flowfile/node_designer/ui_components.py +136 -35
- flowfile_core/flowfile/schema_callbacks.py +77 -54
- flowfile_core/flowfile/setting_generator/__init__.py +0 -1
- flowfile_core/flowfile/setting_generator/setting_generator.py +6 -5
- flowfile_core/flowfile/setting_generator/settings.py +72 -55
- flowfile_core/flowfile/sources/external_sources/base_class.py +12 -10
- flowfile_core/flowfile/sources/external_sources/custom_external_sources/external_source.py +27 -17
- flowfile_core/flowfile/sources/external_sources/custom_external_sources/sample_users.py +9 -9
- flowfile_core/flowfile/sources/external_sources/factory.py +0 -1
- flowfile_core/flowfile/sources/external_sources/sql_source/models.py +45 -31
- flowfile_core/flowfile/sources/external_sources/sql_source/sql_source.py +198 -73
- flowfile_core/flowfile/sources/external_sources/sql_source/utils.py +250 -196
- flowfile_core/flowfile/util/calculate_layout.py +9 -13
- flowfile_core/flowfile/util/execution_orderer.py +25 -17
- flowfile_core/flowfile/util/node_skipper.py +4 -4
- flowfile_core/flowfile/utils.py +19 -21
- flowfile_core/main.py +26 -19
- flowfile_core/routes/auth.py +284 -11
- flowfile_core/routes/cloud_connections.py +25 -25
- flowfile_core/routes/logs.py +21 -29
- flowfile_core/routes/public.py +3 -3
- flowfile_core/routes/routes.py +77 -43
- flowfile_core/routes/secrets.py +25 -27
- flowfile_core/routes/user_defined_components.py +483 -4
- flowfile_core/run_lock.py +0 -1
- flowfile_core/schemas/__init__.py +4 -6
- flowfile_core/schemas/analysis_schemas/graphic_walker_schemas.py +55 -55
- flowfile_core/schemas/cloud_storage_schemas.py +59 -55
- flowfile_core/schemas/input_schema.py +398 -154
- flowfile_core/schemas/output_model.py +50 -35
- flowfile_core/schemas/schemas.py +207 -67
- flowfile_core/schemas/transform_schema.py +1360 -435
- flowfile_core/schemas/yaml_types.py +117 -0
- flowfile_core/secret_manager/secret_manager.py +17 -13
- flowfile_core/{flowfile/node_designer/data_types.py → types.py} +33 -3
- flowfile_core/utils/arrow_reader.py +7 -6
- flowfile_core/utils/excel_file_manager.py +3 -3
- flowfile_core/utils/fileManager.py +7 -7
- flowfile_core/utils/fl_executor.py +8 -10
- flowfile_core/utils/utils.py +4 -4
- flowfile_core/utils/validate_setup.py +5 -4
- flowfile_frame/__init__.py +107 -50
- flowfile_frame/adapters.py +2 -9
- flowfile_frame/adding_expr.py +73 -32
- flowfile_frame/cloud_storage/frame_helpers.py +27 -23
- flowfile_frame/cloud_storage/secret_manager.py +12 -26
- flowfile_frame/config.py +2 -5
- flowfile_frame/expr.py +311 -218
- flowfile_frame/expr.pyi +160 -159
- flowfile_frame/expr_name.py +23 -23
- flowfile_frame/flow_frame.py +581 -489
- flowfile_frame/flow_frame.pyi +123 -104
- flowfile_frame/flow_frame_methods.py +236 -252
- flowfile_frame/group_frame.py +50 -20
- flowfile_frame/join.py +2 -2
- flowfile_frame/lazy.py +129 -87
- flowfile_frame/lazy_methods.py +83 -30
- flowfile_frame/list_name_space.py +55 -50
- flowfile_frame/selectors.py +148 -68
- flowfile_frame/series.py +9 -7
- flowfile_frame/utils.py +19 -21
- flowfile_worker/__init__.py +12 -4
- flowfile_worker/configs.py +11 -19
- flowfile_worker/create/__init__.py +14 -27
- flowfile_worker/create/funcs.py +143 -94
- flowfile_worker/create/models.py +139 -68
- flowfile_worker/create/pl_types.py +14 -15
- flowfile_worker/create/read_excel_tables.py +34 -41
- flowfile_worker/create/utils.py +22 -19
- flowfile_worker/external_sources/s3_source/main.py +18 -51
- flowfile_worker/external_sources/s3_source/models.py +34 -27
- flowfile_worker/external_sources/sql_source/main.py +8 -5
- flowfile_worker/external_sources/sql_source/models.py +13 -9
- flowfile_worker/flow_logger.py +10 -8
- flowfile_worker/funcs.py +214 -155
- flowfile_worker/main.py +11 -17
- flowfile_worker/models.py +35 -28
- flowfile_worker/process_manager.py +2 -3
- flowfile_worker/routes.py +121 -93
- flowfile_worker/secrets.py +9 -6
- flowfile_worker/spawner.py +80 -49
- flowfile_worker/utils.py +3 -2
- shared/__init__.py +2 -7
- shared/storage_config.py +25 -13
- test_utils/postgres/commands.py +3 -2
- test_utils/postgres/fixtures.py +9 -9
- test_utils/s3/commands.py +1 -1
- test_utils/s3/data_generator.py +3 -4
- test_utils/s3/demo_data_generator.py +4 -7
- test_utils/s3/fixtures.py +7 -5
- tools/migrate/README.md +56 -0
- tools/migrate/__init__.py +12 -0
- tools/migrate/__main__.py +118 -0
- tools/migrate/legacy_schemas.py +682 -0
- tools/migrate/migrate.py +610 -0
- tools/migrate/tests/__init__.py +0 -0
- tools/migrate/tests/conftest.py +21 -0
- tools/migrate/tests/test_migrate.py +622 -0
- tools/migrate/tests/test_migration_e2e.py +1009 -0
- tools/migrate/tests/test_node_migrations.py +843 -0
- flowfile/web/static/assets/CloudConnectionManager-2dfdce2f.css +0 -86
- flowfile/web/static/assets/CustomNode-74a37f74.css +0 -32
- flowfile/web/static/assets/DatabaseManager-30fa27e5.css +0 -64
- flowfile/web/static/assets/Filter-812dcbca.js +0 -164
- flowfile/web/static/assets/Filter-f62091b3.css +0 -20
- flowfile/web/static/assets/ManualInput-3246a08d.css +0 -96
- flowfile/web/static/assets/PivotValidation-891ddfb0.css +0 -13
- flowfile/web/static/assets/PivotValidation-c46cd420.css +0 -13
- flowfile/web/static/assets/SliderInput-b8fb6a8c.css +0 -4
- flowfile/web/static/assets/UnpivotValidation-0d240eeb.css +0 -13
- flowfile/web/static/assets/outputCsv-9cc59e0b.css +0 -2499
- flowfile/web/static/assets/outputParquet-cf8cf3f2.css +0 -4
- flowfile/web/static/assets/secretApi-538058f3.js +0 -46
- flowfile/web/static/assets/vue-codemirror-bccfde04.css +0 -32
- flowfile-0.4.1.dist-info/RECORD +0 -376
- flowfile_core/flowfile/manage/open_flowfile.py +0 -143
- {flowfile-0.4.1.dist-info → flowfile-0.5.3.dist-info}/licenses/LICENSE +0 -0
- /flowfile_core/flowfile/manage/manage_flowfile.py → /tools/__init__.py +0 -0
|
@@ -1,47 +1,52 @@
|
|
|
1
|
-
from typing import List, Dict, Optional, Any, Literal
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
3
|
-
from datetime import datetime
|
|
4
1
|
import time
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Any, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class NodeResult(BaseModel):
|
|
8
9
|
"""Represents the execution result of a single node in a FlowGraph run."""
|
|
10
|
+
|
|
9
11
|
node_id: int
|
|
10
|
-
node_name:
|
|
12
|
+
node_name: str | None = None
|
|
11
13
|
start_timestamp: float = Field(default_factory=time.time)
|
|
12
14
|
end_timestamp: float = 0
|
|
13
|
-
success:
|
|
14
|
-
error: str =
|
|
15
|
+
success: bool | None = None
|
|
16
|
+
error: str = ""
|
|
15
17
|
run_time: int = -1
|
|
16
18
|
is_running: bool = True
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class RunInformation(BaseModel):
|
|
20
22
|
"""Contains summary information about a complete FlowGraph execution."""
|
|
23
|
+
|
|
21
24
|
flow_id: int
|
|
22
|
-
start_time:
|
|
23
|
-
end_time:
|
|
24
|
-
success:
|
|
25
|
+
start_time: datetime | None = Field(default_factory=datetime.now)
|
|
26
|
+
end_time: datetime | None = None
|
|
27
|
+
success: bool | None = None
|
|
25
28
|
nodes_completed: int = 0
|
|
26
29
|
number_of_nodes: int = 0
|
|
27
|
-
node_step_result:
|
|
28
|
-
run_type: Literal["fetch_one", "full_run"]
|
|
30
|
+
node_step_result: list[NodeResult]
|
|
31
|
+
run_type: Literal["fetch_one", "full_run", "init"]
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
class BaseItem(BaseModel):
|
|
32
35
|
"""A base model for any item in a file system, like a file or directory."""
|
|
36
|
+
|
|
33
37
|
name: str
|
|
34
38
|
path: str
|
|
35
|
-
size:
|
|
36
|
-
creation_date:
|
|
37
|
-
access_date:
|
|
38
|
-
modification_date:
|
|
39
|
-
source_path:
|
|
39
|
+
size: int | None = None
|
|
40
|
+
creation_date: datetime | None = None
|
|
41
|
+
access_date: datetime | None = None
|
|
42
|
+
modification_date: datetime | None = None
|
|
43
|
+
source_path: str | None = None
|
|
40
44
|
number_of_items: int = -1
|
|
41
45
|
|
|
42
46
|
|
|
43
47
|
class FileColumn(BaseModel):
|
|
44
48
|
"""Represents detailed schema and statistics for a single column (field)."""
|
|
49
|
+
|
|
45
50
|
name: str
|
|
46
51
|
data_type: str
|
|
47
52
|
is_unique: bool
|
|
@@ -55,13 +60,14 @@ class FileColumn(BaseModel):
|
|
|
55
60
|
|
|
56
61
|
class TableExample(BaseModel):
|
|
57
62
|
"""Represents a preview of a table, including schema and sample data."""
|
|
63
|
+
|
|
58
64
|
node_id: int
|
|
59
65
|
number_of_records: int
|
|
60
66
|
number_of_columns: int
|
|
61
67
|
name: str
|
|
62
|
-
table_schema:
|
|
63
|
-
columns:
|
|
64
|
-
data:
|
|
68
|
+
table_schema: list[FileColumn]
|
|
69
|
+
columns: list[str]
|
|
70
|
+
data: list[dict] | None = {}
|
|
65
71
|
has_example_data: bool = False
|
|
66
72
|
has_run_with_current_setup: bool = False
|
|
67
73
|
|
|
@@ -71,15 +77,16 @@ class NodeData(BaseModel):
|
|
|
71
77
|
|
|
72
78
|
This includes its input/output data previews, settings, and run status.
|
|
73
79
|
"""
|
|
80
|
+
|
|
74
81
|
flow_id: int
|
|
75
82
|
node_id: int
|
|
76
83
|
flow_type: str
|
|
77
|
-
left_input:
|
|
78
|
-
right_input:
|
|
79
|
-
main_input:
|
|
80
|
-
main_output:
|
|
81
|
-
left_output:
|
|
82
|
-
right_output:
|
|
84
|
+
left_input: TableExample | None = None
|
|
85
|
+
right_input: TableExample | None = None
|
|
86
|
+
main_input: TableExample | None = None
|
|
87
|
+
main_output: TableExample | None = None
|
|
88
|
+
left_output: TableExample | None = None
|
|
89
|
+
right_output: TableExample | None = None
|
|
83
90
|
has_run: bool = False
|
|
84
91
|
is_cached: bool = False
|
|
85
92
|
setting_input: Any = None
|
|
@@ -87,22 +94,26 @@ class NodeData(BaseModel):
|
|
|
87
94
|
|
|
88
95
|
class OutputFile(BaseItem):
|
|
89
96
|
"""Represents a single file in an output directory, extending BaseItem."""
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
|
|
98
|
+
ext: str | None = None
|
|
99
|
+
mimetype: str | None = None
|
|
92
100
|
|
|
93
101
|
|
|
94
102
|
class OutputFiles(BaseItem):
|
|
95
103
|
"""Represents a collection of files, typically within a directory."""
|
|
96
|
-
|
|
104
|
+
|
|
105
|
+
files: list[OutputFile] = Field(default_factory=list)
|
|
97
106
|
|
|
98
107
|
|
|
99
108
|
class OutputTree(OutputFiles):
|
|
100
109
|
"""Represents a directory tree, including subdirectories."""
|
|
101
|
-
|
|
110
|
+
|
|
111
|
+
directories: list[OutputFiles] = Field(default_factory=list)
|
|
102
112
|
|
|
103
113
|
|
|
104
114
|
class ItemInfo(OutputFile):
|
|
105
115
|
"""Provides detailed information about a single item in an output directory."""
|
|
116
|
+
|
|
106
117
|
id: int = -1
|
|
107
118
|
type: str
|
|
108
119
|
analysis_file_available: bool = False
|
|
@@ -112,23 +123,27 @@ class ItemInfo(OutputFile):
|
|
|
112
123
|
|
|
113
124
|
class OutputDir(BaseItem):
|
|
114
125
|
"""Represents the contents of a single output directory."""
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
|
|
127
|
+
all_items: list[str]
|
|
128
|
+
items: list[ItemInfo]
|
|
117
129
|
|
|
118
130
|
|
|
119
131
|
class ExpressionRef(BaseModel):
|
|
120
132
|
"""A reference to a single Polars expression, including its name and docstring."""
|
|
133
|
+
|
|
121
134
|
name: str
|
|
122
|
-
doc:
|
|
135
|
+
doc: str | None
|
|
123
136
|
|
|
124
137
|
|
|
125
138
|
class ExpressionsOverview(BaseModel):
|
|
126
139
|
"""Represents a categorized list of available Polars expressions."""
|
|
140
|
+
|
|
127
141
|
expression_type: str
|
|
128
|
-
expressions:
|
|
142
|
+
expressions: list[ExpressionRef]
|
|
129
143
|
|
|
130
144
|
|
|
131
145
|
class InstantFuncResult(BaseModel):
|
|
132
146
|
"""Represents the result of a function that is expected to execute instantly."""
|
|
133
|
-
|
|
134
|
-
|
|
147
|
+
|
|
148
|
+
success: bool | None = None
|
|
149
|
+
result: str
|
flowfile_core/schemas/schemas.py
CHANGED
|
@@ -1,13 +1,51 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
|
|
3
|
-
from
|
|
1
|
+
from typing import Any, ClassVar, Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_serializer, field_validator
|
|
4
|
+
|
|
4
5
|
from flowfile_core.configs.settings import OFFLOAD_TO_WORKER
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
from flowfile_core.flowfile.utils import create_unique_id
|
|
7
|
+
from flowfile_core.schemas import input_schema
|
|
8
|
+
|
|
9
|
+
ExecutionModeLiteral = Literal["Development", "Performance"]
|
|
10
|
+
ExecutionLocationsLiteral = Literal["local", "remote"]
|
|
7
11
|
|
|
8
12
|
# Type literals for classifying nodes.
|
|
9
|
-
NodeTypeLiteral = Literal[
|
|
10
|
-
TransformTypeLiteral = Literal[
|
|
13
|
+
NodeTypeLiteral = Literal["input", "output", "process"]
|
|
14
|
+
TransformTypeLiteral = Literal["narrow", "wide", "other"]
|
|
15
|
+
_custom_node_store_cache = None
|
|
16
|
+
|
|
17
|
+
NODE_TYPE_TO_SETTINGS_CLASS = {
|
|
18
|
+
"manual_input": input_schema.NodeManualInput,
|
|
19
|
+
"filter": input_schema.NodeFilter,
|
|
20
|
+
"formula": input_schema.NodeFormula,
|
|
21
|
+
"select": input_schema.NodeSelect,
|
|
22
|
+
"sort": input_schema.NodeSort,
|
|
23
|
+
"record_id": input_schema.NodeRecordId,
|
|
24
|
+
"sample": input_schema.NodeSample,
|
|
25
|
+
"unique": input_schema.NodeUnique,
|
|
26
|
+
"group_by": input_schema.NodeGroupBy,
|
|
27
|
+
"pivot": input_schema.NodePivot,
|
|
28
|
+
"unpivot": input_schema.NodeUnpivot,
|
|
29
|
+
"text_to_rows": input_schema.NodeTextToRows,
|
|
30
|
+
"graph_solver": input_schema.NodeGraphSolver,
|
|
31
|
+
"polars_code": input_schema.NodePolarsCode,
|
|
32
|
+
"join": input_schema.NodeJoin,
|
|
33
|
+
"cross_join": input_schema.NodeCrossJoin,
|
|
34
|
+
"fuzzy_match": input_schema.NodeFuzzyMatch,
|
|
35
|
+
"record_count": input_schema.NodeRecordCount,
|
|
36
|
+
"explore_data": input_schema.NodeExploreData,
|
|
37
|
+
"union": input_schema.NodeUnion,
|
|
38
|
+
"output": input_schema.NodeOutput,
|
|
39
|
+
"read": input_schema.NodeRead,
|
|
40
|
+
"database_reader": input_schema.NodeDatabaseReader,
|
|
41
|
+
"database_writer": input_schema.NodeDatabaseWriter,
|
|
42
|
+
"cloud_storage_reader": input_schema.NodeCloudStorageReader,
|
|
43
|
+
"cloud_storage_writer": input_schema.NodeCloudStorageWriter,
|
|
44
|
+
"external_source": input_schema.NodeExternalSource,
|
|
45
|
+
"promise": input_schema.NodePromise,
|
|
46
|
+
"user_defined": input_schema.UserDefinedNode,
|
|
47
|
+
}
|
|
48
|
+
|
|
11
49
|
|
|
12
50
|
def get_global_execution_location() -> ExecutionLocationsLiteral:
|
|
13
51
|
"""
|
|
@@ -21,12 +59,33 @@ def get_global_execution_location() -> ExecutionLocationsLiteral:
|
|
|
21
59
|
return "local"
|
|
22
60
|
|
|
23
61
|
|
|
62
|
+
def _get_custom_node_store():
|
|
63
|
+
"""Lazy load CUSTOM_NODE_STORE once and cache it."""
|
|
64
|
+
global _custom_node_store_cache
|
|
65
|
+
if _custom_node_store_cache is None:
|
|
66
|
+
from flowfile_core.configs.node_store import CUSTOM_NODE_STORE
|
|
67
|
+
|
|
68
|
+
_custom_node_store_cache = CUSTOM_NODE_STORE
|
|
69
|
+
return _custom_node_store_cache
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_settings_class_for_node_type(node_type: str):
|
|
73
|
+
"""Get the settings class for a node type, supporting both standard and user-defined nodes."""
|
|
74
|
+
model_class = NODE_TYPE_TO_SETTINGS_CLASS.get(node_type)
|
|
75
|
+
if model_class is None:
|
|
76
|
+
if node_type in _get_custom_node_store():
|
|
77
|
+
return input_schema.UserDefinedNode
|
|
78
|
+
return None
|
|
79
|
+
return model_class
|
|
80
|
+
|
|
81
|
+
|
|
24
82
|
def is_valid_execution_location_in_current_global_settings(execution_location: ExecutionLocationsLiteral) -> bool:
|
|
25
83
|
return not (get_global_execution_location() == "local" and execution_location == "remote")
|
|
26
84
|
|
|
27
85
|
|
|
28
|
-
def get_prio_execution_location(
|
|
29
|
-
|
|
86
|
+
def get_prio_execution_location(
|
|
87
|
+
local_execution_location: ExecutionLocationsLiteral, global_execution_location: ExecutionLocationsLiteral
|
|
88
|
+
) -> ExecutionLocationsLiteral:
|
|
30
89
|
if local_execution_location == global_execution_location:
|
|
31
90
|
return local_execution_location
|
|
32
91
|
elif global_execution_location == "local" and local_execution_location == "remote":
|
|
@@ -48,16 +107,17 @@ class FlowGraphConfig(BaseModel):
|
|
|
48
107
|
execution_mode (ExecutionModeLiteral): The mode of execution ('Development' or 'Performance').
|
|
49
108
|
execution_location (ExecutionLocationsLiteral): The location for execution ('local', 'remote').
|
|
50
109
|
"""
|
|
110
|
+
|
|
51
111
|
flow_id: int = Field(default_factory=create_unique_id, description="Unique identifier for the flow.")
|
|
52
|
-
description:
|
|
53
|
-
save_location:
|
|
54
|
-
name: str =
|
|
55
|
-
path: str =
|
|
56
|
-
execution_mode: ExecutionModeLiteral =
|
|
112
|
+
description: str | None = None
|
|
113
|
+
save_location: str | None = None
|
|
114
|
+
name: str = ""
|
|
115
|
+
path: str = ""
|
|
116
|
+
execution_mode: ExecutionModeLiteral = "Performance"
|
|
57
117
|
execution_location: ExecutionLocationsLiteral = Field(default_factory=get_global_execution_location)
|
|
58
118
|
|
|
59
|
-
@field_validator(
|
|
60
|
-
def validate_and_set_execution_location(cls, v:
|
|
119
|
+
@field_validator("execution_location", mode="before")
|
|
120
|
+
def validate_and_set_execution_location(cls, v: ExecutionLocationsLiteral | None) -> ExecutionLocationsLiteral:
|
|
61
121
|
"""
|
|
62
122
|
Validates and sets the execution location.
|
|
63
123
|
1. **If `None` is provided**: It defaults to the location determined by global settings.
|
|
@@ -84,8 +144,9 @@ class FlowSettings(FlowGraphConfig):
|
|
|
84
144
|
is_running (bool): Indicates if the flow is currently running.
|
|
85
145
|
is_canceled (bool): Indicates if the flow execution has been canceled.
|
|
86
146
|
"""
|
|
147
|
+
|
|
87
148
|
auto_save: bool = False
|
|
88
|
-
modified_on:
|
|
149
|
+
modified_on: float | None = None
|
|
89
150
|
show_detailed_progress: bool = True
|
|
90
151
|
is_running: bool = False
|
|
91
152
|
is_canceled: bool = False
|
|
@@ -111,10 +172,76 @@ class RawLogInput(BaseModel):
|
|
|
111
172
|
log_type (Literal["INFO", "ERROR"]): The type of log.
|
|
112
173
|
extra (Optional[dict]): Extra context data for the log.
|
|
113
174
|
"""
|
|
175
|
+
|
|
114
176
|
flowfile_flow_id: int
|
|
115
177
|
log_message: str
|
|
116
178
|
log_type: Literal["INFO", "ERROR"]
|
|
117
|
-
extra:
|
|
179
|
+
extra: dict | None = None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class FlowfileSettings(BaseModel):
|
|
183
|
+
"""Settings for flowfile serialization (YAML/JSON).
|
|
184
|
+
|
|
185
|
+
Excludes runtime state fields like is_running, is_canceled, modified_on.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
description: str | None = None
|
|
189
|
+
execution_mode: ExecutionModeLiteral = "Performance"
|
|
190
|
+
execution_location: ExecutionLocationsLiteral = "local"
|
|
191
|
+
auto_save: bool = False
|
|
192
|
+
show_detailed_progress: bool = True
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class FlowfileNode(BaseModel):
|
|
196
|
+
"""Node representation for flowfile serialization (YAML/JSON)."""
|
|
197
|
+
|
|
198
|
+
id: int
|
|
199
|
+
type: str
|
|
200
|
+
is_start_node: bool = False
|
|
201
|
+
description: str | None = ""
|
|
202
|
+
x_position: int | None = 0
|
|
203
|
+
y_position: int | None = 0
|
|
204
|
+
left_input_id: int | None = None
|
|
205
|
+
right_input_id: int | None = None
|
|
206
|
+
input_ids: list[int] | None = Field(default_factory=list)
|
|
207
|
+
outputs: list[int] | None = Field(default_factory=list)
|
|
208
|
+
setting_input: Any | None = None
|
|
209
|
+
|
|
210
|
+
_setting_input_exclude: ClassVar[set] = {
|
|
211
|
+
"flow_id",
|
|
212
|
+
"node_id",
|
|
213
|
+
"pos_x",
|
|
214
|
+
"pos_y",
|
|
215
|
+
"is_setup",
|
|
216
|
+
"description",
|
|
217
|
+
"user_id",
|
|
218
|
+
"is_flow_output",
|
|
219
|
+
"is_user_defined",
|
|
220
|
+
"depending_on_id",
|
|
221
|
+
"depending_on_ids",
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@field_serializer("setting_input")
|
|
225
|
+
def serialize_setting_input(self, value, _info):
|
|
226
|
+
if value is None:
|
|
227
|
+
return None
|
|
228
|
+
if isinstance(value, input_schema.NodePromise):
|
|
229
|
+
return None
|
|
230
|
+
if hasattr(value, "to_yaml_dict"):
|
|
231
|
+
return value.to_yaml_dict()
|
|
232
|
+
if hasattr(value, "to_yaml_dict"):
|
|
233
|
+
return value.to_yaml_dict()
|
|
234
|
+
return value.model_dump(exclude=self._setting_input_exclude)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class FlowfileData(BaseModel):
|
|
238
|
+
"""Root model for flowfile serialization (YAML/JSON)."""
|
|
239
|
+
|
|
240
|
+
flowfile_version: str
|
|
241
|
+
flowfile_id: int
|
|
242
|
+
flowfile_name: str
|
|
243
|
+
flowfile_settings: FlowfileSettings
|
|
244
|
+
nodes: list[FlowfileNode]
|
|
118
245
|
|
|
119
246
|
|
|
120
247
|
class NodeTemplate(BaseModel):
|
|
@@ -132,6 +259,7 @@ class NodeTemplate(BaseModel):
|
|
|
132
259
|
prod_ready (bool): Whether the node is considered production-ready.
|
|
133
260
|
can_be_start (bool): Whether the node can be a starting point in a flow.
|
|
134
261
|
"""
|
|
262
|
+
|
|
135
263
|
name: str
|
|
136
264
|
item: str
|
|
137
265
|
input: int
|
|
@@ -145,54 +273,54 @@ class NodeTemplate(BaseModel):
|
|
|
145
273
|
can_be_start: bool = False
|
|
146
274
|
drawer_title: str = "Node title"
|
|
147
275
|
drawer_intro: str = "Drawer into"
|
|
148
|
-
custom_node:
|
|
276
|
+
custom_node: bool | None = False
|
|
149
277
|
|
|
150
278
|
|
|
151
279
|
class NodeInformation(BaseModel):
|
|
152
280
|
"""
|
|
153
281
|
Stores the state and configuration of a specific node instance within a flow.
|
|
154
|
-
|
|
155
|
-
Attributes:
|
|
156
|
-
id (Optional[int]): The unique ID of the node instance.
|
|
157
|
-
type (Optional[str]): The type of the node (e.g., 'join', 'filter').
|
|
158
|
-
is_setup (Optional[bool]): Whether the node has been configured.
|
|
159
|
-
description (Optional[str]): A user-provided description.
|
|
160
|
-
x_position (Optional[int]): The x-coordinate on the canvas.
|
|
161
|
-
y_position (Optional[int]): The y-coordinate on the canvas.
|
|
162
|
-
left_input_id (Optional[int]): The ID of the node connected to the left input.
|
|
163
|
-
right_input_id (Optional[int]): The ID of the node connected to the right input.
|
|
164
|
-
input_ids (Optional[List[int]]): A list of IDs for main input nodes.
|
|
165
|
-
outputs (Optional[List[int]]): A list of IDs for nodes this node outputs to.
|
|
166
|
-
setting_input (Optional[Any]): The specific settings for this node instance.
|
|
167
282
|
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
283
|
+
|
|
284
|
+
id: int | None = None
|
|
285
|
+
type: str | None = None
|
|
286
|
+
is_setup: bool | None = None
|
|
287
|
+
is_start_node: bool = False
|
|
288
|
+
description: str | None = ""
|
|
289
|
+
x_position: int | None = 0
|
|
290
|
+
y_position: int | None = 0
|
|
291
|
+
left_input_id: int | None = None
|
|
292
|
+
right_input_id: int | None = None
|
|
293
|
+
input_ids: list[int] | None = Field(default_factory=list)
|
|
294
|
+
outputs: list[int] | None = Field(default_factory=list)
|
|
295
|
+
setting_input: Any | None = None
|
|
179
296
|
|
|
180
297
|
@property
|
|
181
298
|
def data(self) -> Any:
|
|
182
|
-
"""
|
|
183
|
-
Property to access the node's specific settings.
|
|
184
|
-
:return: The settings of the node.
|
|
185
|
-
"""
|
|
186
299
|
return self.setting_input
|
|
187
300
|
|
|
188
301
|
@property
|
|
189
|
-
def main_input_ids(self) ->
|
|
190
|
-
"""
|
|
191
|
-
Property to access the main input node IDs.
|
|
192
|
-
:return: A list of main input node IDs.
|
|
193
|
-
"""
|
|
302
|
+
def main_input_ids(self) -> list[int] | None:
|
|
194
303
|
return self.input_ids
|
|
195
304
|
|
|
305
|
+
@field_validator("setting_input", mode="before")
|
|
306
|
+
@classmethod
|
|
307
|
+
def validate_setting_input(cls, v, info: ValidationInfo):
|
|
308
|
+
if v is None:
|
|
309
|
+
return None
|
|
310
|
+
if isinstance(v, BaseModel):
|
|
311
|
+
return v
|
|
312
|
+
|
|
313
|
+
node_type = info.data.get("type")
|
|
314
|
+
model_class = get_settings_class_for_node_type(node_type)
|
|
315
|
+
|
|
316
|
+
if model_class is None:
|
|
317
|
+
raise ValueError(f"Unknown node type: {node_type}")
|
|
318
|
+
|
|
319
|
+
if isinstance(v, model_class):
|
|
320
|
+
return v
|
|
321
|
+
|
|
322
|
+
return model_class.model_validate(v)
|
|
323
|
+
|
|
196
324
|
|
|
197
325
|
class FlowInformation(BaseModel):
|
|
198
326
|
"""
|
|
@@ -206,21 +334,36 @@ class FlowInformation(BaseModel):
|
|
|
206
334
|
node_starts (List[int]): A list of starting node IDs.
|
|
207
335
|
node_connections (List[Tuple[int, int]]): A list of tuples representing connections between nodes.
|
|
208
336
|
"""
|
|
337
|
+
|
|
209
338
|
flow_id: int
|
|
210
|
-
flow_name:
|
|
339
|
+
flow_name: str | None = ""
|
|
211
340
|
flow_settings: FlowSettings
|
|
212
|
-
data:
|
|
213
|
-
node_starts:
|
|
214
|
-
node_connections:
|
|
341
|
+
data: dict[int, NodeInformation] = {}
|
|
342
|
+
node_starts: list[int]
|
|
343
|
+
node_connections: list[tuple[int, int]] = []
|
|
215
344
|
|
|
216
|
-
@field_validator(
|
|
345
|
+
@field_validator("flow_name", mode="before")
|
|
217
346
|
def ensure_string(cls, v):
|
|
218
347
|
"""
|
|
219
348
|
Validator to ensure the flow_name is always a string.
|
|
220
349
|
:param v: The value to validate.
|
|
221
350
|
:return: The value as a string, or an empty string if it's None.
|
|
222
351
|
"""
|
|
223
|
-
return str(v) if v is not None else
|
|
352
|
+
return str(v) if v is not None else ""
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class NodeConnection(BaseModel):
|
|
356
|
+
"""
|
|
357
|
+
Represents a connection between two nodes in the flow.
|
|
358
|
+
|
|
359
|
+
Attributes:
|
|
360
|
+
from_node_id (int): The ID of the source node.
|
|
361
|
+
to_node_id (int): The ID of the target node.
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
model_config = ConfigDict(frozen=True)
|
|
365
|
+
from_node_id: int
|
|
366
|
+
to_node_id: int
|
|
224
367
|
|
|
225
368
|
|
|
226
369
|
class NodeInput(NodeTemplate):
|
|
@@ -232,6 +375,7 @@ class NodeInput(NodeTemplate):
|
|
|
232
375
|
pos_x (float): The x-coordinate on the canvas.
|
|
233
376
|
pos_y (float): The y-coordinate on the canvas.
|
|
234
377
|
"""
|
|
378
|
+
|
|
235
379
|
id: int
|
|
236
380
|
pos_x: float
|
|
237
381
|
pos_y: float
|
|
@@ -248,6 +392,7 @@ class NodeEdge(BaseModel):
|
|
|
248
392
|
targetHandle (str): The specific input handle on the target node.
|
|
249
393
|
sourceHandle (str): The specific output handle on the source node.
|
|
250
394
|
"""
|
|
395
|
+
|
|
251
396
|
model_config = ConfigDict(coerce_numbers_to_str=True)
|
|
252
397
|
id: str
|
|
253
398
|
source: str
|
|
@@ -265,10 +410,9 @@ class VueFlowInput(BaseModel):
|
|
|
265
410
|
node_edges (List[NodeEdge]): A list of all edges in the graph.
|
|
266
411
|
node_inputs (List[NodeInput]): A list of all nodes in the graph.
|
|
267
412
|
"""
|
|
268
|
-
node_edges: List[NodeEdge]
|
|
269
|
-
node_inputs: List[NodeInput]
|
|
270
|
-
|
|
271
413
|
|
|
414
|
+
node_edges: list[NodeEdge]
|
|
415
|
+
node_inputs: list[NodeInput]
|
|
272
416
|
|
|
273
417
|
|
|
274
418
|
class NodeDefault(BaseModel):
|
|
@@ -281,12 +425,8 @@ class NodeDefault(BaseModel):
|
|
|
281
425
|
transform_type (TransformTypeLiteral): The data transformation behavior ('narrow', 'wide', 'other').
|
|
282
426
|
has_default_settings (Optional[Any]): Indicates if the node has predefined default settings.
|
|
283
427
|
"""
|
|
428
|
+
|
|
284
429
|
node_name: str
|
|
285
430
|
node_type: NodeTypeLiteral
|
|
286
431
|
transform_type: TransformTypeLiteral
|
|
287
|
-
has_default_settings:
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
# Define SecretRef here if not in a common location
|
|
291
|
-
SecretRef = Annotated[str, StringConstraints(min_length=1, max_length=100),
|
|
292
|
-
Field(description="An ID referencing an encrypted secret.")]
|
|
432
|
+
has_default_settings: Any | None = None
|