FlowerPower 0.21.0__py3-none-any.whl → 0.30.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/pipeline/run.py +55 -2
- flowerpower/cli/__init__.py +0 -7
- flowerpower/pipeline/manager.py +0 -2
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/METADATA +2 -14
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/RECORD +9 -11
- flowerpower/cli/mqtt.py +0 -168
- flowerpower/plugins/mqtt/__init__.py +0 -8
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/WHEEL +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.21.0.dist-info → flowerpower-0.30.0.dist-info}/top_level.txt +0 -0
flowerpower/cfg/pipeline/run.py
CHANGED
@@ -39,8 +39,34 @@ class RunConfig(BaseConfig):
|
|
39
39
|
project_adapter_cfg: dict | None = msgspec.field(default=None)
|
40
40
|
adapter: dict[str, Any] | None = msgspec.field(default=None)
|
41
41
|
reload: bool = msgspec.field(default=False)
|
42
|
-
|
43
|
-
|
42
|
+
|
43
|
+
|
44
|
+
class CallbackSpec(msgspec.Struct):
|
45
|
+
"""Specification for a callback function with optional arguments."""
|
46
|
+
func: Callable
|
47
|
+
args: tuple | None = None
|
48
|
+
kwargs: dict | None = None
|
49
|
+
|
50
|
+
|
51
|
+
class RunConfig(BaseConfig):
|
52
|
+
inputs: dict | None = msgspec.field(default_factory=dict)
|
53
|
+
final_vars: list[str] | None = msgspec.field(default_factory=list)
|
54
|
+
config: dict | None = msgspec.field(default_factory=dict)
|
55
|
+
cache: dict | bool | None = msgspec.field(default=False)
|
56
|
+
with_adapter: WithAdapterConfig = msgspec.field(default_factory=WithAdapterConfig)
|
57
|
+
executor: ExecutorConfig = msgspec.field(default_factory=ExecutorConfig)
|
58
|
+
log_level: str | None = msgspec.field(default="INFO")
|
59
|
+
max_retries: int = msgspec.field(default=3)
|
60
|
+
retry_delay: int | float = msgspec.field(default=1)
|
61
|
+
jitter_factor: float | None = msgspec.field(default=0.1)
|
62
|
+
retry_exceptions: list[str] = msgspec.field(default_factory=lambda: ["Exception"])
|
63
|
+
# New fields for comprehensive configuration
|
64
|
+
pipeline_adapter_cfg: dict | None = msgspec.field(default=None)
|
65
|
+
project_adapter_cfg: dict | None = msgspec.field(default=None)
|
66
|
+
adapter: dict[str, Any] | None = msgspec.field(default=None)
|
67
|
+
reload: bool = msgspec.field(default=False)
|
68
|
+
on_success: CallbackSpec | None = msgspec.field(default=None)
|
69
|
+
on_failure: CallbackSpec | None = msgspec.field(default=None)
|
44
70
|
|
45
71
|
def __post_init__(self):
|
46
72
|
if isinstance(self.inputs, dict):
|
@@ -81,3 +107,30 @@ class RunConfig(BaseConfig):
|
|
81
107
|
else:
|
82
108
|
converted_exceptions.append(Exception)
|
83
109
|
self.retry_exceptions = converted_exceptions
|
110
|
+
|
111
|
+
# Handle callback conversions
|
112
|
+
if self.on_success is not None and not isinstance(self.on_success, CallbackSpec):
|
113
|
+
if callable(self.on_success):
|
114
|
+
self.on_success = CallbackSpec(func=self.on_success)
|
115
|
+
elif isinstance(self.on_success, tuple) and len(self.on_success) == 3:
|
116
|
+
func, args, kwargs = self.on_success
|
117
|
+
self.on_success = CallbackSpec(func=func, args=args, kwargs=kwargs)
|
118
|
+
else:
|
119
|
+
self.on_success = None
|
120
|
+
warnings.warn(
|
121
|
+
"Invalid on_success format, must be Callable or (Callable, args, kwargs)",
|
122
|
+
RuntimeWarning
|
123
|
+
)
|
124
|
+
|
125
|
+
if self.on_failure is not None and not isinstance(self.on_failure, CallbackSpec):
|
126
|
+
if callable(self.on_failure):
|
127
|
+
self.on_failure = CallbackSpec(func=self.on_failure)
|
128
|
+
elif isinstance(self.on_failure, tuple) and len(self.on_failure) == 3:
|
129
|
+
func, args, kwargs = self.on_failure
|
130
|
+
self.on_failure = CallbackSpec(func=func, args=args, kwargs=kwargs)
|
131
|
+
else:
|
132
|
+
self.on_failure = None
|
133
|
+
warnings.warn(
|
134
|
+
"Invalid on_failure format, must be Callable or (Callable, args, kwargs)",
|
135
|
+
RuntimeWarning
|
136
|
+
)
|
flowerpower/cli/__init__.py
CHANGED
flowerpower/pipeline/manager.py
CHANGED
@@ -40,13 +40,11 @@ class PipelineManager:
|
|
40
40
|
- Configuration management and loading
|
41
41
|
- Pipeline creation, deletion, and discovery
|
42
42
|
- Pipeline execution via PipelineRunner
|
43
|
-
- Job scheduling via PipelineScheduler
|
44
43
|
- Visualization via PipelineVisualizer
|
45
44
|
- Import/export operations via PipelineIOManager
|
46
45
|
|
47
46
|
Attributes:
|
48
47
|
registry (PipelineRegistry): Handles pipeline registration and discovery
|
49
|
-
scheduler (PipelineScheduler): Manages job scheduling and execution
|
50
48
|
visualizer (PipelineVisualizer): Handles pipeline visualization
|
51
49
|
io (PipelineIOManager): Manages pipeline import/export operations
|
52
50
|
project_cfg (ProjectConfig): Current project configuration
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: FlowerPower
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.30.0
|
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
|
@@ -11,7 +11,7 @@ Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
12
12
|
Requires-Dist: duration-parser>=1.0.1
|
13
13
|
Requires-Dist: fsspec>=2024.10.0
|
14
|
-
Requires-Dist: fsspec-utils>=0.1.0
|
14
|
+
Requires-Dist: fsspec-utils[full]>=0.1.0
|
15
15
|
Requires-Dist: humanize>=4.12.2
|
16
16
|
Requires-Dist: msgspec>=0.19.0
|
17
17
|
Requires-Dist: munch>=4.0.0
|
@@ -25,26 +25,14 @@ Provides-Extra: io
|
|
25
25
|
Requires-Dist: flowerpower-io>=0.1.1; extra == "io"
|
26
26
|
Provides-Extra: io-legacy
|
27
27
|
Requires-Dist: flowerpower-io[legacy]>=0.1.1; extra == "io-legacy"
|
28
|
-
Provides-Extra: mongodb
|
29
|
-
Requires-Dist: pymongo>=4.7.2; extra == "mongodb"
|
30
|
-
Provides-Extra: mqtt
|
31
|
-
Requires-Dist: paho-mqtt>=2.1.0; extra == "mqtt"
|
32
|
-
Requires-Dist: orjson>=3.10.11; extra == "mqtt"
|
33
|
-
Requires-Dist: mmh3>=5.1.0; extra == "mqtt"
|
34
28
|
Provides-Extra: opentelemetry
|
35
29
|
Requires-Dist: opentelemetry-api>=1.5.0; extra == "opentelemetry"
|
36
30
|
Requires-Dist: opentelemetry-sdk>=1.5.0; extra == "opentelemetry"
|
37
31
|
Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0; extra == "opentelemetry"
|
38
32
|
Provides-Extra: ray
|
39
33
|
Requires-Dist: ray>=2.34.0; extra == "ray"
|
40
|
-
Provides-Extra: tui
|
41
|
-
Requires-Dist: textual>=0.85.2; extra == "tui"
|
42
34
|
Provides-Extra: ui
|
43
35
|
Requires-Dist: sf-hamilton-ui>=0.0.11; extra == "ui"
|
44
|
-
Provides-Extra: webserver
|
45
|
-
Requires-Dist: sanic>=24.6.0; extra == "webserver"
|
46
|
-
Requires-Dist: sanic-ext>=23.12.0; extra == "webserver"
|
47
|
-
Requires-Dist: orjson>=3.10.11; extra == "webserver"
|
48
36
|
Provides-Extra: openlineage
|
49
37
|
Requires-Dist: openlineage-python>=1.32.0; extra == "openlineage"
|
50
38
|
Dynamic: license-file
|
@@ -6,23 +6,21 @@ flowerpower/cfg/pipeline/__init__.py,sha256=HSUlDt9smo-zPqOljEl329CQg8qsd0EJfCH1
|
|
6
6
|
flowerpower/cfg/pipeline/_schedule.py,sha256=kaDyij3eUj0u6VdmJW4x_AQbSAZ-r7s2Fk7QFkXU5JQ,1029
|
7
7
|
flowerpower/cfg/pipeline/adapter.py,sha256=uBKV6BZlsRRqSYNyC1oEWPchsaH7rFPCBobG5BrF3ss,2265
|
8
8
|
flowerpower/cfg/pipeline/builder.py,sha256=rZ-cspbV-nwtckvOA49vt7DNJNb-gRLHHWiejmJPsFs,13192
|
9
|
-
flowerpower/cfg/pipeline/run.py,sha256=
|
9
|
+
flowerpower/cfg/pipeline/run.py,sha256=cirZbiHsY8D87idBvbfNv1gEtKpgv3xLfiiFIXJFxrA,6733
|
10
10
|
flowerpower/cfg/project/__init__.py,sha256=bMMZ5Zo3YgkgOGt82H1mW8I4WnoCUpa0bSLPpZiB7K4,4560
|
11
11
|
flowerpower/cfg/project/adapter.py,sha256=2k2U25NziDEiUacLTjxaSxOVkaQBRt6ECWGRGX0v4J0,1481
|
12
|
-
flowerpower/cli/__init__.py,sha256=
|
12
|
+
flowerpower/cli/__init__.py,sha256=RkJT3mPlSOi55dNNP8kpm_omF0zEfbmWVP16N-lkijE,4897
|
13
13
|
flowerpower/cli/cfg.py,sha256=P7qEcjraitMxbzVWJMqWeitIdpUkW41QkUi7ol0ksW0,1455
|
14
|
-
flowerpower/cli/mqtt.py,sha256=NuQtvKA3DrmLdGRsR7CFhbVhKZ4qObzwRlvENSkTc0k,6009
|
15
14
|
flowerpower/cli/pipeline.py,sha256=I58cWjK7J4dkXdJXIePcPiD7iILnYqoje0ztkR5mNwg,21958
|
16
15
|
flowerpower/cli/utils.py,sha256=tsxvKIqUhl4m9IzuaSoc5a3_gb6Fu4LYyV8fVodqIdA,5127
|
17
16
|
flowerpower/pipeline/__init__.py,sha256=ltr4LQnM5Boa9w7t-lNVmmcSglIkTPuIoeYnEKWU4Og,122
|
18
17
|
flowerpower/pipeline/base.py,sha256=oQSDfEAyY2_kDRlHNnHr6ihZvfGeOjyMJRPKob1i7U8,3560
|
19
18
|
flowerpower/pipeline/io.py,sha256=phYJhN4LZ0c6d8_udEQ4C9cGzeV3Ku0hsj0gyE1n2UY,16246
|
20
|
-
flowerpower/pipeline/manager.py,sha256=
|
19
|
+
flowerpower/pipeline/manager.py,sha256=gJMWe_T1WpxO2H9GDrNtf61S4oJuLugMHwX82jqAuEU,47579
|
21
20
|
flowerpower/pipeline/pipeline.py,sha256=8Vhc3GGoAJI-5zv8qX4gZ5JwJrTdVoiXHWNpv5OeKGw,26207
|
22
21
|
flowerpower/pipeline/registry.py,sha256=iHdEBPiRpZorAUe6sDkqONoP8t6cicdQYGdK8UyxuAQ,28791
|
23
22
|
flowerpower/pipeline/visualizer.py,sha256=EVpjv-TUe1zGvdEAWyShJcVXurm02W0jkLbj7z1uAv4,4953
|
24
23
|
flowerpower/plugins/io/__init__.py,sha256=ZmSdKoh3TavJagOz0vUItnEqAh3mAM1QpAWj0KufF_k,222
|
25
|
-
flowerpower/plugins/mqtt/__init__.py,sha256=4eTTvYY4SjC7O2lMaK-Hw5LQGvZE8TVl6HsXuVVD9zQ,228
|
26
24
|
flowerpower/settings/__init__.py,sha256=XKQa8AI9VrX8ievs-suq3Cm6PBt4cJ78ZHVIjUbXCyA,130
|
27
25
|
flowerpower/settings/_backend.py,sha256=Up1RBqAs3jtDUOV-9wEpL68Qmom-dRWMOeHXIh0F3lw,4273
|
28
26
|
flowerpower/settings/executor.py,sha256=vNF383g1gMGkq_CXUzateGMNcJZig-vHkVVb0Hi_b74,249
|
@@ -36,9 +34,9 @@ flowerpower/utils/misc.py,sha256=gY1KVJp4lF4S0THUu1LUrjXaf87TzLO-TcwHxZZh2Zk,841
|
|
36
34
|
flowerpower/utils/monkey.py,sha256=vJMYANjZI13PNbEQThdX0EFP1_6bGNHgnpF7HwReNyM,58
|
37
35
|
flowerpower/utils/open_telemetry.py,sha256=fQWJWbIQFtKIxMBjAWeF12NGnqT0isO3A3j-DSOv_vE,949
|
38
36
|
flowerpower/utils/templates.py,sha256=ouyEeSDqa9PjW8c32fGpcINlpC0WToawRFZkMPtwsLE,1591
|
39
|
-
flowerpower-0.
|
40
|
-
flowerpower-0.
|
41
|
-
flowerpower-0.
|
42
|
-
flowerpower-0.
|
43
|
-
flowerpower-0.
|
44
|
-
flowerpower-0.
|
37
|
+
flowerpower-0.30.0.dist-info/licenses/LICENSE,sha256=9AkLexxrmr0aBgSHiqxpJk9wgazpP1CTJyiDyr56J9k,1063
|
38
|
+
flowerpower-0.30.0.dist-info/METADATA,sha256=3nPehMWbDcryhbkgbieU-_13I_8S3-1aNL54bMdjdDs,17208
|
39
|
+
flowerpower-0.30.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
40
|
+
flowerpower-0.30.0.dist-info/entry_points.txt,sha256=61X11i5a2IwC9LBiP20XCDl5zMOigGCjMCx17B7bDbQ,52
|
41
|
+
flowerpower-0.30.0.dist-info/top_level.txt,sha256=VraH4WtEUfSxs5L-rXwDQhzQb9eLHTUtgvmFZ2dAYnA,12
|
42
|
+
flowerpower-0.30.0.dist-info/RECORD,,
|
flowerpower/cli/mqtt.py
DELETED
@@ -1,168 +0,0 @@
|
|
1
|
-
import importlib
|
2
|
-
import sys
|
3
|
-
|
4
|
-
import typer
|
5
|
-
|
6
|
-
from ..plugins.mqtt import run_pipeline_on_message as run_pipeline_on_message_
|
7
|
-
from ..plugins.mqtt import start_listener as start_listener_
|
8
|
-
from .utils import load_hook, parse_dict_or_list_param
|
9
|
-
|
10
|
-
app = typer.Typer(help="MQTT management commands")
|
11
|
-
|
12
|
-
|
13
|
-
@app.command()
|
14
|
-
def start_listener(
|
15
|
-
on_message: str,
|
16
|
-
topic: str,
|
17
|
-
base_dir: str,
|
18
|
-
host: str = "localhost",
|
19
|
-
port: int = 1883,
|
20
|
-
username: str | None = None,
|
21
|
-
password: str | None = None,
|
22
|
-
):
|
23
|
-
"""Start an MQTT client to listen to messages on a topic
|
24
|
-
|
25
|
-
The connection to the MQTT broker is established using the provided configuration o a
|
26
|
-
MQTT event broker defined in the project configuration file `conf/project.yml`.
|
27
|
-
If not configuration is found, you have to provide the connection parameters,
|
28
|
-
such as `host`, `port`, `username`, and `password`.
|
29
|
-
|
30
|
-
The `on_message` module should contain a function `on_message` that will be called
|
31
|
-
with the message payload as argument.
|
32
|
-
|
33
|
-
Args:
|
34
|
-
on_message: Name of the module containing the on_message function
|
35
|
-
topic: MQTT topic to listen to
|
36
|
-
base_dir: Base directory for the module
|
37
|
-
host: MQTT broker host
|
38
|
-
port: MQTT broker port
|
39
|
-
username: MQTT broker username
|
40
|
-
password: MQTT broker password
|
41
|
-
|
42
|
-
Examples:
|
43
|
-
$ flowerpower mqtt start_listener --on-message my_module --topic my_topic --base-dir /path/to/module
|
44
|
-
"""
|
45
|
-
sys.path.append(base_dir)
|
46
|
-
on_message_module = importlib.import_module(on_message)
|
47
|
-
start_listener_(
|
48
|
-
on_message=on_message_module.on_message,
|
49
|
-
topic=topic,
|
50
|
-
base_dir=base_dir,
|
51
|
-
host=host,
|
52
|
-
port=port,
|
53
|
-
username=username,
|
54
|
-
password=password,
|
55
|
-
background=False,
|
56
|
-
)
|
57
|
-
|
58
|
-
|
59
|
-
@app.command()
|
60
|
-
def run_pipeline_on_message(
|
61
|
-
name: str,
|
62
|
-
topic: str | None = None,
|
63
|
-
executor: str | None = None,
|
64
|
-
base_dir: str | None = None,
|
65
|
-
inputs: str | None = None,
|
66
|
-
final_vars: str | None = None,
|
67
|
-
config: str | None = None,
|
68
|
-
with_tracker: bool = False,
|
69
|
-
with_opentelemetry: bool = False,
|
70
|
-
with_progressbar: bool = False,
|
71
|
-
storage_options: str | None = None,
|
72
|
-
host: str | None = None,
|
73
|
-
port: int | None = None,
|
74
|
-
username: str | None = None,
|
75
|
-
password: str | None = None,
|
76
|
-
clean_session: bool = True,
|
77
|
-
qos: int = 0,
|
78
|
-
client_id: str | None = None,
|
79
|
-
client_id_suffix: str | None = None,
|
80
|
-
config_hook: str | None = None,
|
81
|
-
max_retries: int = typer.Option(
|
82
|
-
3, help="Maximum number of retry attempts if pipeline execution fails"
|
83
|
-
),
|
84
|
-
retry_delay: float = typer.Option(
|
85
|
-
1.0, help="Base delay between retries in seconds"
|
86
|
-
),
|
87
|
-
jitter_factor: float = typer.Option(
|
88
|
-
0.1, help="Random factor (0-1) applied to delay for jitter"
|
89
|
-
),
|
90
|
-
):
|
91
|
-
"""Run a pipeline on a message
|
92
|
-
|
93
|
-
This command sets up an MQTT listener that executes a pipeline whenever a message is
|
94
|
-
received on the specified topic. The pipeline can be configured to retry on failure
|
95
|
-
using exponential backoff with jitter for better resilience.
|
96
|
-
|
97
|
-
Args:
|
98
|
-
name: Name of the pipeline
|
99
|
-
topic: MQTT topic to listen to
|
100
|
-
executor: Name of the executor
|
101
|
-
base_dir: Base directory for the pipeline
|
102
|
-
inputs: Inputs as JSON or key=value pairs or dict string
|
103
|
-
final_vars: Final variables as JSON or list
|
104
|
-
config: Config for the hamilton pipeline executor
|
105
|
-
with_tracker: Enable tracking with hamilton ui
|
106
|
-
with_opentelemetry: Enable OpenTelemetry tracing
|
107
|
-
with_progressbar: Enable progress bar
|
108
|
-
storage_options: Storage options as JSON, dict string or key=value pairs
|
109
|
-
host: MQTT broker host
|
110
|
-
port: MQTT broker port
|
111
|
-
username: MQTT broker username
|
112
|
-
password: MQTT broker password
|
113
|
-
clean_session: Whether to start a clean session with the broker
|
114
|
-
qos: MQTT Quality of Service level (0, 1, or 2)
|
115
|
-
client_id: Custom MQTT client identifier
|
116
|
-
client_id_suffix: Optional suffix to append to client_id
|
117
|
-
config_hook: Function to process incoming messages into pipeline config
|
118
|
-
max_retries: Maximum number of retry attempts if pipeline execution fails
|
119
|
-
retry_delay: Base delay between retries in seconds
|
120
|
-
jitter_factor: Random factor (0-1) applied to delay for jitter
|
121
|
-
|
122
|
-
Examples:
|
123
|
-
# Basic usage with a specific topic
|
124
|
-
$ flowerpower mqtt run-pipeline-on-message my_pipeline --topic sensors/data
|
125
|
-
|
126
|
-
# Configure retries for resilience
|
127
|
-
$ flowerpower mqtt run-pipeline-on-message my_pipeline --topic sensors/data --max-retries 5 --retry-delay 2.0
|
128
|
-
|
129
|
-
# Use a config hook to process messages
|
130
|
-
$ flowerpower mqtt run-pipeline-on-message my_pipeline --topic data/incoming --config-hook process_message
|
131
|
-
|
132
|
-
|
133
|
-
"""
|
134
|
-
|
135
|
-
parsed_inputs = parse_dict_or_list_param(inputs, "dict")
|
136
|
-
parsed_config = parse_dict_or_list_param(config, "dict")
|
137
|
-
parsed_final_vars = parse_dict_or_list_param(final_vars, "list")
|
138
|
-
parsed_storage_options = parse_dict_or_list_param(storage_options, "dict")
|
139
|
-
|
140
|
-
config_hook_function = None
|
141
|
-
if config_hook:
|
142
|
-
config_hook_function = load_hook(name, config_hook, base_dir, storage_options)
|
143
|
-
|
144
|
-
run_pipeline_on_message_(
|
145
|
-
name=name,
|
146
|
-
topic=topic,
|
147
|
-
executor=executor,
|
148
|
-
base_dir=base_dir,
|
149
|
-
inputs=parsed_inputs,
|
150
|
-
final_vars=parsed_final_vars,
|
151
|
-
config=parsed_config,
|
152
|
-
with_tracker=with_tracker,
|
153
|
-
with_opentelemetry=with_opentelemetry,
|
154
|
-
with_progressbar=with_progressbar,
|
155
|
-
storage_options=parsed_storage_options,
|
156
|
-
host=host,
|
157
|
-
port=port,
|
158
|
-
username=username,
|
159
|
-
password=password,
|
160
|
-
clean_session=clean_session,
|
161
|
-
qos=qos,
|
162
|
-
client_id=client_id,
|
163
|
-
client_id_suffix=client_id_suffix,
|
164
|
-
config_hook=config_hook_function,
|
165
|
-
max_retries=max_retries,
|
166
|
-
retry_delay=retry_delay,
|
167
|
-
jitter_factor=jitter_factor,
|
168
|
-
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|