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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. flowfile/__init__.py +8 -1
  2. flowfile/api.py +1 -3
  3. flowfile/web/static/assets/{CloudConnectionManager-c97c25f8.js → CloudConnectionManager-0dfba9f2.js} +2 -2
  4. flowfile/web/static/assets/{CloudStorageReader-f1ff509e.js → CloudStorageReader-d5b1b6c9.js} +11 -78
  5. flowfile/web/static/assets/{CloudStorageWriter-034f8b78.js → CloudStorageWriter-00d87aad.js} +12 -79
  6. flowfile/web/static/assets/{CloudStorageWriter-49c9a4b2.css → CloudStorageWriter-b0ee067f.css} +24 -24
  7. flowfile/web/static/assets/ColumnSelector-4685e75d.js +83 -0
  8. flowfile/web/static/assets/ColumnSelector-47996a16.css +10 -0
  9. flowfile/web/static/assets/ContextMenu-23e909da.js +41 -0
  10. flowfile/web/static/assets/{SettingsSection-9c836ecc.css → ContextMenu-4c74eef1.css} +0 -21
  11. flowfile/web/static/assets/ContextMenu-63cfa99b.css +26 -0
  12. flowfile/web/static/assets/ContextMenu-70ae0c79.js +41 -0
  13. flowfile/web/static/assets/ContextMenu-c13f91d0.css +26 -0
  14. flowfile/web/static/assets/ContextMenu-f149cf7c.js +41 -0
  15. flowfile/web/static/assets/{CrossJoin-41efa4cb.css → CrossJoin-1119d18e.css} +18 -18
  16. flowfile/web/static/assets/{CrossJoin-9e156ebe.js → CrossJoin-702a3edd.js} +14 -84
  17. flowfile/web/static/assets/CustomNode-74a37f74.css +32 -0
  18. flowfile/web/static/assets/CustomNode-b1519993.js +211 -0
  19. flowfile/web/static/assets/{DatabaseConnectionSettings-d5c625b3.js → DatabaseConnectionSettings-6f3e4ea5.js} +3 -3
  20. flowfile/web/static/assets/{DatabaseManager-265adc5e.js → DatabaseManager-cf5ef661.js} +2 -2
  21. flowfile/web/static/assets/{DatabaseReader-f50c6558.css → DatabaseReader-ae61773c.css} +0 -27
  22. flowfile/web/static/assets/{DatabaseReader-0b10551e.js → DatabaseReader-d38c7295.js} +14 -114
  23. flowfile/web/static/assets/{DatabaseWriter-c17c6916.js → DatabaseWriter-b04ef46a.js} +13 -74
  24. flowfile/web/static/assets/{ExploreData-5bdae813.css → ExploreData-2d0cf4db.css} +8 -14
  25. flowfile/web/static/assets/ExploreData-5fa10ed8.js +192 -0
  26. flowfile/web/static/assets/{ExternalSource-3a66556c.js → ExternalSource-d39af878.js} +8 -79
  27. flowfile/web/static/assets/{Filter-91ad87e7.js → Filter-9b6d08db.js} +12 -85
  28. flowfile/web/static/assets/{Filter-a9d08ba1.css → Filter-f62091b3.css} +3 -3
  29. flowfile/web/static/assets/{Formula-3c395ab1.js → Formula-6b04fb1d.js} +20 -87
  30. flowfile/web/static/assets/{Formula-29f19d21.css → Formula-bb96803d.css} +4 -4
  31. flowfile/web/static/assets/{FuzzyMatch-6857de82.css → FuzzyMatch-1010f966.css} +42 -42
  32. flowfile/web/static/assets/{FuzzyMatch-2df0d230.js → FuzzyMatch-999521f4.js} +16 -87
  33. flowfile/web/static/assets/{GraphSolver-d285877f.js → GraphSolver-17dd2198.js} +13 -159
  34. flowfile/web/static/assets/GraphSolver-f0cb7bfb.css +22 -0
  35. flowfile/web/static/assets/{GroupBy-0bd1cc6b.js → GroupBy-6b039e18.js} +12 -75
  36. flowfile/web/static/assets/{Unique-b5615727.css → GroupBy-b9505323.css} +8 -8
  37. flowfile/web/static/assets/{Join-5a78a203.js → Join-24d0f113.js} +15 -85
  38. flowfile/web/static/assets/{Join-f45eff22.css → Join-fd79b451.css} +20 -20
  39. flowfile/web/static/assets/{ManualInput-a71b52c6.css → ManualInput-3246a08d.css} +20 -20
  40. flowfile/web/static/assets/{ManualInput-93aef9d6.js → ManualInput-34639209.js} +11 -82
  41. flowfile/web/static/assets/MultiSelect-0e8724a3.js +5 -0
  42. flowfile/web/static/assets/MultiSelect.vue_vue_type_script_setup_true_lang-b0e538c2.js +63 -0
  43. flowfile/web/static/assets/NumericInput-3d63a470.js +5 -0
  44. flowfile/web/static/assets/NumericInput.vue_vue_type_script_setup_true_lang-e0edeccc.js +35 -0
  45. flowfile/web/static/assets/Output-283fe388.css +37 -0
  46. flowfile/web/static/assets/{Output-411ecaee.js → Output-edea9802.js} +62 -273
  47. flowfile/web/static/assets/{Pivot-89db4b04.js → Pivot-61d19301.js} +14 -138
  48. flowfile/web/static/assets/Pivot-cf333e3d.css +22 -0
  49. flowfile/web/static/assets/PivotValidation-891ddfb0.css +13 -0
  50. flowfile/web/static/assets/PivotValidation-c46cd420.css +13 -0
  51. flowfile/web/static/assets/PivotValidation-de9f43fe.js +61 -0
  52. flowfile/web/static/assets/PivotValidation-f97fec5b.js +61 -0
  53. flowfile/web/static/assets/{PolarsCode-a9f974f8.js → PolarsCode-bc3c9984.js} +13 -80
  54. flowfile/web/static/assets/Read-64a3f259.js +218 -0
  55. flowfile/web/static/assets/Read-e808b239.css +62 -0
  56. flowfile/web/static/assets/RecordCount-3d5039be.js +53 -0
  57. flowfile/web/static/assets/{RecordId-55ae7d36.js → RecordId-597510e0.js} +8 -80
  58. flowfile/web/static/assets/SQLQueryComponent-36cef432.css +27 -0
  59. flowfile/web/static/assets/SQLQueryComponent-df51adbe.js +38 -0
  60. flowfile/web/static/assets/{Sample-b4a18476.js → Sample-4be0a507.js} +8 -77
  61. flowfile/web/static/assets/{SecretManager-b066d13a.js → SecretManager-4839be57.js} +2 -2
  62. flowfile/web/static/assets/{Select-727688dc.js → Select-9b72f201.js} +11 -85
  63. flowfile/web/static/assets/SettingsSection-2e4d03c4.css +21 -0
  64. flowfile/web/static/assets/SettingsSection-5c696bee.css +20 -0
  65. flowfile/web/static/assets/SettingsSection-71e6b7e3.css +21 -0
  66. flowfile/web/static/assets/SettingsSection-7ded385d.js +45 -0
  67. flowfile/web/static/assets/{SettingsSection-695ac487.js → SettingsSection-e1e9c953.js} +2 -40
  68. flowfile/web/static/assets/SettingsSection-f0f75a42.js +53 -0
  69. flowfile/web/static/assets/SingleSelect-6c777aac.js +5 -0
  70. flowfile/web/static/assets/SingleSelect.vue_vue_type_script_setup_true_lang-33e3ff9b.js +62 -0
  71. flowfile/web/static/assets/SliderInput-7cb93e62.js +40 -0
  72. flowfile/web/static/assets/SliderInput-b8fb6a8c.css +4 -0
  73. flowfile/web/static/assets/{GroupBy-ab1ea74b.css → Sort-3643d625.css} +8 -8
  74. flowfile/web/static/assets/{Sort-be3339a8.js → Sort-6cbde21a.js} +12 -97
  75. flowfile/web/static/assets/TextInput-d9a40c11.js +5 -0
  76. flowfile/web/static/assets/TextInput.vue_vue_type_script_setup_true_lang-5896c375.js +32 -0
  77. flowfile/web/static/assets/{TextToRows-c92d1ec2.css → TextToRows-5d2c1190.css} +9 -9
  78. flowfile/web/static/assets/{TextToRows-7b8998da.js → TextToRows-c4fcbf4d.js} +14 -83
  79. flowfile/web/static/assets/ToggleSwitch-4ef91d19.js +5 -0
  80. flowfile/web/static/assets/ToggleSwitch.vue_vue_type_script_setup_true_lang-38478c20.js +31 -0
  81. flowfile/web/static/assets/{UnavailableFields-8b0cb48e.js → UnavailableFields-a03f512c.js} +2 -2
  82. flowfile/web/static/assets/{Union-8d9ac7f9.css → Union-af6c3d9b.css} +6 -6
  83. flowfile/web/static/assets/Union-bfe9b996.js +77 -0
  84. flowfile/web/static/assets/{Unique-af5a80b4.js → Unique-5d023a27.js} +23 -104
  85. flowfile/web/static/assets/{Sort-7ccfa0fe.css → Unique-f9fb0809.css} +8 -8
  86. flowfile/web/static/assets/Unpivot-1e422df3.css +30 -0
  87. flowfile/web/static/assets/{Unpivot-5195d411.js → Unpivot-91cc5354.js} +12 -166
  88. flowfile/web/static/assets/UnpivotValidation-0d240eeb.css +13 -0
  89. flowfile/web/static/assets/UnpivotValidation-7ee2de44.js +51 -0
  90. flowfile/web/static/assets/{ExploreData-18a4fe52.js → VueGraphicWalker-e51b9924.js} +4 -264
  91. flowfile/web/static/assets/VueGraphicWalker-ed5ab88b.css +6 -0
  92. flowfile/web/static/assets/{api-cb00cce6.js → api-c1bad5ca.js} +1 -1
  93. flowfile/web/static/assets/{api-023d1733.js → api-cf1221f0.js} +1 -1
  94. flowfile/web/static/assets/{designer-2197d782.css → designer-8da3ba3a.css} +859 -201
  95. flowfile/web/static/assets/{designer-6c322d8e.js → designer-9633482a.js} +2297 -733
  96. flowfile/web/static/assets/{documentation-4d1fafe1.js → documentation-ca400224.js} +1 -1
  97. flowfile/web/static/assets/{dropDown-0b46dd77.js → dropDown-614b998d.js} +1 -1
  98. flowfile/web/static/assets/{fullEditor-ec4e4f95.js → fullEditor-f7971590.js} +2 -2
  99. flowfile/web/static/assets/{genericNodeSettings-def5879b.js → genericNodeSettings-4fe5f36b.js} +3 -3
  100. flowfile/web/static/assets/{index-681a3ed0.css → index-50508d4d.css} +8 -0
  101. flowfile/web/static/assets/{index-683fc198.js → index-5429bbf8.js} +208 -31
  102. flowfile/web/static/assets/nodeInput-5d0d6b79.js +41 -0
  103. flowfile/web/static/assets/outputCsv-076b85ab.js +86 -0
  104. flowfile/web/static/assets/{Output-48f81019.css → outputCsv-9cc59e0b.css} +0 -143
  105. flowfile/web/static/assets/outputExcel-0fd17dbe.js +56 -0
  106. flowfile/web/static/assets/outputExcel-b41305c0.css +102 -0
  107. flowfile/web/static/assets/outputParquet-b61e0847.js +31 -0
  108. flowfile/web/static/assets/outputParquet-cf8cf3f2.css +4 -0
  109. flowfile/web/static/assets/readCsv-a8bb8b61.js +179 -0
  110. flowfile/web/static/assets/readCsv-c767cb37.css +52 -0
  111. flowfile/web/static/assets/readExcel-67b4aee0.js +201 -0
  112. flowfile/web/static/assets/readExcel-806d2826.css +64 -0
  113. flowfile/web/static/assets/readParquet-48c81530.css +19 -0
  114. flowfile/web/static/assets/readParquet-92ce1dbc.js +23 -0
  115. flowfile/web/static/assets/{secretApi-baceb6f9.js → secretApi-68435402.js} +1 -1
  116. flowfile/web/static/assets/{selectDynamic-de91449a.js → selectDynamic-92e25ee3.js} +7 -7
  117. flowfile/web/static/assets/{selectDynamic-b062bc9b.css → selectDynamic-aa913ff4.css} +16 -16
  118. flowfile/web/static/assets/user-defined-icon-0ae16c90.png +0 -0
  119. flowfile/web/static/assets/{vue-codemirror.esm-dc5e3348.js → vue-codemirror.esm-41b0e0d7.js} +65 -36
  120. flowfile/web/static/assets/{vue-content-loader.es-ba94b82f.js → vue-content-loader.es-2c8e608f.js} +1 -1
  121. flowfile/web/static/index.html +2 -2
  122. {flowfile-0.3.9.dist-info → flowfile-0.5.1.dist-info}/METADATA +5 -3
  123. {flowfile-0.3.9.dist-info → flowfile-0.5.1.dist-info}/RECORD +191 -121
  124. {flowfile-0.3.9.dist-info → flowfile-0.5.1.dist-info}/WHEEL +1 -1
  125. {flowfile-0.3.9.dist-info → flowfile-0.5.1.dist-info}/entry_points.txt +1 -0
  126. flowfile_core/__init__.py +3 -0
  127. flowfile_core/configs/flow_logger.py +5 -13
  128. flowfile_core/configs/node_store/__init__.py +30 -0
  129. flowfile_core/configs/node_store/nodes.py +383 -99
  130. flowfile_core/configs/node_store/user_defined_node_registry.py +193 -0
  131. flowfile_core/configs/settings.py +2 -1
  132. flowfile_core/database/connection.py +5 -21
  133. flowfile_core/fileExplorer/funcs.py +239 -121
  134. flowfile_core/flowfile/analytics/analytics_processor.py +1 -0
  135. flowfile_core/flowfile/code_generator/code_generator.py +62 -64
  136. flowfile_core/flowfile/flow_data_engine/create/funcs.py +73 -56
  137. flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +77 -86
  138. flowfile_core/flowfile/flow_data_engine/flow_file_column/interface.py +4 -0
  139. flowfile_core/flowfile/flow_data_engine/flow_file_column/main.py +19 -34
  140. flowfile_core/flowfile/flow_data_engine/flow_file_column/type_registry.py +36 -0
  141. flowfile_core/flowfile/flow_data_engine/fuzzy_matching/prepare_for_fuzzy_match.py +23 -23
  142. flowfile_core/flowfile/flow_data_engine/join/utils.py +1 -1
  143. flowfile_core/flowfile/flow_data_engine/join/verify_integrity.py +9 -4
  144. flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +212 -86
  145. flowfile_core/flowfile/flow_data_engine/utils.py +2 -0
  146. flowfile_core/flowfile/flow_graph.py +240 -54
  147. flowfile_core/flowfile/flow_node/flow_node.py +48 -13
  148. flowfile_core/flowfile/flow_node/models.py +2 -1
  149. flowfile_core/flowfile/handler.py +24 -5
  150. flowfile_core/flowfile/manage/compatibility_enhancements.py +404 -41
  151. flowfile_core/flowfile/manage/io_flowfile.py +394 -0
  152. flowfile_core/flowfile/node_designer/__init__.py +47 -0
  153. flowfile_core/flowfile/node_designer/_type_registry.py +197 -0
  154. flowfile_core/flowfile/node_designer/custom_node.py +371 -0
  155. flowfile_core/flowfile/node_designer/ui_components.py +277 -0
  156. flowfile_core/flowfile/schema_callbacks.py +17 -10
  157. flowfile_core/flowfile/setting_generator/settings.py +15 -10
  158. flowfile_core/main.py +5 -1
  159. flowfile_core/routes/routes.py +73 -30
  160. flowfile_core/routes/user_defined_components.py +55 -0
  161. flowfile_core/schemas/cloud_storage_schemas.py +0 -2
  162. flowfile_core/schemas/input_schema.py +228 -65
  163. flowfile_core/schemas/output_model.py +5 -2
  164. flowfile_core/schemas/schemas.py +153 -35
  165. flowfile_core/schemas/transform_schema.py +1083 -412
  166. flowfile_core/schemas/yaml_types.py +103 -0
  167. flowfile_core/types.py +156 -0
  168. flowfile_core/utils/validate_setup.py +3 -1
  169. flowfile_frame/__init__.py +3 -1
  170. flowfile_frame/flow_frame.py +31 -24
  171. flowfile_frame/flow_frame_methods.py +12 -9
  172. flowfile_worker/__init__.py +9 -35
  173. flowfile_worker/create/__init__.py +3 -21
  174. flowfile_worker/create/funcs.py +68 -56
  175. flowfile_worker/create/models.py +130 -62
  176. flowfile_worker/main.py +5 -2
  177. flowfile_worker/routes.py +52 -13
  178. shared/__init__.py +15 -0
  179. shared/storage_config.py +258 -0
  180. tools/migrate/README.md +56 -0
  181. tools/migrate/__init__.py +12 -0
  182. tools/migrate/__main__.py +131 -0
  183. tools/migrate/legacy_schemas.py +621 -0
  184. tools/migrate/migrate.py +598 -0
  185. tools/migrate/tests/__init__.py +0 -0
  186. tools/migrate/tests/conftest.py +23 -0
  187. tools/migrate/tests/test_migrate.py +627 -0
  188. tools/migrate/tests/test_migration_e2e.py +1010 -0
  189. tools/migrate/tests/test_node_migrations.py +813 -0
  190. flowfile/web/static/assets/GraphSolver-17fd26db.css +0 -68
  191. flowfile/web/static/assets/Pivot-f415e85f.css +0 -35
  192. flowfile/web/static/assets/Read-80dc1675.css +0 -197
  193. flowfile/web/static/assets/Read-c3b1929c.js +0 -701
  194. flowfile/web/static/assets/RecordCount-4e95f98e.js +0 -122
  195. flowfile/web/static/assets/Union-89fd73dc.js +0 -146
  196. flowfile/web/static/assets/Unpivot-246e9bbd.css +0 -77
  197. flowfile/web/static/assets/nodeTitle-a16db7c3.js +0 -227
  198. flowfile/web/static/assets/nodeTitle-f4b12bcb.css +0 -134
  199. flowfile_core/flowfile/manage/open_flowfile.py +0 -135
  200. {flowfile-0.3.9.dist-info → flowfile-0.5.1.dist-info/licenses}/LICENSE +0 -0
  201. /flowfile_core/flowfile/manage/manage_flowfile.py → /tools/__init__.py +0 -0
@@ -0,0 +1,621 @@
1
+ """
2
+ Legacy schema definitions for loading old flowfile pickles.
3
+
4
+ These definitions mirror the OLD schema structure BEFORE the migration to the new
5
+ discriminated union table_settings format.
6
+
7
+ OLD structure:
8
+ - ReceivedTable: All fields flat (delimiter, encoding, sheet_name all at top level)
9
+ - OutputSettings: Separate output_csv_table, output_parquet_table, output_excel_table fields
10
+
11
+ NEW structure:
12
+ - ReceivedTable: Has nested table_settings with discriminated union
13
+ - OutputSettings: Has single table_settings field with discriminated union
14
+
15
+ DO NOT USE THESE IN PRODUCTION CODE - use the actual schemas from flowfile_core.
16
+ """
17
+
18
+ from dataclasses import dataclass, field
19
+ from typing import List, Optional, Set, Any, Literal, Dict, Tuple
20
+ from pydantic import BaseModel, Field
21
+
22
+
23
+ # =============================================================================
24
+ # OLD INPUT/OUTPUT SCHEMAS (before table_settings migration)
25
+ # These mirror the structure that exists in old pickle files
26
+ # =============================================================================
27
+
28
+ class MinimalFieldInfo(BaseModel):
29
+ """Represents the most basic information about a data field (column)."""
30
+ name: str
31
+ data_type: str = "String"
32
+
33
+
34
+ class OutputCsvTable(BaseModel):
35
+ """OLD: Settings for writing a CSV file."""
36
+ file_type: str = 'csv'
37
+ delimiter: str = ','
38
+ encoding: str = 'utf-8'
39
+
40
+
41
+ class OutputParquetTable(BaseModel):
42
+ """OLD: Settings for writing a Parquet file."""
43
+ file_type: str = 'parquet'
44
+
45
+
46
+ class OutputExcelTable(BaseModel):
47
+ """OLD: Settings for writing an Excel file."""
48
+ file_type: str = 'excel'
49
+ sheet_name: str = 'Sheet1'
50
+
51
+
52
+ class OutputSettings(BaseModel):
53
+ """OLD OutputSettings structure with SEPARATE table fields.
54
+
55
+ This is the OLD format where CSV, Parquet, and Excel settings
56
+ were stored in separate fields rather than a unified table_settings.
57
+ """
58
+ name: str
59
+ directory: str
60
+ file_type: str
61
+ fields: Optional[List[str]] = Field(default_factory=list)
62
+ write_mode: str = 'overwrite'
63
+ # OLD: Separate fields for each output type
64
+ output_csv_table: Optional[OutputCsvTable] = Field(default_factory=OutputCsvTable)
65
+ output_parquet_table: OutputParquetTable = Field(default_factory=OutputParquetTable)
66
+ output_excel_table: OutputExcelTable = Field(default_factory=OutputExcelTable)
67
+ abs_file_path: Optional[str] = None
68
+
69
+
70
+ class ReceivedTable(BaseModel):
71
+ """OLD ReceivedTable structure with FLAT fields.
72
+
73
+ This is the OLD format where all settings (CSV, Excel, Parquet)
74
+ were stored as flat fields on the model rather than nested in table_settings.
75
+ """
76
+ # Metadata fields
77
+ id: Optional[int] = None
78
+ name: Optional[str] = None
79
+ path: str = ''
80
+ directory: Optional[str] = None
81
+ analysis_file_available: bool = False
82
+ status: Optional[str] = None
83
+ file_type: Optional[str] = None
84
+ fields: List[MinimalFieldInfo] = Field(default_factory=list)
85
+ abs_file_path: Optional[str] = None
86
+
87
+ # OLD: CSV/JSON fields at top level (not nested)
88
+ reference: str = ''
89
+ starting_from_line: int = 0
90
+ delimiter: str = ','
91
+ has_headers: bool = True
92
+ encoding: Optional[str] = 'utf-8'
93
+ parquet_ref: Optional[str] = None
94
+ row_delimiter: str = '\n'
95
+ quote_char: str = '"'
96
+ infer_schema_length: int = 10_000
97
+ truncate_ragged_lines: bool = False
98
+ ignore_errors: bool = False
99
+
100
+ # OLD: Excel fields at top level (not nested)
101
+ sheet_name: Optional[str] = None
102
+ start_row: int = 0
103
+ start_column: int = 0
104
+ end_row: int = 0
105
+ end_column: int = 0
106
+ type_inference: bool = False
107
+
108
+
109
+ # =============================================================================
110
+ # FLOW AND NODE SCHEMAS (Pydantic - structure unchanged, just re-exported)
111
+ # =============================================================================
112
+
113
+ class FlowGraphConfig(BaseModel):
114
+ """Configuration model for a flow graph's basic properties."""
115
+ flow_id: int = 1
116
+ description: Optional[str] = None
117
+ save_location: Optional[str] = None
118
+ name: str = ''
119
+ path: str = ''
120
+ execution_mode: str = 'Performance'
121
+ execution_location: str = 'local'
122
+
123
+
124
+ class FlowSettings(FlowGraphConfig):
125
+ """Extends FlowGraphConfig with additional operational settings."""
126
+ auto_save: bool = False
127
+ modified_on: Optional[float] = None
128
+ show_detailed_progress: bool = True
129
+ is_running: bool = False
130
+ is_canceled: bool = False
131
+
132
+
133
+ class NodeBase(BaseModel):
134
+ """Base model for all nodes in a FlowGraph."""
135
+ flow_id: int
136
+ node_id: int
137
+ cache_results: Optional[bool] = False
138
+ pos_x: Optional[float] = 0
139
+ pos_y: Optional[float] = 0
140
+ is_setup: Optional[bool] = True
141
+ description: Optional[str] = ''
142
+ user_id: Optional[int] = None
143
+ is_flow_output: Optional[bool] = False
144
+ is_user_defined: Optional[bool] = False
145
+
146
+
147
+ class NodeSingleInput(NodeBase):
148
+ """A base model for any node that takes a single data input."""
149
+ depending_on_id: Optional[int] = -1
150
+
151
+
152
+ class NodeMultiInput(NodeBase):
153
+ """A base model for any node that takes multiple data inputs."""
154
+ depending_on_ids: Optional[List[int]] = Field(default_factory=lambda: [-1])
155
+
156
+
157
+ class NodeRead(NodeBase):
158
+ """Settings for a node that reads data from a file."""
159
+ received_file: ReceivedTable
160
+
161
+
162
+ class NodeSelect(NodeSingleInput):
163
+ """Settings for a node that selects, renames, and reorders columns."""
164
+ keep_missing: bool = True
165
+ select_input: List[Any] = Field(default_factory=list)
166
+ sorted_by: Optional[str] = 'none'
167
+
168
+
169
+ class NodeFilter(NodeSingleInput):
170
+ """Settings for a node that filters rows based on a condition."""
171
+ filter_input: Any = None
172
+
173
+
174
+ class NodeFormula(NodeSingleInput):
175
+ """Settings for a node that applies a formula to create/modify a column."""
176
+ function: Any = None
177
+
178
+
179
+ class NodeJoin(NodeMultiInput):
180
+ """Settings for a node that performs a standard SQL-style join."""
181
+ auto_generate_selection: bool = True
182
+ verify_integrity: bool = True
183
+ join_input: Any = None
184
+ auto_keep_all: bool = True
185
+ auto_keep_right: bool = True
186
+ auto_keep_left: bool = True
187
+
188
+
189
+ class NodeCrossJoin(NodeMultiInput):
190
+ """Settings for a node that performs a cross join."""
191
+ auto_generate_selection: bool = True
192
+ verify_integrity: bool = True
193
+ cross_join_input: Any = None
194
+ auto_keep_all: bool = True
195
+ auto_keep_right: bool = True
196
+ auto_keep_left: bool = True
197
+
198
+
199
+ class NodeFuzzyMatch(NodeMultiInput):
200
+ """Settings for a node that performs a fuzzy join."""
201
+ auto_generate_selection: bool = True
202
+ verify_integrity: bool = True
203
+ join_input: Any = None # FuzzyMatchInput
204
+ auto_keep_all: bool = True
205
+ auto_keep_right: bool = True
206
+ auto_keep_left: bool = True
207
+
208
+
209
+ class NodePolarsCode(NodeMultiInput):
210
+ """Settings for a node that executes arbitrary Polars code."""
211
+ polars_code_input: Any = None
212
+
213
+
214
+ class NodeOutput(NodeSingleInput):
215
+ """Settings for a node that writes its input to a file."""
216
+ output_settings: OutputSettings
217
+
218
+
219
+ class NodeGroupBy(NodeSingleInput):
220
+ """Settings for a node that performs a group-by and aggregation."""
221
+ groupby_input: Any = None
222
+
223
+
224
+ class NodeSort(NodeSingleInput):
225
+ """Settings for a node that sorts the data."""
226
+ sort_input: List[Any] = Field(default_factory=list)
227
+
228
+
229
+ class NodeUnion(NodeMultiInput):
230
+ """Settings for a node that concatenates multiple inputs."""
231
+ union_input: Any = None
232
+
233
+
234
+ class NodeUnique(NodeSingleInput):
235
+ """Settings for a node that returns unique rows."""
236
+ unique_input: Any = None
237
+
238
+
239
+ class NodePivot(NodeSingleInput):
240
+ """Settings for a node that pivots data."""
241
+ pivot_input: Any = None
242
+ output_fields: Optional[List[MinimalFieldInfo]] = None
243
+
244
+
245
+ class NodeUnpivot(NodeSingleInput):
246
+ """Settings for a node that unpivots data."""
247
+ unpivot_input: Any = None
248
+
249
+
250
+ class NodeRecordId(NodeSingleInput):
251
+ """Settings for adding a record ID column."""
252
+ record_id_input: Any = None
253
+
254
+
255
+ class NodeTextToRows(NodeSingleInput):
256
+ """Settings for splitting text into rows."""
257
+ text_to_rows_input: Any = None
258
+
259
+
260
+ class NodeGraphSolver(NodeSingleInput):
261
+ """Settings for graph-solving operations."""
262
+ graph_solver_input: Any = None
263
+
264
+
265
+ class NodeSample(NodeSingleInput):
266
+ """Settings for sampling data."""
267
+ sample_size: int = 1000
268
+
269
+
270
+ class NodePromise(NodeBase):
271
+ """A placeholder node not yet configured."""
272
+ is_setup: bool = False
273
+ node_type: str = ''
274
+
275
+
276
+ class DatabaseConnection(BaseModel):
277
+ """Defines database connection parameters."""
278
+ database_type: str = "postgresql"
279
+ username: Optional[str] = None
280
+ password_ref: Optional[str] = None
281
+ host: Optional[str] = None
282
+ port: Optional[int] = None
283
+ database: Optional[str] = None
284
+ url: Optional[str] = None
285
+
286
+
287
+ class DatabaseSettings(BaseModel):
288
+ """Defines settings for reading from a database."""
289
+ connection_mode: Optional[str] = 'inline'
290
+ database_connection: Optional[DatabaseConnection] = None
291
+ database_connection_name: Optional[str] = None
292
+ schema_name: Optional[str] = None
293
+ table_name: Optional[str] = None
294
+ query: Optional[str] = None
295
+ query_mode: str = 'table'
296
+
297
+
298
+ class NodeDatabaseReader(NodeBase):
299
+ """Settings for reading from a database."""
300
+ database_settings: DatabaseSettings
301
+ fields: Optional[List[MinimalFieldInfo]] = None
302
+
303
+
304
+ class NodeInformation(BaseModel):
305
+ """Stores the state and configuration of a node instance."""
306
+ id: Optional[int] = None
307
+ type: Optional[str] = None
308
+ is_setup: Optional[bool] = None
309
+ description: Optional[str] = ''
310
+ x_position: Optional[int] = 0
311
+ y_position: Optional[int] = 0
312
+ left_input_id: Optional[int] = None
313
+ right_input_id: Optional[int] = None
314
+ input_ids: Optional[List[int]] = Field(default_factory=lambda: [-1])
315
+ outputs: Optional[List[int]] = Field(default_factory=lambda: [-1])
316
+ setting_input: Optional[Any] = None
317
+
318
+
319
+ class FlowInformation(BaseModel):
320
+ """Represents the complete state of a flow."""
321
+ flow_id: int
322
+ flow_name: Optional[str] = ''
323
+ flow_settings: Optional[FlowSettings] = None
324
+ data: Dict[int, NodeInformation] = Field(default_factory=dict)
325
+ node_starts: List[int] = Field(default_factory=list)
326
+ node_connections: List[Tuple[int, int]] = Field(default_factory=list)
327
+
328
+
329
+ # =============================================================================
330
+ # TRANSFORM SCHEMAS (dataclasses - these changed from @dataclass to BaseModel)
331
+ # =============================================================================
332
+
333
+ @dataclass
334
+ class SelectInput:
335
+ """Defines how a single column should be selected, renamed, or type-cast."""
336
+ old_name: str
337
+ original_position: Optional[int] = None
338
+ new_name: Optional[str] = None
339
+ data_type: Optional[str] = None
340
+ data_type_change: Optional[bool] = False
341
+ join_key: Optional[bool] = False
342
+ is_altered: Optional[bool] = False
343
+ position: Optional[int] = None
344
+ is_available: Optional[bool] = True
345
+ keep: Optional[bool] = True
346
+
347
+ def __post_init__(self):
348
+ if self.new_name is None:
349
+ self.new_name = self.old_name
350
+
351
+
352
+ @dataclass
353
+ class FieldInput:
354
+ """Represents a single field with its name and data type."""
355
+ name: str
356
+ data_type: Optional[str] = None
357
+
358
+
359
+ @dataclass
360
+ class FunctionInput:
361
+ """Defines a formula to be applied."""
362
+ field: FieldInput = None
363
+ function: str = ''
364
+
365
+
366
+ @dataclass
367
+ class BasicFilter:
368
+ """Defines a simple, single-condition filter."""
369
+ field: str = ''
370
+ filter_type: str = ''
371
+ filter_value: str = ''
372
+
373
+
374
+ @dataclass
375
+ class FilterInput:
376
+ """Defines the settings for a filter operation."""
377
+ advanced_filter: str = ''
378
+ basic_filter: BasicFilter = None
379
+ filter_type: str = 'basic'
380
+
381
+
382
+ @dataclass
383
+ class SelectInputs:
384
+ """A container for a list of SelectInput objects."""
385
+ renames: List[SelectInput] = field(default_factory=list)
386
+
387
+ @property
388
+ def old_cols(self) -> Set:
389
+ return set(v.old_name for v in self.renames if v.keep)
390
+
391
+ @property
392
+ def new_cols(self) -> Set:
393
+ return set(v.new_name for v in self.renames if v.keep)
394
+
395
+
396
+ @dataclass
397
+ class JoinInputs:
398
+ """Extends SelectInputs with functionality specific to join operations."""
399
+ renames: List[SelectInput] = field(default_factory=list)
400
+
401
+
402
+ @dataclass
403
+ class JoinMap:
404
+ """Defines a single mapping between a left and right column for a join key."""
405
+ left_col: str = None
406
+ right_col: str = None
407
+
408
+
409
+ @dataclass
410
+ class CrossJoinInput:
411
+ """Defines the settings for a cross join operation."""
412
+ left_select: Any = None
413
+ right_select: Any = None
414
+
415
+
416
+ @dataclass
417
+ class JoinInput:
418
+ """Defines the settings for a standard SQL-style join."""
419
+ join_mapping: List[JoinMap] = field(default_factory=list)
420
+ left_select: Any = None
421
+ right_select: Any = None
422
+ how: str = 'inner'
423
+
424
+
425
+ @dataclass
426
+ class FuzzyMapping:
427
+ """Defines a fuzzy match column mapping with threshold."""
428
+ left_col: str = None
429
+ right_col: str = None
430
+ threshold_score: int = 80
431
+ fuzzy_type: str = 'levenshtein'
432
+
433
+
434
+ @dataclass
435
+ class FuzzyMatchInput:
436
+ """Extends JoinInput with settings specific to fuzzy matching."""
437
+ join_mapping: List[FuzzyMapping] = field(default_factory=list)
438
+ left_select: Any = None
439
+ right_select: Any = None
440
+ how: str = 'inner'
441
+ aggregate_output: bool = False
442
+
443
+
444
+ @dataclass
445
+ class AggColl:
446
+ """Represents a single aggregation operation."""
447
+ old_name: str = None
448
+ agg: str = None
449
+ new_name: Optional[str] = None
450
+ output_type: Optional[str] = None
451
+
452
+
453
+ @dataclass
454
+ class GroupByInput:
455
+ """Represents the input for a group by operation."""
456
+ agg_cols: List[AggColl] = field(default_factory=list)
457
+
458
+
459
+ @dataclass
460
+ class PivotInput:
461
+ """Defines the settings for a pivot operation."""
462
+ index_columns: List[str] = field(default_factory=list)
463
+ pivot_column: str = None
464
+ value_col: str = None
465
+ aggregations: List[str] = field(default_factory=list)
466
+
467
+
468
+ @dataclass
469
+ class SortByInput:
470
+ """Defines a single sort condition on a column."""
471
+ column: str = None
472
+ how: str = 'asc'
473
+
474
+
475
+ @dataclass
476
+ class RecordIdInput:
477
+ """Defines settings for adding a record ID column."""
478
+ output_column_name: str = 'record_id'
479
+ offset: int = 1
480
+ group_by: Optional[bool] = False
481
+ group_by_columns: Optional[List[str]] = field(default_factory=list)
482
+
483
+
484
+ @dataclass
485
+ class TextToRowsInput:
486
+ """Defines settings for splitting a text column into multiple rows."""
487
+ column_to_split: str = None
488
+ output_column_name: Optional[str] = None
489
+ split_by_fixed_value: Optional[bool] = True
490
+ split_fixed_value: Optional[str] = ','
491
+ split_by_column: Optional[str] = None
492
+
493
+
494
+ @dataclass
495
+ class UnpivotInput:
496
+ """Defines settings for an unpivot operation."""
497
+ index_columns: Optional[List[str]] = field(default_factory=list)
498
+ value_columns: Optional[List[str]] = field(default_factory=list)
499
+ data_type_selector: Optional[Literal['float', 'all', 'date', 'numeric', 'string']] = None
500
+ data_type_selector_mode: Optional[Literal['data_type', 'column']] = 'column'
501
+
502
+ def __post_init__(self):
503
+ if self.index_columns is None:
504
+ self.index_columns = []
505
+ if self.value_columns is None:
506
+ self.value_columns = []
507
+
508
+
509
+ @dataclass
510
+ class UnionInput:
511
+ """Defines settings for a union operation."""
512
+ mode: Literal['selective', 'relaxed'] = 'relaxed'
513
+
514
+
515
+ @dataclass
516
+ class UniqueInput:
517
+ """Defines settings for a uniqueness operation."""
518
+ columns: Optional[List[str]] = None
519
+ strategy: str = "any"
520
+
521
+
522
+ @dataclass
523
+ class GraphSolverInput:
524
+ """Defines settings for a graph-solving operation."""
525
+ col_from: str = None
526
+ col_to: str = None
527
+ output_column_name: Optional[str] = 'graph_group'
528
+
529
+
530
+ @dataclass
531
+ class PolarsCodeInput:
532
+ """A simple container for user-provided Polars code."""
533
+ polars_code: str = ''
534
+
535
+
536
+ @dataclass
537
+ class SampleInput:
538
+ """Defines settings for sampling rows."""
539
+ n: Optional[int] = None
540
+ fraction: Optional[float] = None
541
+ with_replacement: bool = False
542
+ shuffle: bool = False
543
+ seed: Optional[int] = None
544
+
545
+
546
+ # =============================================================================
547
+ # CLASS NAME MAPPING for pickle.Unpickler.find_class
548
+ # Maps class names to their legacy implementations for unpickling
549
+ # =============================================================================
550
+
551
+ LEGACY_CLASS_MAP = {
552
+ # Transform schema dataclasses
553
+ 'SelectInput': SelectInput,
554
+ 'FieldInput': FieldInput,
555
+ 'FunctionInput': FunctionInput,
556
+ 'BasicFilter': BasicFilter,
557
+ 'FilterInput': FilterInput,
558
+ 'SelectInputs': SelectInputs,
559
+ 'JoinInputs': JoinInputs,
560
+ 'JoinMap': JoinMap,
561
+ 'CrossJoinInput': CrossJoinInput,
562
+ 'JoinInput': JoinInput,
563
+ 'FuzzyMapping': FuzzyMapping,
564
+ 'FuzzyMatchInput': FuzzyMatchInput,
565
+ 'AggColl': AggColl,
566
+ 'GroupByInput': GroupByInput,
567
+ 'PivotInput': PivotInput,
568
+ 'SortByInput': SortByInput,
569
+ 'RecordIdInput': RecordIdInput,
570
+ 'TextToRowsInput': TextToRowsInput,
571
+ 'UnpivotInput': UnpivotInput,
572
+ 'UnionInput': UnionInput,
573
+ 'UniqueInput': UniqueInput,
574
+ 'GraphSolverInput': GraphSolverInput,
575
+ 'PolarsCodeInput': PolarsCodeInput,
576
+ 'SampleInput': SampleInput,
577
+
578
+ # OLD Input/Output schemas (before table_settings)
579
+ 'ReceivedTable': ReceivedTable,
580
+ 'OutputSettings': OutputSettings,
581
+ 'OutputCsvTable': OutputCsvTable,
582
+ 'OutputParquetTable': OutputParquetTable,
583
+ 'OutputExcelTable': OutputExcelTable,
584
+ 'MinimalFieldInfo': MinimalFieldInfo,
585
+
586
+ # Flow and Node schemas
587
+ 'FlowSettings': FlowSettings,
588
+ 'FlowGraphConfig': FlowGraphConfig,
589
+ 'FlowInformation': FlowInformation,
590
+ 'NodeInformation': NodeInformation,
591
+ 'NodeBase': NodeBase,
592
+ 'NodeSingleInput': NodeSingleInput,
593
+ 'NodeMultiInput': NodeMultiInput,
594
+ 'NodeRead': NodeRead,
595
+ 'NodeSelect': NodeSelect,
596
+ 'NodeFilter': NodeFilter,
597
+ 'NodeFormula': NodeFormula,
598
+ 'NodeJoin': NodeJoin,
599
+ 'NodeCrossJoin': NodeCrossJoin,
600
+ 'NodeFuzzyMatch': NodeFuzzyMatch,
601
+ 'NodePolarsCode': NodePolarsCode,
602
+ 'NodeOutput': NodeOutput,
603
+ 'NodeGroupBy': NodeGroupBy,
604
+ 'NodeSort': NodeSort,
605
+ 'NodeUnion': NodeUnion,
606
+ 'NodeUnique': NodeUnique,
607
+ 'NodePivot': NodePivot,
608
+ 'NodeUnpivot': NodeUnpivot,
609
+ 'NodeRecordId': NodeRecordId,
610
+ 'NodeTextToRows': NodeTextToRows,
611
+ 'NodeGraphSolver': NodeGraphSolver,
612
+ 'NodeSample': NodeSample,
613
+ 'NodePromise': NodePromise,
614
+ 'DatabaseConnection': DatabaseConnection,
615
+ 'DatabaseSettings': DatabaseSettings,
616
+ 'NodeDatabaseReader': NodeDatabaseReader,
617
+ }
618
+
619
+
620
+ # Export all classes
621
+ __all__ = list(LEGACY_CLASS_MAP.keys()) + ['LEGACY_CLASS_MAP']