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,14 +1,13 @@
1
- from flowfile_core.schemas import schemas, input_schema
2
- from typing import List, Tuple
3
- from flowfile_core.flowfile.manage.compatibility_enhancements import ensure_compatibility, load_flowfile_pickle
4
- from flowfile_core.flowfile.flow_graph import FlowGraph
1
+ import json
5
2
  from pathlib import Path
3
+
6
4
  from flowfile_core.configs.node_store import CUSTOM_NODE_STORE
7
- from flowfile_core.configs.settings import IS_RUNNING_IN_DOCKER
8
- import json
5
+ from flowfile_core.configs.settings import is_docker_mode
6
+ from flowfile_core.flowfile.flow_graph import FlowGraph
7
+ from flowfile_core.flowfile.manage.compatibility_enhancements import ensure_compatibility, load_flowfile_pickle
8
+ from flowfile_core.schemas import input_schema, schemas
9
9
  from shared.storage_config import storage
10
10
 
11
-
12
11
  try:
13
12
  import yaml
14
13
  except ImportError:
@@ -20,7 +19,7 @@ def _validate_flow_path(flow_path: Path) -> Path:
20
19
  resolved = flow_path.resolve()
21
20
 
22
21
  # Check extension
23
- allowed_extensions = {'.yaml', '.yml', '.json', '.flowfile'}
22
+ allowed_extensions = {".yaml", ".yml", ".json", ".flowfile"}
24
23
  if resolved.suffix.lower() not in allowed_extensions:
25
24
  raise ValueError(f"Unsupported file extension: {resolved.suffix}")
26
25
 
@@ -30,16 +29,13 @@ def _validate_flow_path(flow_path: Path) -> Path:
30
29
 
31
30
  # Allow paths within known safe directories
32
31
 
33
- if IS_RUNNING_IN_DOCKER:
32
+ if is_docker_mode():
34
33
  safe_directories = [
35
34
  storage.flows_directory,
36
35
  storage.uploads_directory,
37
36
  storage.temp_directory_for_flows,
38
37
  ]
39
- is_safe = any(
40
- resolved.is_relative_to(safe_dir)
41
- for safe_dir in safe_directories
42
- )
38
+ is_safe = any(resolved.is_relative_to(safe_dir) for safe_dir in safe_directories)
43
39
  else:
44
40
  is_safe = True
45
41
 
@@ -52,7 +48,7 @@ def _validate_flow_path(flow_path: Path) -> Path:
52
48
  return resolved
53
49
 
54
50
 
55
- def _derive_connections_from_nodes(nodes: List[schemas.FlowfileNode]) -> List[Tuple[int, int]]:
51
+ def _derive_connections_from_nodes(nodes: list[schemas.FlowfileNode]) -> list[tuple[int, int]]:
56
52
  """Derive node connections from the outputs stored in each node."""
57
53
  connections = []
58
54
  for node in nodes:
@@ -63,7 +59,7 @@ def _derive_connections_from_nodes(nodes: List[schemas.FlowfileNode]) -> List[Tu
63
59
 
64
60
 
65
61
  def determine_insertion_order(node_storage: schemas.FlowInformation):
66
- ingest_order: List[int] = []
62
+ ingest_order: list[int] = []
67
63
  ingest_order_set: set[int] = set()
68
64
  all_nodes = set(node_storage.data.keys())
69
65
 
@@ -78,10 +74,11 @@ def determine_insertion_order(node_storage: schemas.FlowInformation):
78
74
  return
79
75
  output_ids = current_node.outputs
80
76
  main_input_ids = current_node.input_ids if current_node.input_ids else []
81
- input_ids = [n for n in [current_node.left_input_id,
82
- current_node.right_input_id] + main_input_ids if (n is not None
83
- and n not in
84
- ingest_order_set)]
77
+ input_ids = [
78
+ n
79
+ for n in [current_node.left_input_id, current_node.right_input_id] + main_input_ids
80
+ if (n is not None and n not in ingest_order_set)
81
+ ]
85
82
  if len(input_ids) > 0:
86
83
  for input_id in input_ids:
87
84
  new_node = node_storage.data.get(input_id)
@@ -123,7 +120,7 @@ def _load_flowfile_yaml(flow_path: Path) -> schemas.FlowInformation:
123
120
  if yaml is None:
124
121
  raise ImportError("PyYAML is required for YAML files. Install with: pip install pyyaml")
125
122
  flow_path = _validate_flow_path(flow_path)
126
- with open(flow_path, 'r', encoding='utf-8') as f:
123
+ with open(flow_path, encoding="utf-8") as f:
127
124
  data = yaml.safe_load(f)
128
125
  # Load as FlowfileData first (handles setting_input validation via node type)
129
126
  flowfile_data = schemas.FlowfileData.model_validate(data)
@@ -142,7 +139,7 @@ def _load_flowfile_json(flow_path: Path) -> schemas.FlowInformation:
142
139
  FlowInformation object
143
140
  """
144
141
  flow_path = _validate_flow_path(flow_path)
145
- with open(flow_path, 'r', encoding='utf-8') as f:
142
+ with open(flow_path, encoding="utf-8") as f:
146
143
  data = json.load(f)
147
144
 
148
145
  # Load as FlowfileData first (handles setting_input validation via node type)
@@ -168,40 +165,42 @@ def _flowfile_data_to_flow_information(flowfile_data: schemas.FlowfileData) -> s
168
165
  is_user_defined = model_class == input_schema.UserDefinedNode
169
166
 
170
167
  # Inject fields that were excluded during serialization
171
- setting_data = node.setting_input if isinstance(node.setting_input, dict) else node.setting_input.model_dump()
172
- setting_data['flow_id'] = flowfile_data.flowfile_id
173
- setting_data['node_id'] = node.id
174
- setting_data['pos_x'] = float(node.x_position or 0)
175
- setting_data['pos_y'] = float(node.y_position or 0)
176
- setting_data['description'] = node.description or ''
177
- setting_data['is_setup'] = True
168
+ setting_data = (
169
+ node.setting_input if isinstance(node.setting_input, dict) else node.setting_input.model_dump()
170
+ )
171
+ setting_data["flow_id"] = flowfile_data.flowfile_id
172
+ setting_data["node_id"] = node.id
173
+ setting_data["pos_x"] = float(node.x_position or 0)
174
+ setting_data["pos_y"] = float(node.y_position or 0)
175
+ setting_data["description"] = node.description or ""
176
+ setting_data["is_setup"] = True
178
177
 
179
178
  if is_user_defined:
180
- setting_data['is_user_defined'] = True
179
+ setting_data["is_user_defined"] = True
181
180
  depending_ids = list(node.input_ids or [])
182
181
  if node.left_input_id:
183
182
  depending_ids.append(node.left_input_id)
184
183
  if node.right_input_id:
185
184
  depending_ids.append(node.right_input_id)
186
- setting_data['depending_on_ids'] = depending_ids
185
+ setting_data["depending_on_ids"] = depending_ids
187
186
  else:
188
- if 'depending_on_id' in model_class.model_fields:
189
- setting_data['depending_on_id'] = node.input_ids[0] if node.input_ids else -1
190
- if 'depending_on_ids' in model_class.model_fields:
187
+ if "depending_on_id" in model_class.model_fields:
188
+ setting_data["depending_on_id"] = node.input_ids[0] if node.input_ids else -1
189
+ if "depending_on_ids" in model_class.model_fields:
191
190
  depending_ids = list(node.input_ids or [])
192
191
  if node.left_input_id:
193
192
  depending_ids.append(node.left_input_id)
194
193
  if node.right_input_id:
195
194
  depending_ids.append(node.right_input_id)
196
- setting_data['depending_on_ids'] = depending_ids
195
+ setting_data["depending_on_ids"] = depending_ids
197
196
 
198
- if node.type == 'output' and 'output_settings' in setting_data:
199
- output_settings = setting_data['output_settings']
200
- file_type = output_settings.get('file_type', None)
197
+ if node.type == "output" and "output_settings" in setting_data:
198
+ output_settings = setting_data["output_settings"]
199
+ file_type = output_settings.get("file_type", None)
201
200
  if file_type is None:
202
201
  raise ValueError("Output node's output_settings must include 'file_type'")
203
- if 'table_settings' not in output_settings:
204
- output_settings['table_settings'] = {"file_type": file_type}
202
+ if "table_settings" not in output_settings:
203
+ output_settings["table_settings"] = {"file_type": file_type}
205
204
 
206
205
  setting_input = model_class.model_validate(setting_data)
207
206
 
@@ -243,6 +242,7 @@ def _flowfile_data_to_flow_information(flowfile_data: schemas.FlowfileData) -> s
243
242
  node_connections=connections,
244
243
  )
245
244
 
245
+
246
246
  def _load_flow_storage(flow_path: Path) -> schemas.FlowInformation:
247
247
  """
248
248
  Load flow storage from any supported format.
@@ -260,21 +260,20 @@ def _load_flow_storage(flow_path: Path) -> schemas.FlowInformation:
260
260
  """
261
261
  flow_path = _validate_flow_path(flow_path)
262
262
  suffix = flow_path.suffix.lower()
263
- if suffix == '.flowfile':
263
+ if suffix == ".flowfile":
264
264
  try:
265
265
  flow_storage_obj = load_flowfile_pickle(str(flow_path))
266
266
  ensure_compatibility(flow_storage_obj, str(flow_path))
267
267
  return flow_storage_obj
268
268
  except Exception as e:
269
269
  raise ValueError(
270
- f"Failed to open legacy .flowfile: {e}\n\n"
271
- f"Try migrating: migrate_flowfile('{flow_path}')"
270
+ f"Failed to open legacy .flowfile: {e}\n\n" f"Try migrating: migrate_flowfile('{flow_path}')"
272
271
  ) from e
273
272
 
274
- elif suffix in ('.yaml', '.yml'):
273
+ elif suffix in (".yaml", ".yml"):
275
274
  return _load_flowfile_yaml(flow_path)
276
275
 
277
- elif suffix == '.json':
276
+ elif suffix == ".json":
278
277
  return _load_flowfile_json(flow_path)
279
278
  else:
280
279
  raise ValueError(f"Unsupported file format: {suffix}")
@@ -304,9 +303,8 @@ def open_flow(flow_path: Path) -> FlowGraph:
304
303
 
305
304
  # Determine node insertion order
306
305
  ingestion_order = determine_insertion_order(flow_storage_obj)
307
-
308
- # Create new FlowGraph
309
306
  new_flow = FlowGraph(name=flow_storage_obj.flow_name, flow_settings=flow_storage_obj.flow_settings)
307
+ # Create new FlowGraph
310
308
 
311
309
  # First pass: add node promises
312
310
  for node_id in ingestion_order:
@@ -316,9 +314,9 @@ def open_flow(flow_path: Path) -> FlowGraph:
316
314
  node_id=node_info.id,
317
315
  pos_x=node_info.x_position,
318
316
  pos_y=node_info.y_position,
319
- node_type=node_info.type
317
+ node_type=node_info.type,
320
318
  )
321
- if hasattr(node_info.setting_input, 'cache_results'):
319
+ if hasattr(node_info.setting_input, "cache_results"):
322
320
  node_promise.cache_results = node_info.setting_input.cache_results
323
321
  new_flow.add_node_promise(node_promise)
324
322
 
@@ -331,15 +329,14 @@ def open_flow(flow_path: Path) -> FlowGraph:
331
329
  user_defined_node_class = CUSTOM_NODE_STORE[node_info.type]
332
330
  new_flow.add_user_defined_node(
333
331
  custom_node=user_defined_node_class.from_settings(node_info.setting_input.settings),
334
- user_defined_node_settings=node_info.setting_input
332
+ user_defined_node_settings=node_info.setting_input,
335
333
  )
336
334
  else:
337
- getattr(new_flow, 'add_' + node_info.type)(node_info.setting_input)
335
+ getattr(new_flow, "add_" + node_info.type)(node_info.setting_input)
338
336
 
339
337
  # Setup connections
340
338
  from_node = new_flow.get_node(node_id)
341
- for output_node_id in (node_info.outputs or []):
342
-
339
+ for output_node_id in node_info.outputs or []:
343
340
  to_node = new_flow.get_node(output_node_id)
344
341
  if to_node is not None:
345
342
  output_node_obj = flow_storage_obj.data[output_node_id]
@@ -352,17 +349,17 @@ def open_flow(flow_path: Path) -> FlowGraph:
352
349
  is_main_input = node_id in (output_node_obj.input_ids or [])
353
350
 
354
351
  if is_left_input:
355
- insert_type = 'left'
352
+ insert_type = "left"
356
353
  elif is_right_input:
357
- insert_type = 'right'
354
+ insert_type = "right"
358
355
  elif is_main_input:
359
- insert_type = 'main'
356
+ insert_type = "main"
360
357
  else:
361
358
  continue
362
359
  to_node.add_node_connection(from_node, insert_type)
363
360
  else:
364
361
  from_node.delete_lead_to_node(output_node_id)
365
- if not (from_node.node_id, output_node_id) in flow_storage_obj.node_connections:
362
+ if (from_node.node_id, output_node_id) not in flow_storage_obj.node_connections:
366
363
  continue
367
364
  flow_storage_obj.node_connections.pop(
368
365
  flow_storage_obj.node_connections.index((from_node.node_id, output_node_id))
@@ -380,7 +377,7 @@ def open_flow(flow_path: Path) -> FlowGraph:
380
377
  return new_flow
381
378
 
382
379
 
383
- def test_if_circular_connection(connection: Tuple[int, int], flow: FlowGraph):
380
+ def test_if_circular_connection(connection: tuple[int, int], flow: FlowGraph):
384
381
  to_node = flow.get_node(connection[1])
385
382
  leads_to_nodes_queue = [n for n in to_node.leads_to_nodes]
386
383
  circular_connection: bool = False
@@ -8,40 +8,42 @@ custom nodes, define their UI, and implement their data processing logic.
8
8
  """
9
9
 
10
10
  # Import the core base class for creating a new node
11
+ # Import the main `Types` object for filtering in ColumnSelector
12
+ from flowfile_core.types import Types
13
+
11
14
  from .custom_node import CustomNodeBase, NodeSettings
12
15
 
13
16
  # Import all UI components so they can be used directly
14
17
  from .ui_components import (
18
+ AvailableSecrets,
19
+ ColumnSelector,
20
+ IncomingColumns,
21
+ MultiSelect,
22
+ NumericInput,
23
+ SecretSelector,
15
24
  Section,
25
+ SingleSelect,
26
+ SliderInput,
16
27
  TextInput,
17
- NumericInput,
18
28
  ToggleSwitch,
19
- SingleSelect,
20
- MultiSelect,
21
- ColumnSelector,
22
- IncomingColumns, # Important marker class for dynamic dropdowns
23
29
  )
24
30
 
25
- # Import the main `Types` object for filtering in ColumnSelector
26
- from flowfile_core.types import Types
27
-
28
-
29
31
  # Define the public API of this package
30
32
  __all__ = [
31
33
  # Core Node Class
32
34
  "CustomNodeBase",
33
-
34
35
  # UI Components & Layout
35
36
  "Section",
36
37
  "TextInput",
37
38
  "NumericInput",
39
+ "SliderInput",
38
40
  "ToggleSwitch",
39
41
  "SingleSelect",
40
42
  "MultiSelect",
41
43
  "NodeSettings",
42
44
  "ColumnSelector",
43
45
  "IncomingColumns",
44
-
45
- # Data Type Filtering
46
+ "AvailableSecrets",
47
+ "SecretSelector",
46
48
  "Types",
47
- ]
49
+ ]
@@ -5,18 +5,20 @@ This module should not be imported directly by users.
5
5
  """
6
6
 
7
7
  from dataclasses import dataclass
8
- from typing import Type, List, Dict, Set, Any
8
+ from typing import Any
9
+
9
10
  import polars as pl
10
11
 
11
12
  # Import public types
12
- from flowfile_core.types import TypeGroup, DataType
13
+ from flowfile_core.types import DataType, TypeGroup
13
14
 
14
15
 
15
16
  @dataclass(frozen=True)
16
17
  class TypeMapping:
17
18
  """Internal mapping between type representations."""
19
+
18
20
  data_type: DataType
19
- polars_type: Type[pl.DataType]
21
+ polars_type: type[pl.DataType]
20
22
  type_group: TypeGroup
21
23
  aliases: tuple[str, ...] = ()
22
24
 
@@ -28,42 +30,32 @@ class TypeRegistry:
28
30
  """
29
31
 
30
32
  def __init__(self):
31
- self._mappings: List[TypeMapping] = [
33
+ self._mappings: list[TypeMapping] = [
32
34
  # Numeric types
33
35
  TypeMapping(DataType.Int8, pl.Int8, TypeGroup.Numeric, ("i8",)),
34
36
  TypeMapping(DataType.Int16, pl.Int16, TypeGroup.Numeric, ("i16",)),
35
37
  TypeMapping(DataType.Int32, pl.Int32, TypeGroup.Numeric, ("i32", "int32")),
36
- TypeMapping(DataType.Int64, pl.Int64, TypeGroup.Numeric,
37
- ("i64", "int64", "int", "integer", "bigint")),
38
+ TypeMapping(DataType.Int64, pl.Int64, TypeGroup.Numeric, ("i64", "int64", "int", "integer", "bigint")),
38
39
  TypeMapping(DataType.UInt8, pl.UInt8, TypeGroup.Numeric, ("u8",)),
39
40
  TypeMapping(DataType.UInt16, pl.UInt16, TypeGroup.Numeric, ("u16",)),
40
41
  TypeMapping(DataType.UInt32, pl.UInt32, TypeGroup.Numeric, ("u32", "uint32")),
41
42
  TypeMapping(DataType.UInt64, pl.UInt64, TypeGroup.Numeric, ("u64", "uint64")),
42
43
  TypeMapping(DataType.Float32, pl.Float32, TypeGroup.Numeric, ("f32", "float32")),
43
- TypeMapping(DataType.Float64, pl.Float64, TypeGroup.Numeric,
44
- ("f64", "float64", "float", "double")),
45
- TypeMapping(DataType.Decimal, pl.Decimal, TypeGroup.Numeric,
46
- ("decimal", "numeric", "dec")),
47
-
44
+ TypeMapping(DataType.Float64, pl.Float64, TypeGroup.Numeric, ("f64", "float64", "float", "double")),
45
+ TypeMapping(DataType.Decimal, pl.Decimal, TypeGroup.Numeric, ("decimal", "dec")),
48
46
  # String types
49
- TypeMapping(DataType.String, pl.String, TypeGroup.String,
50
- ("str", "string", "utf8", "varchar", "text")),
51
- TypeMapping(DataType.Categorical, pl.Categorical, TypeGroup.String,
52
- ("cat", "categorical", "enum", "factor")),
53
-
47
+ TypeMapping(DataType.String, pl.String, TypeGroup.String, ("str", "string", "utf8", "varchar", "text")),
48
+ TypeMapping(
49
+ DataType.Categorical, pl.Categorical, TypeGroup.String, ("cat", "categorical", "enum", "factor")
50
+ ),
54
51
  # Date types
55
52
  TypeMapping(DataType.Date, pl.Date, TypeGroup.Date, ("date",)),
56
- TypeMapping(DataType.Datetime, pl.Datetime, TypeGroup.Date,
57
- ("datetime", "timestamp")),
53
+ TypeMapping(DataType.Datetime, pl.Datetime, TypeGroup.Date, ("datetime", "timestamp")),
58
54
  TypeMapping(DataType.Time, pl.Time, TypeGroup.Date, ("time",)),
59
- TypeMapping(DataType.Duration, pl.Duration, TypeGroup.Date,
60
- ("duration", "timedelta")),
61
-
55
+ TypeMapping(DataType.Duration, pl.Duration, TypeGroup.Date, ("duration", "timedelta")),
62
56
  # Other types
63
- TypeMapping(DataType.Boolean, pl.Boolean, TypeGroup.Boolean,
64
- ("bool", "boolean")),
65
- TypeMapping(DataType.Binary, pl.Binary, TypeGroup.Binary,
66
- ("binary", "bytes", "bytea")),
57
+ TypeMapping(DataType.Boolean, pl.Boolean, TypeGroup.Boolean, ("bool", "boolean")),
58
+ TypeMapping(DataType.Binary, pl.Binary, TypeGroup.Binary, ("binary", "bytes", "bytea")),
67
59
  TypeMapping(DataType.List, pl.List, TypeGroup.Complex, ("list", "array")),
68
60
  TypeMapping(DataType.Struct, pl.Struct, TypeGroup.Complex, ("struct", "object")),
69
61
  TypeMapping(DataType.Array, pl.Array, TypeGroup.Complex, ("fixed_array",)),
@@ -73,10 +65,10 @@ class TypeRegistry:
73
65
 
74
66
  def _build_indices(self):
75
67
  """Build lookup indices for fast access."""
76
- self._by_data_type: Dict[DataType, TypeMapping] = {}
77
- self._by_polars_type: Dict[Type[pl.DataType], TypeMapping] = {}
78
- self._by_alias: Dict[str, TypeMapping] = {}
79
- self._by_group: Dict[TypeGroup, List[TypeMapping]] = {g: [] for g in TypeGroup}
68
+ self._by_data_type: dict[DataType, TypeMapping] = {}
69
+ self._by_polars_type: dict[type[pl.DataType], TypeMapping] = {}
70
+ self._by_alias: dict[str, TypeMapping] = {}
71
+ self._by_group: dict[TypeGroup, list[TypeMapping]] = {g: [] for g in TypeGroup}
80
72
 
81
73
  for mapping in self._mappings:
82
74
  self._by_data_type[mapping.data_type] = mapping
@@ -96,12 +88,13 @@ class TypeRegistry:
96
88
  # Register "pl.TypeName" format
97
89
  self._by_alias[f"pl.{mapping.polars_type.__name__}".lower()] = mapping
98
90
 
99
- def normalize(self, type_spec: Any) -> Set[DataType]:
91
+ def normalize(self, type_spec: Any) -> set[DataType]:
100
92
  """
101
93
  Normalize any type specification to a set of DataType enums.
102
94
  This is the main internal API for type resolution.
103
95
  """
104
96
  # Handle special case: All types
97
+
105
98
  if type_spec == TypeGroup.All or type_spec == "ALL":
106
99
  return set(self._by_data_type.keys())
107
100
 
@@ -121,7 +114,7 @@ class TypeRegistry:
121
114
 
122
115
  # Handle Polars type instance
123
116
  if isinstance(type_spec, pl.DataType):
124
- base_type = type_spec.base_type() if hasattr(type_spec, 'base_type') else type(type_spec)
117
+ base_type = type_spec.base_type() if hasattr(type_spec, "base_type") else type(type_spec)
125
118
  mapping = self._by_polars_type.get(base_type)
126
119
  if mapping:
127
120
  return {mapping.data_type}
@@ -129,6 +122,10 @@ class TypeRegistry:
129
122
  # Handle string aliases
130
123
  if isinstance(type_spec, str):
131
124
  type_spec_lower = type_spec.lower()
125
+ group: TypeGroup
126
+ for group in TypeGroup:
127
+ if group.lower() == type_spec_lower:
128
+ return {m.data_type for m in (self._by_group.get(group) or [])}
132
129
 
133
130
  # Try TypeGroup name
134
131
  try:
@@ -152,14 +149,14 @@ class TypeRegistry:
152
149
  # Default to empty set if unrecognized
153
150
  return set()
154
151
 
155
- def normalize_list(self, type_specs: List[Any]) -> Set[DataType]:
152
+ def normalize_list(self, type_specs: list[Any]) -> set[DataType]:
156
153
  """Normalize a list of type specifications."""
157
154
  result = set()
158
155
  for spec in type_specs:
159
156
  result.update(self.normalize(spec))
160
157
  return result
161
158
 
162
- def get_polars_types(self, data_types: Set[DataType]) -> Set[Type[pl.DataType]]:
159
+ def get_polars_types(self, data_types: set[DataType]) -> set[type[pl.DataType]]:
163
160
  """Convert a set of DataType enums to Polars types."""
164
161
  result = set()
165
162
  for dt in data_types:
@@ -168,7 +165,7 @@ class TypeRegistry:
168
165
  result.add(mapping.polars_type)
169
166
  return result
170
167
 
171
- def get_polars_type(self, data_type: DataType) -> Type[pl.DataType]:
168
+ def get_polars_type(self, data_type: DataType) -> type[pl.DataType]:
172
169
  """Get the Polars type for a single DataType."""
173
170
  mapping = self._by_data_type.get(data_type)
174
171
  return mapping.polars_type if mapping else pl.String # Default fallback
@@ -179,19 +176,19 @@ _registry = TypeRegistry()
179
176
 
180
177
 
181
178
  # Internal API functions (not for public use)
182
- def normalize_type_spec(type_spec: Any) -> Set[DataType]:
179
+ def normalize_type_spec(type_spec: Any) -> set[DataType]:
183
180
  """Internal function to normalize type specifications."""
184
181
  if isinstance(type_spec, list):
185
182
  return _registry.normalize_list(type_spec)
186
183
  return _registry.normalize(type_spec)
187
184
 
188
185
 
189
- def get_polars_types(data_types: Set[DataType]) -> Set[Type[pl.DataType]]:
186
+ def get_polars_types(data_types: set[DataType]) -> set[type[pl.DataType]]:
190
187
  """Internal function to get Polars types."""
191
188
  return _registry.get_polars_types(data_types)
192
189
 
193
190
 
194
- def check_column_type(column_dtype: pl.DataType, accepted_types: Set[DataType]) -> bool:
191
+ def check_column_type(column_dtype: pl.DataType, accepted_types: set[DataType]) -> bool:
195
192
  """Check if a column's dtype matches the accepted types."""
196
193
  normalized = _registry.normalize(column_dtype)
197
194
  return bool(normalized & accepted_types)