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
@@ -8,11 +8,11 @@ from flowfile_core.configs.flow_logger import NodeLogger
8
8
 
9
9
  from flowfile_core.schemas.output_model import TableExample, FileColumn, NodeData
10
10
  from flowfile_core.flowfile.utils import get_hash
11
- from flowfile_core.configs.node_store import nodes as node_interface
11
+ from flowfile_core.configs import node_store
12
12
  from flowfile_core.flowfile.setting_generator import setting_generator, setting_updator
13
13
  from time import sleep
14
14
  from flowfile_core.flowfile.flow_data_engine.subprocess_operations import (
15
- ExternalDfFetcher, ExternalSampler, results_exists, get_external_df_result,
15
+ ExternalDfFetcher, ExternalSampler, clear_task_from_worker, results_exists, get_external_df_result,
16
16
  ExternalDatabaseFetcher, ExternalDatabaseWriter, ExternalCloudWriter)
17
17
  from flowfile_core.flowfile.flow_node.models import (NodeStepSettings, NodeStepInputs, NodeSchemaInformation,
18
18
  NodeStepStats, NodeResults)
@@ -27,7 +27,7 @@ class FlowNode:
27
27
  """
28
28
  parent_uuid: str
29
29
  node_type: str
30
- node_template: node_interface.NodeTemplate
30
+ node_template: node_store.NodeTemplate
31
31
  node_default: schemas.NodeDefault
32
32
  node_schema: NodeSchemaInformation
33
33
  node_inputs: NodeStepInputs
@@ -251,10 +251,10 @@ class FlowNode:
251
251
  self.results.errors = None
252
252
  self.add_lead_to_in_depend_source()
253
253
  _ = self.hash
254
- self.node_template = node_interface.node_dict.get(self.node_type)
254
+ self.node_template = node_store.node_dict.get(self.node_type)
255
255
  if self.node_template is None:
256
256
  raise Exception(f'Node template {self.node_type} not found')
257
- self.node_default = node_interface.node_defaults.get(self.node_type)
257
+ self.node_default = node_store.node_defaults.get(self.node_type)
258
258
  self.setting_input = setting_input # wait until the end so that the hash is calculated correctly
259
259
 
260
260
  @property
@@ -370,6 +370,7 @@ class FlowNode:
370
370
  self.node_inputs.main_inputs] if self.node_inputs.main_inputs is not None else None
371
371
  node_information.setting_input = self.setting_input
372
372
  node_information.outputs = [n.node_id for n in self.leads_to_nodes]
373
+ node_information.description = self.setting_input.description if hasattr(self.setting_input, 'description') else ''
373
374
  node_information.is_setup = self.is_setup
374
375
  node_information.x_position = self.setting_input.pos_x
375
376
  node_information.y_position = self.setting_input.pos_y
@@ -498,6 +499,7 @@ class FlowNode:
498
499
  Returns:
499
500
  A list of FlowfileColumn objects representing the predicted schema.
500
501
  """
502
+
501
503
  if self.node_schema.predicted_schema and not force:
502
504
  return self.node_schema.predicted_schema
503
505
  if self.schema_callback is not None and (self.node_schema.predicted_schema is None or force):
@@ -514,6 +516,7 @@ class FlowNode:
514
516
  if predicted_data is not None and predicted_data.schema is not None:
515
517
  self.print('Calculating the schema based on the predicted resulting data')
516
518
  self.node_schema.predicted_schema = self._predicted_data_getter().schema
519
+
517
520
  return self.node_schema.predicted_schema
518
521
 
519
522
  @property
@@ -678,9 +681,10 @@ class FlowNode:
678
681
 
679
682
  if results_exists(self.hash):
680
683
  logger.warning('Not implemented')
684
+ clear_task_from_worker(self.hash)
681
685
 
682
686
  def needs_run(self, performance_mode: bool, node_logger: NodeLogger = None,
683
- execution_location: schemas.ExecutionLocationsLiteral = "worker") -> bool:
687
+ execution_location: schemas.ExecutionLocationsLiteral = "remote") -> bool:
684
688
  """Determines if the node needs to be executed.
685
689
 
686
690
  The decision is based on its run state, caching settings, and execution mode.
@@ -723,6 +727,8 @@ class FlowNode:
723
727
  Raises:
724
728
  Exception: Propagates exceptions from the execution.
725
729
  """
730
+ self.clear_table_example()
731
+
726
732
  def example_data_generator():
727
733
  example_data = None
728
734
 
@@ -735,6 +741,7 @@ class FlowNode:
735
741
  resulting_data = self.get_resulting_data()
736
742
 
737
743
  if not performance_mode:
744
+ self.node_stats.has_run_with_current_setup = True
738
745
  self.results.example_data_generator = example_data_generator()
739
746
  self.node_schema.result_schema = self.results.resulting_data.schema
740
747
  self.node_stats.has_completed_last_run = True
@@ -854,8 +861,12 @@ class FlowNode:
854
861
  logger.warning('No external process to cancel')
855
862
  self.node_stats.is_canceled = True
856
863
 
857
- def execute_node(self, run_location: schemas.ExecutionLocationsLiteral, reset_cache: bool = False,
858
- performance_mode: bool = False, retry: bool = True, node_logger: NodeLogger = None):
864
+ def execute_node(self, run_location: schemas.ExecutionLocationsLiteral,
865
+ reset_cache: bool = False,
866
+ performance_mode: bool = False,
867
+ retry: bool = True,
868
+ node_logger: NodeLogger = None,
869
+ optimize_for_downstream: bool = True):
859
870
  """Orchestrates the execution, handling location, caching, and retries.
860
871
 
861
872
  Args:
@@ -864,25 +875,33 @@ class FlowNode:
864
875
  performance_mode: If True, optimizes for speed over diagnostics.
865
876
  retry: If True, allows retrying execution on recoverable errors.
866
877
  node_logger: The logger for this node execution.
878
+ optimize_for_downstream: If true, operations that shuffle the order of rows are fully cached and provided as
879
+ input to downstream steps
867
880
 
868
881
  Raises:
869
882
  Exception: If the node_logger is not defined.
870
883
  """
871
884
  if node_logger is None:
872
885
  raise Exception('Flow logger is not defined')
873
- # node_logger = flow_logger.get_node_logger(self.node_id)
886
+ # TODO: Simplify which route is being picked there are many duplicate checks
887
+
874
888
  if reset_cache:
875
889
  self.remove_cache()
876
890
  self.node_stats.has_run_with_current_setup = False
877
891
  self.node_stats.has_completed_last_run = False
892
+
878
893
  if self.is_setup:
879
894
  node_logger.info(f'Starting to run {self.__name__}')
880
895
  if (self.needs_run(performance_mode, node_logger, run_location) or self.node_template.node_group == "output"
881
896
  and not (run_location == 'local')):
897
+ self.clear_table_example()
882
898
  self.prepare_before_run()
899
+ self.reset()
883
900
  try:
884
- if ((run_location == 'remote' or (self.node_default.transform_type == 'wide')
885
- and not run_location == 'local')) or self.node_settings.cache_results:
901
+ if (((run_location == 'remote' or
902
+ (self.node_default.transform_type == 'wide' and optimize_for_downstream) and
903
+ not run_location == 'local'))
904
+ or self.node_settings.cache_results):
886
905
  node_logger.info('Running the node remotely')
887
906
  if self.node_settings.cache_results:
888
907
  performance_mode = False
@@ -924,7 +943,7 @@ class FlowNode:
924
943
  node_logger.error(f'Error with running the node: {e}')
925
944
  self.node_stats.error = str(e)
926
945
  self.node_stats.has_completed_last_run = False
927
- self.node_stats.has_run_with_current_setup = True
946
+
928
947
  else:
929
948
  node_logger.info('Node has already run, not running the node')
930
949
  else:
@@ -1108,6 +1127,17 @@ class FlowNode:
1108
1127
  if self.singular_input:
1109
1128
  return self.all_inputs[0]
1110
1129
 
1130
+ def clear_table_example(self) -> None:
1131
+ """
1132
+ Clear the table example in the results so that it clears the existing results
1133
+ Returns:
1134
+ None
1135
+ """
1136
+
1137
+ self.results.example_data = None
1138
+ self.results.example_data_generator = None
1139
+ self.results.example_data_path = None
1140
+
1111
1141
  def get_table_example(self, include_data: bool = False) -> TableExample | None:
1112
1142
  """Generates a `TableExample` model summarizing the node's output.
1113
1143
 
@@ -1136,10 +1166,15 @@ class FlowNode:
1136
1166
  data = []
1137
1167
  schema = [FileColumn.model_validate(c.get_column_repr()) for c in self.schema]
1138
1168
  fl = self.get_resulting_data()
1169
+ has_example_data = self.results.example_data_generator is not None
1170
+
1139
1171
  return TableExample(node_id=self.node_id,
1140
1172
  name=str(self.node_id), number_of_records=999,
1141
1173
  number_of_columns=fl.number_of_fields,
1142
- table_schema=schema, columns=fl.columns, data=data)
1174
+ table_schema=schema, columns=fl.columns, data=data,
1175
+ has_example_data=has_example_data,
1176
+ has_run_with_current_setup=self.node_stats.has_run_with_current_setup
1177
+ )
1143
1178
  else:
1144
1179
  logger.warning('getting the table example but the node has not run')
1145
1180
  try:
@@ -130,13 +130,14 @@ class NodeStepInputs:
130
130
  main_inputs: List["FlowNode"] = None
131
131
 
132
132
  @property
133
- def input_ids(self) -> List[int] | None:
133
+ def input_ids(self) -> List[int]:
134
134
  """
135
135
  Gets the IDs of all connected input nodes.
136
136
  :return: A list of integer node IDs.
137
137
  """
138
138
  if self.main_inputs is not None:
139
139
  return [node_input.node_information.id for node_input in self.get_all_inputs()]
140
+ return []
140
141
 
141
142
  def get_all_inputs(self) -> List["FlowNode"]:
142
143
  """
@@ -3,11 +3,25 @@ from dataclasses import dataclass
3
3
  from typing import Dict, List
4
4
  import os
5
5
  from pathlib import Path
6
+ from datetime import datetime
6
7
 
7
- from flowfile_core.flowfile.manage.open_flowfile import open_flow
8
+ from flowfile_core.flowfile.manage.io_flowfile import open_flow
8
9
  from flowfile_core.flowfile.flow_graph import FlowGraph
9
10
  from flowfile_core.schemas.schemas import FlowSettings
10
11
  from flowfile_core.flowfile.utils import create_unique_id
12
+ from shared.storage_config import storage
13
+
14
+
15
+ def get_flow_save_location(flow_name: str) -> Path:
16
+ """Gets the initial save location for flow files"""
17
+ if ".yaml" not in flow_name and ".yml" not in flow_name:
18
+ flow_name += ".yaml"
19
+ return storage.temp_directory_for_flows / flow_name
20
+
21
+
22
+ def create_flow_name() -> str:
23
+ """Creates a unique flow name"""
24
+ return datetime.now().strftime("%Y%m%d_%H_%M_%S")+"_flow.yaml"
11
25
 
12
26
 
13
27
  @dataclass
@@ -25,7 +39,7 @@ class FlowfileHandler:
25
39
  self._flows[other.flow_id] = other
26
40
  return other.flow_id
27
41
 
28
- def import_flow(self, flow_path: Path|str) -> int:
42
+ def import_flow(self, flow_path: Path | str) -> int:
29
43
  if isinstance(flow_path, str):
30
44
  flow_path = Path(flow_path)
31
45
  imported_flow = open_flow(flow_path)
@@ -57,7 +71,7 @@ class FlowfileHandler:
57
71
  else:
58
72
  raise Exception('Flow not found')
59
73
 
60
- def add_flow(self, name: str, flow_path: str) -> int:
74
+ def add_flow(self, name: str = None, flow_path: str = None) -> int:
61
75
  """
62
76
  Creates a new flow with a reference to the flow path
63
77
  Args:
@@ -69,8 +83,13 @@ class FlowfileHandler:
69
83
 
70
84
  """
71
85
  next_id = create_unique_id()
72
- flow_info = FlowSettings(name=name, flow_id=next_id, save_location='', path=flow_path)
73
- _ = self.register_flow(flow_info)
86
+ if not name:
87
+ name = create_flow_name()
88
+ if not flow_path:
89
+ flow_path = get_flow_save_location(name)
90
+ flow_info = FlowSettings(name=name, flow_id=next_id, save_location=str(flow_path), path=str(flow_path))
91
+ flow = self.register_flow(flow_info)
92
+ flow.save_flow(flow.flow_settings.path)
74
93
  return next_id
75
94
 
76
95
  def get_flow_info(self, flow_id: int) -> FlowSettings: