FlowerPower 0.31.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/utils/misc.py +204 -203
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/METADATA +1 -1
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/RECORD +7 -7
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/WHEEL +0 -0
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.31.0.dist-info → flowerpower-0.31.1.dist-info}/top_level.txt +0 -0
flowerpower/utils/misc.py
CHANGED
@@ -9,218 +9,219 @@ from typing import Any
|
|
9
9
|
import msgspec
|
10
10
|
from fsspec_utils import AbstractFileSystem, filesystem
|
11
11
|
from .security import validate_file_path
|
12
|
+
from fsspec_utils.utils import run_parallel
|
12
13
|
|
13
|
-
if importlib.util.find_spec("joblib"):
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# if importlib.util.find_spec("joblib"):
|
15
|
+
# from joblib import Parallel, delayed
|
16
|
+
# from rich.progress import (BarColumn, Progress, TextColumn,
|
17
|
+
# TimeElapsedColumn)
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
# def _prepare_parallel_args(
|
20
|
+
# args: tuple, kwargs: dict
|
21
|
+
# ) -> tuple[list, list, dict, dict, int]:
|
22
|
+
# """Prepare and validate arguments for parallel execution.
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
# Args:
|
25
|
+
# args: Positional arguments
|
26
|
+
# kwargs: Keyword arguments
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
# Returns:
|
29
|
+
# tuple: (iterables, fixed_args, iterable_kwargs, fixed_kwargs, first_iterable_len)
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
31
|
+
# Raises:
|
32
|
+
# ValueError: If no iterable arguments or length mismatch
|
33
|
+
# """
|
34
|
+
# iterables = []
|
35
|
+
# fixed_args = []
|
36
|
+
# iterable_kwargs = {}
|
37
|
+
# fixed_kwargs = {}
|
38
|
+
# first_iterable_len = None
|
39
|
+
|
40
|
+
# # Process positional arguments
|
41
|
+
# for arg in args:
|
42
|
+
# if isinstance(arg, (list, tuple)) and not isinstance(arg[0], (list, tuple)):
|
43
|
+
# iterables.append(arg)
|
44
|
+
# if first_iterable_len is None:
|
45
|
+
# first_iterable_len = len(arg)
|
46
|
+
# elif len(arg) != first_iterable_len:
|
47
|
+
# raise ValueError(
|
48
|
+
# f"Iterable length mismatch: argument has length {len(arg)}, expected {first_iterable_len}"
|
49
|
+
# )
|
50
|
+
# else:
|
51
|
+
# fixed_args.append(arg)
|
52
|
+
|
53
|
+
# # Process keyword arguments
|
54
|
+
# for key, value in kwargs.items():
|
55
|
+
# if isinstance(value, (list, tuple)) and not isinstance(
|
56
|
+
# value[0], (list, tuple)
|
57
|
+
# ):
|
58
|
+
# if first_iterable_len is None:
|
59
|
+
# first_iterable_len = len(value)
|
60
|
+
# elif len(value) != first_iterable_len:
|
61
|
+
# raise ValueError(
|
62
|
+
# f"Iterable length mismatch: {key} has length {len(value)}, expected {first_iterable_len}"
|
63
|
+
# )
|
64
|
+
# iterable_kwargs[key] = value
|
65
|
+
# else:
|
66
|
+
# fixed_kwargs[key] = value
|
67
|
+
|
68
|
+
# if first_iterable_len is None:
|
69
|
+
# raise ValueError("At least one iterable argument is required")
|
70
|
+
|
71
|
+
# return iterables, fixed_args, iterable_kwargs, fixed_kwargs, first_iterable_len
|
72
|
+
|
73
|
+
# def _execute_parallel_with_progress(
|
74
|
+
# func: callable,
|
75
|
+
# iterables: list,
|
76
|
+
# fixed_args: list,
|
77
|
+
# iterable_kwargs: dict,
|
78
|
+
# fixed_kwargs: dict,
|
79
|
+
# param_combinations: list,
|
80
|
+
# parallel_kwargs: dict,
|
81
|
+
# ) -> list:
|
82
|
+
# """Execute parallel tasks with progress tracking.
|
82
83
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
# Args:
|
85
|
+
# func: Function to execute
|
86
|
+
# iterables: List of iterable arguments
|
87
|
+
# fixed_args: List of fixed arguments
|
88
|
+
# iterable_kwargs: Dictionary of iterable keyword arguments
|
89
|
+
# fixed_kwargs: Dictionary of fixed keyword arguments
|
90
|
+
# param_combinations: List of parameter combinations
|
91
|
+
# parallel_kwargs: Parallel execution configuration
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
93
|
+
# Returns:
|
94
|
+
# list: Results from parallel execution
|
95
|
+
# """
|
96
|
+
# results = [None] * len(param_combinations)
|
97
|
+
# with Progress(
|
98
|
+
# TextColumn("[progress.description]{task.description}"),
|
99
|
+
# BarColumn(),
|
100
|
+
# "[progress.percentage]{task.percentage:>3.0f}%",
|
101
|
+
# TimeElapsedColumn(),
|
102
|
+
# transient=True,
|
103
|
+
# ) as progress:
|
104
|
+
# task = progress.add_task(
|
105
|
+
# "Running in parallel...", total=len(param_combinations)
|
106
|
+
# )
|
107
|
+
|
108
|
+
# def wrapper(idx, param_tuple):
|
109
|
+
# res = func(
|
110
|
+
# *(list(param_tuple[: len(iterables)]) + fixed_args),
|
111
|
+
# **{
|
112
|
+
# k: v
|
113
|
+
# for k, v in zip(
|
114
|
+
# iterable_kwargs.keys(), param_tuple[len(iterables) :]
|
115
|
+
# )
|
116
|
+
# },
|
117
|
+
# **fixed_kwargs,
|
118
|
+
# )
|
119
|
+
# progress.update(task, advance=1)
|
120
|
+
# return idx, res
|
121
|
+
#
|
122
|
+
# for idx, result in Parallel(**parallel_kwargs)(
|
123
|
+
# delayed(wrapper)(i, param_tuple)
|
124
|
+
# for i, param_tuple in enumerate(param_combinations)
|
125
|
+
# ):
|
126
|
+
# results[idx] = result
|
127
|
+
# return results
|
128
|
+
|
129
|
+
# def _execute_parallel_without_progress(
|
130
|
+
# func: callable,
|
131
|
+
# iterables: list,
|
132
|
+
# fixed_args: list,
|
133
|
+
# iterable_kwargs: dict,
|
134
|
+
# fixed_kwargs: dict,
|
135
|
+
# param_combinations: list,
|
136
|
+
# parallel_kwargs: dict,
|
137
|
+
# ) -> list:
|
138
|
+
# """Execute parallel tasks without progress tracking.
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
140
|
+
# Args:
|
141
|
+
# func: Function to execute
|
142
|
+
# iterables: List of iterable arguments
|
143
|
+
# fixed_args: List of fixed arguments
|
144
|
+
# iterable_kwargs: Dictionary of iterable keyword arguments
|
145
|
+
# fixed_kwargs: Dictionary of fixed keyword arguments
|
146
|
+
# param_combinations: List of parameter combinations
|
147
|
+
# parallel_kwargs: Parallel execution configuration
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
else:
|
221
|
-
|
222
|
-
|
223
|
-
|
149
|
+
# Returns:
|
150
|
+
# list: Results from parallel execution
|
151
|
+
# """
|
152
|
+
# return Parallel(**parallel_kwargs)(
|
153
|
+
# delayed(func)(
|
154
|
+
# *(list(param_tuple[: len(iterables)]) + fixed_args),
|
155
|
+
# **{
|
156
|
+
# k: v
|
157
|
+
# for k, v in zip(
|
158
|
+
# iterable_kwargs.keys(), param_tuple[len(iterables) :]
|
159
|
+
# )
|
160
|
+
# },
|
161
|
+
# **fixed_kwargs,
|
162
|
+
# )
|
163
|
+
# for param_tuple in param_combinations
|
164
|
+
# )
|
165
|
+
|
166
|
+
# def run_parallel(
|
167
|
+
# func: callable,
|
168
|
+
# *args,
|
169
|
+
# n_jobs: int = -1,
|
170
|
+
# backend: str = "threading",
|
171
|
+
# verbose: bool = True,
|
172
|
+
# **kwargs,
|
173
|
+
# ) -> list[any]:
|
174
|
+
# """Runs a function for a list of parameters in parallel.
|
175
|
+
|
176
|
+
# Args:
|
177
|
+
# func (Callable): function to run in parallel
|
178
|
+
# *args: Positional arguments. Can be single values or iterables
|
179
|
+
# n_jobs (int, optional): Number of joblib workers. Defaults to -1
|
180
|
+
# backend (str, optional): joblib backend. Valid options are
|
181
|
+
# `loky`,`threading`, `mutliprocessing` or `sequential`. Defaults to "threading"
|
182
|
+
# verbose (bool, optional): Show progress bar. Defaults to True
|
183
|
+
# **kwargs: Keyword arguments. Can be single values or iterables
|
184
|
+
|
185
|
+
# Returns:
|
186
|
+
# list[any]: Function output
|
187
|
+
|
188
|
+
# Examples:
|
189
|
+
# >>> # Single iterable argument
|
190
|
+
# >>> run_parallel(func, [1,2,3], fixed_arg=42)
|
191
|
+
|
192
|
+
# >>> # Multiple iterables in args and kwargs
|
193
|
+
# >>> run_parallel(func, [1,2,3], val=[7,8,9], fixed=42)
|
194
|
+
|
195
|
+
# >>> # Only kwargs iterables
|
196
|
+
# >>> run_parallel(func, x=[1,2,3], y=[4,5,6], fixed=42)
|
197
|
+
# """
|
198
|
+
# parallel_kwargs = {"n_jobs": n_jobs, "backend": backend, "verbose": 0}
|
199
|
+
|
200
|
+
# # Prepare and validate arguments
|
201
|
+
# iterables, fixed_args, iterable_kwargs, fixed_kwargs, first_iterable_len = _prepare_parallel_args(
|
202
|
+
# args, kwargs
|
203
|
+
# )
|
204
|
+
|
205
|
+
# # Create parameter combinations
|
206
|
+
# all_iterables = iterables + list(iterable_kwargs.values())
|
207
|
+
# param_combinations = list(zip(*all_iterables))
|
208
|
+
|
209
|
+
# # Execute with or without progress tracking
|
210
|
+
# if not verbose:
|
211
|
+
# return _execute_parallel_without_progress(
|
212
|
+
# func, iterables, fixed_args, iterable_kwargs, fixed_kwargs,
|
213
|
+
# param_combinations, parallel_kwargs
|
214
|
+
# )
|
215
|
+
# else:
|
216
|
+
# return _execute_parallel_with_progress(
|
217
|
+
# func, iterables, fixed_args, iterable_kwargs, fixed_kwargs,
|
218
|
+
# param_combinations, parallel_kwargs
|
219
|
+
# )
|
220
|
+
|
221
|
+
# else:
|
222
|
+
|
223
|
+
# def run_parallel(*args, **kwargs):
|
224
|
+
# raise ImportError("joblib not installed")
|
224
225
|
|
225
226
|
|
226
227
|
def get_partitions_from_path(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: FlowerPower
|
3
|
-
Version: 0.31.
|
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
|
@@ -40,14 +40,14 @@ flowerpower/utils/config.py,sha256=JC_kKq9-VJrW7ndWiehm5s-C0JG4_4oBffuwhVbaibQ,1
|
|
40
40
|
flowerpower/utils/executor.py,sha256=AqO1RLxI9uKWX9OPu9uK6yOX2CNQMptRKpvcG2o-tak,6258
|
41
41
|
flowerpower/utils/filesystem.py,sha256=W5kpJ0IERSsI3hQd7XFtbuk9bcIXidl7Qgw2bQVOkd0,6346
|
42
42
|
flowerpower/utils/logging.py,sha256=WUnpoEmr9H5MGFF68jlshhEJcuMtW49M7VVRstmqIAg,1192
|
43
|
-
flowerpower/utils/misc.py,sha256=
|
43
|
+
flowerpower/utils/misc.py,sha256=_BbAXmcbhDm5Y-RpW-HhJ5txu8KoaDQjdmRJwzNs7aM,14649
|
44
44
|
flowerpower/utils/monkey.py,sha256=vJMYANjZI13PNbEQThdX0EFP1_6bGNHgnpF7HwReNyM,58
|
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.
|
49
|
-
flowerpower-0.31.
|
50
|
-
flowerpower-0.31.
|
51
|
-
flowerpower-0.31.
|
52
|
-
flowerpower-0.31.
|
53
|
-
flowerpower-0.31.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|