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.
Files changed (256) hide show
  1. flowfile/api.py +8 -6
  2. flowfile/web/static/assets/{AdminView-c2c7942b.js → AdminView-C4K1DdHI.js} +28 -33
  3. flowfile/web/static/assets/{CloudConnectionView-7a3042c6.js → CloudConnectionView-BZbPvPUL.js} +39 -50
  4. flowfile/web/static/assets/{CloudStorageReader-24c54524.css → CloudStorageReader-BDByiqPI.css} +25 -25
  5. flowfile/web/static/assets/{CloudStorageReader-709c4037.js → CloudStorageReader-DLVukNJ7.js} +30 -35
  6. flowfile/web/static/assets/{CloudStorageWriter-604c51a8.js → CloudStorageWriter-Bfi-C1QW.js} +32 -37
  7. flowfile/web/static/assets/{CloudStorageWriter-60547855.css → CloudStorageWriter-y8jL8yjG.css} +24 -24
  8. flowfile/web/static/assets/{ColumnActionInput-d63d6746.js → ColumnActionInput-BpiCApw9.js} +7 -12
  9. flowfile/web/static/assets/{ColumnSelector-0c8cd1cd.js → ColumnSelector-CEAwedI7.js} +1 -2
  10. flowfile/web/static/assets/ContextMenu-CdojQu0w.js +9 -0
  11. flowfile/web/static/assets/ContextMenu-D12mhsy1.js +9 -0
  12. flowfile/web/static/assets/ContextMenu-EWUR98va.js +9 -0
  13. 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
  14. flowfile/web/static/assets/{CrossJoin-38e5b99a.js → CrossJoin-BOFfxkJO.js} +19 -18
  15. flowfile/web/static/assets/{CrossJoin-71b4cc10.css → CrossJoin-Cmbyt9im.css} +18 -18
  16. flowfile/web/static/assets/{CustomNode-76e8f3f5.js → CustomNode-Bhpezobq.js} +12 -17
  17. flowfile/web/static/assets/{DatabaseConnectionSettings-38155669.js → DatabaseConnectionSettings-Dw3bSJKB.js} +10 -11
  18. flowfile/web/static/assets/{DatabaseReader-5bf8c75b.css → DatabaseReader-D6pUNUCs.css} +21 -21
  19. flowfile/web/static/assets/{DatabaseReader-2e549c8f.js → DatabaseReader-m87ghlw0.js} +36 -34
  20. flowfile/web/static/assets/{DatabaseView-dc877c29.js → DatabaseView-CisSAtpe.js} +30 -38
  21. flowfile/web/static/assets/{DatabaseWriter-ffb91864.js → DatabaseWriter-Bbj9JLdL.js} +33 -35
  22. flowfile/web/static/assets/{DatabaseWriter-bdcf2c8b.css → DatabaseWriter-RBqdFLj8.css} +17 -17
  23. flowfile/web/static/assets/{DesignerView-a4466dab.js → DesignerView-DemDevTQ.js} +1752 -2054
  24. flowfile/web/static/assets/{DesignerView-71d4e9a1.css → DesignerView-Dm6OzlIc.css} +209 -168
  25. flowfile/web/static/assets/{DocumentationView-979afc84.js → DocumentationView-BrC1ZR3H.js} +3 -4
  26. flowfile/web/static/assets/{ExploreData-e4b92aaf.js → ExploreData-BMKcDuRb.js} +8 -10
  27. flowfile/web/static/assets/{ExternalSource-d08e7227.js → ExternalSource-BXrNNS-f.js} +40 -42
  28. flowfile/web/static/assets/{ExternalSource-7ac7373f.css → ExternalSource-NB6WVl5R.css} +14 -14
  29. flowfile/web/static/assets/{Filter-7add806d.js → Filter-C2MjsN6P.js} +36 -33
  30. flowfile/web/static/assets/{Filter-7494ea97.css → Filter-DCMGGuGC.css} +9 -9
  31. flowfile/web/static/assets/{Formula-53d58c43.css → Formula-BYafbDj8.css} +4 -4
  32. flowfile/web/static/assets/{Formula-36ab24d2.js → Formula-ufuy4mVD.js} +27 -26
  33. flowfile/web/static/assets/{FuzzyMatch-ad6361d6.css → FuzzyMatch-BGJAwgd0.css} +42 -42
  34. flowfile/web/static/assets/{FuzzyMatch-cc01bb04.js → FuzzyMatch-BOHODq3h.js} +36 -38
  35. flowfile/web/static/assets/{GraphSolver-4fb98f3b.js → GraphSolver-B6ZzpNGO.js} +23 -21
  36. flowfile/web/static/assets/{GraphSolver-4b4d7db9.css → GraphSolver-DFN83sj3.css} +4 -4
  37. flowfile/web/static/assets/{GroupBy-b3c8f429.js → GroupBy-B9BRNcfe.js} +30 -29
  38. flowfile/web/static/assets/{Sort-4abb7fae.css → GroupBy-x4ooP5np.css} +1 -1
  39. flowfile/web/static/assets/Join-Bx_g5bZz.css +118 -0
  40. flowfile/web/static/assets/{Join-096b7b26.js → Join-DsBEy1IH.js} +48 -43
  41. flowfile/web/static/assets/{LoginView-c33a246a.js → LoginView-Ct0rhdcO.js} +1 -2
  42. flowfile/web/static/assets/{ManualInput-39111f19.css → ManualInput-DlZmtMdt.css} +48 -48
  43. flowfile/web/static/assets/{ManualInput-7307e9b1.js → ManualInput-bC4BUgnG.js} +40 -41
  44. flowfile/web/static/assets/{MultiSelect-14822c48.js → MultiSelect-DIQ8PuTC.js} +2 -2
  45. 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
  46. flowfile/web/static/assets/{NodeDesigner-5036c392.js → NodeDesigner-D39yzr2k.js} +178 -208
  47. flowfile/web/static/assets/{NodeDesigner-94cd4dd3.css → NodeDesigner-R0l6sYyY.css} +76 -76
  48. flowfile/web/static/assets/{NumericInput-15cf3b72.js → NumericInput-DMSX3oOr.js} +2 -2
  49. 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
  50. flowfile/web/static/assets/{Output-1f8ed42c.js → Output-D0VoXGcW.js} +26 -34
  51. flowfile/web/static/assets/{Output-692dd25d.css → Output-DsmglIDy.css} +5 -5
  52. flowfile/web/static/assets/{Pivot-0e153f4e.js → Pivot-BnMB4sEe.js} +26 -26
  53. flowfile/web/static/assets/{Pivot-0eda81b4.css → Pivot-qKTyWxop.css} +4 -4
  54. flowfile/web/static/assets/{PivotValidation-81ec2a33.js → PivotValidation-B2lWvugt.js} +7 -9
  55. flowfile/web/static/assets/{PivotValidation-5a4f7c79.js → PivotValidation-BPlhRjpL.js} +7 -9
  56. flowfile/web/static/assets/{PolarsCode-a39f15ac.js → PolarsCode-5h0tHnWR.js} +22 -20
  57. flowfile/web/static/assets/{PopOver-ddcfe4f6.js → PopOver-BHpt5rsj.js} +5 -9
  58. flowfile/web/static/assets/{PopOver-d96599db.css → PopOver-CyYM4-rV.css} +1 -1
  59. flowfile/web/static/assets/{Read-90f366bc.css → Read-DJxkrTb_.css} +10 -10
  60. flowfile/web/static/assets/Read-TsLEFh3B.js +227 -0
  61. flowfile/web/static/assets/{RecordCount-e9048ccd.js → RecordCount-DkVixq9v.js} +18 -17
  62. flowfile/web/static/assets/{RecordId-ad02521d.js → RecordId-C2UEGlCf.js} +42 -39
  63. flowfile/web/static/assets/{SQLQueryComponent-2eeecf0b.js → SQLQueryComponent-Dr5KMoD3.js} +2 -3
  64. flowfile/web/static/assets/{Sample-9a68c23d.js → Sample-Cb3eQNmd.js} +30 -30
  65. flowfile/web/static/assets/{SecretSelector-2429f35a.js → SecretSelector-De2L2bSx.js} +3 -4
  66. flowfile/web/static/assets/{SecretsView-c6afc915.js → SecretsView-CheC9BPV.js} +13 -16
  67. flowfile/web/static/assets/{Select-fcd002b6.js → Select-CI8TloRs.js} +41 -36
  68. flowfile/web/static/assets/{SettingsSection-5ce15962.js → SettingsSection-B39ulIiI.js} +1 -2
  69. flowfile/web/static/assets/{SettingsSection-c6b1362c.js → SettingsSection-BiCc7S9h.js} +1 -2
  70. flowfile/web/static/assets/{SettingsSection-cebb91d5.js → SettingsSection-CITK_R7o.js} +2 -3
  71. flowfile/web/static/assets/{SettingsSection-26fe48d4.css → SettingsSection-D2GgY-Aq.css} +4 -4
  72. flowfile/web/static/assets/{SetupView-2d12e01f.js → SetupView-C1aXRDvp.js} +1 -2
  73. flowfile/web/static/assets/{SingleSelect-b67de4eb.js → SingleSelect-Kr_hz90m.js} +2 -2
  74. 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
  75. flowfile/web/static/assets/{SliderInput-fd8134ac.js → SliderInput-CLqpCxCb.js} +1 -2
  76. flowfile/web/static/assets/{GroupBy-5792782d.css → Sort-BIt2kc_p.css} +1 -1
  77. flowfile/web/static/assets/{Sort-c005a573.js → Sort-Dnw_J6Qi.js} +25 -25
  78. flowfile/web/static/assets/{TextInput-1bb31dab.js → TextInput-wdlunIZC.js} +2 -2
  79. 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
  80. flowfile/web/static/assets/{TextToRows-4f363753.js → TextToRows-BhtyGWPq.js} +42 -49
  81. flowfile/web/static/assets/{TextToRows-12afb4f4.css → TextToRows-DivDOLDx.css} +9 -9
  82. flowfile/web/static/assets/{ToggleSwitch-ca0f2e5e.js → ToggleSwitch-B-6WzfFf.js} +2 -2
  83. 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
  84. flowfile/web/static/assets/{UnavailableFields-f6147968.js → UnavailableFields-Yf6XSqFB.js} +2 -3
  85. flowfile/web/static/assets/{Union-c65f17b7.js → Union-CwpjeKYC.js} +20 -23
  86. flowfile/web/static/assets/{Unpivot-b6ad6427.css → Union-DQJcpp3-.css} +6 -6
  87. flowfile/web/static/assets/{Unique-a1d96fb2.js → Unique-25v3urqH.js} +75 -74
  88. flowfile/web/static/assets/{Union-d6a8d7d5.css → Unpivot-Deqh1gtI.css} +6 -6
  89. flowfile/web/static/assets/{Unpivot-c2657ff3.js → Unpivot-sYcTTXrq.js} +34 -27
  90. flowfile/web/static/assets/{UnpivotValidation-28e29a3b.js → UnpivotValidation-C5DDEKY2.js} +5 -7
  91. flowfile/web/static/assets/VueGraphicWalker-B8l1_Z92.js +131 -0
  92. flowfile/web/static/assets/VueGraphicWalker-Da_1-3me.css +21 -0
  93. flowfile/web/static/assets/{api-df48ec50.js → api-C0LvF-0C.js} +1 -1
  94. flowfile/web/static/assets/{api-ee542cf7.js → api-DaC83EO_.js} +1 -1
  95. flowfile/web/static/assets/client-C8Ygr6Gb.js +42 -0
  96. flowfile/web/static/assets/{dropDown-7576a76a.js → dropDown-D5YXaPRR.js} +7 -12
  97. flowfile/web/static/assets/{fullEditor-7583bef5.js → fullEditor-BVYnWm05.js} +300 -18
  98. flowfile/web/static/assets/genericNodeSettings-2wAu-QKn.css +75 -0
  99. flowfile/web/static/assets/genericNodeSettings-BBtW_Cpz.js +590 -0
  100. flowfile/web/static/assets/{VueGraphicWalker-2fc3ddd4.js → graphic-walker.es-VrK6vdGE.js} +92305 -89751
  101. flowfile/web/static/assets/index-BCJxPfM5.js +6693 -0
  102. flowfile/web/static/assets/{index-057d770d.js → index-CHPMUR0d.js} +150 -170
  103. flowfile/web/static/assets/index-DPkoZWq8.js +32 -0
  104. flowfile/web/static/assets/index-DnW_KC_I.js +277 -0
  105. flowfile/web/static/assets/index-UFXyfirV.css +10797 -0
  106. flowfile/web/static/assets/index-bcuE0Z0p.js +87456 -0
  107. flowfile/web/static/assets/{node.types-2c15bb7e.js → node.types-Dl4gtSW9.js} +2 -2
  108. flowfile/web/static/assets/{outputCsv-c492b15e.js → outputCsv-BELuBiJZ.js} +1 -2
  109. flowfile/web/static/assets/outputCsv-CdGkv-fN.css +2581 -0
  110. flowfile/web/static/assets/{outputExcel-13bfa10f.js → outputExcel-D0TTNM79.js} +1 -2
  111. flowfile/web/static/assets/{outputParquet-9be1523a.js → outputParquet-Cz9EbRHj.js} +1 -2
  112. flowfile/web/static/assets/{readCsv-5a49a8c9.js → readCsv-7bd3kUMI.js} +1 -2
  113. flowfile/web/static/assets/{readExcel-27c30ad8.js → readExcel-Cq8CCwIv.js} +3 -4
  114. flowfile/web/static/assets/{readParquet-c5244ad5.css → readParquet-CRDmBrsp.css} +4 -4
  115. flowfile/web/static/assets/{readParquet-446bde68.js → readParquet-DjR4mRaj.js} +4 -5
  116. flowfile/web/static/assets/{secrets.api-34431884.js → secrets.api-C9o2KE5V.js} +1 -1
  117. flowfile/web/static/assets/{selectDynamic-5754a2b1.js → selectDynamic-Bl5FVsME.js} +5 -7
  118. flowfile/web/static/assets/useNodeSettings-dMS9zmh_.js +69 -0
  119. flowfile/web/static/assets/{vue-codemirror.esm-8f46fb36.js → vue-codemirror.esm-CwaYwln0.js} +3469 -3064
  120. flowfile/web/static/assets/{vue-content-loader.es-808fe33a.js → vue-content-loader.es-CMoRXo7N.js} +3 -3
  121. flowfile/web/static/index.html +2 -3
  122. {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/METADATA +2 -1
  123. flowfile-0.6.1.dist-info/RECORD +417 -0
  124. {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/WHEEL +1 -1
  125. flowfile_core/auth/password.py +1 -0
  126. flowfile_core/database/init_db.py +7 -5
  127. flowfile_core/fileExplorer/funcs.py +2 -2
  128. flowfile_core/flowfile/code_generator/code_generator.py +13 -11
  129. flowfile_core/flowfile/filter_expressions.py +327 -0
  130. flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +61 -59
  131. flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +3 -29
  132. flowfile_core/flowfile/flow_data_engine/flow_file_column/utils.py +45 -14
  133. flowfile_core/flowfile/flow_data_engine/subprocess_operations/models.py +20 -3
  134. flowfile_core/flowfile/flow_data_engine/subprocess_operations/streaming.py +206 -0
  135. flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +146 -24
  136. flowfile_core/flowfile/flow_graph.py +504 -190
  137. flowfile_core/flowfile/flow_node/__init__.py +32 -0
  138. flowfile_core/flowfile/flow_node/executor.py +404 -0
  139. flowfile_core/flowfile/flow_node/flow_node.py +207 -106
  140. flowfile_core/flowfile/flow_node/models.py +40 -0
  141. flowfile_core/flowfile/flow_node/output_field_config_applier.py +217 -0
  142. flowfile_core/flowfile/flow_node/schema_utils.py +78 -0
  143. flowfile_core/flowfile/flow_node/state.py +155 -0
  144. flowfile_core/flowfile/history_manager.py +401 -0
  145. flowfile_core/flowfile/manage/compatibility_enhancements.py +9 -0
  146. flowfile_core/flowfile/manage/io_flowfile.py +3 -1
  147. flowfile_core/flowfile/sources/external_sources/sql_source/models.py +20 -4
  148. flowfile_core/flowfile/util/execution_orderer.py +89 -36
  149. flowfile_core/routes/auth.py +8 -9
  150. flowfile_core/routes/routes.py +320 -101
  151. flowfile_core/routes/user_defined_components.py +18 -16
  152. flowfile_core/schemas/history_schema.py +220 -0
  153. flowfile_core/schemas/input_schema.py +130 -6
  154. flowfile_core/schemas/schemas.py +9 -0
  155. flowfile_core/schemas/transform_schema.py +27 -5
  156. flowfile_core/schemas/yaml_types.py +23 -5
  157. flowfile_frame/adding_expr.py +18 -126
  158. flowfile_frame/callable_utils.py +261 -0
  159. flowfile_frame/database/connection_manager.py +0 -1
  160. flowfile_frame/expr.py +8 -4
  161. flowfile_frame/flow_frame.py +41 -41
  162. flowfile_frame/lazy.py +3 -12
  163. flowfile_frame/lazy_methods.py +5 -64
  164. flowfile_frame/utils.py +13 -32
  165. flowfile_worker/funcs.py +6 -4
  166. flowfile_worker/main.py +2 -0
  167. flowfile_worker/models.py +31 -11
  168. flowfile_worker/routes.py +60 -35
  169. flowfile_worker/spawner.py +7 -1
  170. flowfile_worker/streaming.py +335 -0
  171. flowfile/web/static/assets/ContextMenu-366bf1b4.js +0 -9
  172. flowfile/web/static/assets/ContextMenu-85cf5b44.js +0 -9
  173. flowfile/web/static/assets/ContextMenu-9d28ae6d.js +0 -9
  174. flowfile/web/static/assets/Join-28b5e18f.css +0 -109
  175. flowfile/web/static/assets/Read-39b63932.js +0 -222
  176. flowfile/web/static/assets/VueGraphicWalker-430f0b86.css +0 -6
  177. flowfile/web/static/assets/database_reader-ce1e55f3.svg +0 -24
  178. flowfile/web/static/assets/database_writer-b4ad0753.svg +0 -23
  179. flowfile/web/static/assets/element-icons-9c88a535.woff +0 -0
  180. flowfile/web/static/assets/element-icons-de5eb258.ttf +0 -0
  181. flowfile/web/static/assets/genericNodeSettings-0155288b.js +0 -136
  182. flowfile/web/static/assets/genericNodeSettings-3b2507ea.css +0 -46
  183. flowfile/web/static/assets/index-aeec439d.js +0 -38
  184. flowfile/web/static/assets/index-ca6799de.js +0 -62760
  185. flowfile/web/static/assets/index-d60c9dd4.css +0 -10777
  186. flowfile/web/static/assets/nodeInput-d478b9ac.js +0 -2
  187. flowfile/web/static/assets/outputCsv-cc84e09f.css +0 -2499
  188. flowfile-0.5.6.dist-info/RECORD +0 -407
  189. /flowfile/web/static/assets/{AdminView-f53bad23.css → AdminView-B2Dthl3u.css} +0 -0
  190. /flowfile/web/static/assets/{CloudConnectionView-cf85f943.css → CloudConnectionView-BdFYGWV7.css} +0 -0
  191. /flowfile/web/static/assets/{ColumnActionInput-c44b7aee.css → ColumnActionInput-dCasSIC9.css} +0 -0
  192. /flowfile/web/static/assets/{ColumnSelector-371637fb.css → ColumnSelector-j6sEOjo1.css} +0 -0
  193. /flowfile/web/static/assets/{CustomNode-edb9b939.css → CustomNode-VPlajG0j.css} +0 -0
  194. /flowfile/web/static/assets/{DatabaseConnectionSettings-c20a1e16.css → DatabaseConnectionSettings-B78hXYgu.css} +0 -0
  195. /flowfile/web/static/assets/{DatabaseView-6655afd6.css → DatabaseView-B-_adk1s.css} +0 -0
  196. /flowfile/web/static/assets/{DocumentationView-9ea6e871.css → DocumentationView-CL7iipFL.css} +0 -0
  197. /flowfile/web/static/assets/{ExploreData-10c5acc8.css → ExploreData-DHjv0Plr.css} +0 -0
  198. /flowfile/web/static/assets/{LoginView-d325d632.css → LoginView-DN1BXY3e.css} +0 -0
  199. /flowfile/web/static/assets/{PivotValidation-0e905b1a.css → PivotValidation-DK-FARWe.css} +0 -0
  200. /flowfile/web/static/assets/{PivotValidation-41b57ad6.css → PivotValidation-FUa9F47u.css} +0 -0
  201. /flowfile/web/static/assets/{PolarsCode-2b1f1f23.css → PolarsCode-G-gRSrSc.css} +0 -0
  202. /flowfile/web/static/assets/{SQLQueryComponent-edb90b98.css → SQLQueryComponent-oAbWw0r-.css} +0 -0
  203. /flowfile/web/static/assets/{SecretSelector-6329f743.css → SecretSelector-CJSadIZx.css} +0 -0
  204. /flowfile/web/static/assets/{SecretsView-aa291340.css → SecretsView-DbzIRAba.css} +0 -0
  205. /flowfile/web/static/assets/{SettingsSection-8f980839.css → SettingsSection-BGcJnH6q.css} +0 -0
  206. /flowfile/web/static/assets/{SettingsSection-07fbbc39.css → SettingsSection-DDWn_EGW.css} +0 -0
  207. /flowfile/web/static/assets/{SetupView-ec26f76a.css → SetupView-CI1nd-5Z.css} +0 -0
  208. /flowfile/web/static/assets/{SliderInput-f2e4f23c.css → SliderInput-BRk-q_Dk.css} +0 -0
  209. /flowfile/web/static/assets/{UnavailableFields-394a1f78.css → UnavailableFields-DRKDImKe.css} +0 -0
  210. /flowfile/web/static/assets/{Unique-2b705521.css → Unique-Absb0aON.css} +0 -0
  211. /flowfile/web/static/assets/{UnpivotValidation-d5ca3b7b.css → UnpivotValidation-DSBkFgS-.css} +0 -0
  212. /flowfile/web/static/assets/{airbyte-292aa232.png → airbyte-W0xvIXwZ.png} +0 -0
  213. /flowfile/web/static/assets/{cloud_storage_reader-aa1415d6.png → cloud_storage_reader-3GpSCk90.png} +0 -0
  214. /flowfile/web/static/assets/{cross_join-d30c0290.png → cross_join-B0qpgYoV.png} +0 -0
  215. /flowfile/web/static/assets/{dropDown-1d6acbd9.css → dropDown-CE0VF5_P.css} +0 -0
  216. /flowfile/web/static/assets/{explore_data-8a0a2861.png → explore_data-tX6olPPL.png} +0 -0
  217. /flowfile/web/static/assets/{fa-brands-400-808443ae.ttf → fa-brands-400-D1LuMI3I.ttf} +0 -0
  218. /flowfile/web/static/assets/{fa-brands-400-d7236a19.woff2 → fa-brands-400-D_cYUPeE.woff2} +0 -0
  219. /flowfile/web/static/assets/{fa-regular-400-e3456d12.woff2 → fa-regular-400-BjRzuEpd.woff2} +0 -0
  220. /flowfile/web/static/assets/{fa-regular-400-54cf6086.ttf → fa-regular-400-DZaxPHgR.ttf} +0 -0
  221. /flowfile/web/static/assets/{fa-solid-900-aa759986.woff2 → fa-solid-900-CTAAxXor.woff2} +0 -0
  222. /flowfile/web/static/assets/{fa-solid-900-d2f05935.ttf → fa-solid-900-D0aA9rwL.ttf} +0 -0
  223. /flowfile/web/static/assets/{fa-v4compatibility-0ce9033c.woff2 → fa-v4compatibility-C9RhG_FT.woff2} +0 -0
  224. /flowfile/web/static/assets/{fa-v4compatibility-30f6abf6.ttf → fa-v4compatibility-CCth-dXg.ttf} +0 -0
  225. /flowfile/web/static/assets/{filter-d7708bda.png → filter-WRdZyUOw.png} +0 -0
  226. /flowfile/web/static/assets/{formula-eeeb1611.png → formula-CgM7uHVI.png} +0 -0
  227. /flowfile/web/static/assets/{fullEditor-fe9f7e18.css → fullEditor-CmDI7T9F.css} +0 -0
  228. /flowfile/web/static/assets/{fuzzy_match-40c161b2.png → fuzzy_match-Yon3k5Tc.png} +0 -0
  229. /flowfile/web/static/assets/{graph_solver-8b7888b8.png → graph_solver-BlMrBttD.png} +0 -0
  230. /flowfile/web/static/assets/{group_by-80561fc3.png → group_by-Gici0CSS.png} +0 -0
  231. /flowfile/web/static/assets/{input_data-ab2eb678.png → input_data-BRdGecLc.png} +0 -0
  232. /flowfile/web/static/assets/{join-349043ae.png → join-BITWRu73.png} +0 -0
  233. /flowfile/web/static/assets/{manual_input-ae98f31d.png → manual_input-CFvo_EUS.png} +0 -0
  234. /flowfile/web/static/assets/{old_join-5d0eb604.png → old_join-B9bkpPqv.png} +0 -0
  235. /flowfile/web/static/assets/{output-06ec0371.png → output-Dp7-ZpC4.png} +0 -0
  236. /flowfile/web/static/assets/{outputExcel-f5d272b2.css → outputExcel-CKgRe2iT.css} +0 -0
  237. /flowfile/web/static/assets/{outputParquet-54597c3c.css → outputParquet-d7j407cK.css} +0 -0
  238. /flowfile/web/static/assets/{pivot-9660df51.png → pivot-DSxKhNlD.png} +0 -0
  239. /flowfile/web/static/assets/{polars_code-05ce5dc6.png → polars_code-DxiztZ1c.png} +0 -0
  240. /flowfile/web/static/assets/{readCsv-3bfac4c3.css → readCsv-BG-1Jilp.css} +0 -0
  241. /flowfile/web/static/assets/{readExcel-3db6b763.css → readExcel-DBQXKPtC.css} +0 -0
  242. /flowfile/web/static/assets/{record_count-dab44eb5.png → record_count-DCeaLtpS.png} +0 -0
  243. /flowfile/web/static/assets/{record_id-0b15856b.png → record_id-FeUjyIFh.png} +0 -0
  244. /flowfile/web/static/assets/{sample-693a88b5.png → sample-DeqfRiB-.png} +0 -0
  245. /flowfile/web/static/assets/{select-b0d0437a.png → select-D4JjbdjS.png} +0 -0
  246. /flowfile/web/static/assets/{selectDynamic-f2fb394f.css → selectDynamic-CjeTPUUo.css} +0 -0
  247. /flowfile/web/static/assets/{sort-2aa579f0.png → sort-DGwUG9WS.png} +0 -0
  248. /flowfile/web/static/assets/{summarize-2a099231.png → summarize-DFaNHpfp.png} +0 -0
  249. /flowfile/web/static/assets/{text_to_rows-859b29ea.png → text_to_rows-BdiAewrN.png} +0 -0
  250. /flowfile/web/static/assets/{union-2d8609f4.png → union-DCK-LSMq.png} +0 -0
  251. /flowfile/web/static/assets/{unique-1958b98a.png → unique-CdP3zZIq.png} +0 -0
  252. /flowfile/web/static/assets/{unpivot-d3cb4b5b.png → unpivot-CHttrEt8.png} +0 -0
  253. /flowfile/web/static/assets/{user-defined-icon-0ae16c90.png → user-defined-icon-BcIp2Vzo.png} +0 -0
  254. /flowfile/web/static/assets/{view-7a0f0be1.png → view-DUSRwjvq.png} +0 -0
  255. {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/entry_points.txt +0 -0
  256. {flowfile-0.5.6.dist-info → flowfile-0.6.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,217 @@
1
+ """Utility module for applying output field configuration to FlowDataEngine results."""
2
+
3
+ from typing import List, Set
4
+ import polars as pl
5
+ from flowfile_core.configs import logger
6
+ from flowfile_core.flowfile.flow_data_engine.flow_data_engine import FlowDataEngine
7
+ from flowfile_core.flowfile.flow_data_engine.flow_file_column.main import FlowfileColumn
8
+ from flowfile_core.flowfile.flow_data_engine.flow_file_column.utils import cast_str_to_polars_type
9
+ from flowfile_core.schemas.input_schema import OutputFieldConfig, OutputFieldInfo
10
+
11
+
12
+ def _parse_default_value(field: OutputFieldInfo) -> pl.Expr:
13
+ """Parse default value from field configuration.
14
+
15
+ Args:
16
+ field: Output field info containing default_value
17
+
18
+ Returns:
19
+ Polars expression for the default value cast to the target data type
20
+ """
21
+ # Get target Polars dtype from the field's data_type
22
+ target_dtype = cast_str_to_polars_type(field.data_type)
23
+ # Treat as literal value and cast to target type
24
+ return pl.lit(field.default_value).cast(target_dtype, strict=False, wrap_numerical=True)
25
+
26
+
27
+ def _select_columns_in_order(df: pl.DataFrame, fields: list[OutputFieldInfo]) -> pl.DataFrame:
28
+ """Select columns in the specified field order.
29
+
30
+ Args:
31
+ df: Input dataframe
32
+ fields: List of fields specifying column order
33
+
34
+ Returns:
35
+ DataFrame with columns selected in specified order
36
+ """
37
+ return df.select([field.name for field in fields])
38
+
39
+
40
+ def _apply_raise_on_missing(
41
+ flowfile_engine: FlowDataEngine,
42
+ fields: list[OutputFieldInfo],
43
+ ) -> FlowDataEngine:
44
+ """Apply raise_on_missing validation mode.
45
+
46
+ Raises error if any expected columns are missing, then selects columns in order.
47
+
48
+ Args:
49
+ flowfile_engine: Input flow data engine
50
+ fields: List of expected output fields
51
+
52
+ Returns:
53
+ Flow Data Engine with columns selected in specified order
54
+
55
+ Raises:
56
+ ValueError: If any expected columns are missing
57
+ """
58
+ cols = [f.name for f in fields]
59
+ missing_columns = set(cols) - set(flowfile_engine.columns)
60
+ if missing_columns:
61
+ raise ValueError(f"Missing required columns: {', '.join(sorted(missing_columns))}")
62
+ if flowfile_engine.columns != cols:
63
+ return FlowDataEngine(_select_columns_in_order(flowfile_engine.data_frame, fields))
64
+ else:
65
+ return flowfile_engine
66
+
67
+
68
+ def _apply_add_missing(
69
+ engine: FlowDataEngine,
70
+ fields: list[OutputFieldInfo],
71
+ ) -> FlowDataEngine:
72
+ """Apply add_missing validation mode.
73
+
74
+ Adds missing columns with default values, then selects columns in order.
75
+ Extra columns not in the config are removed.
76
+
77
+ Args:
78
+ engine: Input flow data engine
79
+ fields: List of expected output fields
80
+
81
+ Returns:
82
+ FlowDataEngine with missing columns added and only configured columns in specified order
83
+ """
84
+ # Add missing columns with default values
85
+ current_columns = set(engine.columns)
86
+ expressions = [_parse_default_value(field).alias(field.name)
87
+ for field in fields if field.name not in current_columns]
88
+ if expressions:
89
+ new_df = engine.data_frame.with_columns(expressions)
90
+ else:
91
+ new_df = engine.data_frame
92
+ return FlowDataEngine(_select_columns_in_order(new_df, fields))
93
+
94
+
95
+ def _apply_add_missing_keep_extra(
96
+ engine: FlowDataEngine,
97
+ fields: list[OutputFieldInfo],
98
+ ) -> FlowDataEngine:
99
+ """Apply add_missing_keep_extra validation mode.
100
+
101
+ Adds missing columns with default values, but keeps all incoming columns.
102
+ Configured columns come first in specified order, followed by extra columns.
103
+
104
+ Args:
105
+ engine: Input flow data engine
106
+ fields: List of expected output fields
107
+
108
+ Returns:
109
+ FlowDataEngine with missing columns added and all columns preserved
110
+ (configured columns first, then extras)
111
+ """
112
+ current_columns = set(engine.columns)
113
+ configured_names = {field.name for field in fields}
114
+
115
+ # Add missing columns with default values
116
+ expressions = [_parse_default_value(field).alias(field.name)
117
+ for field in fields if field.name not in current_columns]
118
+ if expressions:
119
+ new_df = engine.data_frame.with_columns(expressions)
120
+ else:
121
+ new_df = engine.data_frame
122
+
123
+ # Build column order: configured columns first (in order), then extras
124
+ configured_column_order = [field.name for field in fields]
125
+ extra_columns = [col for col in engine.columns if col not in configured_names]
126
+
127
+ final_column_order = configured_column_order + extra_columns
128
+ return FlowDataEngine(new_df.select(final_column_order))
129
+
130
+
131
+ def _validate_data_types(df: FlowDataEngine, fields: list[OutputFieldInfo]) -> None:
132
+ """Validate that dataframe column types match expected types.
133
+
134
+ Args:
135
+ df: Input dataframe or lazyframe
136
+ fields: List of expected output fields with data types
137
+
138
+ Raises:
139
+ ValueError: If any data type mismatches are found
140
+ """
141
+ # Get schema (works for both DataFrame and LazyFrame)
142
+ schema: dict[str, FlowfileColumn] = {column.column_name: column for column in df.schema}
143
+ mismatches = []
144
+ for field in fields:
145
+
146
+ if field.name not in schema:
147
+ continue
148
+ # Use FlowfileColumn infrastructure to convert dtype to string
149
+ column = schema.get(field.name)
150
+ column.get_minimal_field_info()
151
+ if column.data_type != field.data_type:
152
+ mismatches.append(
153
+ f"Column '{field.name}': expected {field.data_type}, got {column.data_type}"
154
+ )
155
+
156
+ if mismatches:
157
+ error_msg = "Data type validation failed:\n" + "\n".join(f" - {m}" for m in mismatches)
158
+ logger.error(error_msg)
159
+ raise ValueError(error_msg)
160
+
161
+ logger.info(f"Data type validation passed for {len(fields)} fields")
162
+
163
+
164
+ def apply_output_field_config(
165
+ flow_data_engine: FlowDataEngine, output_field_config: OutputFieldConfig
166
+ ) -> FlowDataEngine:
167
+ """Apply output field configuration to enforce schema requirements.
168
+
169
+ Args:
170
+ flow_data_engine: The FlowDataEngine instance to apply configuration to
171
+ output_field_config: The output field configuration specifying behavior
172
+
173
+ Returns:
174
+ Modified FlowDataEngine with enforced schema
175
+
176
+ Raises:
177
+ ValueError: If raise_on_missing behavior is set and required columns are missing,
178
+ or if data type validation fails
179
+ """
180
+ if not output_field_config or not output_field_config.enabled:
181
+ return flow_data_engine
182
+
183
+ if not output_field_config.fields:
184
+ return flow_data_engine
185
+ # breakpoint()
186
+ try:
187
+ # Get column sets for validation (works for both DataFrame and LazyFrame)
188
+
189
+ # Apply validation mode behavior
190
+ mode = output_field_config.validation_mode_behavior
191
+ if mode == "raise_on_missing":
192
+ new_flow_engine = _apply_raise_on_missing(flow_data_engine, output_field_config.fields)
193
+ elif mode == "add_missing":
194
+ new_flow_engine = _apply_add_missing(engine=flow_data_engine, fields=output_field_config.fields)
195
+ elif mode == "add_missing_keep_extra":
196
+ new_flow_engine = _apply_add_missing_keep_extra(engine=flow_data_engine, fields=output_field_config.fields)
197
+ elif mode == "select_only":
198
+ new_flow_engine = flow_data_engine.select_columns(
199
+ [field.name for field in output_field_config.fields]
200
+ )
201
+ else:
202
+ raise ValueError(f"Unknown validation mode behavior: {mode}")
203
+ # Validate data types if enabled
204
+ if output_field_config.validate_data_types:
205
+ _validate_data_types(new_flow_engine, output_field_config.fields)
206
+
207
+ logger.info(
208
+ f"Applied output field config: behavior={mode}, "
209
+ f"fields={len(output_field_config.fields)}, "
210
+ f"validate_data_types={output_field_config.validate_data_types}"
211
+ )
212
+
213
+ except Exception as e:
214
+ logger.error(f"Error applying output field config: {e}")
215
+ raise
216
+
217
+ return new_flow_engine
@@ -0,0 +1,78 @@
1
+ """Schema utilities for output field configuration."""
2
+
3
+ from flowfile_core.configs import logger
4
+ from flowfile_core.flowfile.flow_data_engine.flow_file_column.main import FlowfileColumn
5
+ from flowfile_core.schemas.input_schema import OutputFieldConfig
6
+
7
+
8
+ def create_schema_from_output_field_config(output_field_config: OutputFieldConfig) -> list[FlowfileColumn]:
9
+ """Create a FlowfileColumn schema from OutputFieldConfig.
10
+
11
+ This is used for schema prediction - instead of running the transformation,
12
+ we can directly return the configured output schema.
13
+
14
+ Note: For 'add_missing_keep_extra' mode, this returns only the configured fields.
15
+ Extra columns from the incoming data are not predictable without running the flow,
16
+ so _predicted_data_getter provides more accurate results for that mode.
17
+
18
+ Args:
19
+ output_field_config: The output field configuration
20
+
21
+ Returns:
22
+ List of FlowfileColumn objects representing the expected output schema
23
+ """
24
+ if not output_field_config or not output_field_config.enabled or not output_field_config.fields:
25
+ logger.debug("create_schema_from_output_field_config: config not enabled or no fields, returning None")
26
+ return None
27
+
28
+ schema = [
29
+ FlowfileColumn.from_input(column_name=field.name, data_type=field.data_type)
30
+ for field in output_field_config.fields
31
+ ]
32
+ logger.info(
33
+ f"create_schema_from_output_field_config: Created schema with {len(schema)} fields: "
34
+ f"{[f.name for f in schema]}"
35
+ )
36
+ return schema
37
+
38
+
39
+ def create_schema_callback_with_output_config(
40
+ base_schema_callback: callable,
41
+ output_field_config: OutputFieldConfig | None
42
+ ) -> callable:
43
+ """Wraps a schema callback to use output_field_config when available.
44
+
45
+ This allows nodes to use their configured output schema for prediction
46
+ instead of running through transformation logic.
47
+
48
+ Args:
49
+ base_schema_callback: The original schema callback function
50
+ output_field_config: The output field configuration, if any
51
+
52
+ Returns:
53
+ A wrapped schema callback that prioritizes output_field_config
54
+ """
55
+ logger.debug(
56
+ f"create_schema_callback_with_output_config called: "
57
+ f"base_callback={'present' if base_schema_callback else 'None'}, "
58
+ f"config={'enabled' if (output_field_config and output_field_config.enabled) else 'disabled/None'}"
59
+ )
60
+
61
+ def wrapped_schema_callback():
62
+ # If output_field_config is enabled, use it directly for schema prediction
63
+ if output_field_config and output_field_config.enabled and output_field_config.fields:
64
+ logger.info(
65
+ f"wrapped_schema_callback: Using output_field_config for schema prediction "
66
+ f"(validation_mode={output_field_config.validation_mode_behavior}, {len(output_field_config.fields)} fields)"
67
+ )
68
+ return create_schema_from_output_field_config(output_field_config)
69
+
70
+ # Otherwise fall back to the original schema callback
71
+ if base_schema_callback:
72
+ logger.debug("wrapped_schema_callback: Falling back to base_schema_callback")
73
+ return base_schema_callback()
74
+ else:
75
+ logger.warning("wrapped_schema_callback: No base_schema_callback and no output_field_config, returning None")
76
+ return None
77
+
78
+ return wrapped_schema_callback
@@ -0,0 +1,155 @@
1
+ """
2
+ Node execution state - separable from node definition.
3
+ Can be persisted to database/cache for stateless operation.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import os
8
+ from collections.abc import Callable
9
+ from dataclasses import dataclass, field
10
+ from typing import TYPE_CHECKING
11
+
12
+ import pyarrow as pa
13
+
14
+ if TYPE_CHECKING:
15
+ from flowfile_core.flowfile.flow_data_engine.flow_data_engine import FlowDataEngine
16
+ from flowfile_core.flowfile.flow_data_engine.flow_file_column.main import FlowfileColumn
17
+
18
+
19
+ @dataclass
20
+ class SourceFileInfo:
21
+ """
22
+ Tracks source file state for cache invalidation.
23
+ Used by read nodes to detect when source files change.
24
+ """
25
+ path: str
26
+ mtime: float
27
+ size: int
28
+
29
+ @classmethod
30
+ def from_path(cls, path: str) -> SourceFileInfo | None:
31
+ """Create from file path, returns None if file doesn't exist."""
32
+ try:
33
+ stat = os.stat(path)
34
+ return cls(path=path, mtime=stat.st_mtime, size=stat.st_size)
35
+ except OSError:
36
+ return None
37
+
38
+ def has_changed(self) -> bool:
39
+ """Check if file has changed since this info was recorded."""
40
+ try:
41
+ stat = os.stat(self.path)
42
+ return stat.st_mtime != self.mtime or stat.st_size != self.size
43
+ except OSError:
44
+ return True # File missing = changed
45
+
46
+ def to_dict(self) -> dict:
47
+ """Serialize for external storage."""
48
+ return {"path": self.path, "mtime": self.mtime, "size": self.size}
49
+
50
+ @classmethod
51
+ def from_dict(cls, data: dict) -> SourceFileInfo:
52
+ """Deserialize from external storage."""
53
+ return cls(path=data["path"], mtime=data["mtime"], size=data["size"])
54
+
55
+
56
+ @dataclass
57
+ class NodeExecutionState:
58
+ """
59
+ All mutable state for a node's execution.
60
+
61
+ This can be:
62
+ - Stored in memory (current behavior)
63
+ - Persisted to database (stateless workers)
64
+ - Stored in Redis/cache (distributed execution)
65
+
66
+ Kept separate from FlowNode to enable stateless execution patterns.
67
+ """
68
+ # Execution tracking
69
+ has_run_with_current_setup: bool = False
70
+ has_completed_last_run: bool = False
71
+ is_canceled: bool = False
72
+ error: str | None = None
73
+
74
+ # Results (not serialized - too large)
75
+ resulting_data: FlowDataEngine | None = field(default=None, repr=False)
76
+ example_data_path: str | None = None
77
+ example_data_generator: Callable[[], pa.Table] | None = field(default=None, repr=False)
78
+ warnings: str | None = None
79
+
80
+ # Schema
81
+ result_schema: list[FlowfileColumn] | None = field(default=None, repr=False)
82
+ predicted_schema: list[FlowfileColumn] | None = field(default=None, repr=False)
83
+
84
+ # Source tracking (for read nodes)
85
+ source_file_info: SourceFileInfo | None = None
86
+
87
+ # Hash for cache lookup
88
+ execution_hash: str | None = None
89
+
90
+ def reset(self) -> None:
91
+ """Reset to clean state for re-execution."""
92
+ self.has_run_with_current_setup = False
93
+ self.has_completed_last_run = False
94
+ self.is_canceled = False
95
+ self.error = None
96
+ self.resulting_data = None
97
+ self.example_data_path = None
98
+ self.example_data_generator = None
99
+ self.warnings = None
100
+ self.result_schema = None
101
+ self.predicted_schema = None
102
+ # Note: source_file_info intentionally NOT reset - needed for change detection
103
+ self.execution_hash = None
104
+
105
+ def reset_results_only(self) -> None:
106
+ """Reset just the results, keep tracking state."""
107
+ self.error = None
108
+ self.resulting_data = None
109
+ self.example_data_path = None
110
+ self.example_data_generator = None
111
+ self.warnings = None
112
+
113
+ def mark_successful(self) -> None:
114
+ """Mark execution as successful."""
115
+ self.has_run_with_current_setup = True
116
+ self.has_completed_last_run = True
117
+ self.error = None
118
+
119
+ def mark_failed(self, error: str) -> None:
120
+ """Mark execution as failed."""
121
+ self.has_run_with_current_setup = False
122
+ self.has_completed_last_run = False
123
+ self.error = error
124
+
125
+ def to_dict(self) -> dict:
126
+ """
127
+ Serialize for external storage (stateless mode).
128
+ Note: resulting_data and generators are not serialized.
129
+ """
130
+ return {
131
+ "has_run_with_current_setup": self.has_run_with_current_setup,
132
+ "has_completed_last_run": self.has_completed_last_run,
133
+ "is_canceled": self.is_canceled,
134
+ "error": self.error,
135
+ "example_data_path": self.example_data_path,
136
+ "warnings": self.warnings,
137
+ "execution_hash": self.execution_hash,
138
+ "source_file_info": self.source_file_info.to_dict() if self.source_file_info else None,
139
+ }
140
+
141
+ @classmethod
142
+ def from_dict(cls, data: dict) -> NodeExecutionState:
143
+ """Deserialize from external storage."""
144
+ state = cls(
145
+ has_run_with_current_setup=data.get("has_run_with_current_setup", False),
146
+ has_completed_last_run=data.get("has_completed_last_run", False),
147
+ is_canceled=data.get("is_canceled", False),
148
+ error=data.get("error"),
149
+ example_data_path=data.get("example_data_path"),
150
+ warnings=data.get("warnings"),
151
+ execution_hash=data.get("execution_hash"),
152
+ )
153
+ if data.get("source_file_info"):
154
+ state.source_file_info = SourceFileInfo.from_dict(data["source_file_info"])
155
+ return state