FlowerPower 0.30.0__py3-none-any.whl → 0.31.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.
- 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 +99 -40
- flowerpower/cfg/project/__init__.py +59 -14
- flowerpower/cfg/project/adapter.py +6 -0
- flowerpower/cli/__init__.py +8 -2
- 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 -274
- 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 +312 -138
- flowerpower/utils/security.py +221 -0
- {flowerpower-0.30.0.dist-info → flowerpower-0.31.1.dist-info}/METADATA +2 -2
- flowerpower-0.31.1.dist-info/RECORD +53 -0
- flowerpower/cfg/pipeline/_schedule.py +0 -32
- flowerpower-0.30.0.dist-info/RECORD +0 -42
- {flowerpower-0.30.0.dist-info → flowerpower-0.31.1.dist-info}/WHEEL +0 -0
- {flowerpower-0.30.0.dist-info → flowerpower-0.31.1.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.30.0.dist-info → flowerpower-0.31.1.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.30.0.dist-info → flowerpower-0.31.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
"""Security utilities for input validation and sanitization."""
|
2
|
+
|
3
|
+
import os
|
4
|
+
import re
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from collections.abc import Callable
|
10
|
+
|
11
|
+
|
12
|
+
class SecurityError(Exception):
|
13
|
+
"""Raised when security validation fails."""
|
14
|
+
pass
|
15
|
+
|
16
|
+
|
17
|
+
def validate_file_path(path: Union[str, Path],
|
18
|
+
allowed_extensions: Optional[List[str]] = None,
|
19
|
+
allow_absolute: bool = True,
|
20
|
+
allow_relative: bool = True) -> Path:
|
21
|
+
"""Validate and sanitize file paths to prevent directory traversal attacks.
|
22
|
+
|
23
|
+
Args:
|
24
|
+
path: File path to validate
|
25
|
+
allowed_extensions: List of allowed file extensions (e.g., ['.yaml', '.yml'])
|
26
|
+
allow_absolute: Whether to allow absolute paths
|
27
|
+
allow_relative: Whether to allow relative paths
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
Validated Path object
|
31
|
+
|
32
|
+
Raises:
|
33
|
+
SecurityError: If path is invalid or potentially dangerous
|
34
|
+
ValueError: If path is empty or None
|
35
|
+
"""
|
36
|
+
if not path:
|
37
|
+
raise ValueError("Path cannot be empty or None")
|
38
|
+
|
39
|
+
# Convert to Path object
|
40
|
+
path_obj = Path(path)
|
41
|
+
|
42
|
+
# Check for directory traversal attempts
|
43
|
+
path_str = str(path_obj)
|
44
|
+
if '..' in path_obj.parts or path_str.startswith('..'):
|
45
|
+
raise SecurityError(f"Directory traversal detected in path: {path}")
|
46
|
+
|
47
|
+
# Check absolute vs relative path restrictions
|
48
|
+
if path_obj.is_absolute() and not allow_absolute:
|
49
|
+
raise SecurityError(f"Absolute paths not allowed: {path}")
|
50
|
+
|
51
|
+
if not path_obj.is_absolute() and not allow_relative:
|
52
|
+
raise SecurityError(f"Relative paths not allowed: {path}")
|
53
|
+
|
54
|
+
# Validate file extension if specified
|
55
|
+
if allowed_extensions:
|
56
|
+
if not path_obj.suffix.lower() in [ext.lower() for ext in allowed_extensions]:
|
57
|
+
raise SecurityError(
|
58
|
+
f"File extension '{path_obj.suffix}' not allowed. "
|
59
|
+
f"Allowed: {allowed_extensions}"
|
60
|
+
)
|
61
|
+
|
62
|
+
# Check for potentially dangerous characters
|
63
|
+
dangerous_chars = ['|', '&', ';', '`', '$', '<', '>', '"', "'"]
|
64
|
+
if any(char in path_str for char in dangerous_chars):
|
65
|
+
raise SecurityError(f"Dangerous characters detected in path: {path}")
|
66
|
+
|
67
|
+
return path_obj
|
68
|
+
|
69
|
+
|
70
|
+
def validate_pipeline_name(name: str) -> str:
|
71
|
+
"""Validate pipeline name to prevent injection attacks.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
name: Pipeline name to validate
|
75
|
+
|
76
|
+
Returns:
|
77
|
+
Validated name
|
78
|
+
|
79
|
+
Raises:
|
80
|
+
ValueError: If name is invalid
|
81
|
+
SecurityError: If name contains dangerous characters
|
82
|
+
"""
|
83
|
+
if not name or not isinstance(name, str):
|
84
|
+
raise ValueError("Pipeline name must be a non-empty string")
|
85
|
+
|
86
|
+
name = name.strip()
|
87
|
+
if not name:
|
88
|
+
raise ValueError("Pipeline name cannot be empty or only whitespace")
|
89
|
+
|
90
|
+
# Check for dangerous characters
|
91
|
+
if not re.match(r'^[a-zA-Z0-9_-]+$', name):
|
92
|
+
raise SecurityError(
|
93
|
+
f"Pipeline name '{name}' contains invalid characters. "
|
94
|
+
"Only alphanumeric, underscore, and hyphen are allowed."
|
95
|
+
)
|
96
|
+
|
97
|
+
# Check length constraints
|
98
|
+
if len(name) > 100:
|
99
|
+
raise SecurityError(f"Pipeline name too long: {len(name)} > 100 characters")
|
100
|
+
|
101
|
+
return name
|
102
|
+
|
103
|
+
|
104
|
+
def validate_config_dict(config: Dict[str, Any],
|
105
|
+
allowed_keys: Optional[List[str]] = None,
|
106
|
+
max_depth: int = 10) -> Dict[str, Any]:
|
107
|
+
"""Validate configuration dictionary to prevent malicious content.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
config: Configuration dictionary to validate
|
111
|
+
allowed_keys: List of allowed top-level keys
|
112
|
+
max_depth: Maximum nesting depth to prevent DoS attacks
|
113
|
+
|
114
|
+
Returns:
|
115
|
+
Validated configuration dictionary
|
116
|
+
|
117
|
+
Raises:
|
118
|
+
SecurityError: If configuration contains dangerous content
|
119
|
+
ValueError: If configuration is invalid
|
120
|
+
"""
|
121
|
+
if not isinstance(config, dict):
|
122
|
+
raise ValueError("Configuration must be a dictionary")
|
123
|
+
|
124
|
+
# Check for allowed keys
|
125
|
+
if allowed_keys:
|
126
|
+
invalid_keys = set(config.keys()) - set(allowed_keys)
|
127
|
+
if invalid_keys:
|
128
|
+
raise SecurityError(f"Invalid configuration keys: {invalid_keys}")
|
129
|
+
|
130
|
+
# Check nesting depth
|
131
|
+
def check_depth(obj, depth=0):
|
132
|
+
if depth > max_depth:
|
133
|
+
raise SecurityError(f"Configuration nesting too deep: {depth} > {max_depth}")
|
134
|
+
|
135
|
+
if isinstance(obj, dict):
|
136
|
+
for value in obj.values():
|
137
|
+
check_depth(value, depth + 1)
|
138
|
+
elif isinstance(obj, (list, tuple)):
|
139
|
+
for item in obj:
|
140
|
+
check_depth(item, depth + 1)
|
141
|
+
|
142
|
+
check_depth(config)
|
143
|
+
|
144
|
+
return config
|
145
|
+
|
146
|
+
|
147
|
+
def sanitize_log_data(data: Any) -> Any:
|
148
|
+
"""Sanitize data for safe logging to prevent log injection.
|
149
|
+
|
150
|
+
Args:
|
151
|
+
data: Data to sanitize for logging
|
152
|
+
|
153
|
+
Returns:
|
154
|
+
Sanitized data safe for logging
|
155
|
+
"""
|
156
|
+
if isinstance(data, str):
|
157
|
+
# Remove potential log injection characters
|
158
|
+
sanitized = re.sub(r'[\r\n\t]', ' ', data)
|
159
|
+
# Limit length to prevent log flooding
|
160
|
+
if len(sanitized) > 1000:
|
161
|
+
sanitized = sanitized[:997] + "..."
|
162
|
+
return sanitized
|
163
|
+
elif isinstance(data, (dict, list)):
|
164
|
+
# For complex objects, convert to string and sanitize
|
165
|
+
return sanitize_log_data(str(data))
|
166
|
+
else:
|
167
|
+
return data
|
168
|
+
|
169
|
+
|
170
|
+
def validate_executor_type(executor_type: str) -> str:
|
171
|
+
"""Validate executor type to prevent arbitrary code execution.
|
172
|
+
|
173
|
+
Args:
|
174
|
+
executor_type: Executor type string to validate
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
Validated executor type
|
178
|
+
|
179
|
+
Raises:
|
180
|
+
SecurityError: If executor type is invalid or dangerous
|
181
|
+
"""
|
182
|
+
if not executor_type or not isinstance(executor_type, str):
|
183
|
+
raise ValueError("Executor type must be a non-empty string")
|
184
|
+
|
185
|
+
allowed_executors = {
|
186
|
+
'synchronous', 'threadpool', 'processpool', 'ray', 'dask'
|
187
|
+
}
|
188
|
+
|
189
|
+
if executor_type not in allowed_executors:
|
190
|
+
raise SecurityError(
|
191
|
+
f"Invalid executor type: {executor_type}. "
|
192
|
+
f"Allowed types: {allowed_executors}"
|
193
|
+
)
|
194
|
+
|
195
|
+
return executor_type
|
196
|
+
|
197
|
+
|
198
|
+
def validate_callback_function(callback: Any) -> bool:
|
199
|
+
"""Validate callback function to ensure it's safe to execute.
|
200
|
+
|
201
|
+
Args:
|
202
|
+
callback: Callback function or callable to validate
|
203
|
+
|
204
|
+
Returns:
|
205
|
+
True if callback is valid
|
206
|
+
|
207
|
+
Raises:
|
208
|
+
SecurityError: If callback is dangerous or invalid
|
209
|
+
"""
|
210
|
+
if callback is None:
|
211
|
+
return True
|
212
|
+
|
213
|
+
if not callable(callback):
|
214
|
+
raise SecurityError("Callback must be callable")
|
215
|
+
|
216
|
+
# Check if it's a built-in function that could be dangerous
|
217
|
+
dangerous_functions = {'eval', 'exec', 'compile', '__import__'}
|
218
|
+
if hasattr(callback, '__name__') and callback.__name__ in dangerous_functions:
|
219
|
+
raise SecurityError(f"Dangerous callback function: {callback.__name__}")
|
220
|
+
|
221
|
+
return True
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: FlowerPower
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.31.1
|
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
|
14
|
+
Requires-Dist: fsspec-utils>=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
|
@@ -0,0 +1,53 @@
|
|
1
|
+
flowerpower/__init__.py,sha256=nHFrD6twJyR-Ti6Yn0lLcyXXcKOi0tFfOD96oAu17Js,431
|
2
|
+
flowerpower/flowerpower.py,sha256=RCQFRvzZhuxmaIw8Q28lCb2XwArFmTNcUbHqxMcmRZk,21422
|
3
|
+
flowerpower/cfg/__init__.py,sha256=bEvxYCjYGO5djgjiYmLMIMrrSB2uaEdA7LbcVOT_6Ow,13345
|
4
|
+
flowerpower/cfg/base.py,sha256=-hYLxx7aoSvh_w_GRefPRicT3M5L3fTsUtCnhYDiQF8,9907
|
5
|
+
flowerpower/cfg/exceptions.py,sha256=zUJabfUekr_BFLehv_v7SewPTUkC-nZ3vcbA7iB8ujc,1628
|
6
|
+
flowerpower/cfg/pipeline/__init__.py,sha256=e9IMjpFBo61SiEg7aVH7AYyqwfZeSYn7YhoNdKvpUKE,13820
|
7
|
+
flowerpower/cfg/pipeline/adapter.py,sha256=PGRo-4-Dorevh9HttVDmVNvyX1BWfNj_SQ5kcqYOXuA,2275
|
8
|
+
flowerpower/cfg/pipeline/builder.py,sha256=drQv5j6fAygfVk3ShawuYQPZbfuNYYqbLoGdA8o6NCQ,13215
|
9
|
+
flowerpower/cfg/pipeline/builder_adapter.py,sha256=UJRdZKkzAzklA-JtxpZ6Atp2oxWsoYY5mWejXykOvDQ,4526
|
10
|
+
flowerpower/cfg/pipeline/builder_executor.py,sha256=GArx-PKTt3AujqrJE2ShvfZ5rIQu9oGPKhfDaddqsVY,3185
|
11
|
+
flowerpower/cfg/pipeline/run.py,sha256=6a8tYuxjvTGiE6E7M7kd0fTAZtJyHUnWoRb_dIAXVMA,8488
|
12
|
+
flowerpower/cfg/project/__init__.py,sha256=WJpjSV8N3e8xpBDAQawOZa--fflnQ0Efz_hl4hmV_p4,6311
|
13
|
+
flowerpower/cfg/project/adapter.py,sha256=oI_LIs-DObJWNcb3W39h4OqrfgBajwA_QQtPA7Gi_Eo,1686
|
14
|
+
flowerpower/cli/__init__.py,sha256=z0VqloACt6C1hHti1r-_ZP9XW4S4hxpJp2sR8wKErVw,5236
|
15
|
+
flowerpower/cli/cfg.py,sha256=Ic8nXHm_myOx6uZgZAjs3OU8vWoZghdNG6pC1mdeM_M,67
|
16
|
+
flowerpower/cli/pipeline.py,sha256=VjAHgtvhX9wFSGHmQ2hYpz3QCBoJwvUkJwJvza6nbvA,25585
|
17
|
+
flowerpower/cli/utils.py,sha256=wBaPE_6VC8Bgoz_uxfeXBiVFpYY_1iQh-_GKqBuIQbI,6714
|
18
|
+
flowerpower/pipeline/__init__.py,sha256=ltr4LQnM5Boa9w7t-lNVmmcSglIkTPuIoeYnEKWU4Og,122
|
19
|
+
flowerpower/pipeline/base.py,sha256=oQSDfEAyY2_kDRlHNnHr6ihZvfGeOjyMJRPKob1i7U8,3560
|
20
|
+
flowerpower/pipeline/config_manager.py,sha256=0u_Nn_XGafjW3LmhGyp39CP9KXfLo02Z9ivDAsHvKmA,6166
|
21
|
+
flowerpower/pipeline/executor.py,sha256=AAiMbNKIQKNrumu1lavG_yVK9rzhPYjZAIt0BxAbJjc,4567
|
22
|
+
flowerpower/pipeline/io.py,sha256=phYJhN4LZ0c6d8_udEQ4C9cGzeV3Ku0hsj0gyE1n2UY,16246
|
23
|
+
flowerpower/pipeline/lifecycle_manager.py,sha256=JKJXdgdwhH8yUYdwlAJp5-dSbDFFb-EqmgiY-O5KIoA,7670
|
24
|
+
flowerpower/pipeline/manager.py,sha256=XLrCY5x9WmQithe0QmeYonR4LyqzqSQHR-y7cL6DKr4,41143
|
25
|
+
flowerpower/pipeline/pipeline.py,sha256=x4nQeKC7irJoD6x2RzU52dN4VGWJFSGTDYKNuDhG7fk,15742
|
26
|
+
flowerpower/pipeline/registry.py,sha256=gIc1N7yRm95dEhc5WnZapTK827VeydGxZSYcWFqB10U,30122
|
27
|
+
flowerpower/pipeline/visualizer.py,sha256=EVpjv-TUe1zGvdEAWyShJcVXurm02W0jkLbj7z1uAv4,4953
|
28
|
+
flowerpower/plugins/io/__init__.py,sha256=ZmSdKoh3TavJagOz0vUItnEqAh3mAM1QpAWj0KufF_k,222
|
29
|
+
flowerpower/settings/__init__.py,sha256=XKQa8AI9VrX8ievs-suq3Cm6PBt4cJ78ZHVIjUbXCyA,130
|
30
|
+
flowerpower/settings/_backend.py,sha256=Up1RBqAs3jtDUOV-9wEpL68Qmom-dRWMOeHXIh0F3lw,4273
|
31
|
+
flowerpower/settings/executor.py,sha256=vNF383g1gMGkq_CXUzateGMNcJZig-vHkVVb0Hi_b74,249
|
32
|
+
flowerpower/settings/general.py,sha256=RxY6PGF_L8ApFlLPHulZ2I8_-aHYqOj63fUu9kSQTjI,227
|
33
|
+
flowerpower/settings/hamilton.py,sha256=GVzWKz3B-wy07etY1mNUstEa4DFrQ_lM2cjE0qG_6qw,623
|
34
|
+
flowerpower/settings/logging.py,sha256=BHahxfuiofByiTU8TYQ2AObPDRz9SYH-MalSEu1DRro,71
|
35
|
+
flowerpower/settings/retry.py,sha256=W3AAVSxmTUAeeSbzRGA37RxqtKKyUdi2MkwDzCsXP94,181
|
36
|
+
flowerpower/utils/__init__.py,sha256=SGFNcfks88cBRoxQnLIfHX3BTXcKf-SbWo-zxklXDJY,533
|
37
|
+
flowerpower/utils/adapter.py,sha256=3axZ1QIf72x_2AiS7F7X2ySrHkZQnhMnpGel6-9psVU,9645
|
38
|
+
flowerpower/utils/callback.py,sha256=ZIDMGwR30m35Fmj-mChkgAhZ0Zf8HeNtsGdsZ727hIQ,6916
|
39
|
+
flowerpower/utils/config.py,sha256=JC_kKq9-VJrW7ndWiehm5s-C0JG4_4oBffuwhVbaibQ,11507
|
40
|
+
flowerpower/utils/executor.py,sha256=AqO1RLxI9uKWX9OPu9uK6yOX2CNQMptRKpvcG2o-tak,6258
|
41
|
+
flowerpower/utils/filesystem.py,sha256=W5kpJ0IERSsI3hQd7XFtbuk9bcIXidl7Qgw2bQVOkd0,6346
|
42
|
+
flowerpower/utils/logging.py,sha256=WUnpoEmr9H5MGFF68jlshhEJcuMtW49M7VVRstmqIAg,1192
|
43
|
+
flowerpower/utils/misc.py,sha256=_BbAXmcbhDm5Y-RpW-HhJ5txu8KoaDQjdmRJwzNs7aM,14649
|
44
|
+
flowerpower/utils/monkey.py,sha256=vJMYANjZI13PNbEQThdX0EFP1_6bGNHgnpF7HwReNyM,58
|
45
|
+
flowerpower/utils/open_telemetry.py,sha256=fQWJWbIQFtKIxMBjAWeF12NGnqT0isO3A3j-DSOv_vE,949
|
46
|
+
flowerpower/utils/security.py,sha256=7TPwD4nqjVm2rFBjJ0qM86wEQql-9j3Jo8udV3mSBoA,7113
|
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,,
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import datetime as dt
|
2
|
-
|
3
|
-
import msgspec
|
4
|
-
from munch import munchify
|
5
|
-
|
6
|
-
from ..base import BaseConfig
|
7
|
-
|
8
|
-
|
9
|
-
class ScheduleConfig(BaseConfig):
|
10
|
-
cron: str | dict | None = msgspec.field(default=None)
|
11
|
-
interval: str | int | dict | None = msgspec.field(default=None)
|
12
|
-
date: str | None = msgspec.field(default=None)
|
13
|
-
|
14
|
-
def __post_init__(self):
|
15
|
-
if isinstance(self.date, str):
|
16
|
-
try:
|
17
|
-
self.date = dt.datetime.fromisoformat(self.date)
|
18
|
-
except ValueError:
|
19
|
-
raise ValueError(
|
20
|
-
f"Invalid date format: {self.date}. Expected ISO format."
|
21
|
-
)
|
22
|
-
if isinstance(self.cron, dict):
|
23
|
-
self.cron = munchify(self.cron)
|
24
|
-
if isinstance(self.interval, dict):
|
25
|
-
self.interval = munchify(self.interval)
|
26
|
-
|
27
|
-
|
28
|
-
# class ScheduleConfig(BaseConfig):
|
29
|
-
# run: ScheduleRunConfig = msgspec.field(default_factory=ScheduleRunConfig)
|
30
|
-
# trigger: ScheduleTriggerConfig = msgspec.field(
|
31
|
-
# default_factory=ScheduleTriggerConfig
|
32
|
-
# )
|
@@ -1,42 +0,0 @@
|
|
1
|
-
flowerpower/__init__.py,sha256=nHFrD6twJyR-Ti6Yn0lLcyXXcKOi0tFfOD96oAu17Js,431
|
2
|
-
flowerpower/flowerpower.py,sha256=-taA0uemnoy1B5ugNxzwQ_Jir8jfmaGNXTk_uewaN88,23755
|
3
|
-
flowerpower/cfg/__init__.py,sha256=aWeKlBNgJ4LCtWBzZns5RmQm9GN9SpTbozE-NsS2_9w,8481
|
4
|
-
flowerpower/cfg/base.py,sha256=IpvCcUvGTjmjN69D34IFNn692hxTwZzYQJ1utgKANWo,4795
|
5
|
-
flowerpower/cfg/pipeline/__init__.py,sha256=HSUlDt9smo-zPqOljEl329CQg8qsd0EJfCH1FOtuMdk,9276
|
6
|
-
flowerpower/cfg/pipeline/_schedule.py,sha256=kaDyij3eUj0u6VdmJW4x_AQbSAZ-r7s2Fk7QFkXU5JQ,1029
|
7
|
-
flowerpower/cfg/pipeline/adapter.py,sha256=uBKV6BZlsRRqSYNyC1oEWPchsaH7rFPCBobG5BrF3ss,2265
|
8
|
-
flowerpower/cfg/pipeline/builder.py,sha256=rZ-cspbV-nwtckvOA49vt7DNJNb-gRLHHWiejmJPsFs,13192
|
9
|
-
flowerpower/cfg/pipeline/run.py,sha256=cirZbiHsY8D87idBvbfNv1gEtKpgv3xLfiiFIXJFxrA,6733
|
10
|
-
flowerpower/cfg/project/__init__.py,sha256=bMMZ5Zo3YgkgOGt82H1mW8I4WnoCUpa0bSLPpZiB7K4,4560
|
11
|
-
flowerpower/cfg/project/adapter.py,sha256=2k2U25NziDEiUacLTjxaSxOVkaQBRt6ECWGRGX0v4J0,1481
|
12
|
-
flowerpower/cli/__init__.py,sha256=RkJT3mPlSOi55dNNP8kpm_omF0zEfbmWVP16N-lkijE,4897
|
13
|
-
flowerpower/cli/cfg.py,sha256=P7qEcjraitMxbzVWJMqWeitIdpUkW41QkUi7ol0ksW0,1455
|
14
|
-
flowerpower/cli/pipeline.py,sha256=I58cWjK7J4dkXdJXIePcPiD7iILnYqoje0ztkR5mNwg,21958
|
15
|
-
flowerpower/cli/utils.py,sha256=tsxvKIqUhl4m9IzuaSoc5a3_gb6Fu4LYyV8fVodqIdA,5127
|
16
|
-
flowerpower/pipeline/__init__.py,sha256=ltr4LQnM5Boa9w7t-lNVmmcSglIkTPuIoeYnEKWU4Og,122
|
17
|
-
flowerpower/pipeline/base.py,sha256=oQSDfEAyY2_kDRlHNnHr6ihZvfGeOjyMJRPKob1i7U8,3560
|
18
|
-
flowerpower/pipeline/io.py,sha256=phYJhN4LZ0c6d8_udEQ4C9cGzeV3Ku0hsj0gyE1n2UY,16246
|
19
|
-
flowerpower/pipeline/manager.py,sha256=gJMWe_T1WpxO2H9GDrNtf61S4oJuLugMHwX82jqAuEU,47579
|
20
|
-
flowerpower/pipeline/pipeline.py,sha256=8Vhc3GGoAJI-5zv8qX4gZ5JwJrTdVoiXHWNpv5OeKGw,26207
|
21
|
-
flowerpower/pipeline/registry.py,sha256=iHdEBPiRpZorAUe6sDkqONoP8t6cicdQYGdK8UyxuAQ,28791
|
22
|
-
flowerpower/pipeline/visualizer.py,sha256=EVpjv-TUe1zGvdEAWyShJcVXurm02W0jkLbj7z1uAv4,4953
|
23
|
-
flowerpower/plugins/io/__init__.py,sha256=ZmSdKoh3TavJagOz0vUItnEqAh3mAM1QpAWj0KufF_k,222
|
24
|
-
flowerpower/settings/__init__.py,sha256=XKQa8AI9VrX8ievs-suq3Cm6PBt4cJ78ZHVIjUbXCyA,130
|
25
|
-
flowerpower/settings/_backend.py,sha256=Up1RBqAs3jtDUOV-9wEpL68Qmom-dRWMOeHXIh0F3lw,4273
|
26
|
-
flowerpower/settings/executor.py,sha256=vNF383g1gMGkq_CXUzateGMNcJZig-vHkVVb0Hi_b74,249
|
27
|
-
flowerpower/settings/general.py,sha256=RxY6PGF_L8ApFlLPHulZ2I8_-aHYqOj63fUu9kSQTjI,227
|
28
|
-
flowerpower/settings/hamilton.py,sha256=GVzWKz3B-wy07etY1mNUstEa4DFrQ_lM2cjE0qG_6qw,623
|
29
|
-
flowerpower/settings/logging.py,sha256=BHahxfuiofByiTU8TYQ2AObPDRz9SYH-MalSEu1DRro,71
|
30
|
-
flowerpower/settings/retry.py,sha256=W3AAVSxmTUAeeSbzRGA37RxqtKKyUdi2MkwDzCsXP94,181
|
31
|
-
flowerpower/utils/callback.py,sha256=sGYSrEbnl0xfRa1X-mA-om3erpH7pmpsWdyPQ9HpU7E,6736
|
32
|
-
flowerpower/utils/logging.py,sha256=WUnpoEmr9H5MGFF68jlshhEJcuMtW49M7VVRstmqIAg,1192
|
33
|
-
flowerpower/utils/misc.py,sha256=gY1KVJp4lF4S0THUu1LUrjXaf87TzLO-TcwHxZZh2Zk,8414
|
34
|
-
flowerpower/utils/monkey.py,sha256=vJMYANjZI13PNbEQThdX0EFP1_6bGNHgnpF7HwReNyM,58
|
35
|
-
flowerpower/utils/open_telemetry.py,sha256=fQWJWbIQFtKIxMBjAWeF12NGnqT0isO3A3j-DSOv_vE,949
|
36
|
-
flowerpower/utils/templates.py,sha256=ouyEeSDqa9PjW8c32fGpcINlpC0WToawRFZkMPtwsLE,1591
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|