FlowerPower 0.11.6.20__py3-none-any.whl → 0.21.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/__init__.py +2 -6
- flowerpower/cfg/__init__.py +7 -14
- flowerpower/cfg/base.py +29 -25
- flowerpower/cfg/pipeline/__init__.py +8 -6
- flowerpower/cfg/pipeline/_schedule.py +32 -0
- flowerpower/cfg/pipeline/adapter.py +0 -5
- flowerpower/cfg/pipeline/builder.py +377 -0
- flowerpower/cfg/pipeline/run.py +36 -0
- flowerpower/cfg/project/__init__.py +11 -24
- flowerpower/cfg/project/adapter.py +0 -12
- flowerpower/cli/__init__.py +2 -21
- flowerpower/cli/cfg.py +0 -3
- flowerpower/cli/mqtt.py +0 -6
- flowerpower/cli/pipeline.py +22 -415
- flowerpower/cli/utils.py +0 -1
- flowerpower/flowerpower.py +345 -146
- flowerpower/pipeline/__init__.py +2 -0
- flowerpower/pipeline/base.py +21 -12
- flowerpower/pipeline/io.py +58 -54
- flowerpower/pipeline/manager.py +165 -726
- flowerpower/pipeline/pipeline.py +643 -0
- flowerpower/pipeline/registry.py +285 -18
- flowerpower/pipeline/visualizer.py +5 -6
- flowerpower/plugins/io/__init__.py +8 -0
- flowerpower/plugins/mqtt/__init__.py +7 -11
- flowerpower/settings/__init__.py +0 -2
- flowerpower/settings/{backend.py → _backend.py} +0 -21
- flowerpower/settings/logging.py +1 -1
- flowerpower/utils/logging.py +24 -12
- flowerpower/utils/misc.py +17 -256
- flowerpower/utils/monkey.py +1 -83
- flowerpower-0.21.0.dist-info/METADATA +463 -0
- flowerpower-0.21.0.dist-info/RECORD +44 -0
- flowerpower/cfg/pipeline/schedule.py +0 -74
- flowerpower/cfg/project/job_queue.py +0 -238
- flowerpower/cli/job_queue.py +0 -1061
- flowerpower/fs/__init__.py +0 -29
- flowerpower/fs/base.py +0 -662
- flowerpower/fs/ext.py +0 -2143
- flowerpower/fs/storage_options.py +0 -1420
- flowerpower/job_queue/__init__.py +0 -294
- flowerpower/job_queue/apscheduler/__init__.py +0 -11
- flowerpower/job_queue/apscheduler/_setup/datastore.py +0 -110
- flowerpower/job_queue/apscheduler/_setup/eventbroker.py +0 -93
- flowerpower/job_queue/apscheduler/manager.py +0 -1051
- flowerpower/job_queue/apscheduler/setup.py +0 -554
- flowerpower/job_queue/apscheduler/trigger.py +0 -169
- flowerpower/job_queue/apscheduler/utils.py +0 -311
- flowerpower/job_queue/base.py +0 -413
- flowerpower/job_queue/rq/__init__.py +0 -10
- flowerpower/job_queue/rq/_trigger.py +0 -37
- flowerpower/job_queue/rq/concurrent_workers/gevent_worker.py +0 -226
- flowerpower/job_queue/rq/concurrent_workers/thread_worker.py +0 -231
- flowerpower/job_queue/rq/manager.py +0 -1582
- flowerpower/job_queue/rq/setup.py +0 -154
- flowerpower/job_queue/rq/utils.py +0 -69
- flowerpower/mqtt.py +0 -12
- flowerpower/pipeline/job_queue.py +0 -583
- flowerpower/pipeline/runner.py +0 -603
- flowerpower/plugins/io/base.py +0 -2520
- flowerpower/plugins/io/helpers/datetime.py +0 -298
- flowerpower/plugins/io/helpers/polars.py +0 -875
- flowerpower/plugins/io/helpers/pyarrow.py +0 -570
- flowerpower/plugins/io/helpers/sql.py +0 -202
- flowerpower/plugins/io/loader/__init__.py +0 -28
- flowerpower/plugins/io/loader/csv.py +0 -37
- flowerpower/plugins/io/loader/deltatable.py +0 -190
- flowerpower/plugins/io/loader/duckdb.py +0 -19
- flowerpower/plugins/io/loader/json.py +0 -37
- flowerpower/plugins/io/loader/mqtt.py +0 -159
- flowerpower/plugins/io/loader/mssql.py +0 -26
- flowerpower/plugins/io/loader/mysql.py +0 -26
- flowerpower/plugins/io/loader/oracle.py +0 -26
- flowerpower/plugins/io/loader/parquet.py +0 -35
- flowerpower/plugins/io/loader/postgres.py +0 -26
- flowerpower/plugins/io/loader/pydala.py +0 -19
- flowerpower/plugins/io/loader/sqlite.py +0 -23
- flowerpower/plugins/io/metadata.py +0 -244
- flowerpower/plugins/io/saver/__init__.py +0 -28
- flowerpower/plugins/io/saver/csv.py +0 -36
- flowerpower/plugins/io/saver/deltatable.py +0 -186
- flowerpower/plugins/io/saver/duckdb.py +0 -19
- flowerpower/plugins/io/saver/json.py +0 -36
- flowerpower/plugins/io/saver/mqtt.py +0 -28
- flowerpower/plugins/io/saver/mssql.py +0 -26
- flowerpower/plugins/io/saver/mysql.py +0 -26
- flowerpower/plugins/io/saver/oracle.py +0 -26
- flowerpower/plugins/io/saver/parquet.py +0 -36
- flowerpower/plugins/io/saver/postgres.py +0 -26
- flowerpower/plugins/io/saver/pydala.py +0 -20
- flowerpower/plugins/io/saver/sqlite.py +0 -24
- flowerpower/plugins/mqtt/cfg.py +0 -17
- flowerpower/plugins/mqtt/manager.py +0 -962
- flowerpower/settings/job_queue.py +0 -87
- flowerpower/utils/scheduler.py +0 -311
- flowerpower-0.11.6.20.dist-info/METADATA +0 -537
- flowerpower-0.11.6.20.dist-info/RECORD +0 -102
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/WHEEL +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/top_level.txt +0 -0
flowerpower/pipeline/base.py
CHANGED
@@ -3,11 +3,12 @@ import posixpath
|
|
3
3
|
import sys
|
4
4
|
from types import TracebackType
|
5
5
|
|
6
|
+
from fsspec_utils import AbstractFileSystem, BaseStorageOptions, filesystem
|
6
7
|
from loguru import logger
|
7
8
|
from munch import Munch
|
8
9
|
|
10
|
+
from ..settings import CONFIG_DIR, PIPELINES_DIR
|
9
11
|
from ..cfg import PipelineConfig, ProjectConfig
|
10
|
-
from ..fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
|
11
12
|
from ..utils.logging import setup_logging
|
12
13
|
|
13
14
|
setup_logging()
|
@@ -40,26 +41,35 @@ class BasePipeline:
|
|
40
41
|
base_dir: str | None = None,
|
41
42
|
storage_options: dict | Munch | BaseStorageOptions = {},
|
42
43
|
fs: AbstractFileSystem | None = None,
|
43
|
-
|
44
|
-
pipelines_dir: str = "pipelines",
|
45
|
-
job_queue_type: str | None = None, # New parameter for worker backend
|
44
|
+
|
46
45
|
):
|
47
46
|
self._base_dir = base_dir
|
48
47
|
self._storage_options = storage_options
|
49
48
|
if fs is None:
|
50
|
-
fs =
|
49
|
+
fs = filesystem(self._base_dir, **self._storage_options)
|
51
50
|
self._fs = fs
|
52
|
-
|
53
|
-
self._pipelines_dir = pipelines_dir
|
54
|
-
self._job_queue_type = job_queue_type
|
51
|
+
|
55
52
|
|
53
|
+
self._setup_paths()
|
54
|
+
self._setup_directories()
|
55
|
+
self._add_modules_path()
|
56
|
+
|
57
|
+
def _setup_paths(self) -> None:
|
58
|
+
"""Set up configuration and pipeline directory paths."""
|
59
|
+
self._cfg_dir = CONFIG_DIR
|
60
|
+
self._pipelines_dir = PIPELINES_DIR
|
61
|
+
|
62
|
+
def _setup_directories(self) -> None:
|
63
|
+
"""Set up required directories with proper error handling."""
|
56
64
|
try:
|
57
65
|
self._fs.makedirs(f"{self._cfg_dir}/pipelines", exist_ok=True)
|
58
66
|
self._fs.makedirs(self._pipelines_dir, exist_ok=True)
|
59
|
-
except
|
67
|
+
except (OSError, PermissionError) as e:
|
60
68
|
logger.error(f"Error creating directories: {e}")
|
61
|
-
|
62
|
-
|
69
|
+
raise
|
70
|
+
except Exception as e:
|
71
|
+
logger.error(f"Unexpected error creating directories: {e}")
|
72
|
+
raise
|
63
73
|
|
64
74
|
def __enter__(self) -> "BasePipeline":
|
65
75
|
return self
|
@@ -98,7 +108,6 @@ class BasePipeline:
|
|
98
108
|
"""
|
99
109
|
return ProjectConfig.load(
|
100
110
|
base_dir=self._base_dir,
|
101
|
-
job_queue_type=self._job_queue_type,
|
102
111
|
fs=self._fs,
|
103
112
|
storage_options=self._storage_options,
|
104
113
|
)
|
flowerpower/pipeline/io.py
CHANGED
@@ -7,16 +7,18 @@ Manages the import and export of pipelines.
|
|
7
7
|
|
8
8
|
import posixpath
|
9
9
|
|
10
|
+
from fsspec_utils import (AbstractFileSystem, BaseStorageOptions,
|
11
|
+
DirFileSystem, filesystem)
|
10
12
|
from loguru import logger
|
11
13
|
from rich.console import Console
|
12
14
|
|
13
|
-
# Import necessary config types and utility functions
|
14
|
-
from ..fs.base import (AbstractFileSystem, BaseStorageOptions, DirFileSystem,
|
15
|
-
get_filesystem)
|
16
15
|
from ..settings import LOG_LEVEL
|
17
16
|
from ..utils.logging import setup_logging
|
18
17
|
from .registry import PipelineRegistry
|
19
18
|
|
19
|
+
# Import necessary config types and utility functions
|
20
|
+
|
21
|
+
|
20
22
|
console = Console()
|
21
23
|
|
22
24
|
setup_logging(level=LOG_LEVEL)
|
@@ -41,6 +43,41 @@ class PipelineIOManager:
|
|
41
43
|
self._cfg_dir = registry._cfg_dir
|
42
44
|
self._pipelines_dir = registry._pipelines_dir
|
43
45
|
|
46
|
+
def _get_pipeline_files(self, name: str) -> list[str]:
|
47
|
+
"""Get the list of files for a single pipeline."""
|
48
|
+
return [
|
49
|
+
"conf/project.yml",
|
50
|
+
f"conf/pipelines/{name}.yml",
|
51
|
+
f"pipelines/{name}.py",
|
52
|
+
]
|
53
|
+
|
54
|
+
def _get_many_pipeline_files(self, names: list[str]) -> list[str]:
|
55
|
+
"""Get the list of files for multiple pipelines."""
|
56
|
+
files = ["conf/project.yml"]
|
57
|
+
for name in names:
|
58
|
+
files.extend([
|
59
|
+
f"conf/pipelines/{name}.yml",
|
60
|
+
f"pipelines/{name}.py",
|
61
|
+
])
|
62
|
+
return files
|
63
|
+
|
64
|
+
def _get_all_pipeline_files(self) -> list[str] | None:
|
65
|
+
"""Get all pipeline files (returns None to let _sync_filesystem auto-discover)."""
|
66
|
+
return None
|
67
|
+
|
68
|
+
def _print_import_success(self, names: list[str], src_base_dir: str) -> None:
|
69
|
+
"""Print success message for import operations."""
|
70
|
+
console.print(
|
71
|
+
f"✅ Imported pipelines [bold blue]{', '.join(names)}[/bold blue] from [green]{src_base_dir}[/green] to [bold blue]{self.project_cfg.name}[/bold blue]"
|
72
|
+
)
|
73
|
+
|
74
|
+
def _print_export_success(self, names: list[str] | None, dest_base_dir: str) -> None:
|
75
|
+
"""Print success message for export operations."""
|
76
|
+
if names:
|
77
|
+
self._print_export_success(names, dest_base_dir)
|
78
|
+
else:
|
79
|
+
self._print_export_success(None, dest_base_dir)
|
80
|
+
|
44
81
|
def _sync_filesystem(
|
45
82
|
self,
|
46
83
|
src_base_dir: str,
|
@@ -69,7 +106,7 @@ class PipelineIOManager:
|
|
69
106
|
|
70
107
|
def _get_filesystem(base_dir, fs, storage_options):
|
71
108
|
if fs is None:
|
72
|
-
fs =
|
109
|
+
fs = filesystem(base_dir, storage_options=storage_options)
|
73
110
|
else:
|
74
111
|
if not isinstance(fs, AbstractFileSystem):
|
75
112
|
raise ValueError(
|
@@ -154,12 +191,7 @@ class PipelineIOManager:
|
|
154
191
|
pm.import_pipeline("my_pipeline", "/path/to/pipeline")
|
155
192
|
```
|
156
193
|
"""
|
157
|
-
files =
|
158
|
-
"conf/project.yml",
|
159
|
-
f"conf/pipelines/{name}.yml",
|
160
|
-
f"pipelines/{name}.py",
|
161
|
-
]
|
162
|
-
|
194
|
+
files = self._get_pipeline_files(name)
|
163
195
|
self._sync_filesystem(
|
164
196
|
src_base_dir=src_base_dir,
|
165
197
|
src_fs=src_fs,
|
@@ -171,10 +203,7 @@ class PipelineIOManager:
|
|
171
203
|
overwrite=overwrite,
|
172
204
|
)
|
173
205
|
|
174
|
-
|
175
|
-
console.print(
|
176
|
-
f"✅ Imported pipeline [bold blue]{name}[/bold blue] from [green]{src_base_dir}[/green] to [bold blue]{self.project_cfg.name}[/bold blue]"
|
177
|
-
)
|
206
|
+
self._print_import_success([name], src_base_dir)
|
178
207
|
|
179
208
|
def import_many(
|
180
209
|
self,
|
@@ -208,17 +237,8 @@ class PipelineIOManager:
|
|
208
237
|
```
|
209
238
|
"""
|
210
239
|
|
211
|
-
files =
|
240
|
+
files = self._get_many_pipeline_files(names)
|
212
241
|
|
213
|
-
for name in names:
|
214
|
-
files.extend(
|
215
|
-
[
|
216
|
-
f"conf/pipelines/{name}.yml",
|
217
|
-
f"pipelines/{name}.py",
|
218
|
-
]
|
219
|
-
)
|
220
|
-
|
221
|
-
# Sync the filesystem
|
222
242
|
self._sync_filesystem(
|
223
243
|
src_base_dir=src_base_dir,
|
224
244
|
src_fs=src_fs,
|
@@ -229,9 +249,7 @@ class PipelineIOManager:
|
|
229
249
|
files=files,
|
230
250
|
overwrite=overwrite,
|
231
251
|
)
|
232
|
-
|
233
|
-
f"✅ Imported pipelines [bold blue]{', '.join(names)}[/bold blue] from [green]{src_base_dir}[/green] to [bold blue]{self.project_cfg.name}[/bold blue]"
|
234
|
-
)
|
252
|
+
self._print_import_success(names, src_base_dir)
|
235
253
|
|
236
254
|
def import_all(
|
237
255
|
self,
|
@@ -260,6 +278,8 @@ class PipelineIOManager:
|
|
260
278
|
# pm.import_all("s3://my-bucket/pipelines_backup", storage_options={"key": "...", "secret": "..."}, overwrite=False)
|
261
279
|
```
|
262
280
|
"""
|
281
|
+
files = self._get_all_pipeline_files()
|
282
|
+
|
263
283
|
self._sync_filesystem(
|
264
284
|
src_base_dir=src_base_dir,
|
265
285
|
src_fs=src_fs,
|
@@ -267,12 +287,10 @@ class PipelineIOManager:
|
|
267
287
|
dest_base_dir=".",
|
268
288
|
dest_fs=self._fs,
|
269
289
|
dest_storage_options=None,
|
270
|
-
files=
|
290
|
+
files=files,
|
271
291
|
overwrite=overwrite,
|
272
292
|
)
|
273
|
-
|
274
|
-
f"✅ Imported all pipelines from [green]{src_base_dir}[/green] to [bold blue]{self.project_cfg.name}[/bold blue]"
|
275
|
-
)
|
293
|
+
self._print_import_success([], src_base_dir)
|
276
294
|
|
277
295
|
def export_pipeline(
|
278
296
|
self,
|
@@ -306,13 +324,8 @@ class PipelineIOManager:
|
|
306
324
|
# pm.export("my_pipeline", "s3://my-bucket/exports", storage_options={"key": "...", "secret": "..."})
|
307
325
|
```
|
308
326
|
"""
|
309
|
-
files =
|
310
|
-
"conf/project.yml",
|
311
|
-
f"conf/pipelines/{name}.yml",
|
312
|
-
f"pipelines/{name}.py",
|
313
|
-
]
|
327
|
+
files = self._get_pipeline_files(name)
|
314
328
|
|
315
|
-
# Sync the filesystem
|
316
329
|
self._sync_filesystem(
|
317
330
|
src_base_dir=".",
|
318
331
|
src_fs=self._fs,
|
@@ -324,9 +337,7 @@ class PipelineIOManager:
|
|
324
337
|
overwrite=overwrite,
|
325
338
|
)
|
326
339
|
|
327
|
-
|
328
|
-
f"✅ Exported pipeline [bold blue]{self.project_cfg.name}.{name}[/bold blue] to [green]{dest_base_dir}[/green]"
|
329
|
-
)
|
340
|
+
self._print_export_success([name], dest_base_dir)
|
330
341
|
|
331
342
|
def export_many(
|
332
343
|
self,
|
@@ -356,23 +367,15 @@ class PipelineIOManager:
|
|
356
367
|
pm.export_many(pipelines_to_export, "/path/to/export_dir", overwrite=True)
|
357
368
|
```
|
358
369
|
"""
|
359
|
-
|
360
|
-
"conf/project.yml",
|
361
|
-
]
|
370
|
+
# Check if pipelines exist in the registry
|
362
371
|
for name in names:
|
363
|
-
# Check if the pipeline exists in the registry
|
364
372
|
if not self.registry.has_pipeline(name):
|
365
373
|
raise ValueError(
|
366
374
|
f"Pipeline {name} does not exist in the registry. Please check the name."
|
367
375
|
)
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
f"conf/pipelines/{name}.yml",
|
372
|
-
f"pipelines/{name}.py",
|
373
|
-
]
|
374
|
-
)
|
375
|
-
# Sync the filesystem
|
376
|
+
|
377
|
+
files = self._get_many_pipeline_files(names)
|
378
|
+
|
376
379
|
self._sync_filesystem(
|
377
380
|
src_base_dir=".",
|
378
381
|
src_fs=self._fs,
|
@@ -414,7 +417,8 @@ class PipelineIOManager:
|
|
414
417
|
# pm.export_all("s3://my-bucket/pipelines_backup", storage_options={"key": "...", "secret": "..."}, overwrite=False)
|
415
418
|
```
|
416
419
|
"""
|
417
|
-
|
420
|
+
files = self._get_all_pipeline_files()
|
421
|
+
|
418
422
|
self._sync_filesystem(
|
419
423
|
src_base_dir=".",
|
420
424
|
src_fs=self._fs,
|
@@ -422,7 +426,7 @@ class PipelineIOManager:
|
|
422
426
|
dest_base_dir=dest_base_dir,
|
423
427
|
dest_fs=dest_fs,
|
424
428
|
dest_storage_options=dest_storage_options,
|
425
|
-
files=
|
429
|
+
files=files,
|
426
430
|
overwrite=overwrite,
|
427
431
|
)
|
428
432
|
console.print(
|