Flowfile 0.5.1__py3-none-any.whl → 0.5.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. build_backends/main.py +25 -22
  2. build_backends/main_prd.py +10 -19
  3. flowfile/__init__.py +178 -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-49392a9a.js +713 -0
  8. flowfile/web/static/assets/AdminView-f53bad23.css +129 -0
  9. flowfile/web/static/assets/CloudConnectionView-36bcd6df.css +72 -0
  10. flowfile/web/static/assets/{CloudConnectionManager-0dfba9f2.js → CloudConnectionView-f13f202b.js} +11 -11
  11. flowfile/web/static/assets/{CloudStorageReader-d5b1b6c9.js → CloudStorageReader-0023d4a5.js} +10 -8
  12. flowfile/web/static/assets/{CloudStorageReader-29d14fcc.css → CloudStorageReader-24c54524.css} +27 -27
  13. flowfile/web/static/assets/{CloudStorageWriter-b0ee067f.css → CloudStorageWriter-60547855.css} +26 -26
  14. flowfile/web/static/assets/{CloudStorageWriter-00d87aad.js → CloudStorageWriter-8e781e11.js} +10 -8
  15. flowfile/web/static/assets/{ColumnSelector-47996a16.css → ColumnSelector-371637fb.css} +2 -2
  16. flowfile/web/static/assets/{ColumnSelector-4685e75d.js → ColumnSelector-8ad68ea9.js} +3 -5
  17. flowfile/web/static/assets/{ContextMenu-c13f91d0.css → ContextMenu-26d4dd27.css} +6 -6
  18. flowfile/web/static/assets/{ContextMenu-23e909da.js → ContextMenu-31ee57f0.js} +3 -3
  19. flowfile/web/static/assets/{ContextMenu-70ae0c79.js → ContextMenu-69a74055.js} +3 -3
  20. flowfile/web/static/assets/{ContextMenu-f149cf7c.js → ContextMenu-8e2051c6.js} +3 -3
  21. flowfile/web/static/assets/{ContextMenu-4c74eef1.css → ContextMenu-8ec1729e.css} +6 -6
  22. flowfile/web/static/assets/{ContextMenu-63cfa99b.css → ContextMenu-9b310c60.css} +6 -6
  23. flowfile/web/static/assets/{CrossJoin-702a3edd.js → CrossJoin-03df6938.js} +12 -10
  24. flowfile/web/static/assets/{CrossJoin-1119d18e.css → CrossJoin-71b4cc10.css} +20 -20
  25. flowfile/web/static/assets/CustomNode-59e99a86.css +32 -0
  26. flowfile/web/static/assets/{CustomNode-b1519993.js → CustomNode-8479239b.js} +36 -24
  27. flowfile/web/static/assets/{DatabaseConnectionSettings-6f3e4ea5.js → DatabaseConnectionSettings-869e3efd.js} +5 -4
  28. flowfile/web/static/assets/{DatabaseConnectionSettings-0c04b2e5.css → DatabaseConnectionSettings-e91df89a.css} +13 -13
  29. flowfile/web/static/assets/{DatabaseReader-ae61773c.css → DatabaseReader-36898a00.css} +24 -24
  30. flowfile/web/static/assets/{DatabaseReader-d38c7295.js → DatabaseReader-c58b9552.js} +25 -15
  31. flowfile/web/static/assets/DatabaseView-6655afd6.css +57 -0
  32. flowfile/web/static/assets/{DatabaseManager-cf5ef661.js → DatabaseView-d26a9140.js} +11 -11
  33. flowfile/web/static/assets/{DatabaseWriter-2f570e53.css → DatabaseWriter-217a99f1.css} +19 -19
  34. flowfile/web/static/assets/{DatabaseWriter-b04ef46a.js → DatabaseWriter-4d05ddc7.js} +17 -10
  35. flowfile/web/static/assets/{designer-8da3ba3a.css → DesignerView-a6d0ee84.css} +614 -546
  36. flowfile/web/static/assets/{designer-9633482a.js → DesignerView-e6f5c0e8.js} +1107 -3170
  37. flowfile/web/static/assets/{documentation-ca400224.js → DocumentationView-2e78ef1b.js} +5 -5
  38. flowfile/web/static/assets/{documentation-12216a74.css → DocumentationView-fd46c656.css} +7 -7
  39. flowfile/web/static/assets/{ExploreData-2d0cf4db.css → ExploreData-10c5acc8.css} +13 -12
  40. flowfile/web/static/assets/{ExploreData-5fa10ed8.js → ExploreData-7b54caca.js} +18 -9
  41. flowfile/web/static/assets/{ExternalSource-d39af878.js → ExternalSource-3fa399b2.js} +9 -7
  42. flowfile/web/static/assets/{ExternalSource-e37b6275.css → ExternalSource-47ab05a3.css} +17 -17
  43. flowfile/web/static/assets/Filter-7494ea97.css +48 -0
  44. flowfile/web/static/assets/Filter-8cbbdbf3.js +287 -0
  45. flowfile/web/static/assets/{Formula-bb96803d.css → Formula-53d58c43.css} +7 -7
  46. flowfile/web/static/assets/{Formula-6b04fb1d.js → Formula-aac42b1e.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-cd9bbfca.js} +12 -10
  49. flowfile/web/static/assets/{Pivot-cf333e3d.css → GraphSolver-c24dec17.css} +5 -5
  50. flowfile/web/static/assets/{GraphSolver-17dd2198.js → GraphSolver-c7e6780e.js} +13 -11
  51. flowfile/web/static/assets/{GroupBy-6b039e18.js → GroupBy-93c5d22b.js} +9 -7
  52. flowfile/web/static/assets/{GroupBy-b9505323.css → GroupBy-be7ac0bf.css} +10 -10
  53. flowfile/web/static/assets/{Join-fd79b451.css → Join-28b5e18f.css} +22 -22
  54. flowfile/web/static/assets/{Join-24d0f113.js → Join-a19b2de2.js} +13 -11
  55. flowfile/web/static/assets/LoginView-0df4ed0a.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-8d3374b2.js} +170 -116
  59. flowfile/web/static/assets/{MultiSelect-0e8724a3.js → MultiSelect-ad1b6243.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-e278950d.js} +1 -1
  61. flowfile/web/static/assets/NodeDesigner-40b647c9.js +2610 -0
  62. flowfile/web/static/assets/NodeDesigner-5f53be3f.css +1429 -0
  63. flowfile/web/static/assets/{NumericInput-3d63a470.js → NumericInput-7100234c.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-5130219f.js} +5 -2
  65. flowfile/web/static/assets/{Output-283fe388.css → Output-35e97000.css} +6 -6
  66. flowfile/web/static/assets/{Output-edea9802.js → Output-f5efd2aa.js} +12 -9
  67. flowfile/web/static/assets/{GraphSolver-f0cb7bfb.css → Pivot-0eda81b4.css} +5 -5
  68. flowfile/web/static/assets/{Pivot-61d19301.js → Pivot-d981d23c.js} +11 -9
  69. flowfile/web/static/assets/PivotValidation-0e905b1a.css +13 -0
  70. flowfile/web/static/assets/{PivotValidation-f97fec5b.js → PivotValidation-39386e95.js} +3 -3
  71. flowfile/web/static/assets/PivotValidation-41b57ad6.css +13 -0
  72. flowfile/web/static/assets/{PivotValidation-de9f43fe.js → PivotValidation-63de1f73.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-f9d69217.js} +18 -9
  75. flowfile/web/static/assets/PopOver-b22f049e.js +939 -0
  76. flowfile/web/static/assets/PopOver-d96599db.css +33 -0
  77. flowfile/web/static/assets/{Read-e808b239.css → Read-36e7bd51.css} +12 -12
  78. flowfile/web/static/assets/{Read-64a3f259.js → Read-aec2e377.js} +14 -11
  79. flowfile/web/static/assets/{RecordCount-3d5039be.js → RecordCount-78ed6845.js} +6 -4
  80. flowfile/web/static/assets/{RecordId-597510e0.js → RecordId-2156e890.js} +8 -6
  81. flowfile/web/static/assets/{SQLQueryComponent-36cef432.css → SQLQueryComponent-1c2f26b4.css} +5 -5
  82. flowfile/web/static/assets/{SQLQueryComponent-df51adbe.js → SQLQueryComponent-48c72f5b.js} +3 -3
  83. flowfile/web/static/assets/{Sample-4be0a507.js → Sample-1352ca74.js} +6 -4
  84. flowfile/web/static/assets/SecretSelector-22b5ff89.js +113 -0
  85. flowfile/web/static/assets/SecretSelector-6329f743.css +43 -0
  86. flowfile/web/static/assets/{SecretManager-4839be57.js → SecretsView-17df66ee.js} +35 -36
  87. flowfile/web/static/assets/SecretsView-aa291340.css +38 -0
  88. flowfile/web/static/assets/{Select-9b72f201.js → Select-0aee4c54.js} +9 -7
  89. flowfile/web/static/assets/{SettingsSection-f0f75a42.js → SettingsSection-0784e157.js} +3 -3
  90. flowfile/web/static/assets/{SettingsSection-71e6b7e3.css → SettingsSection-07fbbc39.css} +4 -4
  91. flowfile/web/static/assets/{SettingsSection-5c696bee.css → SettingsSection-26fe48d4.css} +4 -4
  92. flowfile/web/static/assets/{SettingsSection-2e4d03c4.css → SettingsSection-8f980839.css} +4 -4
  93. flowfile/web/static/assets/{SettingsSection-e1e9c953.js → SettingsSection-cd341bb6.js} +3 -3
  94. flowfile/web/static/assets/{SettingsSection-7ded385d.js → SettingsSection-f2002a6d.js} +3 -3
  95. flowfile/web/static/assets/{SingleSelect-6c777aac.js → SingleSelect-460cc0ea.js} +2 -2
  96. flowfile/web/static/assets/{SingleSelect.vue_vue_type_script_setup_true_lang-33e3ff9b.js → SingleSelect.vue_vue_type_script_setup_true_lang-30741bb2.js} +1 -1
  97. flowfile/web/static/assets/{SliderInput-7cb93e62.js → SliderInput-5d926864.js} +7 -4
  98. flowfile/web/static/assets/SliderInput-f2e4f23c.css +4 -0
  99. flowfile/web/static/assets/{Sort-6cbde21a.js → Sort-3cdc971b.js} +9 -7
  100. flowfile/web/static/assets/{Unique-f9fb0809.css → Sort-8a871341.css} +10 -10
  101. flowfile/web/static/assets/{TextInput-d9a40c11.js → TextInput-a2d0bfbd.js} +2 -2
  102. flowfile/web/static/assets/{TextInput.vue_vue_type_script_setup_true_lang-5896c375.js → TextInput.vue_vue_type_script_setup_true_lang-abad1ca2.js} +5 -2
  103. flowfile/web/static/assets/{TextToRows-5d2c1190.css → TextToRows-12afb4f4.css} +10 -10
  104. flowfile/web/static/assets/{TextToRows-c4fcbf4d.js → TextToRows-918945f7.js} +11 -10
  105. flowfile/web/static/assets/{ToggleSwitch-4ef91d19.js → ToggleSwitch-f0ef5196.js} +2 -2
  106. flowfile/web/static/assets/{ToggleSwitch.vue_vue_type_script_setup_true_lang-38478c20.js → ToggleSwitch.vue_vue_type_script_setup_true_lang-5605c793.js} +1 -1
  107. flowfile/web/static/assets/{UnavailableFields-5edd5322.css → UnavailableFields-54d2f518.css} +6 -6
  108. flowfile/web/static/assets/{UnavailableFields-a03f512c.js → UnavailableFields-bdad6144.js} +4 -4
  109. flowfile/web/static/assets/{Union-af6c3d9b.css → Union-d6a8d7d5.css} +7 -7
  110. flowfile/web/static/assets/{Union-bfe9b996.js → Union-e8ab8c86.js} +8 -6
  111. flowfile/web/static/assets/{Unique-5d023a27.js → Unique-8cd4f976.js} +13 -10
  112. flowfile/web/static/assets/{Sort-3643d625.css → Unique-9fb2f567.css} +10 -10
  113. flowfile/web/static/assets/{Unpivot-1e422df3.css → Unpivot-710a2948.css} +7 -7
  114. flowfile/web/static/assets/{Unpivot-91cc5354.js → Unpivot-8da14095.js} +10 -8
  115. flowfile/web/static/assets/{UnpivotValidation-7ee2de44.js → UnpivotValidation-6f7d89ff.js} +3 -3
  116. flowfile/web/static/assets/UnpivotValidation-d5ca3b7b.css +13 -0
  117. flowfile/web/static/assets/{VueGraphicWalker-e51b9924.js → VueGraphicWalker-3fb312e1.js} +4 -4
  118. flowfile/web/static/assets/{VueGraphicWalker-ed5ab88b.css → VueGraphicWalker-430f0b86.css} +1 -1
  119. flowfile/web/static/assets/{api-cf1221f0.js → api-24483f0d.js} +1 -1
  120. flowfile/web/static/assets/{api-c1bad5ca.js → api-8b81fa73.js} +1 -1
  121. flowfile/web/static/assets/{dropDown-35135ba8.css → dropDown-3d8dc5fa.css} +40 -40
  122. flowfile/web/static/assets/{dropDown-614b998d.js → dropDown-ac0fda9d.js} +3 -3
  123. flowfile/web/static/assets/{fullEditor-f7971590.js → fullEditor-5497a84a.js} +11 -10
  124. flowfile/web/static/assets/{fullEditor-178376bb.css → fullEditor-a0be62b3.css} +74 -62
  125. flowfile/web/static/assets/{genericNodeSettings-924759c7.css → genericNodeSettings-3b2507ea.css} +10 -10
  126. flowfile/web/static/assets/{genericNodeSettings-4fe5f36b.js → genericNodeSettings-99014e1d.js} +5 -5
  127. flowfile/web/static/assets/index-07dda503.js +38 -0
  128. flowfile/web/static/assets/index-3ba44389.js +2696 -0
  129. flowfile/web/static/assets/{index-50508d4d.css → index-e6289dd0.css} +1945 -569
  130. flowfile/web/static/assets/{index-5429bbf8.js → index-fb6493ae.js} +41626 -40867
  131. flowfile/web/static/assets/node.types-2c15bb7e.js +82 -0
  132. flowfile/web/static/assets/nodeInput-0eb13f1a.js +2 -0
  133. flowfile/web/static/assets/{outputCsv-076b85ab.js → outputCsv-8f8ba42d.js} +3 -3
  134. flowfile/web/static/assets/outputCsv-b9a072af.css +2499 -0
  135. flowfile/web/static/assets/{outputExcel-0fd17dbe.js → outputExcel-393f4fef.js} +3 -3
  136. flowfile/web/static/assets/{outputExcel-b41305c0.css → outputExcel-f5d272b2.css} +26 -26
  137. flowfile/web/static/assets/{outputParquet-b61e0847.js → outputParquet-07c81f65.js} +4 -4
  138. flowfile/web/static/assets/outputParquet-54597c3c.css +4 -0
  139. flowfile/web/static/assets/{readCsv-a8bb8b61.js → readCsv-07f6d9ad.js} +3 -3
  140. flowfile/web/static/assets/{readCsv-c767cb37.css → readCsv-3bfac4c3.css} +15 -15
  141. flowfile/web/static/assets/{readExcel-806d2826.css → readExcel-3db6b763.css} +13 -13
  142. flowfile/web/static/assets/{readExcel-67b4aee0.js → readExcel-ed69bc8f.js} +5 -5
  143. flowfile/web/static/assets/{readParquet-48c81530.css → readParquet-c5244ad5.css} +4 -4
  144. flowfile/web/static/assets/{readParquet-92ce1dbc.js → readParquet-e3ed4528.js} +3 -3
  145. flowfile/web/static/assets/secrets.api-002e7d7e.js +65 -0
  146. flowfile/web/static/assets/{selectDynamic-92e25ee3.js → selectDynamic-80b92899.js} +5 -5
  147. flowfile/web/static/assets/{selectDynamic-aa913ff4.css → selectDynamic-f2fb394f.css} +21 -20
  148. flowfile/web/static/assets/{vue-codemirror.esm-41b0e0d7.js → vue-codemirror.esm-0965f39f.js} +31 -640
  149. flowfile/web/static/assets/{vue-content-loader.es-2c8e608f.js → vue-content-loader.es-c506ad97.js} +1 -1
  150. flowfile/web/static/index.html +2 -2
  151. {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/METADATA +2 -3
  152. flowfile-0.5.3.dist-info/RECORD +402 -0
  153. flowfile_core/__init__.py +13 -6
  154. flowfile_core/auth/jwt.py +51 -16
  155. flowfile_core/auth/models.py +32 -7
  156. flowfile_core/auth/password.py +89 -0
  157. flowfile_core/auth/secrets.py +8 -6
  158. flowfile_core/configs/__init__.py +9 -7
  159. flowfile_core/configs/flow_logger.py +15 -14
  160. flowfile_core/configs/node_store/__init__.py +72 -4
  161. flowfile_core/configs/node_store/nodes.py +155 -172
  162. flowfile_core/configs/node_store/user_defined_node_registry.py +108 -27
  163. flowfile_core/configs/settings.py +28 -15
  164. flowfile_core/database/connection.py +7 -6
  165. flowfile_core/database/init_db.py +96 -2
  166. flowfile_core/database/models.py +3 -1
  167. flowfile_core/fileExplorer/__init__.py +17 -0
  168. flowfile_core/fileExplorer/funcs.py +123 -57
  169. flowfile_core/fileExplorer/utils.py +10 -11
  170. flowfile_core/flowfile/_extensions/real_time_interface.py +10 -8
  171. flowfile_core/flowfile/analytics/analytics_processor.py +26 -24
  172. flowfile_core/flowfile/analytics/graphic_walker.py +11 -12
  173. flowfile_core/flowfile/analytics/utils.py +1 -1
  174. flowfile_core/flowfile/code_generator/code_generator.py +358 -244
  175. flowfile_core/flowfile/connection_manager/_connection_manager.py +6 -5
  176. flowfile_core/flowfile/connection_manager/models.py +1 -1
  177. flowfile_core/flowfile/database_connection_manager/db_connections.py +60 -44
  178. flowfile_core/flowfile/database_connection_manager/models.py +1 -1
  179. flowfile_core/flowfile/extensions.py +17 -12
  180. flowfile_core/flowfile/flow_data_engine/cloud_storage_reader.py +34 -32
  181. flowfile_core/flowfile/flow_data_engine/create/funcs.py +115 -83
  182. flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +481 -423
  183. flowfile_core/flowfile/flow_data_engine/flow_file_column/interface.py +2 -2
  184. flowfile_core/flowfile/flow_data_engine/flow_file_column/main.py +92 -52
  185. flowfile_core/flowfile/flow_data_engine/flow_file_column/polars_type.py +12 -11
  186. flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +6 -6
  187. flowfile_core/flowfile/flow_data_engine/flow_file_column/utils.py +26 -30
  188. flowfile_core/flowfile/flow_data_engine/fuzzy_matching/prepare_for_fuzzy_match.py +31 -20
  189. flowfile_core/flowfile/flow_data_engine/join/__init__.py +1 -1
  190. flowfile_core/flowfile/flow_data_engine/join/utils.py +11 -9
  191. flowfile_core/flowfile/flow_data_engine/join/verify_integrity.py +14 -15
  192. flowfile_core/flowfile/flow_data_engine/pivot_table.py +5 -7
  193. flowfile_core/flowfile/flow_data_engine/polars_code_parser.py +95 -82
  194. flowfile_core/flowfile/flow_data_engine/read_excel_tables.py +66 -65
  195. flowfile_core/flowfile/flow_data_engine/sample_data.py +27 -21
  196. flowfile_core/flowfile/flow_data_engine/subprocess_operations/__init__.py +1 -1
  197. flowfile_core/flowfile/flow_data_engine/subprocess_operations/models.py +13 -11
  198. flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +190 -127
  199. flowfile_core/flowfile/flow_data_engine/threaded_processes.py +8 -8
  200. flowfile_core/flowfile/flow_data_engine/utils.py +99 -67
  201. flowfile_core/flowfile/flow_graph.py +918 -571
  202. flowfile_core/flowfile/flow_graph_utils.py +31 -49
  203. flowfile_core/flowfile/flow_node/flow_node.py +330 -233
  204. flowfile_core/flowfile/flow_node/models.py +53 -41
  205. flowfile_core/flowfile/flow_node/schema_callback.py +14 -19
  206. flowfile_core/flowfile/graph_tree/graph_tree.py +41 -41
  207. flowfile_core/flowfile/handler.py +80 -30
  208. flowfile_core/flowfile/manage/compatibility_enhancements.py +209 -126
  209. flowfile_core/flowfile/manage/io_flowfile.py +54 -57
  210. flowfile_core/flowfile/node_designer/__init__.py +15 -13
  211. flowfile_core/flowfile/node_designer/_type_registry.py +34 -37
  212. flowfile_core/flowfile/node_designer/custom_node.py +162 -36
  213. flowfile_core/flowfile/node_designer/ui_components.py +135 -34
  214. flowfile_core/flowfile/schema_callbacks.py +71 -51
  215. flowfile_core/flowfile/setting_generator/__init__.py +0 -1
  216. flowfile_core/flowfile/setting_generator/setting_generator.py +6 -5
  217. flowfile_core/flowfile/setting_generator/settings.py +64 -53
  218. flowfile_core/flowfile/sources/external_sources/base_class.py +12 -10
  219. flowfile_core/flowfile/sources/external_sources/custom_external_sources/external_source.py +27 -17
  220. flowfile_core/flowfile/sources/external_sources/custom_external_sources/sample_users.py +9 -9
  221. flowfile_core/flowfile/sources/external_sources/factory.py +0 -1
  222. flowfile_core/flowfile/sources/external_sources/sql_source/models.py +45 -31
  223. flowfile_core/flowfile/sources/external_sources/sql_source/sql_source.py +198 -73
  224. flowfile_core/flowfile/sources/external_sources/sql_source/utils.py +250 -196
  225. flowfile_core/flowfile/util/calculate_layout.py +9 -13
  226. flowfile_core/flowfile/util/execution_orderer.py +25 -17
  227. flowfile_core/flowfile/util/node_skipper.py +4 -4
  228. flowfile_core/flowfile/utils.py +19 -21
  229. flowfile_core/main.py +26 -19
  230. flowfile_core/routes/auth.py +284 -11
  231. flowfile_core/routes/cloud_connections.py +25 -25
  232. flowfile_core/routes/logs.py +21 -29
  233. flowfile_core/routes/public.py +3 -3
  234. flowfile_core/routes/routes.py +70 -34
  235. flowfile_core/routes/secrets.py +25 -27
  236. flowfile_core/routes/user_defined_components.py +483 -4
  237. flowfile_core/run_lock.py +0 -1
  238. flowfile_core/schemas/__init__.py +4 -6
  239. flowfile_core/schemas/analysis_schemas/graphic_walker_schemas.py +55 -55
  240. flowfile_core/schemas/cloud_storage_schemas.py +59 -53
  241. flowfile_core/schemas/input_schema.py +231 -144
  242. flowfile_core/schemas/output_model.py +49 -34
  243. flowfile_core/schemas/schemas.py +116 -89
  244. flowfile_core/schemas/transform_schema.py +518 -263
  245. flowfile_core/schemas/yaml_types.py +21 -7
  246. flowfile_core/secret_manager/secret_manager.py +17 -13
  247. flowfile_core/types.py +29 -9
  248. flowfile_core/utils/arrow_reader.py +7 -6
  249. flowfile_core/utils/excel_file_manager.py +3 -3
  250. flowfile_core/utils/fileManager.py +7 -7
  251. flowfile_core/utils/fl_executor.py +8 -10
  252. flowfile_core/utils/utils.py +4 -4
  253. flowfile_core/utils/validate_setup.py +5 -4
  254. flowfile_frame/__init__.py +106 -51
  255. flowfile_frame/adapters.py +2 -9
  256. flowfile_frame/adding_expr.py +73 -32
  257. flowfile_frame/cloud_storage/frame_helpers.py +27 -23
  258. flowfile_frame/cloud_storage/secret_manager.py +12 -26
  259. flowfile_frame/config.py +2 -5
  260. flowfile_frame/expr.py +311 -218
  261. flowfile_frame/expr.pyi +160 -159
  262. flowfile_frame/expr_name.py +23 -23
  263. flowfile_frame/flow_frame.py +571 -476
  264. flowfile_frame/flow_frame.pyi +123 -104
  265. flowfile_frame/flow_frame_methods.py +227 -246
  266. flowfile_frame/group_frame.py +50 -20
  267. flowfile_frame/join.py +2 -2
  268. flowfile_frame/lazy.py +129 -87
  269. flowfile_frame/lazy_methods.py +83 -30
  270. flowfile_frame/list_name_space.py +55 -50
  271. flowfile_frame/selectors.py +148 -68
  272. flowfile_frame/series.py +9 -7
  273. flowfile_frame/utils.py +19 -21
  274. flowfile_worker/__init__.py +12 -7
  275. flowfile_worker/configs.py +11 -19
  276. flowfile_worker/create/__init__.py +14 -9
  277. flowfile_worker/create/funcs.py +114 -77
  278. flowfile_worker/create/models.py +46 -43
  279. flowfile_worker/create/pl_types.py +14 -15
  280. flowfile_worker/create/read_excel_tables.py +34 -41
  281. flowfile_worker/create/utils.py +22 -19
  282. flowfile_worker/external_sources/s3_source/main.py +18 -51
  283. flowfile_worker/external_sources/s3_source/models.py +34 -27
  284. flowfile_worker/external_sources/sql_source/main.py +8 -5
  285. flowfile_worker/external_sources/sql_source/models.py +13 -9
  286. flowfile_worker/flow_logger.py +10 -8
  287. flowfile_worker/funcs.py +214 -155
  288. flowfile_worker/main.py +11 -17
  289. flowfile_worker/models.py +35 -28
  290. flowfile_worker/process_manager.py +2 -3
  291. flowfile_worker/routes.py +121 -90
  292. flowfile_worker/secrets.py +9 -6
  293. flowfile_worker/spawner.py +80 -49
  294. flowfile_worker/utils.py +3 -2
  295. shared/__init__.py +2 -7
  296. shared/storage_config.py +25 -13
  297. test_utils/postgres/commands.py +3 -2
  298. test_utils/postgres/fixtures.py +9 -9
  299. test_utils/s3/commands.py +1 -1
  300. test_utils/s3/data_generator.py +3 -4
  301. test_utils/s3/demo_data_generator.py +4 -7
  302. test_utils/s3/fixtures.py +7 -5
  303. tools/migrate/__init__.py +1 -1
  304. tools/migrate/__main__.py +16 -29
  305. tools/migrate/legacy_schemas.py +251 -190
  306. tools/migrate/migrate.py +193 -181
  307. tools/migrate/tests/conftest.py +1 -3
  308. tools/migrate/tests/test_migrate.py +36 -41
  309. tools/migrate/tests/test_migration_e2e.py +28 -29
  310. tools/migrate/tests/test_node_migrations.py +50 -20
  311. flowfile/web/static/assets/CloudConnectionManager-2dfdce2f.css +0 -86
  312. flowfile/web/static/assets/CustomNode-74a37f74.css +0 -32
  313. flowfile/web/static/assets/DatabaseManager-30fa27e5.css +0 -64
  314. flowfile/web/static/assets/Filter-9b6d08db.js +0 -164
  315. flowfile/web/static/assets/Filter-f62091b3.css +0 -20
  316. flowfile/web/static/assets/ManualInput-3246a08d.css +0 -96
  317. flowfile/web/static/assets/PivotValidation-891ddfb0.css +0 -13
  318. flowfile/web/static/assets/PivotValidation-c46cd420.css +0 -13
  319. flowfile/web/static/assets/SliderInput-b8fb6a8c.css +0 -4
  320. flowfile/web/static/assets/UnpivotValidation-0d240eeb.css +0 -13
  321. flowfile/web/static/assets/nodeInput-5d0d6b79.js +0 -41
  322. flowfile/web/static/assets/outputCsv-9cc59e0b.css +0 -2499
  323. flowfile/web/static/assets/outputParquet-cf8cf3f2.css +0 -4
  324. flowfile/web/static/assets/secretApi-68435402.js +0 -46
  325. flowfile/web/static/assets/vue-codemirror-bccfde04.css +0 -32
  326. flowfile-0.5.1.dist-info/RECORD +0 -388
  327. {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/WHEEL +0 -0
  328. {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/entry_points.txt +0 -0
  329. {flowfile-0.5.1.dist-info → flowfile-0.5.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,13 +1,14 @@
1
- from faker import Faker
1
+ from collections.abc import Iterable
2
2
  from functools import partial
3
3
  from random import randint
4
+
4
5
  import polars as pl
5
- from typing import Iterable
6
+ from faker import Faker
6
7
 
7
8
 
8
9
  def create_fake_data(n_records: int = 1000) -> pl.DataFrame:
9
10
  fake = Faker()
10
- selector = partial(randint,0)
11
+ selector = partial(randint, 0)
11
12
  min_range = partial(min, n_records)
12
13
  # Pre-generation of static data
13
14
  cities = [fake.city() for _ in range(min_range(7000))]
@@ -35,18 +36,20 @@ def create_fake_data(n_records: int = 1000) -> pl.DataFrame:
35
36
  data = []
36
37
  for i in range(n_records):
37
38
  name = generate_name()
38
- data.append(dict(
39
- ID=randint(1, 1000000),
40
- Name=name,
41
- Address=generate_address(),
42
- City=cities[selector(min_range(7000))-1],
43
- Email=generate_email(name),
44
- Phone=generate_phone_number(),
45
- DOB=dob[selector(min_range(100_000))-1],
46
- Work=companies[selector(min_range(100_000))-1],
47
- Zipcode=zipcodes[selector(min_range(200_000))-1],
48
- Country=countries[selector(min_range(50))-1]
49
- ))
39
+ data.append(
40
+ dict(
41
+ ID=randint(1, 1000000),
42
+ Name=name,
43
+ Address=generate_address(),
44
+ City=cities[selector(min_range(7000)) - 1],
45
+ Email=generate_email(name),
46
+ Phone=generate_phone_number(),
47
+ DOB=dob[selector(min_range(100_000)) - 1],
48
+ Work=companies[selector(min_range(100_000)) - 1],
49
+ Zipcode=zipcodes[selector(min_range(200_000)) - 1],
50
+ Country=countries[selector(min_range(50)) - 1],
51
+ )
52
+ )
50
53
 
51
54
  return pl.DataFrame(data)
52
55
 
@@ -68,7 +71,7 @@ def standardize_col_dtype(vals):
68
71
  return [convert_to_string(v) for v in vals]
69
72
 
70
73
 
71
- def create_pl_df_type_save(raw_data: Iterable[Iterable], orient: str = 'row') -> pl.DataFrame:
74
+ def create_pl_df_type_save(raw_data: Iterable[Iterable], orient: str = "row") -> pl.DataFrame:
72
75
  """
73
76
  orient : {'col', 'row'}, default None
74
77
  Whether to interpret two-dimensional data as columns or as rows. If None,
@@ -78,7 +81,7 @@ def create_pl_df_type_save(raw_data: Iterable[Iterable], orient: str = 'row') ->
78
81
  :param orient:
79
82
  :return: polars dataframe
80
83
  """
81
- if orient == 'row':
82
- raw_data = zip(*raw_data)
84
+ if orient == "row":
85
+ raw_data = zip(*raw_data, strict=False)
83
86
  raw_data = [standardize_col_dtype(values) for values in raw_data]
84
- return pl.DataFrame(raw_data, orient='col')
87
+ return pl.DataFrame(raw_data, orient="col")
@@ -4,23 +4,17 @@ This module provides functionality to write Polars LazyFrames to various cloud s
4
4
  services (S3, Azure ADLS, Google Cloud Storage) in different file formats.
5
5
  """
6
6
 
7
- import polars as pl
8
- from typing import Dict, Any
9
7
  from logging import Logger
8
+ from typing import Any
9
+
10
+ import polars as pl
10
11
 
11
- from flowfile_worker.external_sources.s3_source.models import (
12
- CloudStorageWriteSettings,
13
- WriteSettings
14
- )
12
+ from flowfile_worker.external_sources.s3_source.models import CloudStorageWriteSettings, WriteSettings
15
13
  from flowfile_worker.utils import collect_lazy_frame
16
14
 
17
15
 
18
16
  def _write_parquet_to_cloud(
19
- df: pl.LazyFrame,
20
- resource_path: str,
21
- storage_options: Dict[str, Any],
22
- write_settings: WriteSettings,
23
- logger: Logger
17
+ df: pl.LazyFrame, resource_path: str, storage_options: dict[str, Any], write_settings: WriteSettings, logger: Logger
24
18
  ) -> None:
25
19
  """Write LazyFrame to a Parquet file in cloud storage.
26
20
 
@@ -49,7 +43,7 @@ def _write_parquet_to_cloud(
49
43
  # Fall back to collecting and writing if sink fails
50
44
  logger.warning(f"Failed to use sink_parquet, falling back to collect and write: {str(e)}")
51
45
  pl_df = collect_lazy_frame(df)
52
- sink_kwargs['file'] = sink_kwargs.pop("path")
46
+ sink_kwargs["file"] = sink_kwargs.pop("path")
53
47
  pl_df.write_parquet(**sink_kwargs)
54
48
 
55
49
  except Exception as e:
@@ -58,11 +52,7 @@ def _write_parquet_to_cloud(
58
52
 
59
53
 
60
54
  def _write_delta_to_cloud(
61
- df: pl.LazyFrame,
62
- resource_path: str,
63
- storage_options: Dict[str, Any],
64
- write_settings: WriteSettings,
65
- logger: Logger
55
+ df: pl.LazyFrame, resource_path: str, storage_options: dict[str, Any], write_settings: WriteSettings, logger: Logger
66
56
  ) -> None:
67
57
  """Write LazyFrame to Delta Lake format in cloud storage.
68
58
 
@@ -85,11 +75,7 @@ def _write_delta_to_cloud(
85
75
 
86
76
 
87
77
  def _write_csv_to_cloud(
88
- df: pl.LazyFrame,
89
- resource_path: str,
90
- storage_options: Dict[str, Any],
91
- write_settings: WriteSettings,
92
- logger: Logger
78
+ df: pl.LazyFrame, resource_path: str, storage_options: dict[str, Any], write_settings: WriteSettings, logger: Logger
93
79
  ) -> None:
94
80
  """Write LazyFrame to a CSV file in cloud storage.
95
81
 
@@ -120,11 +106,7 @@ def _write_csv_to_cloud(
120
106
 
121
107
 
122
108
  def _write_json_to_cloud(
123
- df: pl.LazyFrame,
124
- resource_path: str,
125
- storage_options: Dict[str, Any],
126
- write_settings: WriteSettings,
127
- logger: Logger
109
+ df: pl.LazyFrame, resource_path: str, storage_options: dict[str, Any], write_settings: WriteSettings, logger: Logger
128
110
  ) -> None:
129
111
  """Write LazyFrame to a line-delimited JSON (NDJSON) file in cloud storage.
130
112
 
@@ -149,7 +131,7 @@ def _write_json_to_cloud(
149
131
  except Exception as e:
150
132
  # Fall back to collecting and writing if sink fails
151
133
  pl_df = collect_lazy_frame(df)
152
- sink_kwargs['file'] = sink_kwargs.pop("path")
134
+ sink_kwargs["file"] = sink_kwargs.pop("path")
153
135
  pl_df.write_ndjson(**sink_kwargs)
154
136
  logger.error(f"Failed to use sink_ndjson, falling back to collect and write: {str(e)}")
155
137
 
@@ -157,6 +139,7 @@ def _write_json_to_cloud(
157
139
  logger.error(f"Failed to write JSON to {resource_path}: {str(e)}")
158
140
  raise Exception(f"Failed to write JSON to cloud storage: {str(e)}")
159
141
 
142
+
160
143
  writers = {
161
144
  "parquet": _write_parquet_to_cloud,
162
145
  "delta": _write_delta_to_cloud,
@@ -165,11 +148,7 @@ writers = {
165
148
  }
166
149
 
167
150
 
168
- def write_df_to_cloud(
169
- df: pl.LazyFrame,
170
- settings: CloudStorageWriteSettings,
171
- logger: Logger
172
- ) -> None:
151
+ def write_df_to_cloud(df: pl.LazyFrame, settings: CloudStorageWriteSettings, logger: Logger) -> None:
173
152
  """Write a Polars LazyFrame to an object in cloud storage.
174
153
 
175
154
  Supports writing to S3, Azure ADLS, and Google Cloud Storage. Currently supports
@@ -187,30 +166,18 @@ def write_df_to_cloud(
187
166
  """
188
167
  connection = settings.connection
189
168
  write_settings = settings.write_settings
190
- logger.info(
191
- f"Writing to {connection.storage_type} storage: {write_settings.resource_path}"
192
- )
169
+ logger.info(f"Writing to {connection.storage_type} storage: {write_settings.resource_path}")
193
170
  # Validate write mode
194
- if write_settings.write_mode == 'append' and write_settings.file_format != "delta":
195
- raise NotImplementedError(
196
- "The 'append' write mode is not yet supported for this destination."
197
- )
171
+ if write_settings.write_mode == "append" and write_settings.file_format != "delta":
172
+ raise NotImplementedError("The 'append' write mode is not yet supported for this destination.")
198
173
 
199
174
  storage_options = connection.get_storage_options()
200
175
 
201
176
  # Dispatch to the appropriate writer
202
177
  writer_func = writers.get(write_settings.file_format)
203
178
  if not writer_func:
204
- raise ValueError(
205
- f"Unsupported file format for writing: {write_settings.file_format}"
206
- )
207
-
208
- writer_func(
209
- df,
210
- write_settings.resource_path,
211
- storage_options,
212
- write_settings,
213
- logger
214
- )
179
+ raise ValueError(f"Unsupported file format for writing: {write_settings.file_format}")
180
+
181
+ writer_func(df, write_settings.resource_path, storage_options, write_settings, logger)
215
182
 
216
183
  logger.info(f"Successfully wrote data to {write_settings.resource_path}")
@@ -1,16 +1,21 @@
1
1
  """Cloud storage connection schemas for S3, ADLS, and other cloud providers."""
2
2
 
3
- from typing import Optional, Literal, Dict, Any
3
+ from typing import Any, Literal
4
+
4
5
  import boto3
5
6
  from pydantic import BaseModel, SecretStr
7
+
6
8
  from flowfile_worker.secrets import decrypt_secret
7
9
 
8
10
  CloudStorageType = Literal["s3", "adls", "gcs"]
9
- AuthMethod = Literal["access_key", "iam_role", "service_principal", "managed_identity", "sas_token", "aws-cli", "env_vars"]
11
+ AuthMethod = Literal[
12
+ "access_key", "iam_role", "service_principal", "managed_identity", "sas_token", "aws-cli", "env_vars"
13
+ ]
10
14
 
11
15
 
12
- def create_storage_options_from_boto_credentials(profile_name: Optional[str],
13
- region_name: Optional[str] = None) -> Dict[str, Any]:
16
+ def create_storage_options_from_boto_credentials(
17
+ profile_name: str | None, region_name: str | None = None
18
+ ) -> dict[str, Any]:
14
19
  """
15
20
  Create a storage options dictionary from AWS credentials using a boto3 profile.
16
21
  This is the most robust way to handle profile-based authentication as it
@@ -47,29 +52,30 @@ def create_storage_options_from_boto_credentials(profile_name: Optional[str],
47
52
 
48
53
  class FullCloudStorageConnection(BaseModel):
49
54
  """Internal model with decrypted secrets"""
55
+
50
56
  storage_type: CloudStorageType
51
57
  auth_method: AuthMethod
52
- connection_name: Optional[str] = "None" # This is the reference to the item we will fetch that contains the data
58
+ connection_name: str | None = "None" # This is the reference to the item we will fetch that contains the data
53
59
 
54
60
  # AWS S3
55
- aws_region: Optional[str] = None
56
- aws_access_key_id: Optional[str] = None
57
- aws_secret_access_key: Optional[SecretStr] = None
58
- aws_role_arn: Optional[str] = None
59
- aws_allow_unsafe_html: Optional[bool] = None
61
+ aws_region: str | None = None
62
+ aws_access_key_id: str | None = None
63
+ aws_secret_access_key: SecretStr | None = None
64
+ aws_role_arn: str | None = None
65
+ aws_allow_unsafe_html: bool | None = None
60
66
 
61
67
  # Azure ADLS
62
- azure_account_name: Optional[str] = None
63
- azure_account_key: Optional[SecretStr] = None
64
- azure_tenant_id: Optional[str] = None
65
- azure_client_id: Optional[str] = None
66
- azure_client_secret: Optional[SecretStr] = None
68
+ azure_account_name: str | None = None
69
+ azure_account_key: SecretStr | None = None
70
+ azure_tenant_id: str | None = None
71
+ azure_client_id: str | None = None
72
+ azure_client_secret: SecretStr | None = None
67
73
 
68
74
  # Common
69
- endpoint_url: Optional[str] = None
75
+ endpoint_url: str | None = None
70
76
  verify_ssl: bool = True
71
77
 
72
- def get_storage_options(self) -> Dict[str, Any]:
78
+ def get_storage_options(self) -> dict[str, Any]:
73
79
  """
74
80
  Build storage options dict based on the connection type and auth method.
75
81
 
@@ -79,15 +85,14 @@ class FullCloudStorageConnection(BaseModel):
79
85
  if self.storage_type == "s3":
80
86
  return self._get_s3_storage_options()
81
87
 
82
- def _get_s3_storage_options(self) -> Dict[str, Any]:
88
+ def _get_s3_storage_options(self) -> dict[str, Any]:
83
89
  """Build S3-specific storage options."""
84
90
  auth_method = self.auth_method
85
91
  print(f"Building S3 storage options for auth_method: '{auth_method}'")
86
92
 
87
93
  if auth_method == "aws-cli":
88
94
  return create_storage_options_from_boto_credentials(
89
- profile_name=self.connection_name,
90
- region_name=self.aws_region
95
+ profile_name=self.connection_name, region_name=self.aws_region
91
96
  )
92
97
 
93
98
  storage_options = {}
@@ -103,27 +108,29 @@ class FullCloudStorageConnection(BaseModel):
103
108
  if auth_method == "access_key":
104
109
  storage_options["aws_access_key_id"] = self.aws_access_key_id
105
110
  storage_options["aws_secret_access_key"] = decrypt_secret(
106
- self.aws_secret_access_key.get_secret_value()).get_secret_value()
111
+ self.aws_secret_access_key.get_secret_value()
112
+ ).get_secret_value()
107
113
  # Explicitly clear any session token from the environment
108
114
  storage_options["aws_session_token"] = ""
109
115
 
110
116
  elif auth_method == "iam_role":
111
117
  # Correctly implement IAM role assumption using boto3 STS client.
112
- sts_client = boto3.client('sts', region_name=self.aws_region)
118
+ sts_client = boto3.client("sts", region_name=self.aws_region)
113
119
  assumed_role_object = sts_client.assume_role(
114
120
  RoleArn=self.aws_role_arn,
115
- RoleSessionName="PolarsCloudStorageReaderSession" # A descriptive session name
121
+ RoleSessionName="PolarsCloudStorageReaderSession", # A descriptive session name
116
122
  )
117
- credentials = assumed_role_object['Credentials']
118
- storage_options["aws_access_key_id"] = credentials['AccessKeyId']
119
- storage_options["aws_secret_access_key"] = decrypt_secret(credentials['SecretAccessKey']).get_secret_value()
120
- storage_options["aws_session_token"] = decrypt_secret(credentials['SessionToken']).get_secret_value()
123
+ credentials = assumed_role_object["Credentials"]
124
+ storage_options["aws_access_key_id"] = credentials["AccessKeyId"]
125
+ storage_options["aws_secret_access_key"] = decrypt_secret(credentials["SecretAccessKey"]).get_secret_value()
126
+ storage_options["aws_session_token"] = decrypt_secret(credentials["SessionToken"]).get_secret_value()
121
127
 
122
128
  return storage_options
123
129
 
124
130
 
125
131
  class WriteSettings(BaseModel):
126
132
  """Settings for writing to cloud storage"""
133
+
127
134
  resource_path: str # s3://bucket/path/to/file.csv
128
135
 
129
136
  write_mode: Literal["overwrite", "append"] = "overwrite"
@@ -1,6 +1,8 @@
1
+ from io import BytesIO
2
+
1
3
  import polars as pl
4
+
2
5
  from flowfile_worker.external_sources.sql_source.models import DatabaseReadSettings, DatabaseWriteSettings
3
- from io import BytesIO
4
6
 
5
7
 
6
8
  def write_df_to_database(df: pl.DataFrame, database_write_settings: DatabaseWriteSettings):
@@ -11,9 +13,11 @@ def write_df_to_database(df: pl.DataFrame, database_write_settings: DatabaseWrit
11
13
  database_write_settings (DatabaseWriteSettings): The settings for the database connection and table.
12
14
  """
13
15
  # Write the DataFrame to the database
14
- df.write_database(table_name=database_write_settings.table_name,
15
- connection=database_write_settings.connection.create_uri(),
16
- if_table_exists=database_write_settings.if_exists)
16
+ df.write_database(
17
+ table_name=database_write_settings.table_name,
18
+ connection=database_write_settings.connection.create_uri(),
19
+ if_table_exists=database_write_settings.if_exists,
20
+ )
17
21
  return True
18
22
 
19
23
 
@@ -53,4 +57,3 @@ def read_sql_source(database_read_settings: DatabaseReadSettings):
53
57
  # Read the query into a DataFrame
54
58
  df = read_query_as_pd_df(database_read_settings.query, database_read_settings.connection.create_uri())
55
59
  return df
56
-
@@ -1,17 +1,20 @@
1
- from typing import Optional, Literal
1
+ from typing import Literal
2
+
2
3
  from pydantic import BaseModel, SecretStr
4
+
3
5
  from flowfile_worker.secrets import decrypt_secret
4
6
 
5
7
 
6
8
  class DataBaseConnection(BaseModel):
7
9
  """Database connection configuration with secure password handling."""
8
- username: Optional[str] = None
9
- password: Optional[SecretStr] = None # Encrypted password
10
- host: Optional[str] = None
11
- port: Optional[int] = None
12
- database: Optional[str] = None # The database name
10
+
11
+ username: str | None = None
12
+ password: SecretStr | None = None # Encrypted password
13
+ host: str | None = None
14
+ port: int | None = None
15
+ database: str | None = None # The database name
13
16
  database_type: str = "postgresql" # Database type (postgresql, mysql, etc.)
14
- url: Optional[str] = None
17
+ url: str | None = None
15
18
 
16
19
  def get_decrypted_secret(self) -> SecretStr:
17
20
  return decrypt_secret(self.password.get_secret_value())
@@ -48,7 +51,6 @@ class DataBaseConnection(BaseModel):
48
51
  if self.port:
49
52
  port_section = f":{self.port}"
50
53
  if self.database:
51
-
52
54
  base_uri = f"{self.database_type}://{credentials}{self.host}{port_section}/{self.database}"
53
55
  else:
54
56
  base_uri = f"{self.database_type}://{credentials}{self.host}{port_section}"
@@ -57,6 +59,7 @@ class DataBaseConnection(BaseModel):
57
59
 
58
60
  class DatabaseReadSettings(BaseModel):
59
61
  """Settings for SQL source."""
62
+
60
63
  connection: DataBaseConnection
61
64
  query: str
62
65
  flowfile_flow_id: int = 1
@@ -65,8 +68,9 @@ class DatabaseReadSettings(BaseModel):
65
68
 
66
69
  class DatabaseWriteSettings(BaseModel):
67
70
  """Settings for SQL sink."""
71
+
68
72
  connection: DataBaseConnection
69
73
  table_name: str
70
- if_exists: Literal['append', 'replace', 'fail'] = 'append'
74
+ if_exists: Literal["append", "replace", "fail"] = "append"
71
75
  flowfile_flow_id: int = 1
72
76
  flowfile_node_id: int | str = -1
@@ -1,7 +1,9 @@
1
1
  import logging
2
+
2
3
  import requests
3
- from flowfile_worker.models import RawLogInput
4
+
4
5
  from flowfile_worker.configs import FLOWFILE_CORE_URI
6
+ from flowfile_worker.models import RawLogInput
5
7
 
6
8
  LOGGING_URL = FLOWFILE_CORE_URI + "/raw_logs"
7
9
 
@@ -23,12 +25,12 @@ class FlowfileLogHandler(logging.Handler):
23
25
  flowfile_flow_id=self.flowfile_flow_id,
24
26
  log_message=log_message,
25
27
  log_type=record.levelname.upper(),
26
- extra={
27
- }
28
+ extra={},
28
29
  )
29
30
  if self.flowfile_flow_id != -1 and self.flowfile_node_id != -1:
30
- response = requests.post(LOGGING_URL, json=raw_log_input.__dict__,
31
- headers={"Content-Type": "application/json"})
31
+ response = requests.post(
32
+ LOGGING_URL, json=raw_log_input.__dict__, headers={"Content-Type": "application/json"}
33
+ )
32
34
  if response.status_code != 200:
33
35
  raise Exception(f"Failed to send log: {response.text}")
34
36
  except Exception as e:
@@ -45,13 +47,13 @@ def get_worker_logger(flowfile_flow_id: int, flowfile_node_id: int | str) -> log
45
47
  if not logger.handlers:
46
48
  stream_handler = logging.StreamHandler()
47
49
  stream_handler.setLevel(logging.DEBUG)
48
- stream_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
50
+ stream_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
49
51
  stream_handler.setFormatter(stream_formatter)
50
52
  logger.addHandler(stream_handler)
51
53
 
52
- http_handler = FlowfileLogHandler(flowfile_flow_id=flowfile_flow_id, flowfile_node_id = flowfile_node_id)
54
+ http_handler = FlowfileLogHandler(flowfile_flow_id=flowfile_flow_id, flowfile_node_id=flowfile_node_id)
53
55
  http_handler.setLevel(logging.INFO)
54
- http_formatter = logging.Formatter('%(message)s')
56
+ http_formatter = logging.Formatter("%(message)s")
55
57
  http_handler.setFormatter(http_formatter)
56
58
  logger.addHandler(http_handler)
57
59