FlowerPower 0.21.0__py3-none-any.whl → 0.31.0__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.
- flowerpower/cfg/__init__.py +143 -25
- flowerpower/cfg/base.py +132 -11
- flowerpower/cfg/exceptions.py +53 -0
- flowerpower/cfg/pipeline/__init__.py +151 -35
- flowerpower/cfg/pipeline/adapter.py +1 -0
- flowerpower/cfg/pipeline/builder.py +24 -25
- flowerpower/cfg/pipeline/builder_adapter.py +142 -0
- flowerpower/cfg/pipeline/builder_executor.py +101 -0
- flowerpower/cfg/pipeline/run.py +134 -22
- flowerpower/cfg/project/__init__.py +59 -14
- flowerpower/cfg/project/adapter.py +6 -0
- flowerpower/cli/__init__.py +8 -9
- flowerpower/cli/cfg.py +0 -38
- flowerpower/cli/pipeline.py +121 -83
- flowerpower/cli/utils.py +120 -71
- flowerpower/flowerpower.py +94 -120
- flowerpower/pipeline/config_manager.py +180 -0
- flowerpower/pipeline/executor.py +126 -0
- flowerpower/pipeline/lifecycle_manager.py +231 -0
- flowerpower/pipeline/manager.py +121 -276
- flowerpower/pipeline/pipeline.py +66 -278
- flowerpower/pipeline/registry.py +45 -4
- flowerpower/utils/__init__.py +19 -0
- flowerpower/utils/adapter.py +286 -0
- flowerpower/utils/callback.py +73 -67
- flowerpower/utils/config.py +306 -0
- flowerpower/utils/executor.py +178 -0
- flowerpower/utils/filesystem.py +194 -0
- flowerpower/utils/misc.py +249 -76
- flowerpower/utils/security.py +221 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.31.0.dist-info}/METADATA +1 -13
- flowerpower-0.31.0.dist-info/RECORD +53 -0
- flowerpower/cfg/pipeline/_schedule.py +0 -32
- flowerpower/cli/mqtt.py +0 -168
- flowerpower/plugins/mqtt/__init__.py +0 -8
- flowerpower-0.21.0.dist-info/RECORD +0 -44
- {flowerpower-0.21.0.dist-info → flowerpower-0.31.0.dist-info}/WHEEL +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.31.0.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.31.0.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.31.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,231 @@
|
|
1
|
+
"""Pipeline lifecycle management."""
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
4
|
+
|
5
|
+
import rich
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from .registry import PipelineRegistry, HookType
|
9
|
+
|
10
|
+
|
11
|
+
class PipelineLifecycleManager:
|
12
|
+
"""Handles pipeline creation, deletion, and metadata management.
|
13
|
+
|
14
|
+
This class is responsible for:
|
15
|
+
- Creating new pipelines
|
16
|
+
- Deleting existing pipelines
|
17
|
+
- Managing pipeline metadata and summaries
|
18
|
+
- Displaying pipeline information
|
19
|
+
- Managing hooks
|
20
|
+
"""
|
21
|
+
|
22
|
+
def __init__(self, registry: "PipelineRegistry"):
|
23
|
+
"""Initialize the lifecycle manager.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
registry: Pipeline registry for pipeline operations
|
27
|
+
"""
|
28
|
+
self._registry = registry
|
29
|
+
|
30
|
+
def create_pipeline(
|
31
|
+
self,
|
32
|
+
name: str,
|
33
|
+
overwrite: bool = False,
|
34
|
+
template: Optional[str] = None,
|
35
|
+
tags: Optional[list[str]] = None,
|
36
|
+
description: Optional[str] = None
|
37
|
+
) -> None:
|
38
|
+
"""Create a new pipeline.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
name: Name of the pipeline to create
|
42
|
+
overwrite: Whether to overwrite existing pipeline
|
43
|
+
template: Template to use for pipeline creation
|
44
|
+
tags: Tags to associate with the pipeline
|
45
|
+
description: Description of the pipeline
|
46
|
+
"""
|
47
|
+
self._registry.create_pipeline(
|
48
|
+
name=name,
|
49
|
+
overwrite=overwrite,
|
50
|
+
template=template,
|
51
|
+
tags=tags or [],
|
52
|
+
description=description or ""
|
53
|
+
)
|
54
|
+
|
55
|
+
def delete_pipeline(
|
56
|
+
self,
|
57
|
+
name: str,
|
58
|
+
cfg: bool = True,
|
59
|
+
module: bool = False
|
60
|
+
) -> None:
|
61
|
+
"""Delete a pipeline.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
name: Name of the pipeline to delete
|
65
|
+
cfg: Whether to delete configuration file
|
66
|
+
module: Whether to delete module file
|
67
|
+
"""
|
68
|
+
self._registry.delete_pipeline(name=name, cfg=cfg, module=module)
|
69
|
+
|
70
|
+
def get_summary(
|
71
|
+
self,
|
72
|
+
name: Optional[str] = None,
|
73
|
+
cfg: bool = True,
|
74
|
+
code: bool = True,
|
75
|
+
project: bool = True
|
76
|
+
) -> dict:
|
77
|
+
"""Get pipeline summary information.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
name: Name of pipeline to summarize, or None for all pipelines
|
81
|
+
cfg: Whether to include configuration information
|
82
|
+
code: Whether to include code information
|
83
|
+
project: Whether to include project information
|
84
|
+
|
85
|
+
Returns:
|
86
|
+
dict: Summary information
|
87
|
+
"""
|
88
|
+
if name is None:
|
89
|
+
# Get summary for all pipelines
|
90
|
+
return self._registry.get_summaries(cfg=cfg, code=code, project=project)
|
91
|
+
else:
|
92
|
+
# Get summary for specific pipeline
|
93
|
+
pipeline = self._registry.get_pipeline_object(name=name)
|
94
|
+
return pipeline.get_summary(cfg=cfg, code=code, project=project)
|
95
|
+
|
96
|
+
def show_summary(
|
97
|
+
self,
|
98
|
+
name: Optional[str] = None,
|
99
|
+
cfg: bool = True,
|
100
|
+
code: bool = True,
|
101
|
+
project: bool = True,
|
102
|
+
to_html: bool = False,
|
103
|
+
to_svg: bool = False
|
104
|
+
) -> None:
|
105
|
+
"""Display pipeline summary.
|
106
|
+
|
107
|
+
Args:
|
108
|
+
name: Name of pipeline to summarize, or None for all pipelines
|
109
|
+
cfg: Whether to include configuration information
|
110
|
+
code: Whether to include code information
|
111
|
+
project: Whether to include project information
|
112
|
+
to_html: Whether to output HTML
|
113
|
+
to_svg: Whether to output SVG
|
114
|
+
"""
|
115
|
+
summary = self.get_summary(name=name, cfg=cfg, code=code, project=project)
|
116
|
+
|
117
|
+
if name is None:
|
118
|
+
# Display all pipelines in a table
|
119
|
+
from rich.table import Table
|
120
|
+
table = Table(title="Pipeline Summaries")
|
121
|
+
table.add_column("Pipeline", style="cyan")
|
122
|
+
table.add_column("Tags", style="magenta")
|
123
|
+
table.add_column("Description", style="green")
|
124
|
+
table.add_column("Modified", style="yellow")
|
125
|
+
|
126
|
+
for pipeline_name, info in summary.items():
|
127
|
+
tags = ", ".join(info.get("tags", []))
|
128
|
+
desc = info.get("description", "")[:50] + "..." if len(info.get("description", "")) > 50 else info.get("description", "")
|
129
|
+
modified = info.get("modified", "N/A")
|
130
|
+
table.add_row(pipeline_name, tags, desc, modified)
|
131
|
+
|
132
|
+
rich.print(table)
|
133
|
+
else:
|
134
|
+
# Display single pipeline details
|
135
|
+
rich.print(f"Pipeline: {name}")
|
136
|
+
rich.print("=" * 50)
|
137
|
+
|
138
|
+
for key, value in summary.items():
|
139
|
+
if isinstance(value, dict):
|
140
|
+
rich.print(f"{key}:")
|
141
|
+
for sub_key, sub_value in value.items():
|
142
|
+
rich.print(f" {sub_key}: {sub_value}")
|
143
|
+
else:
|
144
|
+
rich.print(f"{key}: {value}")
|
145
|
+
|
146
|
+
def show_pipelines(self) -> None:
|
147
|
+
"""Display available pipelines in a formatted table."""
|
148
|
+
pipelines = self.list_pipelines()
|
149
|
+
|
150
|
+
if not pipelines:
|
151
|
+
rich.print("No pipelines found.")
|
152
|
+
return
|
153
|
+
|
154
|
+
# Get pipeline info for display
|
155
|
+
pipeline_info = []
|
156
|
+
for name in pipelines:
|
157
|
+
try:
|
158
|
+
summary = self.get_summary(name=name, cfg=False, code=False, project=False)
|
159
|
+
pipeline_info.append({
|
160
|
+
"name": name,
|
161
|
+
"tags": ", ".join(summary.get("tags", [])),
|
162
|
+
"description": summary.get("description", "")[:50] + "..."
|
163
|
+
if len(summary.get("description", "")) > 50
|
164
|
+
else summary.get("description", "")
|
165
|
+
})
|
166
|
+
except Exception:
|
167
|
+
pipeline_info.append({
|
168
|
+
"name": name,
|
169
|
+
"tags": "",
|
170
|
+
"description": "Error loading info"
|
171
|
+
})
|
172
|
+
|
173
|
+
# Display as table
|
174
|
+
from rich.table import Table
|
175
|
+
table = Table(title="Available Pipelines")
|
176
|
+
table.add_column("Pipeline", style="cyan")
|
177
|
+
table.add_column("Tags", style="magenta")
|
178
|
+
table.add_column("Description", style="green")
|
179
|
+
|
180
|
+
for info in pipeline_info:
|
181
|
+
table.add_row(info["name"], info["tags"], info["description"])
|
182
|
+
|
183
|
+
rich.print(table)
|
184
|
+
|
185
|
+
def list_pipelines(self) -> list[str]:
|
186
|
+
"""List all available pipeline names.
|
187
|
+
|
188
|
+
Returns:
|
189
|
+
list[str]: List of pipeline names
|
190
|
+
"""
|
191
|
+
return self._registry.list_pipelines()
|
192
|
+
|
193
|
+
@property
|
194
|
+
def pipelines(self) -> list[str]:
|
195
|
+
"""Get list of available pipeline names.
|
196
|
+
|
197
|
+
Returns:
|
198
|
+
list[str]: List of pipeline names
|
199
|
+
"""
|
200
|
+
return self.list_pipelines()
|
201
|
+
|
202
|
+
@property
|
203
|
+
def summary(self) -> dict[str, dict | str]:
|
204
|
+
"""Get complete summary of all pipelines.
|
205
|
+
|
206
|
+
Returns:
|
207
|
+
dict[str, dict | str]: Complete summary information
|
208
|
+
"""
|
209
|
+
return self.get_summary()
|
210
|
+
|
211
|
+
def add_hook(
|
212
|
+
self,
|
213
|
+
name: str,
|
214
|
+
type: "HookType",
|
215
|
+
to: Optional[str] = None,
|
216
|
+
function_name: Optional[str] = None
|
217
|
+
) -> None:
|
218
|
+
"""Add a hook to a pipeline.
|
219
|
+
|
220
|
+
Args:
|
221
|
+
name: Name of the pipeline
|
222
|
+
type: Type of hook to add
|
223
|
+
to: Target for the hook
|
224
|
+
function_name: Name of the function to hook
|
225
|
+
"""
|
226
|
+
self._registry.add_hook(
|
227
|
+
name=name,
|
228
|
+
type=type,
|
229
|
+
to=to,
|
230
|
+
function_name=function_name
|
231
|
+
)
|