Flowfile 0.5.6__py3-none-any.whl → 0.6.1__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.
- flowfile/api.py +8 -6
- flowfile/web/static/assets/{AdminView-c2c7942b.js → AdminView-C4K1DdHI.js} +28 -33
- flowfile/web/static/assets/{CloudConnectionView-7a3042c6.js → CloudConnectionView-BZbPvPUL.js} +39 -50
- flowfile/web/static/assets/{CloudStorageReader-24c54524.css → CloudStorageReader-BDByiqPI.css} +25 -25
- flowfile/web/static/assets/{CloudStorageReader-709c4037.js → CloudStorageReader-DLVukNJ7.js} +30 -35
- flowfile/web/static/assets/{CloudStorageWriter-604c51a8.js → CloudStorageWriter-Bfi-C1QW.js} +32 -37
- flowfile/web/static/assets/{CloudStorageWriter-60547855.css → CloudStorageWriter-y8jL8yjG.css} +24 -24
- flowfile/web/static/assets/{ColumnActionInput-d63d6746.js → ColumnActionInput-BpiCApw9.js} +7 -12
- flowfile/web/static/assets/{ColumnSelector-0c8cd1cd.js → ColumnSelector-CEAwedI7.js} +1 -2
- flowfile/web/static/assets/ContextMenu-CdojQu0w.js +9 -0
- flowfile/web/static/assets/ContextMenu-D12mhsy1.js +9 -0
- flowfile/web/static/assets/ContextMenu-EWUR98va.js +9 -0
- flowfile/web/static/assets/{ContextMenu.vue_vue_type_script_setup_true_lang-774c517c.js → ContextMenu.vue_vue_type_script_setup_true_lang-I4rXXd6G.js} +4 -5
- flowfile/web/static/assets/{CrossJoin-38e5b99a.js → CrossJoin-BOFfxkJO.js} +19 -18
- flowfile/web/static/assets/{CrossJoin-71b4cc10.css → CrossJoin-Cmbyt9im.css} +18 -18
- flowfile/web/static/assets/{CustomNode-76e8f3f5.js → CustomNode-Bhpezobq.js} +12 -17
- flowfile/web/static/assets/{DatabaseConnectionSettings-38155669.js → DatabaseConnectionSettings-Dw3bSJKB.js} +10 -11
- flowfile/web/static/assets/{DatabaseReader-5bf8c75b.css → DatabaseReader-D6pUNUCs.css} +21 -21
- flowfile/web/static/assets/{DatabaseReader-2e549c8f.js → DatabaseReader-m87ghlw0.js} +36 -34
- flowfile/web/static/assets/{DatabaseView-dc877c29.js → DatabaseView-CisSAtpe.js} +30 -38
- flowfile/web/static/assets/{DatabaseWriter-ffb91864.js → DatabaseWriter-Bbj9JLdL.js} +33 -35
- flowfile/web/static/assets/{DatabaseWriter-bdcf2c8b.css → DatabaseWriter-RBqdFLj8.css} +17 -17
- flowfile/web/static/assets/{DesignerView-a4466dab.js → DesignerView-DemDevTQ.js} +1752 -2054
- flowfile/web/static/assets/{DesignerView-71d4e9a1.css → DesignerView-Dm6OzlIc.css} +209 -168
- flowfile/web/static/assets/{DocumentationView-979afc84.js → DocumentationView-BrC1ZR3H.js} +3 -4
- flowfile/web/static/assets/{ExploreData-e4b92aaf.js → ExploreData-BMKcDuRb.js} +8 -10
- flowfile/web/static/assets/{ExternalSource-d08e7227.js → ExternalSource-BXrNNS-f.js} +40 -42
- flowfile/web/static/assets/{ExternalSource-7ac7373f.css → ExternalSource-NB6WVl5R.css} +14 -14
- flowfile/web/static/assets/{Filter-7add806d.js → Filter-C2MjsN6P.js} +36 -33
- flowfile/web/static/assets/{Filter-7494ea97.css → Filter-DCMGGuGC.css} +9 -9
- flowfile/web/static/assets/{Formula-53d58c43.css → Formula-BYafbDj8.css} +4 -4
- flowfile/web/static/assets/{Formula-36ab24d2.js → Formula-ufuy4mVD.js} +27 -26
- flowfile/web/static/assets/{FuzzyMatch-ad6361d6.css → FuzzyMatch-BGJAwgd0.css} +42 -42
- flowfile/web/static/assets/{FuzzyMatch-cc01bb04.js → FuzzyMatch-BOHODq3h.js} +36 -38
- flowfile/web/static/assets/{GraphSolver-4fb98f3b.js → GraphSolver-B6ZzpNGO.js} +23 -21
- flowfile/web/static/assets/{GraphSolver-4b4d7db9.css → GraphSolver-DFN83sj3.css} +4 -4
- flowfile/web/static/assets/{GroupBy-b3c8f429.js → GroupBy-B9BRNcfe.js} +30 -29
- flowfile/web/static/assets/{Sort-4abb7fae.css → GroupBy-x4ooP5np.css} +1 -1
- flowfile/web/static/assets/Join-Bx_g5bZz.css +118 -0
- flowfile/web/static/assets/{Join-096b7b26.js → Join-DsBEy1IH.js} +48 -43
- flowfile/web/static/assets/{LoginView-c33a246a.js → LoginView-Ct0rhdcO.js} +1 -2
- flowfile/web/static/assets/{ManualInput-39111f19.css → ManualInput-DlZmtMdt.css} +48 -48
- flowfile/web/static/assets/{ManualInput-7307e9b1.js → ManualInput-bC4BUgnG.js} +40 -41
- flowfile/web/static/assets/{MultiSelect-14822c48.js → MultiSelect-DIQ8PuTC.js} +2 -2
- flowfile/web/static/assets/{MultiSelect.vue_vue_type_script_setup_true_lang-90c4d340.js → MultiSelect.vue_vue_type_script_setup_true_lang-BefHfqTI.js} +1 -1
- flowfile/web/static/assets/{NodeDesigner-5036c392.js → NodeDesigner-D39yzr2k.js} +178 -208
- flowfile/web/static/assets/{NodeDesigner-94cd4dd3.css → NodeDesigner-R0l6sYyY.css} +76 -76
- flowfile/web/static/assets/{NumericInput-15cf3b72.js → NumericInput-DMSX3oOr.js} +2 -2
- flowfile/web/static/assets/{NumericInput.vue_vue_type_script_setup_true_lang-91e679d7.js → NumericInput.vue_vue_type_script_setup_true_lang-d0YlVHAl.js} +1 -1
- flowfile/web/static/assets/{Output-1f8ed42c.js → Output-D0VoXGcW.js} +26 -34
- flowfile/web/static/assets/{Output-692dd25d.css → Output-DsmglIDy.css} +5 -5
- flowfile/web/static/assets/{Pivot-0e153f4e.js → Pivot-BnMB4sEe.js} +26 -26
- flowfile/web/static/assets/{Pivot-0eda81b4.css → Pivot-qKTyWxop.css} +4 -4
- flowfile/web/static/assets/{PivotValidation-81ec2a33.js → PivotValidation-B2lWvugt.js} +7 -9
- flowfile/web/static/assets/{PivotValidation-5a4f7c79.js → PivotValidation-BPlhRjpL.js} +7 -9
- flowfile/web/static/assets/{PolarsCode-a39f15ac.js → PolarsCode-5h0tHnWR.js} +22 -20
- flowfile/web/static/assets/{PopOver-ddcfe4f6.js → PopOver-BHpt5rsj.js} +5 -9
- flowfile/web/static/assets/{PopOver-d96599db.css → PopOver-CyYM4-rV.css} +1 -1
- flowfile/web/static/assets/{Read-90f366bc.css → Read-DJxkrTb_.css} +10 -10
- flowfile/web/static/assets/Read-TsLEFh3B.js +227 -0
- flowfile/web/static/assets/{RecordCount-e9048ccd.js → RecordCount-DkVixq9v.js} +18 -17
- flowfile/web/static/assets/{RecordId-ad02521d.js → RecordId-C2UEGlCf.js} +42 -39
- flowfile/web/static/assets/{SQLQueryComponent-2eeecf0b.js → SQLQueryComponent-Dr5KMoD3.js} +2 -3
- flowfile/web/static/assets/{Sample-9a68c23d.js → Sample-Cb3eQNmd.js} +30 -30
- flowfile/web/static/assets/{SecretSelector-2429f35a.js → SecretSelector-De2L2bSx.js} +3 -4
- flowfile/web/static/assets/{SecretsView-c6afc915.js → SecretsView-CheC9BPV.js} +13 -16
- flowfile/web/static/assets/{Select-fcd002b6.js → Select-CI8TloRs.js} +41 -36
- flowfile/web/static/assets/{SettingsSection-5ce15962.js → SettingsSection-B39ulIiI.js} +1 -2
- flowfile/web/static/assets/{SettingsSection-c6b1362c.js → SettingsSection-BiCc7S9h.js} +1 -2
- flowfile/web/static/assets/{SettingsSection-cebb91d5.js → SettingsSection-CITK_R7o.js} +2 -3
- flowfile/web/static/assets/{SettingsSection-26fe48d4.css → SettingsSection-D2GgY-Aq.css} +4 -4
- flowfile/web/static/assets/{SetupView-2d12e01f.js → SetupView-C1aXRDvp.js} +1 -2
- flowfile/web/static/assets/{SingleSelect-b67de4eb.js → SingleSelect-Kr_hz90m.js} +2 -2
- flowfile/web/static/assets/{SingleSelect.vue_vue_type_script_setup_true_lang-eedb70eb.js → SingleSelect.vue_vue_type_script_setup_true_lang-Rxht5Z5N.js} +1 -1
- flowfile/web/static/assets/{SliderInput-fd8134ac.js → SliderInput-CLqpCxCb.js} +1 -2
- flowfile/web/static/assets/{GroupBy-5792782d.css → Sort-BIt2kc_p.css} +1 -1
- flowfile/web/static/assets/{Sort-c005a573.js → Sort-Dnw_J6Qi.js} +25 -25
- flowfile/web/static/assets/{TextInput-1bb31dab.js → TextInput-wdlunIZC.js} +2 -2
- flowfile/web/static/assets/{TextInput.vue_vue_type_script_setup_true_lang-a51fe730.js → TextInput.vue_vue_type_script_setup_true_lang-Bcj3ywzv.js} +1 -1
- flowfile/web/static/assets/{TextToRows-4f363753.js → TextToRows-BhtyGWPq.js} +42 -49
- flowfile/web/static/assets/{TextToRows-12afb4f4.css → TextToRows-DivDOLDx.css} +9 -9
- flowfile/web/static/assets/{ToggleSwitch-ca0f2e5e.js → ToggleSwitch-B-6WzfFf.js} +2 -2
- flowfile/web/static/assets/{ToggleSwitch.vue_vue_type_script_setup_true_lang-49aa41d8.js → ToggleSwitch.vue_vue_type_script_setup_true_lang-Cj8LqT-b.js} +1 -1
- flowfile/web/static/assets/{UnavailableFields-f6147968.js → UnavailableFields-Yf6XSqFB.js} +2 -3
- flowfile/web/static/assets/{Union-c65f17b7.js → Union-CwpjeKYC.js} +20 -23
- flowfile/web/static/assets/{Unpivot-b6ad6427.css → Union-DQJcpp3-.css} +6 -6
- flowfile/web/static/assets/{Unique-a1d96fb2.js → Unique-25v3urqH.js} +75 -74
- flowfile/web/static/assets/{Union-d6a8d7d5.css → Unpivot-Deqh1gtI.css} +6 -6
- flowfile/web/static/assets/{Unpivot-c2657ff3.js → Unpivot-sYcTTXrq.js} +34 -27
- flowfile/web/static/assets/{UnpivotValidation-28e29a3b.js → UnpivotValidation-C5DDEKY2.js} +5 -7
- flowfile/web/static/assets/VueGraphicWalker-B8l1_Z92.js +131 -0
- flowfile/web/static/assets/VueGraphicWalker-Da_1-3me.css +21 -0
- flowfile/web/static/assets/{api-df48ec50.js → api-C0LvF-0C.js} +1 -1
- flowfile/web/static/assets/{api-ee542cf7.js → api-DaC83EO_.js} +1 -1
- flowfile/web/static/assets/client-C8Ygr6Gb.js +42 -0
- flowfile/web/static/assets/{dropDown-7576a76a.js → dropDown-D5YXaPRR.js} +7 -12
- flowfile/web/static/assets/{fullEditor-7583bef5.js → fullEditor-BVYnWm05.js} +300 -18
- flowfile/web/static/assets/genericNodeSettings-2wAu-QKn.css +75 -0
- flowfile/web/static/assets/genericNodeSettings-BBtW_Cpz.js +590 -0
- flowfile/web/static/assets/{VueGraphicWalker-2fc3ddd4.js → graphic-walker.es-VrK6vdGE.js} +92305 -89751
- flowfile/web/static/assets/index-BCJxPfM5.js +6693 -0
- flowfile/web/static/assets/{index-057d770d.js → index-CHPMUR0d.js} +150 -170
- flowfile/web/static/assets/index-DPkoZWq8.js +32 -0
- flowfile/web/static/assets/index-DnW_KC_I.js +277 -0
- flowfile/web/static/assets/index-UFXyfirV.css +10797 -0
- flowfile/web/static/assets/index-bcuE0Z0p.js +87456 -0
- flowfile/web/static/assets/{node.types-2c15bb7e.js → node.types-Dl4gtSW9.js} +2 -2
- flowfile/web/static/assets/{outputCsv-c492b15e.js → outputCsv-BELuBiJZ.js} +1 -2
- flowfile/web/static/assets/outputCsv-CdGkv-fN.css +2581 -0
- flowfile/web/static/assets/{outputExcel-13bfa10f.js → outputExcel-D0TTNM79.js} +1 -2
- flowfile/web/static/assets/{outputParquet-9be1523a.js → outputParquet-Cz9EbRHj.js} +1 -2
- flowfile/web/static/assets/{readCsv-5a49a8c9.js → readCsv-7bd3kUMI.js} +1 -2
- flowfile/web/static/assets/{readExcel-27c30ad8.js → readExcel-Cq8CCwIv.js} +3 -4
- flowfile/web/static/assets/{readParquet-c5244ad5.css → readParquet-CRDmBrsp.css} +4 -4
- flowfile/web/static/assets/{readParquet-446bde68.js → readParquet-DjR4mRaj.js} +4 -5
- flowfile/web/static/assets/{secrets.api-34431884.js → secrets.api-C9o2KE5V.js} +1 -1
- flowfile/web/static/assets/{selectDynamic-5754a2b1.js → selectDynamic-Bl5FVsME.js} +5 -7
- flowfile/web/static/assets/useNodeSettings-dMS9zmh_.js +69 -0
- flowfile/web/static/assets/{vue-codemirror.esm-8f46fb36.js → vue-codemirror.esm-CwaYwln0.js} +3469 -3064
- flowfile/web/static/assets/{vue-content-loader.es-808fe33a.js → vue-content-loader.es-CMoRXo7N.js} +3 -3
- flowfile/web/static/index.html +2 -3
- {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/METADATA +2 -1
- flowfile-0.6.1.dist-info/RECORD +417 -0
- {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/WHEEL +1 -1
- flowfile_core/auth/password.py +1 -0
- flowfile_core/database/init_db.py +7 -5
- flowfile_core/fileExplorer/funcs.py +2 -2
- flowfile_core/flowfile/code_generator/code_generator.py +13 -11
- flowfile_core/flowfile/filter_expressions.py +327 -0
- flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +61 -59
- flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +3 -29
- flowfile_core/flowfile/flow_data_engine/flow_file_column/utils.py +45 -14
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/models.py +20 -3
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/streaming.py +206 -0
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +146 -24
- flowfile_core/flowfile/flow_graph.py +504 -190
- flowfile_core/flowfile/flow_node/__init__.py +32 -0
- flowfile_core/flowfile/flow_node/executor.py +404 -0
- flowfile_core/flowfile/flow_node/flow_node.py +207 -106
- flowfile_core/flowfile/flow_node/models.py +40 -0
- flowfile_core/flowfile/flow_node/output_field_config_applier.py +217 -0
- flowfile_core/flowfile/flow_node/schema_utils.py +78 -0
- flowfile_core/flowfile/flow_node/state.py +155 -0
- flowfile_core/flowfile/history_manager.py +401 -0
- flowfile_core/flowfile/manage/compatibility_enhancements.py +9 -0
- flowfile_core/flowfile/manage/io_flowfile.py +3 -1
- flowfile_core/flowfile/sources/external_sources/sql_source/models.py +20 -4
- flowfile_core/flowfile/util/execution_orderer.py +89 -36
- flowfile_core/routes/auth.py +8 -9
- flowfile_core/routes/routes.py +320 -101
- flowfile_core/routes/user_defined_components.py +18 -16
- flowfile_core/schemas/history_schema.py +220 -0
- flowfile_core/schemas/input_schema.py +130 -6
- flowfile_core/schemas/schemas.py +9 -0
- flowfile_core/schemas/transform_schema.py +27 -5
- flowfile_core/schemas/yaml_types.py +23 -5
- flowfile_frame/adding_expr.py +18 -126
- flowfile_frame/callable_utils.py +261 -0
- flowfile_frame/database/connection_manager.py +0 -1
- flowfile_frame/expr.py +8 -4
- flowfile_frame/flow_frame.py +41 -41
- flowfile_frame/lazy.py +3 -12
- flowfile_frame/lazy_methods.py +5 -64
- flowfile_frame/utils.py +13 -32
- flowfile_worker/funcs.py +6 -4
- flowfile_worker/main.py +2 -0
- flowfile_worker/models.py +31 -11
- flowfile_worker/routes.py +60 -35
- flowfile_worker/spawner.py +7 -1
- flowfile_worker/streaming.py +335 -0
- flowfile/web/static/assets/ContextMenu-366bf1b4.js +0 -9
- flowfile/web/static/assets/ContextMenu-85cf5b44.js +0 -9
- flowfile/web/static/assets/ContextMenu-9d28ae6d.js +0 -9
- flowfile/web/static/assets/Join-28b5e18f.css +0 -109
- flowfile/web/static/assets/Read-39b63932.js +0 -222
- flowfile/web/static/assets/VueGraphicWalker-430f0b86.css +0 -6
- flowfile/web/static/assets/database_reader-ce1e55f3.svg +0 -24
- flowfile/web/static/assets/database_writer-b4ad0753.svg +0 -23
- flowfile/web/static/assets/element-icons-9c88a535.woff +0 -0
- flowfile/web/static/assets/element-icons-de5eb258.ttf +0 -0
- flowfile/web/static/assets/genericNodeSettings-0155288b.js +0 -136
- flowfile/web/static/assets/genericNodeSettings-3b2507ea.css +0 -46
- flowfile/web/static/assets/index-aeec439d.js +0 -38
- flowfile/web/static/assets/index-ca6799de.js +0 -62760
- flowfile/web/static/assets/index-d60c9dd4.css +0 -10777
- flowfile/web/static/assets/nodeInput-d478b9ac.js +0 -2
- flowfile/web/static/assets/outputCsv-cc84e09f.css +0 -2499
- flowfile-0.5.6.dist-info/RECORD +0 -407
- /flowfile/web/static/assets/{AdminView-f53bad23.css → AdminView-B2Dthl3u.css} +0 -0
- /flowfile/web/static/assets/{CloudConnectionView-cf85f943.css → CloudConnectionView-BdFYGWV7.css} +0 -0
- /flowfile/web/static/assets/{ColumnActionInput-c44b7aee.css → ColumnActionInput-dCasSIC9.css} +0 -0
- /flowfile/web/static/assets/{ColumnSelector-371637fb.css → ColumnSelector-j6sEOjo1.css} +0 -0
- /flowfile/web/static/assets/{CustomNode-edb9b939.css → CustomNode-VPlajG0j.css} +0 -0
- /flowfile/web/static/assets/{DatabaseConnectionSettings-c20a1e16.css → DatabaseConnectionSettings-B78hXYgu.css} +0 -0
- /flowfile/web/static/assets/{DatabaseView-6655afd6.css → DatabaseView-B-_adk1s.css} +0 -0
- /flowfile/web/static/assets/{DocumentationView-9ea6e871.css → DocumentationView-CL7iipFL.css} +0 -0
- /flowfile/web/static/assets/{ExploreData-10c5acc8.css → ExploreData-DHjv0Plr.css} +0 -0
- /flowfile/web/static/assets/{LoginView-d325d632.css → LoginView-DN1BXY3e.css} +0 -0
- /flowfile/web/static/assets/{PivotValidation-0e905b1a.css → PivotValidation-DK-FARWe.css} +0 -0
- /flowfile/web/static/assets/{PivotValidation-41b57ad6.css → PivotValidation-FUa9F47u.css} +0 -0
- /flowfile/web/static/assets/{PolarsCode-2b1f1f23.css → PolarsCode-G-gRSrSc.css} +0 -0
- /flowfile/web/static/assets/{SQLQueryComponent-edb90b98.css → SQLQueryComponent-oAbWw0r-.css} +0 -0
- /flowfile/web/static/assets/{SecretSelector-6329f743.css → SecretSelector-CJSadIZx.css} +0 -0
- /flowfile/web/static/assets/{SecretsView-aa291340.css → SecretsView-DbzIRAba.css} +0 -0
- /flowfile/web/static/assets/{SettingsSection-8f980839.css → SettingsSection-BGcJnH6q.css} +0 -0
- /flowfile/web/static/assets/{SettingsSection-07fbbc39.css → SettingsSection-DDWn_EGW.css} +0 -0
- /flowfile/web/static/assets/{SetupView-ec26f76a.css → SetupView-CI1nd-5Z.css} +0 -0
- /flowfile/web/static/assets/{SliderInput-f2e4f23c.css → SliderInput-BRk-q_Dk.css} +0 -0
- /flowfile/web/static/assets/{UnavailableFields-394a1f78.css → UnavailableFields-DRKDImKe.css} +0 -0
- /flowfile/web/static/assets/{Unique-2b705521.css → Unique-Absb0aON.css} +0 -0
- /flowfile/web/static/assets/{UnpivotValidation-d5ca3b7b.css → UnpivotValidation-DSBkFgS-.css} +0 -0
- /flowfile/web/static/assets/{airbyte-292aa232.png → airbyte-W0xvIXwZ.png} +0 -0
- /flowfile/web/static/assets/{cloud_storage_reader-aa1415d6.png → cloud_storage_reader-3GpSCk90.png} +0 -0
- /flowfile/web/static/assets/{cross_join-d30c0290.png → cross_join-B0qpgYoV.png} +0 -0
- /flowfile/web/static/assets/{dropDown-1d6acbd9.css → dropDown-CE0VF5_P.css} +0 -0
- /flowfile/web/static/assets/{explore_data-8a0a2861.png → explore_data-tX6olPPL.png} +0 -0
- /flowfile/web/static/assets/{fa-brands-400-808443ae.ttf → fa-brands-400-D1LuMI3I.ttf} +0 -0
- /flowfile/web/static/assets/{fa-brands-400-d7236a19.woff2 → fa-brands-400-D_cYUPeE.woff2} +0 -0
- /flowfile/web/static/assets/{fa-regular-400-e3456d12.woff2 → fa-regular-400-BjRzuEpd.woff2} +0 -0
- /flowfile/web/static/assets/{fa-regular-400-54cf6086.ttf → fa-regular-400-DZaxPHgR.ttf} +0 -0
- /flowfile/web/static/assets/{fa-solid-900-aa759986.woff2 → fa-solid-900-CTAAxXor.woff2} +0 -0
- /flowfile/web/static/assets/{fa-solid-900-d2f05935.ttf → fa-solid-900-D0aA9rwL.ttf} +0 -0
- /flowfile/web/static/assets/{fa-v4compatibility-0ce9033c.woff2 → fa-v4compatibility-C9RhG_FT.woff2} +0 -0
- /flowfile/web/static/assets/{fa-v4compatibility-30f6abf6.ttf → fa-v4compatibility-CCth-dXg.ttf} +0 -0
- /flowfile/web/static/assets/{filter-d7708bda.png → filter-WRdZyUOw.png} +0 -0
- /flowfile/web/static/assets/{formula-eeeb1611.png → formula-CgM7uHVI.png} +0 -0
- /flowfile/web/static/assets/{fullEditor-fe9f7e18.css → fullEditor-CmDI7T9F.css} +0 -0
- /flowfile/web/static/assets/{fuzzy_match-40c161b2.png → fuzzy_match-Yon3k5Tc.png} +0 -0
- /flowfile/web/static/assets/{graph_solver-8b7888b8.png → graph_solver-BlMrBttD.png} +0 -0
- /flowfile/web/static/assets/{group_by-80561fc3.png → group_by-Gici0CSS.png} +0 -0
- /flowfile/web/static/assets/{input_data-ab2eb678.png → input_data-BRdGecLc.png} +0 -0
- /flowfile/web/static/assets/{join-349043ae.png → join-BITWRu73.png} +0 -0
- /flowfile/web/static/assets/{manual_input-ae98f31d.png → manual_input-CFvo_EUS.png} +0 -0
- /flowfile/web/static/assets/{old_join-5d0eb604.png → old_join-B9bkpPqv.png} +0 -0
- /flowfile/web/static/assets/{output-06ec0371.png → output-Dp7-ZpC4.png} +0 -0
- /flowfile/web/static/assets/{outputExcel-f5d272b2.css → outputExcel-CKgRe2iT.css} +0 -0
- /flowfile/web/static/assets/{outputParquet-54597c3c.css → outputParquet-d7j407cK.css} +0 -0
- /flowfile/web/static/assets/{pivot-9660df51.png → pivot-DSxKhNlD.png} +0 -0
- /flowfile/web/static/assets/{polars_code-05ce5dc6.png → polars_code-DxiztZ1c.png} +0 -0
- /flowfile/web/static/assets/{readCsv-3bfac4c3.css → readCsv-BG-1Jilp.css} +0 -0
- /flowfile/web/static/assets/{readExcel-3db6b763.css → readExcel-DBQXKPtC.css} +0 -0
- /flowfile/web/static/assets/{record_count-dab44eb5.png → record_count-DCeaLtpS.png} +0 -0
- /flowfile/web/static/assets/{record_id-0b15856b.png → record_id-FeUjyIFh.png} +0 -0
- /flowfile/web/static/assets/{sample-693a88b5.png → sample-DeqfRiB-.png} +0 -0
- /flowfile/web/static/assets/{select-b0d0437a.png → select-D4JjbdjS.png} +0 -0
- /flowfile/web/static/assets/{selectDynamic-f2fb394f.css → selectDynamic-CjeTPUUo.css} +0 -0
- /flowfile/web/static/assets/{sort-2aa579f0.png → sort-DGwUG9WS.png} +0 -0
- /flowfile/web/static/assets/{summarize-2a099231.png → summarize-DFaNHpfp.png} +0 -0
- /flowfile/web/static/assets/{text_to_rows-859b29ea.png → text_to_rows-BdiAewrN.png} +0 -0
- /flowfile/web/static/assets/{union-2d8609f4.png → union-DCK-LSMq.png} +0 -0
- /flowfile/web/static/assets/{unique-1958b98a.png → unique-CdP3zZIq.png} +0 -0
- /flowfile/web/static/assets/{unpivot-d3cb4b5b.png → unpivot-CHttrEt8.png} +0 -0
- /flowfile/web/static/assets/{user-defined-icon-0ae16c90.png → user-defined-icon-BcIp2Vzo.png} +0 -0
- /flowfile/web/static/assets/{view-7a0f0be1.png → view-DUSRwjvq.png} +0 -0
- {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/entry_points.txt +0 -0
- {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""Filter expression builder for converting BasicFilter objects to expression strings.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for building filter expressions from BasicFilter objects
|
|
4
|
+
that are compatible with the Flowfile expression language (polars_expr_transformer).
|
|
5
|
+
|
|
6
|
+
The main entry point is `build_filter_expression()` which converts a BasicFilter
|
|
7
|
+
to a filter expression string.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from flowfile_core.schemas.transform_schema import BasicFilter
|
|
16
|
+
|
|
17
|
+
from flowfile_core.schemas.transform_schema import FilterOperator
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _is_numeric_string(value: str) -> bool:
|
|
21
|
+
"""Check if a string value represents a numeric value.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
value: The string to check.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
True if the value is numeric (int or float), False otherwise.
|
|
28
|
+
"""
|
|
29
|
+
if not value:
|
|
30
|
+
return False
|
|
31
|
+
try:
|
|
32
|
+
float(value)
|
|
33
|
+
return True
|
|
34
|
+
except ValueError:
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _should_quote_value(value: str, field_data_type: str | None) -> bool:
|
|
39
|
+
"""Determine if a value should be quoted in the expression.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
value: The value to check.
|
|
43
|
+
field_data_type: The data type of the field ("str", "numeric", "date", or None).
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
True if the value should be quoted, False otherwise.
|
|
47
|
+
"""
|
|
48
|
+
# If field is explicitly string type, always quote
|
|
49
|
+
if field_data_type == "str":
|
|
50
|
+
return True
|
|
51
|
+
# If field is explicitly numeric type, never quote
|
|
52
|
+
if field_data_type == "numeric":
|
|
53
|
+
return False
|
|
54
|
+
# Otherwise, quote if the value doesn't look numeric
|
|
55
|
+
return not _is_numeric_string(value)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _format_field(field_name: str) -> str:
|
|
59
|
+
"""Format a field name for use in an expression.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
field_name: The name of the field.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
The field name wrapped in brackets.
|
|
66
|
+
"""
|
|
67
|
+
return f"[{field_name}]"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _build_comparison_expression(
|
|
71
|
+
field: str, operator_symbol: str, value: str, should_quote: bool
|
|
72
|
+
) -> str:
|
|
73
|
+
"""Build a simple comparison expression.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
field: The formatted field name (e.g., "[column]").
|
|
77
|
+
operator_symbol: The comparison operator (e.g., "=", "!=", ">").
|
|
78
|
+
value: The value to compare against.
|
|
79
|
+
should_quote: Whether to quote the value.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
The comparison expression string.
|
|
83
|
+
"""
|
|
84
|
+
if should_quote:
|
|
85
|
+
return f'{field}{operator_symbol}"{value}"'
|
|
86
|
+
return f"{field}{operator_symbol}{value}"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _build_equals_expression(field: str, value: str, should_quote: bool) -> str:
|
|
90
|
+
"""Build an equals expression."""
|
|
91
|
+
return _build_comparison_expression(field, "=", value, should_quote)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _build_not_equals_expression(field: str, value: str, should_quote: bool) -> str:
|
|
95
|
+
"""Build a not equals expression."""
|
|
96
|
+
return _build_comparison_expression(field, "!=", value, should_quote)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _build_greater_than_expression(field: str, value: str, should_quote: bool) -> str:
|
|
100
|
+
"""Build a greater than expression."""
|
|
101
|
+
return _build_comparison_expression(field, ">", value, should_quote)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _build_greater_than_or_equals_expression(field: str, value: str, should_quote: bool) -> str:
|
|
105
|
+
"""Build a greater than or equals expression."""
|
|
106
|
+
return _build_comparison_expression(field, ">=", value, should_quote)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _build_less_than_expression(field: str, value: str, should_quote: bool) -> str:
|
|
110
|
+
"""Build a less than expression."""
|
|
111
|
+
return _build_comparison_expression(field, "<", value, should_quote)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _build_less_than_or_equals_expression(field: str, value: str, should_quote: bool) -> str:
|
|
115
|
+
"""Build a less than or equals expression."""
|
|
116
|
+
return _build_comparison_expression(field, "<=", value, should_quote)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _build_contains_expression(field: str, value: str) -> str:
|
|
120
|
+
"""Build a contains expression."""
|
|
121
|
+
return f'contains({field}, "{value}")'
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _build_not_contains_expression(field: str, value: str) -> str:
|
|
125
|
+
"""Build a not contains expression."""
|
|
126
|
+
return f'contains({field}, "{value}") = false'
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _build_starts_with_expression(field: str, value: str) -> str:
|
|
130
|
+
"""Build a starts with expression."""
|
|
131
|
+
return f'left({field}, {len(value)}) = "{value}"'
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _build_ends_with_expression(field: str, value: str) -> str:
|
|
135
|
+
"""Build an ends with expression."""
|
|
136
|
+
return f'right({field}, {len(value)}) = "{value}"'
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _build_is_null_expression(field: str) -> str:
|
|
140
|
+
"""Build an is null expression."""
|
|
141
|
+
return f"is_empty({field})"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _build_is_not_null_expression(field: str) -> str:
|
|
145
|
+
"""Build an is not null expression."""
|
|
146
|
+
return f"is_not_empty({field})"
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _build_in_expression(field: str, value: str, field_data_type: str | None) -> str:
|
|
150
|
+
"""Build an IN expression for matching any of multiple values.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
field: The formatted field name.
|
|
154
|
+
value: Comma-separated list of values.
|
|
155
|
+
field_data_type: The data type of the field.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
An OR-combined expression for each value.
|
|
159
|
+
"""
|
|
160
|
+
values = [v.strip() for v in value.split(",")]
|
|
161
|
+
if len(values) == 1:
|
|
162
|
+
should_quote = _should_quote_value(values[0], field_data_type)
|
|
163
|
+
return _build_equals_expression(field, values[0], should_quote)
|
|
164
|
+
|
|
165
|
+
conditions = []
|
|
166
|
+
for v in values:
|
|
167
|
+
should_quote = _should_quote_value(v, field_data_type)
|
|
168
|
+
if should_quote:
|
|
169
|
+
conditions.append(f'({field}="{v}")')
|
|
170
|
+
else:
|
|
171
|
+
conditions.append(f"({field}={v})")
|
|
172
|
+
return " | ".join(conditions)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _build_not_in_expression(field: str, value: str, field_data_type: str | None) -> str:
|
|
176
|
+
"""Build a NOT IN expression for excluding multiple values.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
field: The formatted field name.
|
|
180
|
+
value: Comma-separated list of values.
|
|
181
|
+
field_data_type: The data type of the field.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
An AND-combined expression for each value.
|
|
185
|
+
"""
|
|
186
|
+
values = [v.strip() for v in value.split(",")]
|
|
187
|
+
if len(values) == 1:
|
|
188
|
+
should_quote = _should_quote_value(values[0], field_data_type)
|
|
189
|
+
return _build_not_equals_expression(field, values[0], should_quote)
|
|
190
|
+
|
|
191
|
+
conditions = []
|
|
192
|
+
for v in values:
|
|
193
|
+
should_quote = _should_quote_value(v, field_data_type)
|
|
194
|
+
if should_quote:
|
|
195
|
+
conditions.append(f'({field}!="{v}")')
|
|
196
|
+
else:
|
|
197
|
+
conditions.append(f"({field}!={v})")
|
|
198
|
+
return " & ".join(conditions)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _build_between_expression(
|
|
202
|
+
field: str, value: str, value2: str, field_data_type: str | None
|
|
203
|
+
) -> str:
|
|
204
|
+
"""Build a BETWEEN expression for range filtering.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
field: The formatted field name.
|
|
208
|
+
value: The lower bound.
|
|
209
|
+
value2: The upper bound.
|
|
210
|
+
field_data_type: The data type of the field.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
An AND-combined range expression.
|
|
214
|
+
|
|
215
|
+
Raises:
|
|
216
|
+
ValueError: If value2 is None.
|
|
217
|
+
"""
|
|
218
|
+
if value2 is None:
|
|
219
|
+
raise ValueError("BETWEEN operator requires value2")
|
|
220
|
+
|
|
221
|
+
should_quote_v1 = _should_quote_value(value, field_data_type)
|
|
222
|
+
should_quote_v2 = _should_quote_value(value2, field_data_type)
|
|
223
|
+
|
|
224
|
+
if should_quote_v1:
|
|
225
|
+
lower = f'({field}>="{value}")'
|
|
226
|
+
else:
|
|
227
|
+
lower = f"({field}>={value})"
|
|
228
|
+
|
|
229
|
+
if should_quote_v2:
|
|
230
|
+
upper = f'({field}<="{value2}")'
|
|
231
|
+
else:
|
|
232
|
+
upper = f"({field}<={value2})"
|
|
233
|
+
|
|
234
|
+
return f"{lower} & {upper}"
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def build_filter_expression(
|
|
238
|
+
basic_filter: BasicFilter, field_data_type: str | None = None
|
|
239
|
+
) -> str:
|
|
240
|
+
"""Build a filter expression string from a BasicFilter object.
|
|
241
|
+
|
|
242
|
+
Uses the Flowfile expression language that is compatible with polars_expr_transformer.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
basic_filter: The basic filter configuration.
|
|
246
|
+
field_data_type: The data type of the field ("str", "numeric", "date", or None).
|
|
247
|
+
If None, the type is inferred from the value.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
A filter expression string compatible with polars_expr_transformer.
|
|
251
|
+
|
|
252
|
+
Examples:
|
|
253
|
+
>>> from flowfile_core.schemas.transform_schema import BasicFilter, FilterOperator
|
|
254
|
+
>>> bf = BasicFilter(field="age", operator=FilterOperator.GREATER_THAN, value="30")
|
|
255
|
+
>>> build_filter_expression(bf, "numeric")
|
|
256
|
+
'[age]>30'
|
|
257
|
+
|
|
258
|
+
>>> bf = BasicFilter(field="name", operator=FilterOperator.EQUALS, value="John")
|
|
259
|
+
>>> build_filter_expression(bf, "str")
|
|
260
|
+
'[name]="John"'
|
|
261
|
+
|
|
262
|
+
>>> bf = BasicFilter(field="id", operator=FilterOperator.NOT_IN, value="1, 2, 3")
|
|
263
|
+
>>> build_filter_expression(bf, "numeric")
|
|
264
|
+
'([id]!=1) & ([id]!=2) & ([id]!=3)'
|
|
265
|
+
"""
|
|
266
|
+
field = _format_field(basic_filter.field)
|
|
267
|
+
value = basic_filter.value
|
|
268
|
+
value2 = basic_filter.value2
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
operator = basic_filter.get_operator()
|
|
272
|
+
except (ValueError, AttributeError):
|
|
273
|
+
operator = FilterOperator.from_symbol(str(basic_filter.operator))
|
|
274
|
+
|
|
275
|
+
# For simple comparison operators, determine quoting based on the single value
|
|
276
|
+
should_quote = _should_quote_value(value, field_data_type)
|
|
277
|
+
|
|
278
|
+
if operator == FilterOperator.EQUALS:
|
|
279
|
+
return _build_equals_expression(field, value, should_quote)
|
|
280
|
+
|
|
281
|
+
elif operator == FilterOperator.NOT_EQUALS:
|
|
282
|
+
return _build_not_equals_expression(field, value, should_quote)
|
|
283
|
+
|
|
284
|
+
elif operator == FilterOperator.GREATER_THAN:
|
|
285
|
+
return _build_greater_than_expression(field, value, should_quote)
|
|
286
|
+
|
|
287
|
+
elif operator == FilterOperator.GREATER_THAN_OR_EQUALS:
|
|
288
|
+
return _build_greater_than_or_equals_expression(field, value, should_quote)
|
|
289
|
+
|
|
290
|
+
elif operator == FilterOperator.LESS_THAN:
|
|
291
|
+
return _build_less_than_expression(field, value, should_quote)
|
|
292
|
+
|
|
293
|
+
elif operator == FilterOperator.LESS_THAN_OR_EQUALS:
|
|
294
|
+
return _build_less_than_or_equals_expression(field, value, should_quote)
|
|
295
|
+
|
|
296
|
+
elif operator == FilterOperator.CONTAINS:
|
|
297
|
+
return _build_contains_expression(field, value)
|
|
298
|
+
|
|
299
|
+
elif operator == FilterOperator.NOT_CONTAINS:
|
|
300
|
+
return _build_not_contains_expression(field, value)
|
|
301
|
+
|
|
302
|
+
elif operator == FilterOperator.STARTS_WITH:
|
|
303
|
+
return _build_starts_with_expression(field, value)
|
|
304
|
+
|
|
305
|
+
elif operator == FilterOperator.ENDS_WITH:
|
|
306
|
+
return _build_ends_with_expression(field, value)
|
|
307
|
+
|
|
308
|
+
elif operator == FilterOperator.IS_NULL:
|
|
309
|
+
return _build_is_null_expression(field)
|
|
310
|
+
|
|
311
|
+
elif operator == FilterOperator.IS_NOT_NULL:
|
|
312
|
+
return _build_is_not_null_expression(field)
|
|
313
|
+
|
|
314
|
+
elif operator == FilterOperator.IN:
|
|
315
|
+
return _build_in_expression(field, value, field_data_type)
|
|
316
|
+
|
|
317
|
+
elif operator == FilterOperator.NOT_IN:
|
|
318
|
+
return _build_not_in_expression(field, value, field_data_type)
|
|
319
|
+
|
|
320
|
+
elif operator == FilterOperator.BETWEEN:
|
|
321
|
+
return _build_between_expression(field, value, value2, field_data_type)
|
|
322
|
+
|
|
323
|
+
else:
|
|
324
|
+
# Fallback for unknown operators - use legacy format
|
|
325
|
+
if should_quote:
|
|
326
|
+
return f'{field}{operator.to_symbol()}"{value}"'
|
|
327
|
+
return f"{field}{operator.to_symbol()}{value}"
|