Flowfile 0.5.1__py3-none-any.whl → 0.5.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- build_backends/main.py +25 -22
- build_backends/main_prd.py +10 -19
- flowfile/__init__.py +194 -74
- flowfile/__main__.py +10 -7
- flowfile/api.py +51 -57
- flowfile/web/__init__.py +14 -9
- flowfile/web/static/assets/AdminView-f53bad23.css +129 -0
- flowfile/web/static/assets/AdminView-f9847d67.js +713 -0
- flowfile/web/static/assets/CloudConnectionView-cf85f943.css +72 -0
- flowfile/web/static/assets/{CloudConnectionManager-0dfba9f2.js → CloudConnectionView-faace55b.js} +11 -11
- flowfile/web/static/assets/{CloudStorageReader-29d14fcc.css → CloudStorageReader-24c54524.css} +27 -27
- flowfile/web/static/assets/{CloudStorageReader-d5b1b6c9.js → CloudStorageReader-d86ecaa7.js} +10 -8
- flowfile/web/static/assets/{CloudStorageWriter-00d87aad.js → CloudStorageWriter-0f4d9a44.js} +10 -8
- flowfile/web/static/assets/{CloudStorageWriter-b0ee067f.css → CloudStorageWriter-60547855.css} +26 -26
- flowfile/web/static/assets/ColumnActionInput-c44b7aee.css +159 -0
- flowfile/web/static/assets/ColumnActionInput-f4189ae0.js +330 -0
- flowfile/web/static/assets/{ColumnSelector-47996a16.css → ColumnSelector-371637fb.css} +2 -2
- flowfile/web/static/assets/{ColumnSelector-4685e75d.js → ColumnSelector-e66b33da.js} +3 -5
- flowfile/web/static/assets/ContextMenu-49463352.js +9 -0
- flowfile/web/static/assets/ContextMenu-dd5f3f25.js +9 -0
- flowfile/web/static/assets/ContextMenu-f709b884.js +9 -0
- flowfile/web/static/assets/ContextMenu.vue_vue_type_script_setup_true_lang-a1bd6314.js +59 -0
- flowfile/web/static/assets/{CrossJoin-702a3edd.js → CrossJoin-24694b8f.js} +12 -10
- flowfile/web/static/assets/{CrossJoin-1119d18e.css → CrossJoin-71b4cc10.css} +20 -20
- flowfile/web/static/assets/{CustomNode-b1519993.js → CustomNode-569d45ff.js} +43 -24
- flowfile/web/static/assets/CustomNode-edb9b939.css +42 -0
- flowfile/web/static/assets/{DatabaseConnectionSettings-0c04b2e5.css → DatabaseConnectionSettings-c20a1e16.css} +23 -21
- flowfile/web/static/assets/{DatabaseConnectionSettings-6f3e4ea5.js → DatabaseConnectionSettings-cfc08938.js} +5 -4
- flowfile/web/static/assets/{DatabaseReader-ae61773c.css → DatabaseReader-5bf8c75b.css} +41 -46
- flowfile/web/static/assets/{DatabaseReader-d38c7295.js → DatabaseReader-701feabb.js} +25 -15
- flowfile/web/static/assets/{DatabaseManager-cf5ef661.js → DatabaseView-0482e5b5.js} +11 -11
- flowfile/web/static/assets/DatabaseView-6655afd6.css +57 -0
- flowfile/web/static/assets/{DatabaseWriter-b04ef46a.js → DatabaseWriter-16721989.js} +17 -10
- flowfile/web/static/assets/{DatabaseWriter-2f570e53.css → DatabaseWriter-bdcf2c8b.css} +29 -27
- flowfile/web/static/assets/{designer-8da3ba3a.css → DesignerView-49abb835.css} +783 -663
- flowfile/web/static/assets/{designer-9633482a.js → DesignerView-f64749fb.js} +1292 -3253
- flowfile/web/static/assets/{documentation-ca400224.js → DocumentationView-61bd2990.js} +5 -5
- flowfile/web/static/assets/{documentation-12216a74.css → DocumentationView-9ea6e871.css} +9 -9
- flowfile/web/static/assets/{ExploreData-2d0cf4db.css → ExploreData-10c5acc8.css} +13 -12
- flowfile/web/static/assets/{ExploreData-5fa10ed8.js → ExploreData-e2735b13.js} +18 -9
- flowfile/web/static/assets/{ExternalSource-d39af878.js → ExternalSource-2535c3b2.js} +9 -7
- flowfile/web/static/assets/{ExternalSource-e37b6275.css → ExternalSource-7ac7373f.css} +20 -20
- flowfile/web/static/assets/Filter-2cdbc93c.js +287 -0
- flowfile/web/static/assets/Filter-7494ea97.css +48 -0
- flowfile/web/static/assets/{Formula-bb96803d.css → Formula-53d58c43.css} +7 -7
- flowfile/web/static/assets/{Formula-6b04fb1d.js → Formula-fcda3c2c.js} +13 -11
- flowfile/web/static/assets/{FuzzyMatch-1010f966.css → FuzzyMatch-ad6361d6.css} +68 -69
- flowfile/web/static/assets/{FuzzyMatch-999521f4.js → FuzzyMatch-f8d3b7d3.js} +12 -10
- flowfile/web/static/assets/{Pivot-cf333e3d.css → GraphSolver-4b4d7db9.css} +5 -5
- flowfile/web/static/assets/{GraphSolver-17dd2198.js → GraphSolver-72eaa695.js} +14 -12
- flowfile/web/static/assets/GroupBy-5792782d.css +9 -0
- flowfile/web/static/assets/{GroupBy-6b039e18.js → GroupBy-8aa0598b.js} +9 -7
- flowfile/web/static/assets/{Join-fd79b451.css → Join-28b5e18f.css} +22 -22
- flowfile/web/static/assets/{Join-24d0f113.js → Join-e40f0ffa.js} +13 -11
- flowfile/web/static/assets/LoginView-5111c9ae.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-9b6f3224.js} +170 -116
- flowfile/web/static/assets/{MultiSelect-0e8724a3.js → MultiSelect-ef28e19e.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-83b3bbfd.js} +1 -1
- flowfile/web/static/assets/NodeDesigner-94cd4dd3.css +1429 -0
- flowfile/web/static/assets/NodeDesigner-d2b7ee2b.js +2712 -0
- flowfile/web/static/assets/{NumericInput-3d63a470.js → NumericInput-1d789794.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-7775f83e.js} +5 -2
- flowfile/web/static/assets/Output-692dd25d.css +37 -0
- flowfile/web/static/assets/{Output-edea9802.js → Output-cefef801.js} +14 -10
- flowfile/web/static/assets/{GraphSolver-f0cb7bfb.css → Pivot-0eda81b4.css} +5 -5
- flowfile/web/static/assets/{Pivot-61d19301.js → Pivot-bab1b75b.js} +12 -10
- flowfile/web/static/assets/PivotValidation-0e905b1a.css +13 -0
- flowfile/web/static/assets/PivotValidation-41b57ad6.css +13 -0
- flowfile/web/static/assets/{PivotValidation-f97fec5b.js → PivotValidation-e7941f91.js} +3 -3
- flowfile/web/static/assets/{PivotValidation-de9f43fe.js → PivotValidation-fba09336.js} +3 -3
- flowfile/web/static/assets/{PolarsCode-650322d1.css → PolarsCode-2b1f1f23.css} +4 -4
- flowfile/web/static/assets/{PolarsCode-bc3c9984.js → PolarsCode-740e40fa.js} +18 -9
- flowfile/web/static/assets/PopOver-862d7e28.js +939 -0
- flowfile/web/static/assets/PopOver-d96599db.css +33 -0
- flowfile/web/static/assets/{Read-64a3f259.js → Read-225cc63f.js} +16 -12
- flowfile/web/static/assets/{Read-e808b239.css → Read-90f366bc.css} +15 -15
- flowfile/web/static/assets/{RecordCount-3d5039be.js → RecordCount-ffc71eca.js} +6 -4
- flowfile/web/static/assets/{RecordId-597510e0.js → RecordId-a70bb8df.js} +9 -7
- flowfile/web/static/assets/{SQLQueryComponent-df51adbe.js → SQLQueryComponent-15a421f5.js} +3 -3
- flowfile/web/static/assets/SQLQueryComponent-edb90b98.css +29 -0
- flowfile/web/static/assets/{Sample-4be0a507.js → Sample-6c26afc7.js} +6 -4
- flowfile/web/static/assets/SecretSelector-6329f743.css +43 -0
- flowfile/web/static/assets/SecretSelector-ceed9496.js +113 -0
- flowfile/web/static/assets/{SecretManager-4839be57.js → SecretsView-214d255a.js} +35 -36
- flowfile/web/static/assets/SecretsView-aa291340.css +38 -0
- flowfile/web/static/assets/{Select-9b72f201.js → Select-8fc29999.js} +9 -7
- 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-7ded385d.js → SettingsSection-3f70e4c3.js} +3 -3
- flowfile/web/static/assets/{SettingsSection-f0f75a42.js → SettingsSection-83090218.js} +3 -3
- flowfile/web/static/assets/{SettingsSection-2e4d03c4.css → SettingsSection-8f980839.css} +4 -4
- flowfile/web/static/assets/{SettingsSection-e1e9c953.js → SettingsSection-9f0d1725.js} +3 -3
- flowfile/web/static/assets/SetupView-3fa0aa03.js +160 -0
- flowfile/web/static/assets/SetupView-e2da3442.css +230 -0
- flowfile/web/static/assets/{SingleSelect-6c777aac.js → SingleSelect-a4a568cb.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-c8ebdd33.js} +1 -1
- flowfile/web/static/assets/{SliderInput-7cb93e62.js → SliderInput-be533e71.js} +7 -4
- flowfile/web/static/assets/SliderInput-f2e4f23c.css +4 -0
- flowfile/web/static/assets/{Sort-6cbde21a.js → Sort-154dad81.js} +9 -7
- flowfile/web/static/assets/Sort-4abb7fae.css +9 -0
- flowfile/web/static/assets/{TextInput-d9a40c11.js → TextInput-454e2bda.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-e86510d0.js} +5 -2
- flowfile/web/static/assets/{TextToRows-5d2c1190.css → TextToRows-12afb4f4.css} +10 -10
- flowfile/web/static/assets/{TextToRows-c4fcbf4d.js → TextToRows-ea73433d.js} +11 -10
- flowfile/web/static/assets/{ToggleSwitch-4ef91d19.js → ToggleSwitch-9d7b30f1.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-00f2580e.js} +1 -1
- flowfile/web/static/assets/{UnavailableFields-5edd5322.css → UnavailableFields-394a1f78.css} +14 -14
- flowfile/web/static/assets/{UnavailableFields-a03f512c.js → UnavailableFields-b72a2c72.js} +4 -4
- flowfile/web/static/assets/{Union-bfe9b996.js → Union-1e44f263.js} +8 -6
- flowfile/web/static/assets/{Union-af6c3d9b.css → Union-d6a8d7d5.css} +7 -7
- flowfile/web/static/assets/Unique-2b705521.css +3 -0
- flowfile/web/static/assets/{Unique-5d023a27.js → Unique-a3bc6d0a.js} +13 -10
- flowfile/web/static/assets/{Unpivot-1e422df3.css → Unpivot-b6ad6427.css} +7 -7
- flowfile/web/static/assets/{Unpivot-91cc5354.js → Unpivot-e27935fc.js} +11 -9
- flowfile/web/static/assets/{UnpivotValidation-7ee2de44.js → UnpivotValidation-72497680.js} +3 -3
- flowfile/web/static/assets/UnpivotValidation-d5ca3b7b.css +13 -0
- flowfile/web/static/assets/{VueGraphicWalker-ed5ab88b.css → VueGraphicWalker-430f0b86.css} +1 -1
- flowfile/web/static/assets/{VueGraphicWalker-e51b9924.js → VueGraphicWalker-d9ab70a3.js} +4 -4
- flowfile/web/static/assets/{api-cf1221f0.js → api-a2102880.js} +1 -1
- flowfile/web/static/assets/{api-c1bad5ca.js → api-f75042b0.js} +1 -1
- flowfile/web/static/assets/{dropDown-35135ba8.css → dropDown-1d6acbd9.css} +41 -41
- flowfile/web/static/assets/{dropDown-614b998d.js → dropDown-2798a109.js} +3 -3
- flowfile/web/static/assets/{fullEditor-f7971590.js → fullEditor-cf7d7d93.js} +11 -10
- flowfile/web/static/assets/{fullEditor-178376bb.css → fullEditor-fe9f7e18.css} +77 -65
- flowfile/web/static/assets/{genericNodeSettings-4fe5f36b.js → genericNodeSettings-14eac1c3.js} +5 -5
- flowfile/web/static/assets/{genericNodeSettings-924759c7.css → genericNodeSettings-3b2507ea.css} +10 -10
- flowfile/web/static/assets/{index-5429bbf8.js → index-387a6f18.js} +41806 -40958
- flowfile/web/static/assets/index-6b367bb5.js +38 -0
- flowfile/web/static/assets/{index-50508d4d.css → index-e96ab018.css} +2184 -569
- flowfile/web/static/assets/index-f0a6e5a5.js +2696 -0
- flowfile/web/static/assets/node.types-2c15bb7e.js +82 -0
- flowfile/web/static/assets/nodeInput-ed2ae8d7.js +2 -0
- flowfile/web/static/assets/{outputCsv-076b85ab.js → outputCsv-3c1757e8.js} +3 -3
- flowfile/web/static/assets/outputCsv-b9a072af.css +2499 -0
- flowfile/web/static/assets/{outputExcel-0fd17dbe.js → outputExcel-686e1f48.js} +3 -3
- flowfile/web/static/assets/{outputExcel-b41305c0.css → outputExcel-f5d272b2.css} +26 -26
- flowfile/web/static/assets/outputParquet-54597c3c.css +4 -0
- flowfile/web/static/assets/{outputParquet-b61e0847.js → outputParquet-df28faa7.js} +4 -4
- flowfile/web/static/assets/{readCsv-c767cb37.css → readCsv-3bfac4c3.css} +15 -15
- flowfile/web/static/assets/{readCsv-a8bb8b61.js → readCsv-e37eee21.js} +3 -3
- flowfile/web/static/assets/{readExcel-806d2826.css → readExcel-3db6b763.css} +13 -13
- flowfile/web/static/assets/{readExcel-67b4aee0.js → readExcel-a13f14bb.js} +5 -5
- flowfile/web/static/assets/{readParquet-92ce1dbc.js → readParquet-344cf746.js} +3 -3
- flowfile/web/static/assets/{readParquet-48c81530.css → readParquet-c5244ad5.css} +4 -4
- flowfile/web/static/assets/secrets.api-ae198c5c.js +65 -0
- flowfile/web/static/assets/{selectDynamic-92e25ee3.js → selectDynamic-6b4b0767.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-31ba0e0b.js} +31 -640
- flowfile/web/static/assets/{vue-content-loader.es-2c8e608f.js → vue-content-loader.es-4469c8ff.js} +1 -1
- flowfile/web/static/index.html +2 -2
- {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/METADATA +3 -4
- flowfile-0.5.4.dist-info/RECORD +407 -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 +64 -19
- 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 +145 -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/__init__.py +11 -0
- flowfile_core/flowfile/code_generator/code_generator.py +706 -247
- 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 +493 -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 +920 -571
- flowfile_core/flowfile/flow_graph_utils.py +31 -49
- flowfile_core/flowfile/flow_node/flow_node.py +379 -258
- 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 +19 -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 +278 -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 +46 -4
- 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 +96 -66
- 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 +123 -18
- 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 +117 -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/database/__init__.py +36 -0
- flowfile_frame/database/connection_manager.py +205 -0
- flowfile_frame/database/frame_helpers.py +249 -0
- 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 +41 -33
- 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 +114 -21
- flowfile_worker/spawner.py +89 -54
- 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/ContextMenu-23e909da.js +0 -41
- flowfile/web/static/assets/ContextMenu-4c74eef1.css +0 -26
- flowfile/web/static/assets/ContextMenu-63cfa99b.css +0 -26
- flowfile/web/static/assets/ContextMenu-70ae0c79.js +0 -41
- flowfile/web/static/assets/ContextMenu-c13f91d0.css +0 -26
- flowfile/web/static/assets/ContextMenu-f149cf7c.js +0 -41
- 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/GroupBy-b9505323.css +0 -51
- flowfile/web/static/assets/ManualInput-3246a08d.css +0 -96
- flowfile/web/static/assets/Output-283fe388.css +0 -37
- flowfile/web/static/assets/PivotValidation-891ddfb0.css +0 -13
- flowfile/web/static/assets/PivotValidation-c46cd420.css +0 -13
- flowfile/web/static/assets/SQLQueryComponent-36cef432.css +0 -27
- flowfile/web/static/assets/SliderInput-b8fb6a8c.css +0 -4
- flowfile/web/static/assets/Sort-3643d625.css +0 -51
- flowfile/web/static/assets/Unique-f9fb0809.css +0 -51
- 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.4.dist-info}/WHEEL +0 -0
- {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/entry_points.txt +0 -0
- {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
# Fixed custom_node.py with proper type hints
|
|
2
2
|
|
|
3
|
+
from typing import Any, TypeVar
|
|
4
|
+
|
|
3
5
|
import polars as pl
|
|
4
6
|
from pydantic import BaseModel
|
|
5
|
-
|
|
6
|
-
from flowfile_core.flowfile.node_designer.ui_components import
|
|
7
|
+
|
|
8
|
+
from flowfile_core.flowfile.node_designer.ui_components import (
|
|
9
|
+
FlowfileInComponent,
|
|
10
|
+
IncomingColumns,
|
|
11
|
+
SecretSelector,
|
|
12
|
+
Section,
|
|
13
|
+
)
|
|
7
14
|
from flowfile_core.schemas.schemas import NodeTemplate, NodeTypeLiteral, TransformTypeLiteral
|
|
8
15
|
|
|
9
16
|
|
|
@@ -22,9 +29,9 @@ def to_frontend_schema(model_instance: BaseModel) -> dict:
|
|
|
22
29
|
A dictionary representation of the model.
|
|
23
30
|
"""
|
|
24
31
|
result = {}
|
|
25
|
-
extra_fields = getattr(model_instance,
|
|
32
|
+
extra_fields = getattr(model_instance, "__pydantic_extra__", {})
|
|
26
33
|
model_fields = {k: getattr(model_instance, k) for k in model_instance.model_fields.keys()}
|
|
27
|
-
for key, value in (extra_fields|model_fields).items():
|
|
34
|
+
for key, value in (extra_fields | model_fields).items():
|
|
28
35
|
result[key] = _convert_value(value)
|
|
29
36
|
return result
|
|
30
37
|
|
|
@@ -34,25 +41,18 @@ def _convert_value(value: Any) -> Any:
|
|
|
34
41
|
Helper function to convert any value to a frontend-ready format.
|
|
35
42
|
"""
|
|
36
43
|
if isinstance(value, Section):
|
|
37
|
-
section_data = value.model_dump(
|
|
38
|
-
include={'title', 'description', 'hidden'},
|
|
39
|
-
exclude_none=True
|
|
40
|
-
)
|
|
44
|
+
section_data = value.model_dump(include={"title", "description", "hidden"}, exclude_none=True)
|
|
41
45
|
section_data["component_type"] = "Section"
|
|
42
|
-
section_data["components"] = {
|
|
43
|
-
key: _convert_value(comp)
|
|
44
|
-
for key, comp in value.get_components().items()
|
|
45
|
-
}
|
|
46
|
+
section_data["components"] = {key: _convert_value(comp) for key, comp in value.get_components().items()}
|
|
46
47
|
return section_data
|
|
47
48
|
|
|
48
49
|
elif isinstance(value, FlowfileInComponent):
|
|
49
50
|
component_dict = value.model_dump(exclude_none=True)
|
|
50
|
-
if
|
|
51
|
-
if component_dict[
|
|
52
|
-
|
|
53
|
-
issubclass(component_dict['options'], IncomingColumns)
|
|
51
|
+
if "options" in component_dict:
|
|
52
|
+
if component_dict["options"] is IncomingColumns or (
|
|
53
|
+
isinstance(component_dict["options"], type) and issubclass(component_dict["options"], IncomingColumns)
|
|
54
54
|
):
|
|
55
|
-
component_dict[
|
|
55
|
+
component_dict["options"] = {"__type__": "IncomingColumns"}
|
|
56
56
|
return component_dict
|
|
57
57
|
elif isinstance(value, BaseModel):
|
|
58
58
|
return to_frontend_schema(value)
|
|
@@ -67,7 +67,7 @@ def _convert_value(value: Any) -> Any:
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
# Type variable for the Section factory
|
|
70
|
-
T = TypeVar(
|
|
70
|
+
T = TypeVar("T", bound=Section)
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def create_section(**components: FlowfileInComponent) -> Section:
|
|
@@ -104,17 +104,30 @@ class NodeSettings(BaseModel):
|
|
|
104
104
|
main_config = main_config_section
|
|
105
105
|
advanced_options = advanced_config_section
|
|
106
106
|
"""
|
|
107
|
+
|
|
107
108
|
class Config:
|
|
108
|
-
extra =
|
|
109
|
+
extra = "allow"
|
|
109
110
|
arbitrary_types_allowed = True
|
|
110
111
|
|
|
112
|
+
def has_sections(self) -> bool:
|
|
113
|
+
"""Check if this settings class has any sections defined."""
|
|
114
|
+
if self.model_fields:
|
|
115
|
+
return True
|
|
116
|
+
extra = getattr(self, "__pydantic_extra__", {})
|
|
117
|
+
return bool(extra)
|
|
118
|
+
|
|
119
|
+
def is_empty(self) -> bool:
|
|
120
|
+
"""Check if this is an empty settings class with no configuration."""
|
|
121
|
+
|
|
122
|
+
return not self.has_sections()
|
|
123
|
+
|
|
111
124
|
def __init__(self, **sections):
|
|
112
125
|
"""
|
|
113
126
|
Initialize NodeSettings with sections as keyword arguments.
|
|
114
127
|
"""
|
|
115
128
|
super().__init__(**sections)
|
|
116
129
|
|
|
117
|
-
def populate_values(self, values:
|
|
130
|
+
def populate_values(self, values: dict[str, Any]) -> "NodeSettings":
|
|
118
131
|
"""
|
|
119
132
|
Populates the settings with values received from the frontend.
|
|
120
133
|
|
|
@@ -133,7 +146,7 @@ class NodeSettings(BaseModel):
|
|
|
133
146
|
all_sections = {}
|
|
134
147
|
|
|
135
148
|
# Get extra fields
|
|
136
|
-
extra_fields = getattr(self,
|
|
149
|
+
extra_fields = getattr(self, "__pydantic_extra__", {})
|
|
137
150
|
all_sections.update(extra_fields)
|
|
138
151
|
|
|
139
152
|
# Get defined fields that are Sections
|
|
@@ -150,6 +163,80 @@ class NodeSettings(BaseModel):
|
|
|
150
163
|
component.set_value(section_values[component_name])
|
|
151
164
|
return self
|
|
152
165
|
|
|
166
|
+
def get_value(self, field_name: str) -> Any:
|
|
167
|
+
"""
|
|
168
|
+
Gets the current value of a field by name.
|
|
169
|
+
|
|
170
|
+
Searches through direct fields, extra fields, and sections.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
field_name: The name of the field to retrieve.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
The current value of the field, or None if not found.
|
|
177
|
+
"""
|
|
178
|
+
# Check direct model fields
|
|
179
|
+
if field_name in self.model_fields:
|
|
180
|
+
component = getattr(self, field_name, None)
|
|
181
|
+
if component is not None:
|
|
182
|
+
if isinstance(component, FlowfileInComponent):
|
|
183
|
+
return component.value
|
|
184
|
+
return component
|
|
185
|
+
|
|
186
|
+
# Check pydantic extra fields
|
|
187
|
+
extras = getattr(self, "__pydantic_extra__", {}) or {}
|
|
188
|
+
if field_name in extras:
|
|
189
|
+
component = extras[field_name]
|
|
190
|
+
if isinstance(component, FlowfileInComponent):
|
|
191
|
+
return component.value
|
|
192
|
+
return component
|
|
193
|
+
|
|
194
|
+
# Check within sections (both in model_fields and extras)
|
|
195
|
+
all_fields = {**{k: getattr(self, k) for k in self.model_fields}, **extras}
|
|
196
|
+
for value in all_fields.values():
|
|
197
|
+
if isinstance(value, Section):
|
|
198
|
+
components = value.get_components()
|
|
199
|
+
if field_name in components:
|
|
200
|
+
component = components[field_name]
|
|
201
|
+
if isinstance(component, FlowfileInComponent):
|
|
202
|
+
return component.value
|
|
203
|
+
return component
|
|
204
|
+
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
def get_all_components(self) -> dict[str, FlowfileInComponent]:
|
|
208
|
+
"""
|
|
209
|
+
Returns all UI components in the settings, including those nested in sections.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
Dictionary mapping field names to their FlowfileInComponent instances.
|
|
213
|
+
"""
|
|
214
|
+
components = {}
|
|
215
|
+
|
|
216
|
+
# Get from model fields
|
|
217
|
+
for field_name in self.model_fields:
|
|
218
|
+
value = getattr(self, field_name, None)
|
|
219
|
+
if isinstance(value, FlowfileInComponent):
|
|
220
|
+
components[field_name] = value
|
|
221
|
+
elif isinstance(value, Section):
|
|
222
|
+
components.update(value.get_components())
|
|
223
|
+
|
|
224
|
+
# Get from extra fields
|
|
225
|
+
extras = getattr(self, "__pydantic_extra__", {}) or {}
|
|
226
|
+
for field_name, value in extras.items():
|
|
227
|
+
if isinstance(value, FlowfileInComponent):
|
|
228
|
+
components[field_name] = value
|
|
229
|
+
elif isinstance(value, Section):
|
|
230
|
+
components.update(value.get_components())
|
|
231
|
+
|
|
232
|
+
return components
|
|
233
|
+
|
|
234
|
+
def set_secret_context(self, user_id: int, accessed_secrets: set):
|
|
235
|
+
"""Inject execution context into all SecretSelector components."""
|
|
236
|
+
for component in self.get_all_components().values():
|
|
237
|
+
if isinstance(component, SecretSelector):
|
|
238
|
+
component.set_execution_context(user_id, accessed_secrets)
|
|
239
|
+
|
|
153
240
|
|
|
154
241
|
def create_node_settings(**sections: Section) -> NodeSettings:
|
|
155
242
|
"""
|
|
@@ -187,13 +274,13 @@ class SectionBuilder:
|
|
|
187
274
|
advanced_section = builder.build()
|
|
188
275
|
"""
|
|
189
276
|
|
|
190
|
-
def __init__(self, title:
|
|
277
|
+
def __init__(self, title: str | None = None, description: str | None = None, hidden: bool = False):
|
|
191
278
|
self._section = Section(title=title, description=description, hidden=hidden)
|
|
192
279
|
|
|
193
|
-
def add_component(self, name: str, component: FlowfileInComponent) ->
|
|
280
|
+
def add_component(self, name: str, component: FlowfileInComponent) -> "SectionBuilder":
|
|
194
281
|
"""Add a component to the section."""
|
|
195
282
|
setattr(self._section, name, component)
|
|
196
|
-
extra = getattr(self._section,
|
|
283
|
+
extra = getattr(self._section, "__pydantic_extra__", {})
|
|
197
284
|
extra[name] = component
|
|
198
285
|
return self
|
|
199
286
|
|
|
@@ -219,10 +306,10 @@ class NodeSettingsBuilder:
|
|
|
219
306
|
def __init__(self):
|
|
220
307
|
self._settings = NodeSettings()
|
|
221
308
|
|
|
222
|
-
def add_section(self, name: str, section: Section) ->
|
|
309
|
+
def add_section(self, name: str, section: Section) -> "NodeSettingsBuilder":
|
|
223
310
|
"""Add a section to the node settings."""
|
|
224
311
|
setattr(self._settings, name, section)
|
|
225
|
-
extra = getattr(self._settings,
|
|
312
|
+
extra = getattr(self._settings, "__pydantic_extra__", {})
|
|
226
313
|
extra[name] = section
|
|
227
314
|
return self
|
|
228
315
|
|
|
@@ -238,25 +325,29 @@ class CustomNodeBase(BaseModel):
|
|
|
238
325
|
To create a new node, you should inherit from this class and define its
|
|
239
326
|
attributes and the `process` method.
|
|
240
327
|
"""
|
|
328
|
+
|
|
241
329
|
# Core node properties
|
|
242
330
|
node_name: str
|
|
243
331
|
node_category: str = "Custom"
|
|
244
332
|
node_icon: str = "user-defined-icon.png"
|
|
245
|
-
settings_schema:
|
|
333
|
+
settings_schema: NodeSettings | None = None
|
|
246
334
|
|
|
247
335
|
# I/O configuration
|
|
248
336
|
number_of_inputs: int = 1
|
|
249
337
|
number_of_outputs: int = 1
|
|
250
338
|
|
|
251
339
|
# Display properties in the UI
|
|
252
|
-
node_group:
|
|
253
|
-
title:
|
|
254
|
-
intro:
|
|
340
|
+
node_group: str | None = "custom"
|
|
341
|
+
title: str | None = "Custom Node"
|
|
342
|
+
intro: str | None = "A custom node for data processing"
|
|
255
343
|
|
|
256
344
|
# Behavior properties
|
|
257
345
|
node_type: NodeTypeLiteral = "process"
|
|
258
346
|
transform_type: TransformTypeLiteral = "wide"
|
|
259
347
|
|
|
348
|
+
_user_id: int | None = None
|
|
349
|
+
accessed_secrets: set[str] = set()
|
|
350
|
+
|
|
260
351
|
@property
|
|
261
352
|
def item(self):
|
|
262
353
|
"""A unique identifier for the node, derived from its name."""
|
|
@@ -269,11 +360,46 @@ class CustomNodeBase(BaseModel):
|
|
|
269
360
|
"""
|
|
270
361
|
Initialize the node, optionally populating settings from initial values.
|
|
271
362
|
"""
|
|
272
|
-
initial_values = data.pop(
|
|
363
|
+
initial_values = data.pop("initial_values", None)
|
|
273
364
|
super().__init__(**data)
|
|
274
365
|
if self.settings_schema and initial_values:
|
|
275
366
|
self.settings_schema.populate_values(initial_values)
|
|
276
367
|
|
|
368
|
+
def set_execution_context(self, user_id: int):
|
|
369
|
+
"""
|
|
370
|
+
Sets the execution context for the node.
|
|
371
|
+
Called by the framework before executing the node.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
user_id: The ID of the user executing this node.
|
|
375
|
+
"""
|
|
376
|
+
self._user_id = user_id
|
|
377
|
+
self.accessed_secrets = set()
|
|
378
|
+
|
|
379
|
+
def get_accessed_secrets(self) -> set[str]:
|
|
380
|
+
"""
|
|
381
|
+
Returns the set of secret values accessed during this execution.
|
|
382
|
+
Used by the output scanner to detect accidental leaks.
|
|
383
|
+
"""
|
|
384
|
+
return self.accessed_secrets.copy()
|
|
385
|
+
|
|
386
|
+
def get_secret_names(self) -> list[str]:
|
|
387
|
+
"""
|
|
388
|
+
Returns a list of all SecretSelector field names in the settings schema.
|
|
389
|
+
Useful for validation and debugging.
|
|
390
|
+
"""
|
|
391
|
+
from flowfile_core.flowfile.node_designer.ui_components import SecretSelector
|
|
392
|
+
|
|
393
|
+
if self.settings_schema is None:
|
|
394
|
+
return []
|
|
395
|
+
|
|
396
|
+
secret_fields = []
|
|
397
|
+
for name, field in self.settings_schema.get_all_components().items():
|
|
398
|
+
if isinstance(field, SecretSelector):
|
|
399
|
+
secret_fields.append(name)
|
|
400
|
+
|
|
401
|
+
return secret_fields
|
|
402
|
+
|
|
277
403
|
def get_frontend_schema(self) -> dict:
|
|
278
404
|
"""
|
|
279
405
|
Get the frontend-ready schema with current values.
|
|
@@ -303,20 +429,20 @@ class CustomNodeBase(BaseModel):
|
|
|
303
429
|
return schema
|
|
304
430
|
|
|
305
431
|
@classmethod
|
|
306
|
-
def from_frontend_schema(cls, schema: dict) ->
|
|
432
|
+
def from_frontend_schema(cls, schema: dict) -> "CustomNodeBase":
|
|
307
433
|
"""
|
|
308
434
|
Create a node instance from a frontend schema.
|
|
309
435
|
|
|
310
436
|
This is used when loading a node from a saved flow.
|
|
311
437
|
"""
|
|
312
|
-
settings_values = schema.pop(
|
|
438
|
+
settings_values = schema.pop("settings_schema", {})
|
|
313
439
|
node = cls(**schema)
|
|
314
440
|
if settings_values and node.settings_schema:
|
|
315
441
|
node.settings_schema.populate_values(settings_values)
|
|
316
442
|
return node
|
|
317
443
|
|
|
318
444
|
@classmethod
|
|
319
|
-
def from_settings(cls, settings_values: dict) ->
|
|
445
|
+
def from_settings(cls, settings_values: dict) -> "CustomNodeBase":
|
|
320
446
|
"""
|
|
321
447
|
Create a node instance with just its settings values.
|
|
322
448
|
|
|
@@ -327,7 +453,7 @@ class CustomNodeBase(BaseModel):
|
|
|
327
453
|
node.settings_schema.populate_values(settings_values)
|
|
328
454
|
return node
|
|
329
455
|
|
|
330
|
-
def update_settings(self, values:
|
|
456
|
+
def update_settings(self, values: dict[str, Any]) -> "CustomNodeBase":
|
|
331
457
|
"""
|
|
332
458
|
Update the settings with new values from the frontend.
|
|
333
459
|
"""
|
|
@@ -367,5 +493,5 @@ class CustomNodeBase(BaseModel):
|
|
|
367
493
|
drawer_intro=self.intro,
|
|
368
494
|
node_type=self.node_type,
|
|
369
495
|
transform_type=self.transform_type,
|
|
370
|
-
custom_node=True
|
|
496
|
+
custom_node=True,
|
|
371
497
|
)
|