Flowfile 0.5.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 +178 -74
- flowfile/__main__.py +10 -7
- flowfile/api.py +51 -57
- 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-0dfba9f2.js → CloudConnectionView-f13f202b.js} +11 -11
- flowfile/web/static/assets/{CloudStorageReader-d5b1b6c9.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-00d87aad.js → CloudStorageWriter-8e781e11.js} +10 -8
- flowfile/web/static/assets/{ColumnSelector-47996a16.css → ColumnSelector-371637fb.css} +2 -2
- flowfile/web/static/assets/{ColumnSelector-4685e75d.js → ColumnSelector-8ad68ea9.js} +3 -5
- flowfile/web/static/assets/{ContextMenu-c13f91d0.css → ContextMenu-26d4dd27.css} +6 -6
- flowfile/web/static/assets/{ContextMenu-23e909da.js → ContextMenu-31ee57f0.js} +3 -3
- flowfile/web/static/assets/{ContextMenu-70ae0c79.js → ContextMenu-69a74055.js} +3 -3
- flowfile/web/static/assets/{ContextMenu-f149cf7c.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-702a3edd.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-b1519993.js → CustomNode-8479239b.js} +36 -24
- flowfile/web/static/assets/{DatabaseConnectionSettings-6f3e4ea5.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-d38c7295.js → DatabaseReader-c58b9552.js} +25 -15
- flowfile/web/static/assets/DatabaseView-6655afd6.css +57 -0
- flowfile/web/static/assets/{DatabaseManager-cf5ef661.js → DatabaseView-d26a9140.js} +11 -11
- flowfile/web/static/assets/{DatabaseWriter-2f570e53.css → DatabaseWriter-217a99f1.css} +19 -19
- flowfile/web/static/assets/{DatabaseWriter-b04ef46a.js → DatabaseWriter-4d05ddc7.js} +17 -10
- flowfile/web/static/assets/{designer-8da3ba3a.css → DesignerView-a6d0ee84.css} +614 -546
- flowfile/web/static/assets/{designer-9633482a.js → DesignerView-e6f5c0e8.js} +1107 -3170
- flowfile/web/static/assets/{documentation-ca400224.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-5fa10ed8.js → ExploreData-7b54caca.js} +18 -9
- flowfile/web/static/assets/{ExternalSource-d39af878.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-6b04fb1d.js → Formula-aac42b1e.js} +13 -11
- flowfile/web/static/assets/{FuzzyMatch-1010f966.css → FuzzyMatch-ad6361d6.css} +68 -69
- flowfile/web/static/assets/{FuzzyMatch-999521f4.js → FuzzyMatch-cd9bbfca.js} +12 -10
- flowfile/web/static/assets/{Pivot-cf333e3d.css → GraphSolver-c24dec17.css} +5 -5
- flowfile/web/static/assets/{GraphSolver-17dd2198.js → GraphSolver-c7e6780e.js} +13 -11
- flowfile/web/static/assets/{GroupBy-6b039e18.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-24d0f113.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-34639209.js → ManualInput-8d3374b2.js} +170 -116
- flowfile/web/static/assets/{MultiSelect-0e8724a3.js → MultiSelect-ad1b6243.js} +2 -2
- flowfile/web/static/assets/{MultiSelect.vue_vue_type_script_setup_true_lang-b0e538c2.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-3d63a470.js → NumericInput-7100234c.js} +2 -2
- flowfile/web/static/assets/{NumericInput.vue_vue_type_script_setup_true_lang-e0edeccc.js → NumericInput.vue_vue_type_script_setup_true_lang-5130219f.js} +5 -2
- flowfile/web/static/assets/{Output-283fe388.css → Output-35e97000.css} +6 -6
- flowfile/web/static/assets/{Output-edea9802.js → Output-f5efd2aa.js} +12 -9
- flowfile/web/static/assets/{GraphSolver-f0cb7bfb.css → Pivot-0eda81b4.css} +5 -5
- flowfile/web/static/assets/{Pivot-61d19301.js → Pivot-d981d23c.js} +11 -9
- flowfile/web/static/assets/PivotValidation-0e905b1a.css +13 -0
- flowfile/web/static/assets/{PivotValidation-f97fec5b.js → PivotValidation-39386e95.js} +3 -3
- flowfile/web/static/assets/PivotValidation-41b57ad6.css +13 -0
- flowfile/web/static/assets/{PivotValidation-de9f43fe.js → PivotValidation-63de1f73.js} +3 -3
- flowfile/web/static/assets/{PolarsCode-650322d1.css → PolarsCode-2b1f1f23.css} +4 -4
- flowfile/web/static/assets/{PolarsCode-bc3c9984.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-e808b239.css → Read-36e7bd51.css} +12 -12
- flowfile/web/static/assets/{Read-64a3f259.js → Read-aec2e377.js} +14 -11
- flowfile/web/static/assets/{RecordCount-3d5039be.js → RecordCount-78ed6845.js} +6 -4
- flowfile/web/static/assets/{RecordId-597510e0.js → RecordId-2156e890.js} +8 -6
- flowfile/web/static/assets/{SQLQueryComponent-36cef432.css → SQLQueryComponent-1c2f26b4.css} +5 -5
- flowfile/web/static/assets/{SQLQueryComponent-df51adbe.js → SQLQueryComponent-48c72f5b.js} +3 -3
- flowfile/web/static/assets/{Sample-4be0a507.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-4839be57.js → SecretsView-17df66ee.js} +35 -36
- flowfile/web/static/assets/SecretsView-aa291340.css +38 -0
- flowfile/web/static/assets/{Select-9b72f201.js → Select-0aee4c54.js} +9 -7
- flowfile/web/static/assets/{SettingsSection-f0f75a42.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-e1e9c953.js → SettingsSection-cd341bb6.js} +3 -3
- flowfile/web/static/assets/{SettingsSection-7ded385d.js → SettingsSection-f2002a6d.js} +3 -3
- flowfile/web/static/assets/{SingleSelect-6c777aac.js → SingleSelect-460cc0ea.js} +2 -2
- flowfile/web/static/assets/{SingleSelect.vue_vue_type_script_setup_true_lang-33e3ff9b.js → SingleSelect.vue_vue_type_script_setup_true_lang-30741bb2.js} +1 -1
- flowfile/web/static/assets/{SliderInput-7cb93e62.js → SliderInput-5d926864.js} +7 -4
- flowfile/web/static/assets/SliderInput-f2e4f23c.css +4 -0
- flowfile/web/static/assets/{Sort-6cbde21a.js → Sort-3cdc971b.js} +9 -7
- flowfile/web/static/assets/{Unique-f9fb0809.css → Sort-8a871341.css} +10 -10
- flowfile/web/static/assets/{TextInput-d9a40c11.js → TextInput-a2d0bfbd.js} +2 -2
- flowfile/web/static/assets/{TextInput.vue_vue_type_script_setup_true_lang-5896c375.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-c4fcbf4d.js → TextToRows-918945f7.js} +11 -10
- flowfile/web/static/assets/{ToggleSwitch-4ef91d19.js → ToggleSwitch-f0ef5196.js} +2 -2
- flowfile/web/static/assets/{ToggleSwitch.vue_vue_type_script_setup_true_lang-38478c20.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-a03f512c.js → UnavailableFields-bdad6144.js} +4 -4
- flowfile/web/static/assets/{Union-af6c3d9b.css → Union-d6a8d7d5.css} +7 -7
- flowfile/web/static/assets/{Union-bfe9b996.js → Union-e8ab8c86.js} +8 -6
- flowfile/web/static/assets/{Unique-5d023a27.js → Unique-8cd4f976.js} +13 -10
- 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-91cc5354.js → Unpivot-8da14095.js} +10 -8
- flowfile/web/static/assets/{UnpivotValidation-7ee2de44.js → UnpivotValidation-6f7d89ff.js} +3 -3
- flowfile/web/static/assets/UnpivotValidation-d5ca3b7b.css +13 -0
- flowfile/web/static/assets/{VueGraphicWalker-e51b9924.js → VueGraphicWalker-3fb312e1.js} +4 -4
- flowfile/web/static/assets/{VueGraphicWalker-ed5ab88b.css → VueGraphicWalker-430f0b86.css} +1 -1
- flowfile/web/static/assets/{api-cf1221f0.js → api-24483f0d.js} +1 -1
- flowfile/web/static/assets/{api-c1bad5ca.js → api-8b81fa73.js} +1 -1
- flowfile/web/static/assets/{dropDown-35135ba8.css → dropDown-3d8dc5fa.css} +40 -40
- flowfile/web/static/assets/{dropDown-614b998d.js → dropDown-ac0fda9d.js} +3 -3
- flowfile/web/static/assets/{fullEditor-f7971590.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-4fe5f36b.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-5429bbf8.js → index-fb6493ae.js} +41626 -40867
- flowfile/web/static/assets/node.types-2c15bb7e.js +82 -0
- flowfile/web/static/assets/nodeInput-0eb13f1a.js +2 -0
- flowfile/web/static/assets/{outputCsv-076b85ab.js → outputCsv-8f8ba42d.js} +3 -3
- flowfile/web/static/assets/outputCsv-b9a072af.css +2499 -0
- flowfile/web/static/assets/{outputExcel-0fd17dbe.js → outputExcel-393f4fef.js} +3 -3
- flowfile/web/static/assets/{outputExcel-b41305c0.css → outputExcel-f5d272b2.css} +26 -26
- flowfile/web/static/assets/{outputParquet-b61e0847.js → outputParquet-07c81f65.js} +4 -4
- flowfile/web/static/assets/outputParquet-54597c3c.css +4 -0
- flowfile/web/static/assets/{readCsv-a8bb8b61.js → readCsv-07f6d9ad.js} +3 -3
- flowfile/web/static/assets/{readCsv-c767cb37.css → readCsv-3bfac4c3.css} +15 -15
- flowfile/web/static/assets/{readExcel-806d2826.css → readExcel-3db6b763.css} +13 -13
- flowfile/web/static/assets/{readExcel-67b4aee0.js → readExcel-ed69bc8f.js} +5 -5
- flowfile/web/static/assets/{readParquet-48c81530.css → readParquet-c5244ad5.css} +4 -4
- flowfile/web/static/assets/{readParquet-92ce1dbc.js → readParquet-e3ed4528.js} +3 -3
- flowfile/web/static/assets/secrets.api-002e7d7e.js +65 -0
- flowfile/web/static/assets/{selectDynamic-92e25ee3.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-41b0e0d7.js → vue-codemirror.esm-0965f39f.js} +31 -640
- flowfile/web/static/assets/{vue-content-loader.es-2c8e608f.js → vue-content-loader.es-c506ad97.js} +1 -1
- flowfile/web/static/index.html +2 -2
- {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/METADATA +2 -3
- flowfile-0.5.3.dist-info/RECORD +402 -0
- flowfile_core/__init__.py +13 -6
- 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 +26 -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 +358 -244
- 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 +115 -83
- flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +481 -423
- 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 +31 -20
- 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 +14 -15
- 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 +190 -127
- flowfile_core/flowfile/flow_data_engine/threaded_processes.py +8 -8
- flowfile_core/flowfile/flow_data_engine/utils.py +99 -67
- flowfile_core/flowfile/flow_graph.py +918 -571
- flowfile_core/flowfile/flow_graph_utils.py +31 -49
- flowfile_core/flowfile/flow_node/flow_node.py +330 -233
- flowfile_core/flowfile/flow_node/models.py +53 -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 +80 -30
- flowfile_core/flowfile/manage/compatibility_enhancements.py +209 -126
- flowfile_core/flowfile/manage/io_flowfile.py +54 -57
- 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 +135 -34
- flowfile_core/flowfile/schema_callbacks.py +71 -51
- 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 +64 -53
- 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 +70 -34
- 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 -53
- flowfile_core/schemas/input_schema.py +231 -144
- flowfile_core/schemas/output_model.py +49 -34
- flowfile_core/schemas/schemas.py +116 -89
- flowfile_core/schemas/transform_schema.py +518 -263
- flowfile_core/schemas/yaml_types.py +21 -7
- flowfile_core/secret_manager/secret_manager.py +17 -13
- flowfile_core/types.py +29 -9
- 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 +106 -51
- 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 +571 -476
- flowfile_frame/flow_frame.pyi +123 -104
- flowfile_frame/flow_frame_methods.py +227 -246
- 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 -7
- flowfile_worker/configs.py +11 -19
- flowfile_worker/create/__init__.py +14 -9
- flowfile_worker/create/funcs.py +114 -77
- flowfile_worker/create/models.py +46 -43
- 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 -90
- 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/__init__.py +1 -1
- tools/migrate/__main__.py +16 -29
- tools/migrate/legacy_schemas.py +251 -190
- tools/migrate/migrate.py +193 -181
- tools/migrate/tests/conftest.py +1 -3
- tools/migrate/tests/test_migrate.py +36 -41
- tools/migrate/tests/test_migration_e2e.py +28 -29
- tools/migrate/tests/test_node_migrations.py +50 -20
- 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-9b6d08db.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/nodeInput-5d0d6b79.js +0 -41
- flowfile/web/static/assets/outputCsv-9cc59e0b.css +0 -2499
- flowfile/web/static/assets/outputParquet-cf8cf3f2.css +0 -4
- flowfile/web/static/assets/secretApi-68435402.js +0 -46
- flowfile/web/static/assets/vue-codemirror-bccfde04.css +0 -32
- flowfile-0.5.1.dist-info/RECORD +0 -388
- {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/WHEEL +0 -0
- {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/entry_points.txt +0 -0
- {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/licenses/LICENSE +0 -0
flowfile/api.py
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# flowfile/api.py
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import atexit
|
|
4
|
+
import logging
|
|
5
5
|
import os
|
|
6
|
-
import
|
|
6
|
+
import platform
|
|
7
|
+
import shutil
|
|
7
8
|
import subprocess
|
|
8
9
|
import sys
|
|
9
|
-
import
|
|
10
|
-
import
|
|
10
|
+
import time
|
|
11
|
+
import uuid
|
|
11
12
|
import webbrowser
|
|
12
|
-
import shutil
|
|
13
|
-
import platform
|
|
14
|
-
|
|
15
13
|
from pathlib import Path
|
|
16
|
-
from typing import Optional, Dict, Any, Union, Tuple, List
|
|
17
14
|
from subprocess import Popen
|
|
18
|
-
from flowfile_core.flowfile.flow_graph import FlowGraph
|
|
19
15
|
from tempfile import TemporaryDirectory
|
|
20
|
-
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
import requests
|
|
19
|
+
|
|
20
|
+
from flowfile_core.flowfile.flow_graph import FlowGraph
|
|
21
21
|
|
|
22
22
|
# Configuration
|
|
23
23
|
FLOWFILE_HOST: str = os.environ.get("FLOWFILE_HOST", "127.0.0.1")
|
|
@@ -30,7 +30,7 @@ POETRY_PATH: str = os.environ.get("POETRY_PATH", "poetry")
|
|
|
30
30
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
31
31
|
|
|
32
32
|
# Global variable to track the managed server process
|
|
33
|
-
_server_process:
|
|
33
|
+
_server_process: Popen | None = None
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def is_flowfile_running() -> bool:
|
|
@@ -56,9 +56,7 @@ def stop_flowfile_server_process() -> None:
|
|
|
56
56
|
try:
|
|
57
57
|
# On Windows, use subprocess to kill the process tree
|
|
58
58
|
subprocess.run(
|
|
59
|
-
["taskkill", "/F", "/T", "/PID", str(_server_process.pid)],
|
|
60
|
-
capture_output=True,
|
|
61
|
-
check=False
|
|
59
|
+
["taskkill", "/F", "/T", "/PID", str(_server_process.pid)], capture_output=True, check=False
|
|
62
60
|
)
|
|
63
61
|
logger.info("Server process terminated (Windows).")
|
|
64
62
|
except Exception as e:
|
|
@@ -116,10 +114,7 @@ def is_poetry_environment() -> bool:
|
|
|
116
114
|
|
|
117
115
|
# Check if we're in a poetry virtual environment
|
|
118
116
|
venv_path = os.environ.get("VIRTUAL_ENV", "")
|
|
119
|
-
if venv_path and (
|
|
120
|
-
"poetry" in venv_path.lower() or
|
|
121
|
-
Path(venv_path).joinpath(".poetry-venv").exists()
|
|
122
|
-
):
|
|
117
|
+
if venv_path and ("poetry" in venv_path.lower() or Path(venv_path).joinpath(".poetry-venv").exists()):
|
|
123
118
|
return True
|
|
124
119
|
|
|
125
120
|
# Look for pyproject.toml with poetry section
|
|
@@ -128,7 +123,7 @@ def is_poetry_environment() -> bool:
|
|
|
128
123
|
pyproject = parent / "pyproject.toml"
|
|
129
124
|
if pyproject.exists():
|
|
130
125
|
try:
|
|
131
|
-
with open(pyproject
|
|
126
|
+
with open(pyproject) as f:
|
|
132
127
|
content = f.read()
|
|
133
128
|
if "[tool.poetry]" in content:
|
|
134
129
|
return True
|
|
@@ -143,7 +138,7 @@ def is_command_available(command: str) -> bool:
|
|
|
143
138
|
return shutil.which(command) is not None
|
|
144
139
|
|
|
145
140
|
|
|
146
|
-
def build_server_command(module_name: str) ->
|
|
141
|
+
def build_server_command(module_name: str) -> list[str]:
|
|
147
142
|
"""
|
|
148
143
|
Build the appropriate command to start the server based on environment detection.
|
|
149
144
|
Tries Poetry first if in a Poetry environment, falls back to direct module execution.
|
|
@@ -167,7 +162,7 @@ def build_server_command(module_name: str) -> List[str]:
|
|
|
167
162
|
# Case 2: Fallback to direct script execution
|
|
168
163
|
logger.info("Falling back to direct script execution.")
|
|
169
164
|
python_parent_dir = Path(sys.executable).parent
|
|
170
|
-
command:
|
|
165
|
+
command: list[str]
|
|
171
166
|
scripts_dir = Path(sys.executable).parent
|
|
172
167
|
|
|
173
168
|
if platform.system() == "Windows":
|
|
@@ -194,7 +189,7 @@ def build_server_command(module_name: str) -> List[str]:
|
|
|
194
189
|
# On Unix-like systems, the script in 'bin' is directly executable
|
|
195
190
|
script_path = python_parent_dir / "bin" / module_name
|
|
196
191
|
if not script_path.exists():
|
|
197
|
-
script_path = python_parent_dir / module_name
|
|
192
|
+
script_path = python_parent_dir / module_name # Fallback for different venv structures
|
|
198
193
|
|
|
199
194
|
logger.info(f"Using direct script execution path: {script_path}")
|
|
200
195
|
command = [str(script_path), "run", "ui", "--no-browser"]
|
|
@@ -213,7 +208,7 @@ def check_if_in_single_mode() -> bool:
|
|
|
213
208
|
return False
|
|
214
209
|
|
|
215
210
|
|
|
216
|
-
def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) ->
|
|
211
|
+
def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) -> tuple[bool, bool]:
|
|
217
212
|
"""
|
|
218
213
|
Start the Flowfile server as a background process if it's not already running.
|
|
219
214
|
Automatically detects and uses Poetry if in a Poetry environment.
|
|
@@ -241,7 +236,7 @@ def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) -> Tup
|
|
|
241
236
|
command,
|
|
242
237
|
stdout=subprocess.DEVNULL,
|
|
243
238
|
stderr=subprocess.PIPE,
|
|
244
|
-
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
|
239
|
+
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,
|
|
245
240
|
)
|
|
246
241
|
else:
|
|
247
242
|
_server_process = Popen(
|
|
@@ -265,12 +260,14 @@ def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) -> Tup
|
|
|
265
260
|
print("Waiting for Flowfile UI to start...")
|
|
266
261
|
time.sleep(1)
|
|
267
262
|
else:
|
|
268
|
-
logger.error(
|
|
269
|
-
|
|
270
|
-
|
|
263
|
+
logger.error(
|
|
264
|
+
"Failed to start server: API did not become responsive within 60 seconds. "
|
|
265
|
+
"Try again or start service by running\n"
|
|
266
|
+
"flowfile run ui"
|
|
267
|
+
)
|
|
271
268
|
if _server_process and _server_process.stderr:
|
|
272
269
|
try:
|
|
273
|
-
stderr_output: str = _server_process.stderr.read().decode(errors=
|
|
270
|
+
stderr_output: str = _server_process.stderr.read().decode(errors="ignore")
|
|
274
271
|
logger.error(f"Server process stderr:\n{stderr_output[:1000]}...")
|
|
275
272
|
except Exception as read_err:
|
|
276
273
|
logger.error(f"Could not read stderr from server process: {read_err}")
|
|
@@ -286,7 +283,7 @@ def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) -> Tup
|
|
|
286
283
|
logger.error(f"An unexpected error occurred while starting the server process: {e}")
|
|
287
284
|
if _server_process and _server_process.stderr:
|
|
288
285
|
try:
|
|
289
|
-
stderr_output = _server_process.stderr.read().decode(errors=
|
|
286
|
+
stderr_output = _server_process.stderr.read().decode(errors="ignore")
|
|
290
287
|
logger.error(f"Server process stderr:\n{stderr_output[:1000]}...")
|
|
291
288
|
except Exception as read_err:
|
|
292
289
|
logger.error(f"Could not read stderr from server process: {read_err}")
|
|
@@ -295,17 +292,13 @@ def start_flowfile_server_process(module_name: str = DEFAULT_MODULE_NAME) -> Tup
|
|
|
295
292
|
return False, False
|
|
296
293
|
|
|
297
294
|
|
|
298
|
-
def get_auth_token() ->
|
|
295
|
+
def get_auth_token() -> str | None:
|
|
299
296
|
"""Get an authentication token from the Flowfile API."""
|
|
300
297
|
try:
|
|
301
|
-
response: requests.Response = requests.post(
|
|
302
|
-
f"{FLOWFILE_BASE_URL}/auth/token",
|
|
303
|
-
json={},
|
|
304
|
-
timeout=5
|
|
305
|
-
)
|
|
298
|
+
response: requests.Response = requests.post(f"{FLOWFILE_BASE_URL}/auth/token", json={}, timeout=5)
|
|
306
299
|
response.raise_for_status()
|
|
307
|
-
token_data:
|
|
308
|
-
access_token:
|
|
300
|
+
token_data: dict[str, Any] = response.json()
|
|
301
|
+
access_token: str | None = token_data.get("access_token")
|
|
309
302
|
if not access_token:
|
|
310
303
|
logger.error("Auth token endpoint succeeded but 'access_token' was missing in response.")
|
|
311
304
|
return None
|
|
@@ -319,7 +312,7 @@ def get_auth_token() -> Optional[str]:
|
|
|
319
312
|
return None
|
|
320
313
|
|
|
321
314
|
|
|
322
|
-
def import_flow_to_editor(flow_path: Path, auth_token: str) ->
|
|
315
|
+
def import_flow_to_editor(flow_path: Path, auth_token: str) -> int | None:
|
|
323
316
|
"""Import the flow into the Flowfile editor using the API endpoint."""
|
|
324
317
|
if not flow_path.is_file():
|
|
325
318
|
logger.error(f"Flow file not found: {flow_path}")
|
|
@@ -329,18 +322,15 @@ def import_flow_to_editor(flow_path: Path, auth_token: str) -> Optional[int]:
|
|
|
329
322
|
return None
|
|
330
323
|
|
|
331
324
|
try:
|
|
332
|
-
headers:
|
|
333
|
-
params:
|
|
325
|
+
headers: dict[str, str] = {"Authorization": f"Bearer {auth_token}"}
|
|
326
|
+
params: dict[str, str] = {"flow_path": str(flow_path)}
|
|
334
327
|
response: requests.Response = requests.get(
|
|
335
|
-
f"{FLOWFILE_BASE_URL}/import_flow/",
|
|
336
|
-
params=params,
|
|
337
|
-
headers=headers,
|
|
338
|
-
timeout=10
|
|
328
|
+
f"{FLOWFILE_BASE_URL}/import_flow/", params=params, headers=headers, timeout=10
|
|
339
329
|
)
|
|
340
330
|
response.raise_for_status()
|
|
341
331
|
|
|
342
|
-
flow_id_data:
|
|
343
|
-
flow_id:
|
|
332
|
+
flow_id_data: int | dict[str, Any] | Any = response.json()
|
|
333
|
+
flow_id: int | None = None
|
|
344
334
|
|
|
345
335
|
if isinstance(flow_id_data, int):
|
|
346
336
|
flow_id = flow_id_data
|
|
@@ -355,7 +345,7 @@ def import_flow_to_editor(flow_path: Path, auth_token: str) -> Optional[int]:
|
|
|
355
345
|
|
|
356
346
|
except requests.exceptions.RequestException as e:
|
|
357
347
|
logger.error(f"Failed to import flow: {e}")
|
|
358
|
-
if hasattr(e,
|
|
348
|
+
if hasattr(e, "response") and e.response is not None:
|
|
359
349
|
logger.error(f"Server response: {e.response.status_code} - {e.response.text[:500]}")
|
|
360
350
|
return None
|
|
361
351
|
except Exception as e:
|
|
@@ -364,10 +354,10 @@ def import_flow_to_editor(flow_path: Path, auth_token: str) -> Optional[int]:
|
|
|
364
354
|
|
|
365
355
|
|
|
366
356
|
def _save_flow_to_location(
|
|
367
|
-
|
|
368
|
-
) ->
|
|
357
|
+
flow_graph: FlowGraph, storage_location: str | None
|
|
358
|
+
) -> tuple[Path | None, TemporaryDirectory | None]:
|
|
369
359
|
"""Handles graph saving, path resolution, and temporary directory creation."""
|
|
370
|
-
temp_dir_obj:
|
|
360
|
+
temp_dir_obj: TemporaryDirectory | None = None
|
|
371
361
|
flow_file_path: Path
|
|
372
362
|
try:
|
|
373
363
|
if storage_location:
|
|
@@ -409,7 +399,7 @@ def _open_flow_in_browser(flow_id: int) -> None:
|
|
|
409
399
|
logger.info("Not in unified mode ('electron'), browser will not be opened automatically.")
|
|
410
400
|
|
|
411
401
|
|
|
412
|
-
def _cleanup_temporary_storage(temp_dir_obj:
|
|
402
|
+
def _cleanup_temporary_storage(temp_dir_obj: TemporaryDirectory | None) -> None:
|
|
413
403
|
"""Safely cleans up the temporary directory if one was created."""
|
|
414
404
|
if temp_dir_obj:
|
|
415
405
|
try:
|
|
@@ -419,8 +409,12 @@ def _cleanup_temporary_storage(temp_dir_obj: Optional[TemporaryDirectory]) -> No
|
|
|
419
409
|
logger.error(f"Error cleaning up temporary directory {temp_dir_obj.name}: {e}")
|
|
420
410
|
|
|
421
411
|
|
|
422
|
-
def open_graph_in_editor(
|
|
423
|
-
|
|
412
|
+
def open_graph_in_editor(
|
|
413
|
+
flow_graph: FlowGraph,
|
|
414
|
+
storage_location: str | None = None,
|
|
415
|
+
module_name: str = DEFAULT_MODULE_NAME,
|
|
416
|
+
automatically_open_browser: bool = True,
|
|
417
|
+
) -> bool:
|
|
424
418
|
"""
|
|
425
419
|
Save the ETL graph, ensure the Flowfile server is running (starting it
|
|
426
420
|
if necessary), import the graph via API, and open it in a new browser
|
|
@@ -436,7 +430,7 @@ def open_graph_in_editor(flow_graph: FlowGraph, storage_location: Optional[str]
|
|
|
436
430
|
Returns:
|
|
437
431
|
True if the graph was successfully imported, False otherwise.
|
|
438
432
|
"""
|
|
439
|
-
temp_dir_obj:
|
|
433
|
+
temp_dir_obj: TemporaryDirectory | None = None
|
|
440
434
|
try:
|
|
441
435
|
original_execution_settings = flow_graph.flow_settings.model_copy()
|
|
442
436
|
flow_graph.flow_settings.execution_location = "local"
|
|
@@ -457,7 +451,7 @@ def open_graph_in_editor(flow_graph: FlowGraph, storage_location: Optional[str]
|
|
|
457
451
|
if flow_id is not None:
|
|
458
452
|
if flow_in_single_mode and automatically_open_browser:
|
|
459
453
|
_open_flow_in_browser(flow_id)
|
|
460
|
-
logger.info(
|
|
454
|
+
logger.info("Ui available at: http://127.0.0.1:63578/ui#/main/designer")
|
|
461
455
|
return True
|
|
462
456
|
else:
|
|
463
457
|
return False
|
|
@@ -466,4 +460,4 @@ def open_graph_in_editor(flow_graph: FlowGraph, storage_location: Optional[str]
|
|
|
466
460
|
logger.error(f"An unexpected error occurred in open_graph_in_editor: {e}", exc_info=True)
|
|
467
461
|
return False
|
|
468
462
|
finally:
|
|
469
|
-
_cleanup_temporary_storage(temp_dir_obj)
|
|
463
|
+
_cleanup_temporary_storage(temp_dir_obj)
|
flowfile/web/__init__.py
CHANGED
|
@@ -4,14 +4,16 @@ Web interface for Flowfile.
|
|
|
4
4
|
Extends the flowfile_core FastAPI app to serve the Vue.js frontend
|
|
5
5
|
and includes worker functionality.
|
|
6
6
|
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
7
9
|
import os
|
|
8
10
|
import time
|
|
9
|
-
from pathlib import Path
|
|
10
11
|
import webbrowser
|
|
11
|
-
import
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
12
14
|
from fastapi import FastAPI, Response
|
|
13
|
-
from fastapi.staticfiles import StaticFiles
|
|
14
15
|
from fastapi.responses import FileResponse, RedirectResponse
|
|
16
|
+
from fastapi.staticfiles import StaticFiles
|
|
15
17
|
|
|
16
18
|
static_dir = Path(__file__).parent / "static"
|
|
17
19
|
|
|
@@ -52,8 +54,8 @@ def extend_app(app: FastAPI):
|
|
|
52
54
|
@app.get("/single_mode")
|
|
53
55
|
async def in_single_mode() -> bool:
|
|
54
56
|
print("Checking if single file mode is enabled")
|
|
55
|
-
print(os.environ.get(
|
|
56
|
-
return os.environ.get(
|
|
57
|
+
print(os.environ.get("FLOWFILE_SINGLE_FILE_MODE"))
|
|
58
|
+
return os.environ.get("FLOWFILE_SINGLE_FILE_MODE", "0") == "1"
|
|
57
59
|
|
|
58
60
|
@app.get("/ui", include_in_schema=False)
|
|
59
61
|
async def web_ui_root():
|
|
@@ -95,8 +97,8 @@ def include_worker_routes(app: FastAPI):
|
|
|
95
97
|
"""
|
|
96
98
|
try:
|
|
97
99
|
# Import worker modules
|
|
100
|
+
from flowfile_worker import CACHE_DIR, mp_context
|
|
98
101
|
from flowfile_worker.routes import router as worker_router
|
|
99
|
-
from flowfile_worker import mp_context, CACHE_DIR
|
|
100
102
|
|
|
101
103
|
# Add lifecycle event handler for worker cleanup
|
|
102
104
|
@app.on_event("shutdown")
|
|
@@ -133,12 +135,15 @@ def start_server(host="127.0.0.1", port=63578, open_browser=True):
|
|
|
133
135
|
This function is a wrapper around flowfile_core.main.run().
|
|
134
136
|
"""
|
|
135
137
|
# Set electron mode
|
|
136
|
-
|
|
138
|
+
if "FLOWFILE_MODE" not in os.environ:
|
|
139
|
+
os.environ["FLOWFILE_MODE"] = "electron"
|
|
137
140
|
|
|
138
141
|
# Import core app
|
|
139
|
-
from flowfile_core.main import run, app as core_app
|
|
140
142
|
from flowfile_core.configs.settings import OFFLOAD_TO_WORKER
|
|
141
|
-
|
|
143
|
+
from flowfile_core.main import app as core_app
|
|
144
|
+
from flowfile_core.main import run
|
|
145
|
+
|
|
146
|
+
if host != "127.0.0.1":
|
|
142
147
|
raise NotImplementedError("Other then local host is not supported")
|
|
143
148
|
if port != 63578:
|
|
144
149
|
raise NotImplementedError("Service must run on port 63578")
|