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.
Files changed (346) hide show
  1. build_backends/main.py +25 -22
  2. build_backends/main_prd.py +10 -19
  3. flowfile/__init__.py +194 -74
  4. flowfile/__main__.py +10 -7
  5. flowfile/api.py +51 -57
  6. flowfile/web/__init__.py +14 -9
  7. flowfile/web/static/assets/AdminView-f53bad23.css +129 -0
  8. flowfile/web/static/assets/AdminView-f9847d67.js +713 -0
  9. flowfile/web/static/assets/CloudConnectionView-cf85f943.css +72 -0
  10. flowfile/web/static/assets/{CloudConnectionManager-0dfba9f2.js → CloudConnectionView-faace55b.js} +11 -11
  11. flowfile/web/static/assets/{CloudStorageReader-29d14fcc.css → CloudStorageReader-24c54524.css} +27 -27
  12. flowfile/web/static/assets/{CloudStorageReader-d5b1b6c9.js → CloudStorageReader-d86ecaa7.js} +10 -8
  13. flowfile/web/static/assets/{CloudStorageWriter-00d87aad.js → CloudStorageWriter-0f4d9a44.js} +10 -8
  14. flowfile/web/static/assets/{CloudStorageWriter-b0ee067f.css → CloudStorageWriter-60547855.css} +26 -26
  15. flowfile/web/static/assets/ColumnActionInput-c44b7aee.css +159 -0
  16. flowfile/web/static/assets/ColumnActionInput-f4189ae0.js +330 -0
  17. flowfile/web/static/assets/{ColumnSelector-47996a16.css → ColumnSelector-371637fb.css} +2 -2
  18. flowfile/web/static/assets/{ColumnSelector-4685e75d.js → ColumnSelector-e66b33da.js} +3 -5
  19. flowfile/web/static/assets/ContextMenu-49463352.js +9 -0
  20. flowfile/web/static/assets/ContextMenu-dd5f3f25.js +9 -0
  21. flowfile/web/static/assets/ContextMenu-f709b884.js +9 -0
  22. flowfile/web/static/assets/ContextMenu.vue_vue_type_script_setup_true_lang-a1bd6314.js +59 -0
  23. flowfile/web/static/assets/{CrossJoin-702a3edd.js → CrossJoin-24694b8f.js} +12 -10
  24. flowfile/web/static/assets/{CrossJoin-1119d18e.css → CrossJoin-71b4cc10.css} +20 -20
  25. flowfile/web/static/assets/{CustomNode-b1519993.js → CustomNode-569d45ff.js} +43 -24
  26. flowfile/web/static/assets/CustomNode-edb9b939.css +42 -0
  27. flowfile/web/static/assets/{DatabaseConnectionSettings-0c04b2e5.css → DatabaseConnectionSettings-c20a1e16.css} +23 -21
  28. flowfile/web/static/assets/{DatabaseConnectionSettings-6f3e4ea5.js → DatabaseConnectionSettings-cfc08938.js} +5 -4
  29. flowfile/web/static/assets/{DatabaseReader-ae61773c.css → DatabaseReader-5bf8c75b.css} +41 -46
  30. flowfile/web/static/assets/{DatabaseReader-d38c7295.js → DatabaseReader-701feabb.js} +25 -15
  31. flowfile/web/static/assets/{DatabaseManager-cf5ef661.js → DatabaseView-0482e5b5.js} +11 -11
  32. flowfile/web/static/assets/DatabaseView-6655afd6.css +57 -0
  33. flowfile/web/static/assets/{DatabaseWriter-b04ef46a.js → DatabaseWriter-16721989.js} +17 -10
  34. flowfile/web/static/assets/{DatabaseWriter-2f570e53.css → DatabaseWriter-bdcf2c8b.css} +29 -27
  35. flowfile/web/static/assets/{designer-8da3ba3a.css → DesignerView-49abb835.css} +783 -663
  36. flowfile/web/static/assets/{designer-9633482a.js → DesignerView-f64749fb.js} +1292 -3253
  37. flowfile/web/static/assets/{documentation-ca400224.js → DocumentationView-61bd2990.js} +5 -5
  38. flowfile/web/static/assets/{documentation-12216a74.css → DocumentationView-9ea6e871.css} +9 -9
  39. flowfile/web/static/assets/{ExploreData-2d0cf4db.css → ExploreData-10c5acc8.css} +13 -12
  40. flowfile/web/static/assets/{ExploreData-5fa10ed8.js → ExploreData-e2735b13.js} +18 -9
  41. flowfile/web/static/assets/{ExternalSource-d39af878.js → ExternalSource-2535c3b2.js} +9 -7
  42. flowfile/web/static/assets/{ExternalSource-e37b6275.css → ExternalSource-7ac7373f.css} +20 -20
  43. flowfile/web/static/assets/Filter-2cdbc93c.js +287 -0
  44. flowfile/web/static/assets/Filter-7494ea97.css +48 -0
  45. flowfile/web/static/assets/{Formula-bb96803d.css → Formula-53d58c43.css} +7 -7
  46. flowfile/web/static/assets/{Formula-6b04fb1d.js → Formula-fcda3c2c.js} +13 -11
  47. flowfile/web/static/assets/{FuzzyMatch-1010f966.css → FuzzyMatch-ad6361d6.css} +68 -69
  48. flowfile/web/static/assets/{FuzzyMatch-999521f4.js → FuzzyMatch-f8d3b7d3.js} +12 -10
  49. flowfile/web/static/assets/{Pivot-cf333e3d.css → GraphSolver-4b4d7db9.css} +5 -5
  50. flowfile/web/static/assets/{GraphSolver-17dd2198.js → GraphSolver-72eaa695.js} +14 -12
  51. flowfile/web/static/assets/GroupBy-5792782d.css +9 -0
  52. flowfile/web/static/assets/{GroupBy-6b039e18.js → GroupBy-8aa0598b.js} +9 -7
  53. flowfile/web/static/assets/{Join-fd79b451.css → Join-28b5e18f.css} +22 -22
  54. flowfile/web/static/assets/{Join-24d0f113.js → Join-e40f0ffa.js} +13 -11
  55. flowfile/web/static/assets/LoginView-5111c9ae.js +134 -0
  56. flowfile/web/static/assets/LoginView-d325d632.css +172 -0
  57. flowfile/web/static/assets/ManualInput-3702e677.css +293 -0
  58. flowfile/web/static/assets/{ManualInput-34639209.js → ManualInput-9b6f3224.js} +170 -116
  59. flowfile/web/static/assets/{MultiSelect-0e8724a3.js → MultiSelect-ef28e19e.js} +2 -2
  60. 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
  61. flowfile/web/static/assets/NodeDesigner-94cd4dd3.css +1429 -0
  62. flowfile/web/static/assets/NodeDesigner-d2b7ee2b.js +2712 -0
  63. flowfile/web/static/assets/{NumericInput-3d63a470.js → NumericInput-1d789794.js} +2 -2
  64. 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
  65. flowfile/web/static/assets/Output-692dd25d.css +37 -0
  66. flowfile/web/static/assets/{Output-edea9802.js → Output-cefef801.js} +14 -10
  67. flowfile/web/static/assets/{GraphSolver-f0cb7bfb.css → Pivot-0eda81b4.css} +5 -5
  68. flowfile/web/static/assets/{Pivot-61d19301.js → Pivot-bab1b75b.js} +12 -10
  69. flowfile/web/static/assets/PivotValidation-0e905b1a.css +13 -0
  70. flowfile/web/static/assets/PivotValidation-41b57ad6.css +13 -0
  71. flowfile/web/static/assets/{PivotValidation-f97fec5b.js → PivotValidation-e7941f91.js} +3 -3
  72. flowfile/web/static/assets/{PivotValidation-de9f43fe.js → PivotValidation-fba09336.js} +3 -3
  73. flowfile/web/static/assets/{PolarsCode-650322d1.css → PolarsCode-2b1f1f23.css} +4 -4
  74. flowfile/web/static/assets/{PolarsCode-bc3c9984.js → PolarsCode-740e40fa.js} +18 -9
  75. flowfile/web/static/assets/PopOver-862d7e28.js +939 -0
  76. flowfile/web/static/assets/PopOver-d96599db.css +33 -0
  77. flowfile/web/static/assets/{Read-64a3f259.js → Read-225cc63f.js} +16 -12
  78. flowfile/web/static/assets/{Read-e808b239.css → Read-90f366bc.css} +15 -15
  79. flowfile/web/static/assets/{RecordCount-3d5039be.js → RecordCount-ffc71eca.js} +6 -4
  80. flowfile/web/static/assets/{RecordId-597510e0.js → RecordId-a70bb8df.js} +9 -7
  81. flowfile/web/static/assets/{SQLQueryComponent-df51adbe.js → SQLQueryComponent-15a421f5.js} +3 -3
  82. flowfile/web/static/assets/SQLQueryComponent-edb90b98.css +29 -0
  83. flowfile/web/static/assets/{Sample-4be0a507.js → Sample-6c26afc7.js} +6 -4
  84. flowfile/web/static/assets/SecretSelector-6329f743.css +43 -0
  85. flowfile/web/static/assets/SecretSelector-ceed9496.js +113 -0
  86. flowfile/web/static/assets/{SecretManager-4839be57.js → SecretsView-214d255a.js} +35 -36
  87. flowfile/web/static/assets/SecretsView-aa291340.css +38 -0
  88. flowfile/web/static/assets/{Select-9b72f201.js → Select-8fc29999.js} +9 -7
  89. flowfile/web/static/assets/{SettingsSection-71e6b7e3.css → SettingsSection-07fbbc39.css} +4 -4
  90. flowfile/web/static/assets/{SettingsSection-5c696bee.css → SettingsSection-26fe48d4.css} +4 -4
  91. flowfile/web/static/assets/{SettingsSection-7ded385d.js → SettingsSection-3f70e4c3.js} +3 -3
  92. flowfile/web/static/assets/{SettingsSection-f0f75a42.js → SettingsSection-83090218.js} +3 -3
  93. flowfile/web/static/assets/{SettingsSection-2e4d03c4.css → SettingsSection-8f980839.css} +4 -4
  94. flowfile/web/static/assets/{SettingsSection-e1e9c953.js → SettingsSection-9f0d1725.js} +3 -3
  95. flowfile/web/static/assets/SetupView-3fa0aa03.js +160 -0
  96. flowfile/web/static/assets/SetupView-e2da3442.css +230 -0
  97. flowfile/web/static/assets/{SingleSelect-6c777aac.js → SingleSelect-a4a568cb.js} +2 -2
  98. 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
  99. flowfile/web/static/assets/{SliderInput-7cb93e62.js → SliderInput-be533e71.js} +7 -4
  100. flowfile/web/static/assets/SliderInput-f2e4f23c.css +4 -0
  101. flowfile/web/static/assets/{Sort-6cbde21a.js → Sort-154dad81.js} +9 -7
  102. flowfile/web/static/assets/Sort-4abb7fae.css +9 -0
  103. flowfile/web/static/assets/{TextInput-d9a40c11.js → TextInput-454e2bda.js} +2 -2
  104. 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
  105. flowfile/web/static/assets/{TextToRows-5d2c1190.css → TextToRows-12afb4f4.css} +10 -10
  106. flowfile/web/static/assets/{TextToRows-c4fcbf4d.js → TextToRows-ea73433d.js} +11 -10
  107. flowfile/web/static/assets/{ToggleSwitch-4ef91d19.js → ToggleSwitch-9d7b30f1.js} +2 -2
  108. 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
  109. flowfile/web/static/assets/{UnavailableFields-5edd5322.css → UnavailableFields-394a1f78.css} +14 -14
  110. flowfile/web/static/assets/{UnavailableFields-a03f512c.js → UnavailableFields-b72a2c72.js} +4 -4
  111. flowfile/web/static/assets/{Union-bfe9b996.js → Union-1e44f263.js} +8 -6
  112. flowfile/web/static/assets/{Union-af6c3d9b.css → Union-d6a8d7d5.css} +7 -7
  113. flowfile/web/static/assets/Unique-2b705521.css +3 -0
  114. flowfile/web/static/assets/{Unique-5d023a27.js → Unique-a3bc6d0a.js} +13 -10
  115. flowfile/web/static/assets/{Unpivot-1e422df3.css → Unpivot-b6ad6427.css} +7 -7
  116. flowfile/web/static/assets/{Unpivot-91cc5354.js → Unpivot-e27935fc.js} +11 -9
  117. flowfile/web/static/assets/{UnpivotValidation-7ee2de44.js → UnpivotValidation-72497680.js} +3 -3
  118. flowfile/web/static/assets/UnpivotValidation-d5ca3b7b.css +13 -0
  119. flowfile/web/static/assets/{VueGraphicWalker-ed5ab88b.css → VueGraphicWalker-430f0b86.css} +1 -1
  120. flowfile/web/static/assets/{VueGraphicWalker-e51b9924.js → VueGraphicWalker-d9ab70a3.js} +4 -4
  121. flowfile/web/static/assets/{api-cf1221f0.js → api-a2102880.js} +1 -1
  122. flowfile/web/static/assets/{api-c1bad5ca.js → api-f75042b0.js} +1 -1
  123. flowfile/web/static/assets/{dropDown-35135ba8.css → dropDown-1d6acbd9.css} +41 -41
  124. flowfile/web/static/assets/{dropDown-614b998d.js → dropDown-2798a109.js} +3 -3
  125. flowfile/web/static/assets/{fullEditor-f7971590.js → fullEditor-cf7d7d93.js} +11 -10
  126. flowfile/web/static/assets/{fullEditor-178376bb.css → fullEditor-fe9f7e18.css} +77 -65
  127. flowfile/web/static/assets/{genericNodeSettings-4fe5f36b.js → genericNodeSettings-14eac1c3.js} +5 -5
  128. flowfile/web/static/assets/{genericNodeSettings-924759c7.css → genericNodeSettings-3b2507ea.css} +10 -10
  129. flowfile/web/static/assets/{index-5429bbf8.js → index-387a6f18.js} +41806 -40958
  130. flowfile/web/static/assets/index-6b367bb5.js +38 -0
  131. flowfile/web/static/assets/{index-50508d4d.css → index-e96ab018.css} +2184 -569
  132. flowfile/web/static/assets/index-f0a6e5a5.js +2696 -0
  133. flowfile/web/static/assets/node.types-2c15bb7e.js +82 -0
  134. flowfile/web/static/assets/nodeInput-ed2ae8d7.js +2 -0
  135. flowfile/web/static/assets/{outputCsv-076b85ab.js → outputCsv-3c1757e8.js} +3 -3
  136. flowfile/web/static/assets/outputCsv-b9a072af.css +2499 -0
  137. flowfile/web/static/assets/{outputExcel-0fd17dbe.js → outputExcel-686e1f48.js} +3 -3
  138. flowfile/web/static/assets/{outputExcel-b41305c0.css → outputExcel-f5d272b2.css} +26 -26
  139. flowfile/web/static/assets/outputParquet-54597c3c.css +4 -0
  140. flowfile/web/static/assets/{outputParquet-b61e0847.js → outputParquet-df28faa7.js} +4 -4
  141. flowfile/web/static/assets/{readCsv-c767cb37.css → readCsv-3bfac4c3.css} +15 -15
  142. flowfile/web/static/assets/{readCsv-a8bb8b61.js → readCsv-e37eee21.js} +3 -3
  143. flowfile/web/static/assets/{readExcel-806d2826.css → readExcel-3db6b763.css} +13 -13
  144. flowfile/web/static/assets/{readExcel-67b4aee0.js → readExcel-a13f14bb.js} +5 -5
  145. flowfile/web/static/assets/{readParquet-92ce1dbc.js → readParquet-344cf746.js} +3 -3
  146. flowfile/web/static/assets/{readParquet-48c81530.css → readParquet-c5244ad5.css} +4 -4
  147. flowfile/web/static/assets/secrets.api-ae198c5c.js +65 -0
  148. flowfile/web/static/assets/{selectDynamic-92e25ee3.js → selectDynamic-6b4b0767.js} +5 -5
  149. flowfile/web/static/assets/{selectDynamic-aa913ff4.css → selectDynamic-f2fb394f.css} +21 -20
  150. flowfile/web/static/assets/{vue-codemirror.esm-41b0e0d7.js → vue-codemirror.esm-31ba0e0b.js} +31 -640
  151. flowfile/web/static/assets/{vue-content-loader.es-2c8e608f.js → vue-content-loader.es-4469c8ff.js} +1 -1
  152. flowfile/web/static/index.html +2 -2
  153. {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/METADATA +3 -4
  154. flowfile-0.5.4.dist-info/RECORD +407 -0
  155. flowfile_core/__init__.py +13 -6
  156. flowfile_core/auth/jwt.py +51 -16
  157. flowfile_core/auth/models.py +32 -7
  158. flowfile_core/auth/password.py +89 -0
  159. flowfile_core/auth/secrets.py +64 -19
  160. flowfile_core/configs/__init__.py +9 -7
  161. flowfile_core/configs/flow_logger.py +15 -14
  162. flowfile_core/configs/node_store/__init__.py +72 -4
  163. flowfile_core/configs/node_store/nodes.py +155 -172
  164. flowfile_core/configs/node_store/user_defined_node_registry.py +108 -27
  165. flowfile_core/configs/settings.py +28 -15
  166. flowfile_core/database/connection.py +7 -6
  167. flowfile_core/database/init_db.py +96 -2
  168. flowfile_core/database/models.py +3 -1
  169. flowfile_core/fileExplorer/__init__.py +17 -0
  170. flowfile_core/fileExplorer/funcs.py +145 -57
  171. flowfile_core/fileExplorer/utils.py +10 -11
  172. flowfile_core/flowfile/_extensions/real_time_interface.py +10 -8
  173. flowfile_core/flowfile/analytics/analytics_processor.py +26 -24
  174. flowfile_core/flowfile/analytics/graphic_walker.py +11 -12
  175. flowfile_core/flowfile/analytics/utils.py +1 -1
  176. flowfile_core/flowfile/code_generator/__init__.py +11 -0
  177. flowfile_core/flowfile/code_generator/code_generator.py +706 -247
  178. flowfile_core/flowfile/connection_manager/_connection_manager.py +6 -5
  179. flowfile_core/flowfile/connection_manager/models.py +1 -1
  180. flowfile_core/flowfile/database_connection_manager/db_connections.py +60 -44
  181. flowfile_core/flowfile/database_connection_manager/models.py +1 -1
  182. flowfile_core/flowfile/extensions.py +17 -12
  183. flowfile_core/flowfile/flow_data_engine/cloud_storage_reader.py +34 -32
  184. flowfile_core/flowfile/flow_data_engine/create/funcs.py +115 -83
  185. flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +493 -423
  186. flowfile_core/flowfile/flow_data_engine/flow_file_column/interface.py +2 -2
  187. flowfile_core/flowfile/flow_data_engine/flow_file_column/main.py +92 -52
  188. flowfile_core/flowfile/flow_data_engine/flow_file_column/polars_type.py +12 -11
  189. flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +6 -6
  190. flowfile_core/flowfile/flow_data_engine/flow_file_column/utils.py +26 -30
  191. flowfile_core/flowfile/flow_data_engine/fuzzy_matching/prepare_for_fuzzy_match.py +31 -20
  192. flowfile_core/flowfile/flow_data_engine/join/__init__.py +1 -1
  193. flowfile_core/flowfile/flow_data_engine/join/utils.py +11 -9
  194. flowfile_core/flowfile/flow_data_engine/join/verify_integrity.py +14 -15
  195. flowfile_core/flowfile/flow_data_engine/pivot_table.py +5 -7
  196. flowfile_core/flowfile/flow_data_engine/polars_code_parser.py +95 -82
  197. flowfile_core/flowfile/flow_data_engine/read_excel_tables.py +66 -65
  198. flowfile_core/flowfile/flow_data_engine/sample_data.py +27 -21
  199. flowfile_core/flowfile/flow_data_engine/subprocess_operations/__init__.py +1 -1
  200. flowfile_core/flowfile/flow_data_engine/subprocess_operations/models.py +13 -11
  201. flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +190 -127
  202. flowfile_core/flowfile/flow_data_engine/threaded_processes.py +8 -8
  203. flowfile_core/flowfile/flow_data_engine/utils.py +99 -67
  204. flowfile_core/flowfile/flow_graph.py +920 -571
  205. flowfile_core/flowfile/flow_graph_utils.py +31 -49
  206. flowfile_core/flowfile/flow_node/flow_node.py +379 -258
  207. flowfile_core/flowfile/flow_node/models.py +53 -41
  208. flowfile_core/flowfile/flow_node/schema_callback.py +14 -19
  209. flowfile_core/flowfile/graph_tree/graph_tree.py +41 -41
  210. flowfile_core/flowfile/handler.py +80 -30
  211. flowfile_core/flowfile/manage/compatibility_enhancements.py +209 -126
  212. flowfile_core/flowfile/manage/io_flowfile.py +54 -57
  213. flowfile_core/flowfile/node_designer/__init__.py +19 -13
  214. flowfile_core/flowfile/node_designer/_type_registry.py +34 -37
  215. flowfile_core/flowfile/node_designer/custom_node.py +162 -36
  216. flowfile_core/flowfile/node_designer/ui_components.py +278 -34
  217. flowfile_core/flowfile/schema_callbacks.py +71 -51
  218. flowfile_core/flowfile/setting_generator/__init__.py +0 -1
  219. flowfile_core/flowfile/setting_generator/setting_generator.py +6 -5
  220. flowfile_core/flowfile/setting_generator/settings.py +64 -53
  221. flowfile_core/flowfile/sources/external_sources/base_class.py +12 -10
  222. flowfile_core/flowfile/sources/external_sources/custom_external_sources/external_source.py +27 -17
  223. flowfile_core/flowfile/sources/external_sources/custom_external_sources/sample_users.py +9 -9
  224. flowfile_core/flowfile/sources/external_sources/factory.py +0 -1
  225. flowfile_core/flowfile/sources/external_sources/sql_source/models.py +45 -31
  226. flowfile_core/flowfile/sources/external_sources/sql_source/sql_source.py +198 -73
  227. flowfile_core/flowfile/sources/external_sources/sql_source/utils.py +250 -196
  228. flowfile_core/flowfile/util/calculate_layout.py +9 -13
  229. flowfile_core/flowfile/util/execution_orderer.py +25 -17
  230. flowfile_core/flowfile/util/node_skipper.py +4 -4
  231. flowfile_core/flowfile/utils.py +19 -21
  232. flowfile_core/main.py +26 -19
  233. flowfile_core/routes/auth.py +284 -11
  234. flowfile_core/routes/cloud_connections.py +25 -25
  235. flowfile_core/routes/logs.py +21 -29
  236. flowfile_core/routes/public.py +46 -4
  237. flowfile_core/routes/routes.py +70 -34
  238. flowfile_core/routes/secrets.py +25 -27
  239. flowfile_core/routes/user_defined_components.py +483 -4
  240. flowfile_core/run_lock.py +0 -1
  241. flowfile_core/schemas/__init__.py +4 -6
  242. flowfile_core/schemas/analysis_schemas/graphic_walker_schemas.py +55 -55
  243. flowfile_core/schemas/cloud_storage_schemas.py +96 -66
  244. flowfile_core/schemas/input_schema.py +231 -144
  245. flowfile_core/schemas/output_model.py +49 -34
  246. flowfile_core/schemas/schemas.py +116 -89
  247. flowfile_core/schemas/transform_schema.py +518 -263
  248. flowfile_core/schemas/yaml_types.py +21 -7
  249. flowfile_core/secret_manager/secret_manager.py +123 -18
  250. flowfile_core/types.py +29 -9
  251. flowfile_core/utils/arrow_reader.py +7 -6
  252. flowfile_core/utils/excel_file_manager.py +3 -3
  253. flowfile_core/utils/fileManager.py +7 -7
  254. flowfile_core/utils/fl_executor.py +8 -10
  255. flowfile_core/utils/utils.py +4 -4
  256. flowfile_core/utils/validate_setup.py +5 -4
  257. flowfile_frame/__init__.py +117 -51
  258. flowfile_frame/adapters.py +2 -9
  259. flowfile_frame/adding_expr.py +73 -32
  260. flowfile_frame/cloud_storage/frame_helpers.py +27 -23
  261. flowfile_frame/cloud_storage/secret_manager.py +12 -26
  262. flowfile_frame/config.py +2 -5
  263. flowfile_frame/database/__init__.py +36 -0
  264. flowfile_frame/database/connection_manager.py +205 -0
  265. flowfile_frame/database/frame_helpers.py +249 -0
  266. flowfile_frame/expr.py +311 -218
  267. flowfile_frame/expr.pyi +160 -159
  268. flowfile_frame/expr_name.py +23 -23
  269. flowfile_frame/flow_frame.py +571 -476
  270. flowfile_frame/flow_frame.pyi +123 -104
  271. flowfile_frame/flow_frame_methods.py +227 -246
  272. flowfile_frame/group_frame.py +50 -20
  273. flowfile_frame/join.py +2 -2
  274. flowfile_frame/lazy.py +129 -87
  275. flowfile_frame/lazy_methods.py +83 -30
  276. flowfile_frame/list_name_space.py +55 -50
  277. flowfile_frame/selectors.py +148 -68
  278. flowfile_frame/series.py +9 -7
  279. flowfile_frame/utils.py +19 -21
  280. flowfile_worker/__init__.py +12 -7
  281. flowfile_worker/configs.py +41 -33
  282. flowfile_worker/create/__init__.py +14 -9
  283. flowfile_worker/create/funcs.py +114 -77
  284. flowfile_worker/create/models.py +46 -43
  285. flowfile_worker/create/pl_types.py +14 -15
  286. flowfile_worker/create/read_excel_tables.py +34 -41
  287. flowfile_worker/create/utils.py +22 -19
  288. flowfile_worker/external_sources/s3_source/main.py +18 -51
  289. flowfile_worker/external_sources/s3_source/models.py +34 -27
  290. flowfile_worker/external_sources/sql_source/main.py +8 -5
  291. flowfile_worker/external_sources/sql_source/models.py +13 -9
  292. flowfile_worker/flow_logger.py +10 -8
  293. flowfile_worker/funcs.py +214 -155
  294. flowfile_worker/main.py +11 -17
  295. flowfile_worker/models.py +35 -28
  296. flowfile_worker/process_manager.py +2 -3
  297. flowfile_worker/routes.py +121 -90
  298. flowfile_worker/secrets.py +114 -21
  299. flowfile_worker/spawner.py +89 -54
  300. flowfile_worker/utils.py +3 -2
  301. shared/__init__.py +2 -7
  302. shared/storage_config.py +25 -13
  303. test_utils/postgres/commands.py +3 -2
  304. test_utils/postgres/fixtures.py +9 -9
  305. test_utils/s3/commands.py +1 -1
  306. test_utils/s3/data_generator.py +3 -4
  307. test_utils/s3/demo_data_generator.py +4 -7
  308. test_utils/s3/fixtures.py +7 -5
  309. tools/migrate/__init__.py +1 -1
  310. tools/migrate/__main__.py +16 -29
  311. tools/migrate/legacy_schemas.py +251 -190
  312. tools/migrate/migrate.py +193 -181
  313. tools/migrate/tests/conftest.py +1 -3
  314. tools/migrate/tests/test_migrate.py +36 -41
  315. tools/migrate/tests/test_migration_e2e.py +28 -29
  316. tools/migrate/tests/test_node_migrations.py +50 -20
  317. flowfile/web/static/assets/CloudConnectionManager-2dfdce2f.css +0 -86
  318. flowfile/web/static/assets/ContextMenu-23e909da.js +0 -41
  319. flowfile/web/static/assets/ContextMenu-4c74eef1.css +0 -26
  320. flowfile/web/static/assets/ContextMenu-63cfa99b.css +0 -26
  321. flowfile/web/static/assets/ContextMenu-70ae0c79.js +0 -41
  322. flowfile/web/static/assets/ContextMenu-c13f91d0.css +0 -26
  323. flowfile/web/static/assets/ContextMenu-f149cf7c.js +0 -41
  324. flowfile/web/static/assets/CustomNode-74a37f74.css +0 -32
  325. flowfile/web/static/assets/DatabaseManager-30fa27e5.css +0 -64
  326. flowfile/web/static/assets/Filter-9b6d08db.js +0 -164
  327. flowfile/web/static/assets/Filter-f62091b3.css +0 -20
  328. flowfile/web/static/assets/GroupBy-b9505323.css +0 -51
  329. flowfile/web/static/assets/ManualInput-3246a08d.css +0 -96
  330. flowfile/web/static/assets/Output-283fe388.css +0 -37
  331. flowfile/web/static/assets/PivotValidation-891ddfb0.css +0 -13
  332. flowfile/web/static/assets/PivotValidation-c46cd420.css +0 -13
  333. flowfile/web/static/assets/SQLQueryComponent-36cef432.css +0 -27
  334. flowfile/web/static/assets/SliderInput-b8fb6a8c.css +0 -4
  335. flowfile/web/static/assets/Sort-3643d625.css +0 -51
  336. flowfile/web/static/assets/Unique-f9fb0809.css +0 -51
  337. flowfile/web/static/assets/UnpivotValidation-0d240eeb.css +0 -13
  338. flowfile/web/static/assets/nodeInput-5d0d6b79.js +0 -41
  339. flowfile/web/static/assets/outputCsv-9cc59e0b.css +0 -2499
  340. flowfile/web/static/assets/outputParquet-cf8cf3f2.css +0 -4
  341. flowfile/web/static/assets/secretApi-68435402.js +0 -46
  342. flowfile/web/static/assets/vue-codemirror-bccfde04.css +0 -32
  343. flowfile-0.5.1.dist-info/RECORD +0 -388
  344. {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/WHEEL +0 -0
  345. {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/entry_points.txt +0 -0
  346. {flowfile-0.5.1.dist-info → flowfile-0.5.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,205 @@
1
+ """Database connection management for flowfile_frame.
2
+
3
+ This module provides functions for managing database connections,
4
+ similar to how cloud_storage/secret_manager.py handles cloud storage connections.
5
+ """
6
+
7
+ from typing import Literal
8
+
9
+ from pydantic import SecretStr
10
+
11
+ from flowfile_core.database.connection import get_db_context
12
+ from flowfile_core.flowfile.database_connection_manager.db_connections import (
13
+ get_database_connection,
14
+ get_database_connection_schema,
15
+ store_database_connection,
16
+ )
17
+ from flowfile_core.schemas.input_schema import (
18
+ FullDatabaseConnection,
19
+ FullDatabaseConnectionInterface,
20
+ )
21
+
22
+
23
+ def get_current_user_id() -> int:
24
+ """Get the current user ID for database operations.
25
+
26
+ Returns:
27
+ int: The current user ID (defaults to 1 for single-user mode).
28
+ """
29
+ # In single-file mode, we use user_id = 1
30
+ return 1
31
+
32
+
33
+ def create_database_connection(
34
+ connection_name: str,
35
+ *,
36
+ database_type: Literal["postgresql", "mysql", "sqlite", "mssql", "oracle"] = "postgresql",
37
+ host: str | None = None,
38
+ port: int | None = None,
39
+ database: str | None = None,
40
+ username: str | None = None,
41
+ password: str | SecretStr | None = None,
42
+ ssl_enabled: bool = False,
43
+ url: str | None = None,
44
+ ) -> FullDatabaseConnection:
45
+ """Create and store a new database connection.
46
+
47
+ Args:
48
+ connection_name: Unique name for this connection.
49
+ database_type: Type of database (postgresql, mysql, sqlite, mssql, oracle).
50
+ host: Database server hostname.
51
+ port: Database server port.
52
+ database: Database name.
53
+ username: Database username.
54
+ password: Database password.
55
+ ssl_enabled: Whether to use SSL for the connection.
56
+ url: Full database URL (overrides other connection parameters).
57
+
58
+ Returns:
59
+ FullDatabaseConnection: The created connection object.
60
+
61
+ Raises:
62
+ ValueError: If a connection with this name already exists.
63
+ """
64
+ user_id = get_current_user_id()
65
+
66
+ # Convert password to SecretStr if it's a plain string
67
+ if isinstance(password, str):
68
+ password = SecretStr(password)
69
+
70
+ connection = FullDatabaseConnection(
71
+ connection_name=connection_name,
72
+ database_type=database_type,
73
+ host=host,
74
+ port=port,
75
+ database=database,
76
+ username=username,
77
+ password=password,
78
+ ssl_enabled=ssl_enabled,
79
+ url=url,
80
+ )
81
+
82
+ with get_db_context() as db:
83
+ store_database_connection(db, connection, user_id)
84
+
85
+ return connection
86
+
87
+
88
+ def create_database_connection_if_not_exists(
89
+ connection_name: str,
90
+ *,
91
+ database_type: Literal["postgresql", "mysql", "sqlite", "mssql", "oracle"] = "postgresql",
92
+ host: str | None = None,
93
+ port: int | None = None,
94
+ database: str | None = None,
95
+ username: str | None = None,
96
+ password: str | SecretStr | None = None,
97
+ ssl_enabled: bool = False,
98
+ url: str | None = None,
99
+ ) -> FullDatabaseConnection:
100
+ """Create a database connection if it doesn't already exist.
101
+
102
+ Args:
103
+ connection_name: Unique name for this connection.
104
+ database_type: Type of database (postgresql, mysql, sqlite, mssql, oracle).
105
+ host: Database server hostname.
106
+ port: Database server port.
107
+ database: Database name.
108
+ username: Database username.
109
+ password: Database password.
110
+ ssl_enabled: Whether to use SSL for the connection.
111
+ url: Full database URL (overrides other connection parameters).
112
+
113
+ Returns:
114
+ FullDatabaseConnection: The existing or newly created connection.
115
+ """
116
+ user_id = get_current_user_id()
117
+
118
+ # Check if connection already exists
119
+ existing = get_database_connection_by_name(connection_name)
120
+ if existing:
121
+ return existing
122
+
123
+ return create_database_connection(
124
+ connection_name,
125
+ database_type=database_type,
126
+ host=host,
127
+ port=port,
128
+ database=database,
129
+ username=username,
130
+ password=password,
131
+ ssl_enabled=ssl_enabled,
132
+ url=url,
133
+ )
134
+
135
+
136
+ def get_database_connection_by_name(connection_name: str) -> FullDatabaseConnection | None:
137
+ """Get a database connection by its name.
138
+
139
+ Args:
140
+ connection_name: The name of the connection to retrieve.
141
+
142
+ Returns:
143
+ FullDatabaseConnection if found, None otherwise.
144
+ """
145
+ user_id = get_current_user_id()
146
+ with get_db_context() as db:
147
+ return get_database_connection_schema(db, connection_name, user_id)
148
+
149
+
150
+ def get_all_available_database_connections() -> list[FullDatabaseConnectionInterface]:
151
+ """Get all available database connections for the current user.
152
+
153
+ Returns:
154
+ List of database connection interfaces (without passwords).
155
+ """
156
+ from flowfile_core.database.models import DatabaseConnection as DBConnectionModel
157
+
158
+ user_id = get_current_user_id()
159
+ with get_db_context() as db:
160
+ connections = (
161
+ db.query(DBConnectionModel)
162
+ .filter(DBConnectionModel.user_id == user_id)
163
+ .all()
164
+ )
165
+
166
+ return [
167
+ FullDatabaseConnectionInterface(
168
+ connection_name=conn.connection_name,
169
+ database_type=conn.database_type,
170
+ username=conn.username,
171
+ host=conn.host,
172
+ port=conn.port,
173
+ database=conn.database,
174
+ ssl_enabled=conn.ssl_enabled,
175
+ )
176
+ for conn in connections
177
+ ]
178
+
179
+
180
+ def del_database_connection(connection_name: str) -> bool:
181
+ """Delete a database connection by its name.
182
+
183
+ Args:
184
+ connection_name: The name of the connection to delete.
185
+
186
+ Returns:
187
+ True if the connection was deleted, False if it didn't exist.
188
+ """
189
+ from flowfile_core.database.models import DatabaseConnection as DBConnectionModel
190
+ from flowfile_core.database.models import Secret
191
+
192
+ user_id = get_current_user_id()
193
+ with get_db_context() as db:
194
+ connection = get_database_connection(db, connection_name, user_id)
195
+ if connection:
196
+ # Delete the associated password secret
197
+ if connection.password_id:
198
+ secret = db.query(Secret).filter(Secret.id == connection.password_id).first()
199
+ if secret:
200
+ db.delete(secret)
201
+
202
+ db.delete(connection)
203
+ db.commit()
204
+ return True
205
+ return False
@@ -0,0 +1,249 @@
1
+ """Database helper functions for FlowFrame operations.
2
+
3
+ This module provides functions for reading from and writing to databases,
4
+ similar to how cloud_storage/frame_helpers.py handles cloud storage operations.
5
+ """
6
+
7
+ from typing import Literal
8
+
9
+ import polars as pl
10
+
11
+ from flowfile_core.flowfile.flow_graph import FlowGraph
12
+ from flowfile_core.schemas import input_schema
13
+ from flowfile_frame.database.connection_manager import get_current_user_id
14
+ from flowfile_frame.utils import generate_node_id
15
+
16
+
17
+ def add_read_from_database(
18
+ flow_graph: FlowGraph,
19
+ *,
20
+ connection_name: str,
21
+ table_name: str | None = None,
22
+ schema_name: str | None = None,
23
+ query: str | None = None,
24
+ description: str | None = None,
25
+ ) -> int:
26
+ """Add a database reader node to the flow graph.
27
+
28
+ Either table_name or query must be provided. If both are provided,
29
+ query takes precedence.
30
+
31
+ Args:
32
+ flow_graph: The flow graph to add the node to.
33
+ connection_name: Name of the stored database connection to use.
34
+ table_name: Name of the table to read from.
35
+ schema_name: Database schema name (e.g., 'public' for PostgreSQL).
36
+ query: SQL query to execute instead of reading a table.
37
+ description: Optional description for the node.
38
+
39
+ Returns:
40
+ int: The node ID of the created database reader node.
41
+
42
+ Raises:
43
+ ValueError: If neither table_name nor query is provided.
44
+ """
45
+ if table_name is None and query is None:
46
+ raise ValueError("Either 'table_name' or 'query' must be provided")
47
+
48
+ node_id = generate_node_id()
49
+ flow_id = flow_graph.flow_id
50
+
51
+ # Determine query mode
52
+ query_mode: Literal["table", "query"] = "query" if query else "table"
53
+
54
+ settings = input_schema.NodeDatabaseReader(
55
+ flow_id=flow_id,
56
+ node_id=node_id,
57
+ user_id=get_current_user_id(),
58
+ description=description,
59
+ database_settings=input_schema.DatabaseSettings(
60
+ connection_mode="reference",
61
+ database_connection_name=connection_name,
62
+ query_mode=query_mode,
63
+ table_name=table_name,
64
+ schema_name=schema_name,
65
+ query=query,
66
+ ),
67
+ )
68
+
69
+ flow_graph.add_database_reader(settings)
70
+ return node_id
71
+
72
+
73
+ def add_write_to_database(
74
+ flow_graph: FlowGraph,
75
+ depends_on_node_id: int,
76
+ *,
77
+ connection_name: str,
78
+ table_name: str,
79
+ schema_name: str | None = None,
80
+ if_exists: Literal["append", "replace", "fail"] = "append",
81
+ description: str | None = None,
82
+ ) -> int:
83
+ """Add a database writer node to the flow graph.
84
+
85
+ Args:
86
+ flow_graph: The flow graph to add the node to.
87
+ depends_on_node_id: The node ID that this writer depends on.
88
+ connection_name: Name of the stored database connection to use.
89
+ table_name: Name of the table to write to.
90
+ schema_name: Database schema name (e.g., 'public' for PostgreSQL).
91
+ if_exists: What to do if the table already exists:
92
+ - 'append': Add rows to existing table
93
+ - 'replace': Drop and recreate table
94
+ - 'fail': Raise an error
95
+ description: Optional description for the node.
96
+
97
+ Returns:
98
+ int: The node ID of the created database writer node.
99
+ """
100
+ node_id = generate_node_id()
101
+ flow_id = flow_graph.flow_id
102
+
103
+ settings = input_schema.NodeDatabaseWriter(
104
+ flow_id=flow_id,
105
+ node_id=node_id,
106
+ user_id=get_current_user_id(),
107
+ depending_on_id=depends_on_node_id,
108
+ description=description,
109
+ database_write_settings=input_schema.DatabaseWriteSettings(
110
+ connection_mode="reference",
111
+ database_connection_name=connection_name,
112
+ table_name=table_name,
113
+ schema_name=schema_name,
114
+ if_exists=if_exists,
115
+ ),
116
+ )
117
+
118
+ flow_graph.add_database_writer(settings)
119
+ return node_id
120
+
121
+
122
+ def read_database(
123
+ connection_name: str,
124
+ *,
125
+ table_name: str | None = None,
126
+ schema_name: str | None = None,
127
+ query: str | None = None,
128
+ ) -> pl.LazyFrame:
129
+ """Read data from a database using a stored connection.
130
+
131
+ This is a convenience function for reading data directly without
132
+ needing to create a FlowGraph.
133
+
134
+ Either table_name or query must be provided. If both are provided,
135
+ query takes precedence.
136
+
137
+ Args:
138
+ connection_name: Name of the stored database connection to use.
139
+ table_name: Name of the table to read from.
140
+ schema_name: Database schema name (e.g., 'public' for PostgreSQL).
141
+ query: SQL query to execute instead of reading a table.
142
+
143
+ Returns:
144
+ pl.LazyFrame: The data read from the database.
145
+
146
+ Raises:
147
+ ValueError: If neither table_name nor query is provided.
148
+ ValueError: If the connection is not found.
149
+ """
150
+ from flowfile_core.flowfile.database_connection_manager.db_connections import get_local_database_connection
151
+ from flowfile_core.flowfile.sources.external_sources.sql_source.sql_source import SqlSource
152
+ from flowfile_core.flowfile.sources.external_sources.sql_source.utils import construct_sql_uri
153
+ from flowfile_core.secret_manager.secret_manager import decrypt_secret
154
+
155
+ if table_name is None and query is None:
156
+ raise ValueError("Either 'table_name' or 'query' must be provided")
157
+
158
+ user_id = get_current_user_id()
159
+ connection = get_local_database_connection(connection_name, user_id)
160
+
161
+ if connection is None:
162
+ raise ValueError(f"Database connection '{connection_name}' not found")
163
+
164
+ # Construct the connection string
165
+ connection_string = construct_sql_uri(
166
+ database_type=connection.database_type,
167
+ host=connection.host,
168
+ port=connection.port,
169
+ database=connection.database,
170
+ username=connection.username,
171
+ password=decrypt_secret(connection.password.get_secret_value()),
172
+ url=connection.url,
173
+ )
174
+
175
+ # Create SQL source and read data
176
+ sql_source = SqlSource(
177
+ connection_string=connection_string,
178
+ query=query,
179
+ table_name=table_name,
180
+ schema_name=schema_name,
181
+ )
182
+
183
+ return sql_source.get_data()
184
+
185
+
186
+ def write_database(
187
+ df: pl.DataFrame | pl.LazyFrame,
188
+ connection_name: str,
189
+ table_name: str,
190
+ *,
191
+ schema_name: str | None = None,
192
+ if_exists: Literal["append", "replace", "fail"] = "append",
193
+ ) -> None:
194
+ """Write data to a database using a stored connection.
195
+
196
+ This is a convenience function for writing data directly without
197
+ needing to create a FlowGraph.
198
+
199
+ Args:
200
+ df: The DataFrame or LazyFrame to write.
201
+ connection_name: Name of the stored database connection to use.
202
+ table_name: Name of the table to write to.
203
+ schema_name: Database schema name (e.g., 'public' for PostgreSQL).
204
+ if_exists: What to do if the table already exists:
205
+ - 'append': Add rows to existing table
206
+ - 'replace': Drop and recreate table
207
+ - 'fail': Raise an error
208
+
209
+ Raises:
210
+ ValueError: If the connection is not found.
211
+ """
212
+ from sqlalchemy import create_engine
213
+
214
+ from flowfile_core.flowfile.database_connection_manager.db_connections import get_local_database_connection
215
+ from flowfile_core.flowfile.sources.external_sources.sql_source.utils import construct_sql_uri
216
+ from flowfile_core.secret_manager.secret_manager import decrypt_secret
217
+
218
+ user_id = get_current_user_id()
219
+ connection = get_local_database_connection(connection_name, user_id)
220
+
221
+ if connection is None:
222
+ raise ValueError(f"Database connection '{connection_name}' not found")
223
+
224
+ # Collect if LazyFrame
225
+ if isinstance(df, pl.LazyFrame):
226
+ df = df.collect()
227
+
228
+ # Construct the connection string
229
+ connection_string = construct_sql_uri(
230
+ database_type=connection.database_type,
231
+ host=connection.host,
232
+ port=connection.port,
233
+ database=connection.database,
234
+ username=connection.username,
235
+ password=decrypt_secret(connection.password.get_secret_value()),
236
+ url=connection.url,
237
+ )
238
+
239
+ # Write to database using pandas (polars doesn't have direct SQL write support)
240
+ engine = create_engine(connection_string)
241
+ pandas_df = df.to_pandas()
242
+
243
+ pandas_df.to_sql(
244
+ name=table_name,
245
+ con=engine,
246
+ schema=schema_name,
247
+ if_exists=if_exists,
248
+ index=False,
249
+ )