FlowerPower 0.31.1__py3-none-any.whl → 0.31.2__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.
@@ -580,11 +580,32 @@ class PipelineManager:
580
580
  """
581
581
  return self._lifecycle_manager.list_pipelines()
582
582
 
583
- def show_pipelines(self) -> None:
584
- """Display all available pipelines in a formatted table.
583
+ def show_pipelines(self, format: str = "table") -> None:
584
+ """Display all available pipelines in a selected format.
585
585
 
586
- Uses rich formatting for terminal display.
586
+ Args:
587
+ format: One of "table", "json", or "yaml". Defaults to "table".
587
588
  """
589
+ fmt = (format or "table").lower()
590
+ if fmt == "table":
591
+ return self.registry.show_pipelines()
592
+ names = self._lifecycle_manager.list_pipelines()
593
+ try:
594
+ if fmt == "json":
595
+ import json
596
+ print(json.dumps(names))
597
+ return None
598
+ if fmt == "yaml":
599
+ import yaml # type: ignore
600
+ print(yaml.safe_dump(names, sort_keys=False))
601
+ return None
602
+ except Exception as e:
603
+ warnings.warn(
604
+ f"Failed to format pipelines as {fmt}: {e}. Falling back to table.",
605
+ RuntimeWarning,
606
+ )
607
+ return self.registry.show_pipelines()
608
+ warnings.warn(f"Unknown format '{format}', using table.", RuntimeWarning)
588
609
  return self.registry.show_pipelines()
589
610
 
590
611
  @property
@@ -985,7 +1006,13 @@ class PipelineManager:
985
1006
  )
986
1007
 
987
1008
  # Visualizer Delegations
988
- def save_dag(self, name: str, format: str = "png", reload: bool = False) -> None:
1009
+ def save_dag(
1010
+ self,
1011
+ name: str,
1012
+ format: str = "png",
1013
+ reload: bool = False,
1014
+ output_path: str | None = None,
1015
+ ) -> str:
989
1016
  """Save pipeline DAG visualization to a file.
990
1017
 
991
1018
  Creates a visual representation of the pipeline's directed acyclic graph (DAG)
@@ -1020,7 +1047,9 @@ class PipelineManager:
1020
1047
  ... reload=True
1021
1048
  ... )
1022
1049
  """
1023
- self.visualizer.save_dag(name=name, format=format, reload=reload)
1050
+ return self.visualizer.save_dag(
1051
+ name=name, format=format, reload=reload, output_path=output_path
1052
+ )
1024
1053
 
1025
1054
  def show_dag(
1026
1055
  self, name: str, format: str = "png", reload: bool = False, raw: bool = False
@@ -67,7 +67,8 @@ class PipelineVisualizer:
67
67
  name: str,
68
68
  format: str = "png",
69
69
  reload: bool = False,
70
- ):
70
+ output_path: str | None = None,
71
+ ) -> str:
71
72
  """
72
73
  Save an image of the graph of functions for a given pipeline name.
73
74
 
@@ -86,25 +87,38 @@ class PipelineVisualizer:
86
87
  """
87
88
  dag = self._get_dag_object(name=name, reload=reload)
88
89
 
89
- # Use project_cfg attributes for path and filesystem access
90
- graph_dir = posixpath.join(self.project_cfg.base_dir, "graphs")
91
- self._fs.makedirs(graph_dir, exist_ok=True)
92
-
93
- output_path = posixpath.join(
94
- graph_dir, name
95
- ) # Output filename is just the pipeline name
96
- output_path_with_ext = f"{output_path}.{format}"
90
+ # Determine final output path
91
+ if output_path is None:
92
+ graph_dir = posixpath.join(self.project_cfg.base_dir, "graphs")
93
+ self._fs.makedirs(graph_dir, exist_ok=True)
94
+ base = posixpath.join(graph_dir, name)
95
+ final_path = f"{base}.{format}"
96
+ render_path = base
97
+ else:
98
+ # If output_path already has an extension, use as-is; otherwise append format
99
+ if "." in posixpath.basename(output_path):
100
+ final_path = output_path
101
+ # Remove extension for graphviz render base path
102
+ render_path = final_path.rsplit(".", 1)[0]
103
+ fmt = final_path.rsplit(".", 1)[1]
104
+ if fmt != format:
105
+ # Honor explicit extension if it differs from format argument
106
+ format = fmt
107
+ else:
108
+ final_path = f"{output_path}.{format}"
109
+ render_path = output_path
97
110
 
98
111
  # Render the DAG using the graphviz object returned by display_all_functions
99
112
  dag.render(
100
- output_path, # graphviz appends the format automatically
113
+ render_path, # graphviz appends the format automatically
101
114
  format=format,
102
115
  cleanup=True,
103
116
  view=False,
104
117
  )
105
118
  print(
106
- f"📊 Saved graph for [bold blue]{self.project_cfg.name}.{name}[/bold blue] to [green]{output_path_with_ext}[/green]"
119
+ f"📊 Saved graph for [bold blue]{self.project_cfg.name}.{name}[/bold blue] to [green]{final_path}[/green]"
107
120
  )
121
+ return final_path
108
122
 
109
123
  def show_dag(
110
124
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FlowerPower
3
- Version: 0.31.1
3
+ Version: 0.31.2
4
4
  Summary: A simple workflow framework for building and managing data processing pipelines
5
5
  Author-email: "Volker L." <ligno.blades@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/legout/flowerpower
@@ -21,10 +21,10 @@ flowerpower/pipeline/config_manager.py,sha256=0u_Nn_XGafjW3LmhGyp39CP9KXfLo02Z9i
21
21
  flowerpower/pipeline/executor.py,sha256=AAiMbNKIQKNrumu1lavG_yVK9rzhPYjZAIt0BxAbJjc,4567
22
22
  flowerpower/pipeline/io.py,sha256=phYJhN4LZ0c6d8_udEQ4C9cGzeV3Ku0hsj0gyE1n2UY,16246
23
23
  flowerpower/pipeline/lifecycle_manager.py,sha256=JKJXdgdwhH8yUYdwlAJp5-dSbDFFb-EqmgiY-O5KIoA,7670
24
- flowerpower/pipeline/manager.py,sha256=XLrCY5x9WmQithe0QmeYonR4LyqzqSQHR-y7cL6DKr4,41143
24
+ flowerpower/pipeline/manager.py,sha256=NTjdWu_SzOmeLvnD5ruJzI72UOx_UFLxhNrUipPK43g,42138
25
25
  flowerpower/pipeline/pipeline.py,sha256=x4nQeKC7irJoD6x2RzU52dN4VGWJFSGTDYKNuDhG7fk,15742
26
26
  flowerpower/pipeline/registry.py,sha256=gIc1N7yRm95dEhc5WnZapTK827VeydGxZSYcWFqB10U,30122
27
- flowerpower/pipeline/visualizer.py,sha256=EVpjv-TUe1zGvdEAWyShJcVXurm02W0jkLbj7z1uAv4,4953
27
+ flowerpower/pipeline/visualizer.py,sha256=5DI9A7JhiwreRjZPIu5FbQCoI65W0cDC8c2iPkpkOGY,5612
28
28
  flowerpower/plugins/io/__init__.py,sha256=ZmSdKoh3TavJagOz0vUItnEqAh3mAM1QpAWj0KufF_k,222
29
29
  flowerpower/settings/__init__.py,sha256=XKQa8AI9VrX8ievs-suq3Cm6PBt4cJ78ZHVIjUbXCyA,130
30
30
  flowerpower/settings/_backend.py,sha256=Up1RBqAs3jtDUOV-9wEpL68Qmom-dRWMOeHXIh0F3lw,4273
@@ -45,9 +45,9 @@ flowerpower/utils/monkey.py,sha256=vJMYANjZI13PNbEQThdX0EFP1_6bGNHgnpF7HwReNyM,5
45
45
  flowerpower/utils/open_telemetry.py,sha256=fQWJWbIQFtKIxMBjAWeF12NGnqT0isO3A3j-DSOv_vE,949
46
46
  flowerpower/utils/security.py,sha256=7TPwD4nqjVm2rFBjJ0qM86wEQql-9j3Jo8udV3mSBoA,7113
47
47
  flowerpower/utils/templates.py,sha256=ouyEeSDqa9PjW8c32fGpcINlpC0WToawRFZkMPtwsLE,1591
48
- flowerpower-0.31.1.dist-info/licenses/LICENSE,sha256=9AkLexxrmr0aBgSHiqxpJk9wgazpP1CTJyiDyr56J9k,1063
49
- flowerpower-0.31.1.dist-info/METADATA,sha256=TgvnINYIvNKmijCZg0U11cHEFzC2eEA3LzO_8YuwdFc,17202
50
- flowerpower-0.31.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
- flowerpower-0.31.1.dist-info/entry_points.txt,sha256=61X11i5a2IwC9LBiP20XCDl5zMOigGCjMCx17B7bDbQ,52
52
- flowerpower-0.31.1.dist-info/top_level.txt,sha256=VraH4WtEUfSxs5L-rXwDQhzQb9eLHTUtgvmFZ2dAYnA,12
53
- flowerpower-0.31.1.dist-info/RECORD,,
48
+ flowerpower-0.31.2.dist-info/licenses/LICENSE,sha256=9AkLexxrmr0aBgSHiqxpJk9wgazpP1CTJyiDyr56J9k,1063
49
+ flowerpower-0.31.2.dist-info/METADATA,sha256=Gv1RElnrVxJg_h-INW7QnoKkjy5G0OYjrzu55AsDwnw,17202
50
+ flowerpower-0.31.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
+ flowerpower-0.31.2.dist-info/entry_points.txt,sha256=61X11i5a2IwC9LBiP20XCDl5zMOigGCjMCx17B7bDbQ,52
52
+ flowerpower-0.31.2.dist-info/top_level.txt,sha256=VraH4WtEUfSxs5L-rXwDQhzQb9eLHTUtgvmFZ2dAYnA,12
53
+ flowerpower-0.31.2.dist-info/RECORD,,