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
flowfile_worker/models.py
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
from typing import Optional, Literal, Any
|
|
3
1
|
from base64 import decodebytes
|
|
2
|
+
from typing import Any, Literal
|
|
4
3
|
|
|
5
4
|
from pl_fuzzy_frame_match import FuzzyMapping
|
|
5
|
+
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
-
from flowfile_worker.external_sources.sql_source.models import DatabaseWriteSettings
|
|
8
7
|
from flowfile_worker.external_sources.s3_source.models import CloudStorageWriteSettings
|
|
9
|
-
|
|
8
|
+
from flowfile_worker.external_sources.sql_source.models import DatabaseWriteSettings
|
|
10
9
|
|
|
11
10
|
OperationType = Literal[
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
"store",
|
|
12
|
+
"calculate_schema",
|
|
13
|
+
"calculate_number_of_records",
|
|
14
|
+
"write_output",
|
|
15
|
+
"fuzzy",
|
|
16
|
+
"store_sample",
|
|
17
|
+
"write_to_database",
|
|
18
|
+
"write_to_cloud_storage",
|
|
19
|
+
]
|
|
20
|
+
ResultType = Literal["polars", "other"]
|
|
15
21
|
|
|
16
22
|
|
|
17
23
|
class PolarsOperation(BaseModel):
|
|
18
24
|
operation: bytes
|
|
19
|
-
flowfile_flow_id:
|
|
20
|
-
flowfile_node_id:
|
|
25
|
+
flowfile_flow_id: int | None = 1
|
|
26
|
+
flowfile_node_id: int | str | None = -1
|
|
27
|
+
|
|
21
28
|
def polars_serializable_object(self):
|
|
22
29
|
return decodebytes(self.operation)
|
|
23
30
|
|
|
24
31
|
|
|
25
32
|
class PolarsScript(PolarsOperation):
|
|
26
|
-
task_id:
|
|
27
|
-
cache_dir:
|
|
33
|
+
task_id: str | None = None
|
|
34
|
+
cache_dir: str | None = None
|
|
28
35
|
operation_type: OperationType
|
|
29
36
|
|
|
30
37
|
|
|
31
38
|
class PolarsScriptSample(PolarsScript):
|
|
32
|
-
sample_size:
|
|
39
|
+
sample_size: int | None = 100
|
|
33
40
|
|
|
34
41
|
|
|
35
42
|
class PolarsScriptWrite(BaseModel):
|
|
@@ -37,10 +44,10 @@ class PolarsScriptWrite(BaseModel):
|
|
|
37
44
|
data_type: str
|
|
38
45
|
path: str
|
|
39
46
|
write_mode: str
|
|
40
|
-
sheet_name:
|
|
41
|
-
delimiter:
|
|
42
|
-
flowfile_flow_id:
|
|
43
|
-
flowfile_node_id:
|
|
47
|
+
sheet_name: str | None = None
|
|
48
|
+
delimiter: str | None = None
|
|
49
|
+
flowfile_flow_id: int | None = -1
|
|
50
|
+
flowfile_node_id: int | str | None = -1
|
|
44
51
|
|
|
45
52
|
def polars_serializable_object(self):
|
|
46
53
|
return decodebytes(self.operation)
|
|
@@ -63,7 +70,7 @@ class DatabaseScriptWrite(DatabaseWriteSettings):
|
|
|
63
70
|
table_name=self.table_name,
|
|
64
71
|
if_exists=self.if_exists,
|
|
65
72
|
flowfile_flow_id=self.flowfile_flow_id,
|
|
66
|
-
flowfile_node_id=self.flowfile_node_id
|
|
73
|
+
flowfile_node_id=self.flowfile_node_id,
|
|
67
74
|
)
|
|
68
75
|
|
|
69
76
|
|
|
@@ -83,28 +90,28 @@ class CloudStorageScriptWrite(CloudStorageWriteSettings):
|
|
|
83
90
|
write_settings=self.write_settings,
|
|
84
91
|
connection=self.connection,
|
|
85
92
|
flowfile_flow_id=self.flowfile_flow_id,
|
|
86
|
-
flowfile_node_id=self.flowfile_node_id
|
|
93
|
+
flowfile_node_id=self.flowfile_node_id,
|
|
87
94
|
)
|
|
88
95
|
|
|
89
96
|
|
|
90
97
|
class FuzzyJoinInput(BaseModel):
|
|
91
|
-
task_id:
|
|
92
|
-
cache_dir:
|
|
98
|
+
task_id: str | None = None
|
|
99
|
+
cache_dir: str | None = None
|
|
93
100
|
left_df_operation: PolarsOperation
|
|
94
101
|
right_df_operation: PolarsOperation
|
|
95
102
|
fuzzy_maps: list[FuzzyMapping]
|
|
96
|
-
flowfile_flow_id:
|
|
97
|
-
flowfile_node_id:
|
|
103
|
+
flowfile_flow_id: int | None = 1
|
|
104
|
+
flowfile_node_id: int | str | None = -1
|
|
98
105
|
|
|
99
106
|
|
|
100
107
|
class Status(BaseModel):
|
|
101
108
|
background_task_id: str
|
|
102
|
-
status: Literal[
|
|
109
|
+
status: Literal["Processing", "Completed", "Error", "Unknown Error", "Starting"] # Type alias for status
|
|
103
110
|
file_ref: str
|
|
104
|
-
progress:
|
|
105
|
-
error_message:
|
|
106
|
-
results:
|
|
107
|
-
result_type:
|
|
111
|
+
progress: int | None = 0
|
|
112
|
+
error_message: str | None = None # Add error_message field
|
|
113
|
+
results: Any | None = None
|
|
114
|
+
result_type: ResultType | None = "polars"
|
|
108
115
|
|
|
109
116
|
def __hash__(self):
|
|
110
117
|
return hash(self.file_ref)
|
|
@@ -114,4 +121,4 @@ class RawLogInput(BaseModel):
|
|
|
114
121
|
flowfile_flow_id: int
|
|
115
122
|
log_message: str
|
|
116
123
|
log_type: Literal["INFO", "ERROR"]
|
|
117
|
-
extra:
|
|
124
|
+
extra: dict | None = None
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
from threading import Lock
|
|
2
1
|
from multiprocessing import Process
|
|
3
|
-
from
|
|
2
|
+
from threading import Lock
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
class ProcessManager:
|
|
7
6
|
def __init__(self):
|
|
8
|
-
self.process_dict:
|
|
7
|
+
self.process_dict: dict[str, Process] = {}
|
|
9
8
|
self.lock = Lock()
|
|
10
9
|
|
|
11
10
|
def add_process(self, task_id: str, process: Process):
|
flowfile_worker/routes.py
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import polars as pl
|
|
2
|
-
import uuid
|
|
3
1
|
import os
|
|
4
|
-
|
|
5
|
-
from typing import Dict
|
|
2
|
+
import uuid
|
|
6
3
|
from base64 import encodebytes
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
from
|
|
10
|
-
|
|
11
|
-
from flowfile_worker
|
|
5
|
+
import polars as pl
|
|
6
|
+
from fastapi import APIRouter, BackgroundTasks, HTTPException, Response
|
|
7
|
+
|
|
8
|
+
from flowfile_worker import CACHE_DIR, PROCESS_MEMORY_USAGE, models, status_dict, status_dict_lock
|
|
12
9
|
from flowfile_worker.configs import logger
|
|
10
|
+
from flowfile_worker.create import FileType, table_creator_factory_method
|
|
11
|
+
from flowfile_worker.create.models import ReceivedTable
|
|
12
|
+
from flowfile_worker.external_sources.sql_source.main import read_sql_source
|
|
13
13
|
from flowfile_worker.external_sources.sql_source.models import DatabaseReadSettings
|
|
14
|
-
from flowfile_worker.
|
|
15
|
-
|
|
14
|
+
from flowfile_worker.spawner import process_manager, start_fuzzy_process, start_generic_process, start_process
|
|
16
15
|
|
|
17
16
|
router = APIRouter()
|
|
18
17
|
|
|
@@ -35,15 +34,20 @@ def submit_query(polars_script: models.PolarsScript, background_tasks: Backgroun
|
|
|
35
34
|
polars_serializable_object = polars_script.polars_serializable_object()
|
|
36
35
|
file_path = os.path.join(polars_script.cache_dir, f"{polars_script.task_id}.arrow")
|
|
37
36
|
result_type = "polars" if polars_script.operation_type == "store" else "other"
|
|
38
|
-
status = models.Status(
|
|
39
|
-
|
|
37
|
+
status = models.Status(
|
|
38
|
+
background_task_id=polars_script.task_id, status="Starting", file_ref=file_path, result_type=result_type
|
|
39
|
+
)
|
|
40
40
|
status_dict[polars_script.task_id] = status
|
|
41
|
-
background_tasks.add_task(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
background_tasks.add_task(
|
|
42
|
+
start_process,
|
|
43
|
+
polars_serializable_object=polars_serializable_object,
|
|
44
|
+
task_id=polars_script.task_id,
|
|
45
|
+
operation=polars_script.operation_type,
|
|
46
|
+
file_ref=file_path,
|
|
47
|
+
flowfile_flow_id=polars_script.flowfile_flow_id,
|
|
48
|
+
flowfile_node_id=polars_script.flowfile_node_id,
|
|
49
|
+
kwargs={},
|
|
50
|
+
)
|
|
47
51
|
logger.info(f"Started background task: {polars_script.task_id}")
|
|
48
52
|
return status
|
|
49
53
|
|
|
@@ -52,7 +56,7 @@ def submit_query(polars_script: models.PolarsScript, background_tasks: Backgroun
|
|
|
52
56
|
raise HTTPException(status_code=500, detail=str(e))
|
|
53
57
|
|
|
54
58
|
|
|
55
|
-
@router.post(
|
|
59
|
+
@router.post("/store_sample/")
|
|
56
60
|
def store_sample(polars_script: models.PolarsScriptSample, background_tasks: BackgroundTasks) -> models.Status:
|
|
57
61
|
logger.info(f"Processing sample storage with size: {polars_script.sample_size}")
|
|
58
62
|
|
|
@@ -63,15 +67,21 @@ def store_sample(polars_script: models.PolarsScriptSample, background_tasks: Bac
|
|
|
63
67
|
polars_serializable_object = polars_script.polars_serializable_object()
|
|
64
68
|
|
|
65
69
|
file_path = os.path.join(polars_script.cache_dir, f"{polars_script.task_id}.arrow")
|
|
66
|
-
status = models.Status(
|
|
67
|
-
|
|
70
|
+
status = models.Status(
|
|
71
|
+
background_task_id=polars_script.task_id, status="Starting", file_ref=file_path, result_type="other"
|
|
72
|
+
)
|
|
68
73
|
status_dict[polars_script.task_id] = status
|
|
69
74
|
|
|
70
|
-
background_tasks.add_task(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
background_tasks.add_task(
|
|
76
|
+
start_process,
|
|
77
|
+
polars_serializable_object=polars_serializable_object,
|
|
78
|
+
task_id=polars_script.task_id,
|
|
79
|
+
operation=polars_script.operation_type,
|
|
80
|
+
file_ref=file_path,
|
|
81
|
+
flowfile_flow_id=polars_script.flowfile_flow_id,
|
|
82
|
+
flowfile_node_id=polars_script.flowfile_node_id,
|
|
83
|
+
kwargs={"sample_size": polars_script.sample_size},
|
|
84
|
+
)
|
|
75
85
|
logger.info(f"Started sample storage task: {polars_script.task_id}")
|
|
76
86
|
|
|
77
87
|
return status
|
|
@@ -82,8 +92,9 @@ def store_sample(polars_script: models.PolarsScriptSample, background_tasks: Bac
|
|
|
82
92
|
|
|
83
93
|
|
|
84
94
|
@router.post("/write_data_to_cloud/")
|
|
85
|
-
def write_data_to_cloud(
|
|
86
|
-
|
|
95
|
+
def write_data_to_cloud(
|
|
96
|
+
cloud_storage_script_write: models.CloudStorageScriptWrite, background_tasks: BackgroundTasks
|
|
97
|
+
) -> models.Status:
|
|
87
98
|
"""
|
|
88
99
|
Write polars dataframe to a file in cloud storage.
|
|
89
100
|
Args:
|
|
@@ -97,30 +108,29 @@ def write_data_to_cloud(cloud_storage_script_write: models.CloudStorageScriptWri
|
|
|
97
108
|
logger.info("Starting write operation to: cloud storage")
|
|
98
109
|
task_id = str(uuid.uuid4())
|
|
99
110
|
polars_serializable_object = cloud_storage_script_write.polars_serializable_object()
|
|
100
|
-
status = models.Status(background_task_id=task_id, status="Starting", file_ref=
|
|
101
|
-
result_type="other")
|
|
111
|
+
status = models.Status(background_task_id=task_id, status="Starting", file_ref="", result_type="other")
|
|
102
112
|
status_dict[task_id] = status
|
|
103
113
|
background_tasks.add_task(
|
|
104
114
|
start_process,
|
|
105
115
|
polars_serializable_object=polars_serializable_object,
|
|
106
116
|
task_id=task_id,
|
|
107
117
|
operation="write_to_cloud_storage",
|
|
108
|
-
file_ref=
|
|
118
|
+
file_ref="",
|
|
109
119
|
flowfile_flow_id=cloud_storage_script_write.flowfile_flow_id,
|
|
110
120
|
flowfile_node_id=cloud_storage_script_write.flowfile_node_id,
|
|
111
121
|
kwargs=dict(cloud_write_settings=cloud_storage_script_write.get_cloud_storage_write_settings()),
|
|
112
122
|
)
|
|
113
|
-
logger.info(
|
|
114
|
-
f"Started write task: {task_id} to database"
|
|
115
|
-
)
|
|
123
|
+
logger.info(f"Started write task: {task_id} to database")
|
|
116
124
|
return status
|
|
117
125
|
except Exception as e:
|
|
118
126
|
logger.error(f"Error in write operation: {str(e)}", exc_info=True)
|
|
119
127
|
raise HTTPException(status_code=500, detail=str(e))
|
|
120
128
|
|
|
121
129
|
|
|
122
|
-
@router.post(
|
|
123
|
-
def store_in_database(
|
|
130
|
+
@router.post("/store_database_write_result/")
|
|
131
|
+
def store_in_database(
|
|
132
|
+
database_script_write: models.DatabaseScriptWrite, background_tasks: BackgroundTasks
|
|
133
|
+
) -> models.Status:
|
|
124
134
|
"""
|
|
125
135
|
Write polars dataframe to a file in specified format.
|
|
126
136
|
|
|
@@ -135,24 +145,21 @@ def store_in_database(database_script_write: models.DatabaseScriptWrite, backgro
|
|
|
135
145
|
try:
|
|
136
146
|
task_id = str(uuid.uuid4())
|
|
137
147
|
polars_serializable_object = database_script_write.polars_serializable_object()
|
|
138
|
-
status = models.Status(background_task_id=task_id, status="Starting", file_ref=
|
|
139
|
-
result_type="other")
|
|
148
|
+
status = models.Status(background_task_id=task_id, status="Starting", file_ref="", result_type="other")
|
|
140
149
|
status_dict[task_id] = status
|
|
141
150
|
background_tasks.add_task(
|
|
142
151
|
start_process,
|
|
143
152
|
polars_serializable_object=polars_serializable_object,
|
|
144
153
|
task_id=task_id,
|
|
145
154
|
operation="write_to_database",
|
|
146
|
-
file_ref=
|
|
155
|
+
file_ref="",
|
|
147
156
|
flowfile_flow_id=database_script_write.flowfile_flow_id,
|
|
148
157
|
flowfile_node_id=database_script_write.flowfile_node_id,
|
|
149
158
|
kwargs=dict(database_write_settings=database_script_write.get_database_write_settings()),
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
logger.info(
|
|
153
|
-
f"Started write task: {task_id} to database"
|
|
154
159
|
)
|
|
155
160
|
|
|
161
|
+
logger.info(f"Started write task: {task_id} to database")
|
|
162
|
+
|
|
156
163
|
return status
|
|
157
164
|
|
|
158
165
|
except Exception as e:
|
|
@@ -160,7 +167,7 @@ def store_in_database(database_script_write: models.DatabaseScriptWrite, backgro
|
|
|
160
167
|
raise HTTPException(status_code=500, detail=str(e))
|
|
161
168
|
|
|
162
169
|
|
|
163
|
-
@router.post(
|
|
170
|
+
@router.post("/write_results/")
|
|
164
171
|
def write_results(polars_script_write: models.PolarsScriptWrite, background_tasks: BackgroundTasks) -> models.Status:
|
|
165
172
|
"""
|
|
166
173
|
Write polars dataframe to a file in specified format.
|
|
@@ -178,22 +185,26 @@ def write_results(polars_script_write: models.PolarsScriptWrite, background_task
|
|
|
178
185
|
file_path = polars_script_write.path
|
|
179
186
|
polars_serializable_object = polars_script_write.polars_serializable_object()
|
|
180
187
|
result_type = "other"
|
|
181
|
-
status = models.Status(
|
|
182
|
-
|
|
188
|
+
status = models.Status(
|
|
189
|
+
background_task_id=task_id, status="Starting", file_ref=file_path, result_type=result_type
|
|
190
|
+
)
|
|
183
191
|
status_dict[task_id] = status
|
|
184
|
-
background_tasks.add_task(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
background_tasks.add_task(
|
|
193
|
+
start_process,
|
|
194
|
+
polars_serializable_object=polars_serializable_object,
|
|
195
|
+
task_id=task_id,
|
|
196
|
+
operation="write_output",
|
|
197
|
+
file_ref=file_path,
|
|
198
|
+
flowfile_flow_id=polars_script_write.flowfile_flow_id,
|
|
199
|
+
flowfile_node_id=polars_script_write.flowfile_node_id,
|
|
200
|
+
kwargs=dict(
|
|
201
|
+
data_type=polars_script_write.data_type,
|
|
202
|
+
path=polars_script_write.path,
|
|
203
|
+
write_mode=polars_script_write.write_mode,
|
|
204
|
+
sheet_name=polars_script_write.sheet_name,
|
|
205
|
+
delimiter=polars_script_write.delimiter,
|
|
206
|
+
),
|
|
207
|
+
)
|
|
197
208
|
logger.info(f"Started write task: {task_id} with type: {polars_script_write.data_type}")
|
|
198
209
|
|
|
199
210
|
return status
|
|
@@ -203,8 +214,10 @@ def write_results(polars_script_write: models.PolarsScriptWrite, background_task
|
|
|
203
214
|
raise HTTPException(status_code=500, detail=str(e))
|
|
204
215
|
|
|
205
216
|
|
|
206
|
-
@router.post(
|
|
207
|
-
def store_sql_db_result(
|
|
217
|
+
@router.post("/store_database_read_result")
|
|
218
|
+
def store_sql_db_result(
|
|
219
|
+
database_read_settings: DatabaseReadSettings, background_tasks: BackgroundTasks
|
|
220
|
+
) -> models.Status:
|
|
208
221
|
"""
|
|
209
222
|
Store the result of an sql source operation.
|
|
210
223
|
|
|
@@ -219,16 +232,21 @@ def store_sql_db_result(database_read_settings: DatabaseReadSettings, background
|
|
|
219
232
|
|
|
220
233
|
try:
|
|
221
234
|
task_id = str(uuid.uuid4())
|
|
222
|
-
file_path = os.path.join(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
235
|
+
file_path = os.path.join(
|
|
236
|
+
create_and_get_default_cache_dir(database_read_settings.flowfile_flow_id), f"{task_id}.arrow"
|
|
237
|
+
)
|
|
238
|
+
status = models.Status(background_task_id=task_id, status="Starting", file_ref=file_path, result_type="polars")
|
|
226
239
|
status_dict[task_id] = status
|
|
227
240
|
logger.info(f"Starting reading from database source task: {task_id}")
|
|
228
|
-
background_tasks.add_task(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
241
|
+
background_tasks.add_task(
|
|
242
|
+
start_generic_process,
|
|
243
|
+
func_ref=read_sql_source,
|
|
244
|
+
file_ref=file_path,
|
|
245
|
+
flowfile_flow_id=database_read_settings.flowfile_flow_id,
|
|
246
|
+
flowfile_node_id=database_read_settings.flowfile_node_id,
|
|
247
|
+
task_id=task_id,
|
|
248
|
+
kwargs=dict(database_read_settings=database_read_settings),
|
|
249
|
+
)
|
|
232
250
|
return status
|
|
233
251
|
|
|
234
252
|
except Exception as e:
|
|
@@ -236,9 +254,14 @@ def store_sql_db_result(database_read_settings: DatabaseReadSettings, background
|
|
|
236
254
|
raise HTTPException(status_code=500, detail=str(e))
|
|
237
255
|
|
|
238
256
|
|
|
239
|
-
@router.post(
|
|
240
|
-
def create_table(
|
|
241
|
-
|
|
257
|
+
@router.post("/create_table/{file_type}")
|
|
258
|
+
def create_table(
|
|
259
|
+
file_type: FileType,
|
|
260
|
+
received_table: ReceivedTable,
|
|
261
|
+
background_tasks: BackgroundTasks,
|
|
262
|
+
flowfile_flow_id: int = 1,
|
|
263
|
+
flowfile_node_id: int | str = -1,
|
|
264
|
+
) -> models.Status:
|
|
242
265
|
"""
|
|
243
266
|
Create a Polars table from received dictionary data based on specified file type.
|
|
244
267
|
|
|
@@ -253,20 +276,21 @@ def create_table(file_type: FileType, received_table: Dict, background_tasks: Ba
|
|
|
253
276
|
models.Status: Status object tracking the table creation
|
|
254
277
|
"""
|
|
255
278
|
logger.info(f"Creating table of type: {file_type}")
|
|
256
|
-
|
|
257
279
|
try:
|
|
258
280
|
task_id = str(uuid.uuid4())
|
|
259
281
|
file_ref = os.path.join(create_and_get_default_cache_dir(flowfile_flow_id), f"{task_id}.arrow")
|
|
260
|
-
|
|
261
|
-
status = models.Status(background_task_id=task_id, status="Starting", file_ref=file_ref,
|
|
262
|
-
result_type="polars")
|
|
282
|
+
status = models.Status(background_task_id=task_id, status="Starting", file_ref=file_ref, result_type="polars")
|
|
263
283
|
status_dict[task_id] = status
|
|
264
284
|
func_ref = table_creator_factory_method(file_type)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
285
|
+
background_tasks.add_task(
|
|
286
|
+
start_generic_process,
|
|
287
|
+
func_ref=func_ref,
|
|
288
|
+
file_ref=file_ref,
|
|
289
|
+
task_id=task_id,
|
|
290
|
+
kwargs={"received_table": received_table},
|
|
291
|
+
flowfile_flow_id=flowfile_flow_id,
|
|
292
|
+
flowfile_node_id=flowfile_node_id,
|
|
293
|
+
)
|
|
270
294
|
logger.info(f"Started table creation task: {task_id}")
|
|
271
295
|
|
|
272
296
|
return status
|
|
@@ -288,7 +312,7 @@ def validate_result(task_id: str) -> bool | None:
|
|
|
288
312
|
"""
|
|
289
313
|
logger.debug(f"Validating result for task: {task_id}")
|
|
290
314
|
status = status_dict.get(task_id)
|
|
291
|
-
if status.status ==
|
|
315
|
+
if status.status == "Completed" and status.result_type == "polars":
|
|
292
316
|
try:
|
|
293
317
|
pl.scan_ipc(status.file_ref)
|
|
294
318
|
logger.debug(f"Validation successful for task: {task_id}")
|
|
@@ -299,7 +323,7 @@ def validate_result(task_id: str) -> bool | None:
|
|
|
299
323
|
return True
|
|
300
324
|
|
|
301
325
|
|
|
302
|
-
@router.get(
|
|
326
|
+
@router.get("/status/{task_id}", response_model=models.Status)
|
|
303
327
|
def get_status(task_id: str) -> models.Status:
|
|
304
328
|
"""Get status of a task by ID and validate its result if completed.
|
|
305
329
|
|
|
@@ -399,16 +423,20 @@ async def add_fuzzy_join(polars_script: models.FuzzyJoinInput, background_tasks:
|
|
|
399
423
|
right_serializable_object = polars_script.right_df_operation.polars_serializable_object()
|
|
400
424
|
|
|
401
425
|
file_path = os.path.join(polars_script.cache_dir, f"{polars_script.task_id}.arrow")
|
|
402
|
-
status = models.Status(
|
|
403
|
-
|
|
426
|
+
status = models.Status(
|
|
427
|
+
background_task_id=polars_script.task_id, status="Starting", file_ref=file_path, result_type="polars"
|
|
428
|
+
)
|
|
404
429
|
status_dict[polars_script.task_id] = status
|
|
405
|
-
background_tasks.add_task(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
430
|
+
background_tasks.add_task(
|
|
431
|
+
start_fuzzy_process,
|
|
432
|
+
left_serializable_object=left_serializable_object,
|
|
433
|
+
right_serializable_object=right_serializable_object,
|
|
434
|
+
file_ref=file_path,
|
|
435
|
+
fuzzy_maps=polars_script.fuzzy_maps,
|
|
436
|
+
task_id=polars_script.task_id,
|
|
437
|
+
flowfile_flow_id=polars_script.flowfile_flow_id,
|
|
438
|
+
flowfile_node_id=polars_script.flowfile_node_id,
|
|
439
|
+
)
|
|
412
440
|
logger.info(f"Started fuzzy join task: {polars_script.task_id}")
|
|
413
441
|
return status
|
|
414
442
|
except Exception as e:
|
|
@@ -471,7 +499,7 @@ def cancel_task(task_id: str):
|
|
|
471
499
|
return {"message": f"Task {task_id} has been cancelled."}
|
|
472
500
|
|
|
473
501
|
|
|
474
|
-
@router.get(
|
|
502
|
+
@router.get("/ids")
|
|
475
503
|
async def get_all_ids():
|
|
476
504
|
"""Get list of all task IDs in the system.
|
|
477
505
|
|
flowfile_worker/secrets.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Simplified secure storage module for FlowFile worker to read credentials and secrets.
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
from pathlib import Path
|
|
4
|
+
|
|
7
5
|
import json
|
|
8
6
|
import logging
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from cryptography.fernet import Fernet
|
|
9
11
|
from pydantic import SecretStr
|
|
12
|
+
|
|
10
13
|
from flowfile_worker.configs import TEST_MODE
|
|
11
14
|
|
|
12
15
|
# Set up logging
|
|
@@ -79,7 +82,7 @@ def get_docker_secret_key():
|
|
|
79
82
|
secret_path = "/run/secrets/flowfile_master_key"
|
|
80
83
|
if os.path.exists(secret_path):
|
|
81
84
|
try:
|
|
82
|
-
with open(secret_path
|
|
85
|
+
with open(secret_path) as f:
|
|
83
86
|
return f.read().strip()
|
|
84
87
|
except Exception as e:
|
|
85
88
|
logger.error(f"Failed to read master key from Docker secret: {e}")
|
|
@@ -105,10 +108,10 @@ def get_master_key() -> str:
|
|
|
105
108
|
"""
|
|
106
109
|
# First check for test mode
|
|
107
110
|
if TEST_MODE:
|
|
108
|
-
return b
|
|
111
|
+
return b"06t640eu3AG2FmglZS0n0zrEdqadoT7lYDwgSmKyxE4=".decode()
|
|
109
112
|
|
|
110
113
|
# Next check if running in Docker
|
|
111
|
-
if os.environ.get("
|
|
114
|
+
if os.environ.get("FLOWFILE_MODE") == "docker":
|
|
112
115
|
return get_docker_secret_key()
|
|
113
116
|
|
|
114
117
|
# Otherwise read from local storage
|