code-loader 1.0.101.dev0__py3-none-any.whl → 1.0.102.dev1__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.

Potentially problematic release.


This version of code-loader might be problematic. Click here for more details.

@@ -43,6 +43,9 @@ class PreprocessResponse:
43
43
  instance_ids_to_names: Optional[Dict[str, str]] = None # in use only for element instance
44
44
 
45
45
  def __post_init__(self) -> None:
46
+ def is_valid_string(s: str) -> bool:
47
+ return bool(re.match(r'^[A-Za-z0-9_]+$', s))
48
+
46
49
  assert self.sample_ids_to_instance_mappings is None, f"Keep sample_ids_to_instance_mappings None when initializing PreprocessResponse"
47
50
  assert self.instance_to_sample_ids_mappings is None, f"Keep instance_to_sample_ids_mappings None when initializing PreprocessResponse"
48
51
  assert self.instance_ids_to_names is None, f"Keep instance_ids_to_names None when initializing PreprocessResponse"
@@ -57,6 +60,8 @@ class PreprocessResponse:
57
60
  if self.sample_id_type == str:
58
61
  for sample_id in self.sample_ids:
59
62
  assert isinstance(sample_id, str), f"Sample id should be of type str. Got: {type(sample_id)}"
63
+ if not is_valid_string(sample_id):
64
+ raise Exception(f"Sample id should contain only letters (A-Z, a-z), numbers or '_'. Got: {sample_id}")
60
65
  else:
61
66
  raise Exception("length is deprecated.")
62
67
 
File without changes
@@ -0,0 +1,443 @@
1
+
2
+ import os
3
+
4
+ from code_loader.inner_leap_binder.leapbinder import mapping_runtime_mode_env_var_mame
5
+
6
+ if not os.environ.get(mapping_runtime_mode_env_var_mame):
7
+ try:
8
+ import matplotlib.pyplot as plt # type: ignore
9
+ except ImportError:
10
+ raise ImportError(
11
+ "Matplotlib is not installed. Please install it using 'pip install matplotlib' to visualize Leap data."
12
+ )
13
+
14
+
15
+ import numpy as np
16
+ from code_loader.contract.enums import LeapDataType
17
+ from textwrap import wrap
18
+ import math
19
+
20
+ from code_loader.contract.visualizer_classes import LeapImage, LeapImageWithBBox, LeapGraph, LeapText, \
21
+ LeapHorizontalBar, LeapImageMask, LeapTextMask, LeapImageWithHeatmap
22
+
23
+ def run_only_on_non_mapping_mode():
24
+ """
25
+ Decorator to ensure that the function is only run when not in mapping mode.
26
+ """
27
+ def decorator(func):
28
+ def wrapper(*args, **kwargs):
29
+ if os.environ.get(mapping_runtime_mode_env_var_mame):
30
+ print(f"Skipping {func.__name__} in mapping mode.")
31
+ return
32
+ return func(*args, **kwargs)
33
+ return wrapper
34
+ return decorator
35
+
36
+
37
+ @run_only_on_non_mapping_mode()
38
+ def plot_image_with_b_box(leap_data: LeapImageWithBBox, title: str) -> None:
39
+ """
40
+ Plot an image with overlaid bounding boxes.
41
+
42
+ Returns:
43
+ None
44
+
45
+ Example:
46
+ image_data = np.random.rand(100, 100, 3).astype(np.float32)
47
+ bbox = BoundingBox(x=0.5, y=0.5, width=0.2, height=0.2, confidence=0.9, label="object")
48
+ leap_image_with_bbox = LeapImageWithBBox(data=image_data, bounding_boxes=[bbox])
49
+ title = "Image With bbox"
50
+ visualize(leap_image_with_bbox, title)
51
+ """
52
+
53
+ image = leap_data.data
54
+ bounding_boxes = leap_data.bounding_boxes
55
+
56
+ # Create figure and axes
57
+ fig, ax = plt.subplots(1)
58
+ fig.patch.set_facecolor('black')
59
+ ax.set_facecolor('black')
60
+
61
+ # Display the image
62
+ ax.imshow(image)
63
+ ax.set_title(title, color='white')
64
+
65
+ # Draw bounding boxes on the image
66
+ for bbox in bounding_boxes:
67
+ x, y, width, height = bbox.x, bbox.y, bbox.width, bbox.height
68
+ confidence, label = bbox.confidence, bbox.label
69
+
70
+ # Convert relative coordinates to absolute coordinates
71
+ abs_x = x * image.shape[1]
72
+ abs_y = y * image.shape[0]
73
+ abs_width = width * image.shape[1]
74
+ abs_height = height * image.shape[0]
75
+
76
+ # Create a rectangle patch
77
+ rect = plt.Rectangle(
78
+ (abs_x - abs_width / 2, abs_y - abs_height / 2),
79
+ abs_width, abs_height,
80
+ linewidth=3, edgecolor='r', facecolor='none'
81
+ )
82
+
83
+ # Add the rectangle to the axes
84
+ ax.add_patch(rect)
85
+
86
+ # Display label and confidence
87
+ ax.text(abs_x - abs_width / 2, abs_y - abs_height / 2 - 5,
88
+ f"{label} {confidence:.2f}", color='r', fontsize=8,
89
+ bbox=dict(facecolor='white', alpha=0.7, edgecolor='none', boxstyle='round,pad=0.3'))
90
+
91
+ # Show the image with bounding boxes
92
+ plt.show()
93
+
94
+
95
+ @run_only_on_non_mapping_mode()
96
+ def plot_image(leap_data: LeapImage, title: str) -> None:
97
+ """
98
+ Display the image contained in the LeapImage object.
99
+
100
+ Returns:
101
+ None
102
+
103
+ Example:
104
+ image_data = np.random.rand(100, 100, 3).astype(np.float32)
105
+ leap_image = LeapImage(data=image_data)
106
+ title = "Image"
107
+ visualize(leap_image, title)
108
+ """
109
+ image_data = leap_data.data
110
+
111
+ # If the image has one channel, convert it to a 3-channel image for display
112
+ if image_data.shape[2] == 1:
113
+ image_data = np.repeat(image_data, 3, axis=2)
114
+
115
+ fig, ax = plt.subplots()
116
+ fig.patch.set_facecolor('black')
117
+ ax.set_facecolor('black')
118
+
119
+ ax.imshow(image_data)
120
+
121
+ plt.axis('off')
122
+ plt.title(title, color='white')
123
+ plt.show()
124
+
125
+
126
+ @run_only_on_non_mapping_mode()
127
+ def plot_graph(leap_data: LeapGraph, title: str) -> None:
128
+ """
129
+ Display the line chart contained in the LeapGraph object.
130
+
131
+ Returns:
132
+ None
133
+
134
+ Example:
135
+ graph_data = np.random.rand(100, 3).astype(np.float32)
136
+ leap_graph = LeapGraph(data=graph_data)
137
+ title = "Graph"
138
+ visualize(leap_graph, title)
139
+ """
140
+ graph_data = leap_data.data
141
+ num_variables = graph_data.shape[1]
142
+
143
+ fig, ax = plt.subplots(figsize=(10, 6))
144
+
145
+ # Set the background color to black
146
+ fig.patch.set_facecolor('black')
147
+ ax.set_facecolor('black')
148
+
149
+ for i in range(num_variables):
150
+ plt.plot(graph_data[:, i], label=f'Variable {i + 1}')
151
+
152
+ ax.set_xlabel('Data Points', color='white')
153
+ ax.set_ylabel('Values', color='white')
154
+ ax.set_title(title, color='white')
155
+ ax.legend()
156
+ ax.grid(True, color='white')
157
+
158
+ # Change the color of the tick labels to white
159
+ ax.tick_params(colors='white')
160
+
161
+ plt.show()
162
+
163
+
164
+ @run_only_on_non_mapping_mode()
165
+ def plot_text_with_heatmap(leap_data: LeapText, title: str) -> None:
166
+ """
167
+ Display the text contained in the LeapText object with a heatmap overlay.
168
+
169
+ Args:
170
+ leap_data (LeapData): The LeapText object containing text tokens and an optional heatmap.
171
+ title (str): The title of the visualization.
172
+
173
+ Returns:
174
+ None
175
+
176
+ Example:
177
+ text_data = ['I', 'ate', 'a', 'banana', '', '', '']
178
+ heatmap = [0.1, 0.3, 0.2, 0.9, 0.0, 0.0, 0.0]
179
+ leap_text = LeapText(data=text_data, heatmap=heatmap) # Create LeapText object
180
+ title = "Text with Heatmap"
181
+ visualize(leap_text, title)
182
+ """
183
+ text_data = leap_data.data
184
+ heatmap = leap_data.heatmap
185
+
186
+ text_data = [s for s in text_data if s != "[PAD]"]
187
+
188
+ fig, ax = plt.subplots(figsize=(12, 5))
189
+ fig.patch.set_facecolor('black')
190
+ ax.set_facecolor('black')
191
+ ax.axis('off') # Hide axes
192
+
193
+ font_size = 20
194
+
195
+ if heatmap is not None:
196
+ heatmap = heatmap[:len(text_data)]
197
+ if len(heatmap) != len(text_data):
198
+ raise ValueError(
199
+ f"Heatmap length ({len(heatmap)}) must match the number of tokens in `data` ({len(text_data)}).")
200
+
201
+ max_tokens_per_row = 10
202
+ num_rows = math.ceil(len(text_data) / max_tokens_per_row)
203
+
204
+ fig.set_size_inches(12, num_rows * 1.2)
205
+ for idx, (token, value) in enumerate(zip(text_data, heatmap)):
206
+ if token:
207
+ row = idx // max_tokens_per_row
208
+ col = idx % max_tokens_per_row
209
+
210
+ x_pos = col / max_tokens_per_row + 0.03
211
+ y_pos = 1 - (row + 0.5) / num_rows
212
+ color = plt.cm.jet(value)
213
+ ax.text(
214
+ x_pos,
215
+ y_pos,
216
+ token,
217
+ fontsize=font_size,
218
+ color=color,
219
+ ha="left",
220
+ va="center"
221
+ )
222
+ else:
223
+ display_text = ' '.join([token for token in text_data if token])
224
+ wrapped_text = "\n".join(wrap(display_text, width=80))
225
+ font_color = 'white'
226
+ ax.text(0.5, 0.5, wrapped_text, color=font_color, fontsize=font_size, ha='center', va='center')
227
+
228
+ ax.set_title(title, color='white', fontsize=16)
229
+
230
+ plt.tight_layout()
231
+ plt.show()
232
+
233
+ @run_only_on_non_mapping_mode()
234
+ def plot_hbar(leap_data: LeapHorizontalBar, title: str) -> None:
235
+ """
236
+ Display the horizontal bar chart contained in the LeapHorizontalBar object.
237
+
238
+ Returns:
239
+ None
240
+
241
+ Example:
242
+ body_data = np.random.rand(5).astype(np.float32)
243
+ gt_data = np.random.rand(5).astype(np.float32)
244
+ labels = ['Class A', 'Class B', 'Class C', 'Class D', 'Class E']
245
+ leap_horizontal_bar = LeapHorizontalBar(body=body_data, gt=gt_data, labels=labels)
246
+ title = "Horizontal Bar"
247
+ visualize(leap_horizontal_bar, title)
248
+ """
249
+ body_data = leap_data.body
250
+ labels = leap_data.labels
251
+
252
+ # Check if 'gt' attribute exists and is not None
253
+ gt_data = getattr(leap_data, 'gt', None)
254
+
255
+ fig, ax = plt.subplots()
256
+
257
+ fig.patch.set_facecolor('black')
258
+ ax.set_facecolor('black')
259
+
260
+ # Adjust positions for side-by-side bars
261
+ y_positions = range(len(labels))
262
+ bar_width = 0.4
263
+
264
+ # Plot horizontal bar chart
265
+ if gt_data is not None:
266
+ ax.barh([y - bar_width / 2 for y in y_positions], body_data, color='green', height=bar_width, label='Prediction')
267
+ ax.barh([y + bar_width / 2 for y in y_positions], gt_data, color='orange', height=bar_width, label='GT')
268
+ else:
269
+ ax.barh(y_positions, body_data, color='green', label='Body Data')
270
+
271
+ # Set the y-ticks to align with the center of the bars
272
+ ax.set_yticks(y_positions)
273
+ ax.set_yticklabels(labels, color='white')
274
+
275
+ # Set the color of the labels and title to white
276
+ ax.set_xlabel('Scores', color='white')
277
+ ax.set_title(title, color='white')
278
+
279
+ # Set the color of the ticks to white
280
+ ax.tick_params(axis='x', colors='white')
281
+ ax.tick_params(axis='y', colors='white')
282
+
283
+ # Add legend if gt is present
284
+ if gt_data is not None:
285
+ ax.legend(loc='best', facecolor='black', edgecolor='white', labelcolor='white')
286
+
287
+ plt.show()
288
+
289
+ @run_only_on_non_mapping_mode()
290
+ def plot_image_mask(leap_data: LeapImageMask, title: str) -> None:
291
+ """
292
+ Plots an image with overlaid masks given a LeapImageMask visualizer object.
293
+
294
+ Returns:
295
+ None
296
+
297
+
298
+ Example:
299
+ image_data = np.random.rand(100, 100, 3).astype(np.float32)
300
+ mask_data = np.random.randint(0, 2, (100, 100)).astype(np.uint8)
301
+ labels = ["background", "object"]
302
+ leap_image_mask = LeapImageMask(image=image_data, mask=mask_data, labels=labels)
303
+ title = "Image Mask"
304
+ visualize(leap_image_mask, title)
305
+ """
306
+
307
+ image = leap_data.image
308
+ mask = leap_data.mask
309
+ labels = leap_data.labels
310
+
311
+ # Create a color map for each label
312
+ colors = plt.cm.jet(np.linspace(0, 1, len(labels)))
313
+ if image.dtype == np.uint8:
314
+ colors = colors * 255
315
+
316
+ # Make a copy of the image to draw on
317
+ overlayed_image = image.copy()
318
+
319
+ # Iterate through the unique values in the mask (excluding 0)
320
+ for i, label in enumerate(labels):
321
+ # Extract binary mask for the current instance
322
+ instance_mask = (mask == (i + 1))
323
+
324
+ # fill the instance mask with a translucent color
325
+ overlayed_image[instance_mask] = (
326
+ overlayed_image[instance_mask] * (1 - 0.5) + np.array(colors[i][:image.shape[-1]], dtype=np.uint8) * 0.5)
327
+
328
+ # Display the result using matplotlib
329
+ fig, ax = plt.subplots(1)
330
+ fig.patch.set_facecolor('black') # Set the figure background to black
331
+ ax.set_facecolor('black') # Set the axis background to black
332
+
333
+ ax.imshow(overlayed_image)
334
+ ax.set_title(title, color='white')
335
+ plt.axis('off') # Hide the axis
336
+ plt.show()
337
+
338
+ @run_only_on_non_mapping_mode()
339
+ def plot_text_mask(leap_data: LeapTextMask, title: str) -> None:
340
+ """
341
+ Plots text with overlaid masks given a LeapTextMask visualizer object.
342
+
343
+ Returns:
344
+ None
345
+
346
+ Example:
347
+ text_data = ['I', 'ate', 'a', 'banana', '', '', '']
348
+ mask_data = np.array([0, 0, 0, 1, 0, 0, 0]).astype(np.uint8)
349
+ labels = ["object"]
350
+ leap_text_mask = LeapTextMask(text=text_data, mask=mask_data, labels=labels)
351
+ title = "Text Mask"
352
+ visualize(leap_text_mask, title)
353
+ """
354
+
355
+ text_data = leap_data.text
356
+ mask_data = leap_data.mask
357
+ labels = leap_data.labels
358
+
359
+ # Create a color map for each label
360
+ colors = plt.cm.jet(np.linspace(0, 1, len(labels)))
361
+
362
+ # Create a figure and axis
363
+ fig, ax = plt.subplots()
364
+
365
+ # Set background to black
366
+ fig.patch.set_facecolor('black')
367
+ ax.set_facecolor('black')
368
+ ax.set_title(title, color='white')
369
+ ax.axis('off')
370
+
371
+ # Set initial position
372
+ x_pos, y_pos = 0.01, 0.5 # Adjusted initial position for better visibility
373
+
374
+ # Display the text with colors
375
+ for token, mask_value in zip(text_data, mask_data):
376
+ if mask_value > 0:
377
+ color = colors[mask_value % len(colors)]
378
+ bbox = dict(facecolor=color, edgecolor='none',
379
+ boxstyle='round,pad=0.3') # Background color for masked tokens
380
+ else:
381
+ bbox = None
382
+
383
+ ax.text(x_pos, y_pos, token, fontsize=12, color='white', ha='left', va='center', bbox=bbox)
384
+
385
+ # Update the x position for the next token
386
+ x_pos += len(token) * 0.03 + 0.02 # Adjust the spacing between tokens
387
+
388
+ plt.show()
389
+
390
+ @run_only_on_non_mapping_mode()
391
+ def plot_image_with_heatmap(leap_data: LeapImageWithHeatmap, title: str) -> None:
392
+ """
393
+ Display the image with overlaid heatmaps contained in the LeapImageWithHeatmap object.
394
+
395
+ Returns:
396
+ None
397
+
398
+ Example:
399
+ image_data = np.random.rand(100, 100, 3).astype(np.float32)
400
+ heatmaps = np.random.rand(3, 100, 100).astype(np.float32)
401
+ labels = ["heatmap1", "heatmap2", "heatmap3"]
402
+ leap_image_with_heatmap = LeapImageWithHeatmap(image=image_data, heatmaps=heatmaps, labels=labels)
403
+ title = "Image With Heatmap"
404
+ visualize(leap_image_with_heatmap, title)
405
+ """
406
+ image = leap_data.image
407
+ heatmaps = leap_data.heatmaps
408
+ labels = leap_data.labels
409
+
410
+ # Plot the base image
411
+ fig, ax = plt.subplots()
412
+ fig.patch.set_facecolor('black') # Set the figure background to black
413
+ ax.set_facecolor('black') # Set the axis background to black
414
+ ax.imshow(image, cmap='gray')
415
+
416
+ # Overlay each heatmap with some transparency
417
+ for i in range(len(labels)):
418
+ heatmap = heatmaps[i]
419
+ ax.imshow(heatmap, cmap='jet', alpha=0.5) # Adjust alpha for transparency
420
+ ax.set_title(f'Heatmap: {labels[i]}', color='white')
421
+
422
+ # Display a colorbar for the heatmap
423
+ cbar = plt.colorbar(ax.imshow(heatmap, cmap='jet', alpha=0.5))
424
+ cbar.set_label(labels[i], color='white')
425
+ cbar.ax.yaxis.set_tick_params(color='white') # Set color for the colorbar ticks
426
+ plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='white') # Set color for the colorbar labels
427
+
428
+ plt.axis('off')
429
+ plt.title(title, color='white')
430
+ plt.show()
431
+
432
+
433
+
434
+ plot_switch = {
435
+ LeapDataType.Image: plot_image,
436
+ LeapDataType.Text: plot_text_with_heatmap,
437
+ LeapDataType.Graph: plot_graph,
438
+ LeapDataType.HorizontalBar: plot_hbar,
439
+ LeapDataType.ImageMask: plot_image_mask,
440
+ LeapDataType.TextMask: plot_text_mask,
441
+ LeapDataType.ImageWithHeatmap: plot_image_with_heatmap,
442
+ LeapDataType.ImageWithBBox: plot_image_with_b_box,
443
+ }
@@ -0,0 +1,19 @@
1
+ import sys
2
+
3
+ from code_loader.contract.datasetclasses import LeapData
4
+
5
+ from typing import Optional
6
+
7
+ from code_loader.helpers.plot_functions import plot_switch
8
+
9
+
10
+ def visualize(leap_data: LeapData, title: Optional[str] = None) -> None:
11
+ vis_function = plot_switch.get(leap_data.type)
12
+ if vis_function is None:
13
+ print(f"Error: leap data type is not supported, leap data type: {leap_data.type}")
14
+ sys.exit(1)
15
+
16
+ if not title:
17
+ title = f"Leap {leap_data.type.name} Visualization"
18
+ vis_function(leap_data, title) # type: ignore[operator]
19
+
@@ -49,6 +49,7 @@ class LeapBinder:
49
49
  self._extend_with_default_losses()
50
50
 
51
51
  self.mapping_connections: List[NodeConnection] = []
52
+ self.integration_test_func: Optional[Callable] = None
52
53
 
53
54
  self.batch_size_to_validate: Optional[int] = None
54
55
 
@@ -35,6 +35,34 @@ def _add_mapping_connections(connects_to, arg_names, node_mapping_type, name):
35
35
 
36
36
 
37
37
 
38
+ def integration_test():
39
+ def decorating_function(integration_test_function: Callable):
40
+ leap_binder.integration_test_func = integration_test_function
41
+
42
+
43
+ def inner(*args, **kwargs):
44
+ ret = integration_test_function(*args, **kwargs)
45
+
46
+ try:
47
+ os.environ[mapping_runtime_mode_env_var_mame] = 'True'
48
+ integration_test_function(None, None)
49
+ except Exception as e:
50
+ print(f'Error during integration test: Make sure to disable any non tensorleap decorators '
51
+ f'functions before pushing a new TL version')
52
+ finally:
53
+ if mapping_runtime_mode_env_var_mame in os.environ:
54
+ del os.environ[mapping_runtime_mode_env_var_mame]
55
+
56
+
57
+ return inner
58
+
59
+ return decorating_function
60
+
61
+
62
+
63
+
64
+
65
+
38
66
 
39
67
  def tensorleap_load_model(prediction_types: Optional[List[PredictionTypeHandler]] = None):
40
68
  for i, prediction_type in enumerate(prediction_types):
code_loader/leaploader.py CHANGED
@@ -26,7 +26,7 @@ from code_loader.contract.responsedataclasses import DatasetIntegParseResult, Da
26
26
  from code_loader.inner_leap_binder import global_leap_binder
27
27
  from code_loader.inner_leap_binder.leapbinder import mapping_runtime_mode_env_var_mame
28
28
  from code_loader.leaploaderbase import LeapLoaderBase
29
- from code_loader.utils import get_root_exception_file_and_line_number, flatten
29
+ from code_loader.utils import get_root_exception_file_and_line_number
30
30
 
31
31
 
32
32
  class LeapLoader(LeapLoaderBase):
@@ -514,18 +514,22 @@ class LeapLoader(LeapLoaderBase):
514
514
 
515
515
  return converted_value, is_none
516
516
 
517
- def _get_metadata(self, state: DataStateEnum, sample_id: Union[int, str]) -> Tuple[
518
- Dict[str, Union[str, int, bool, float]], Dict[str, bool]]:
517
+ def _get_metadata(self, state: DataStateEnum, sample_id: Union[int, str]) -> Tuple[Dict[str, Union[str, int, bool, float]], Dict[str, bool]]:
519
518
  result_agg = {}
520
519
  is_none = {}
521
520
  preprocess_result = self._preprocess_result()
522
521
  preprocess_state = preprocess_result[state]
523
522
  for handler in global_leap_binder.setup_container.metadata:
524
523
  handler_result = handler.function(sample_id, preprocess_state)
525
-
526
- for flat_name, flat_result in flatten(handler_result, prefix=handler.name):
527
- result_agg[flat_name], is_none[flat_name] = self._convert_metadata_to_correct_type(
528
- flat_name, flat_result)
524
+ if isinstance(handler_result, dict):
525
+ for single_metadata_name, single_metadata_result in handler_result.items():
526
+ handler_name = f'{handler.name}_{single_metadata_name}'
527
+ result_agg[handler_name], is_none[handler_name] = self._convert_metadata_to_correct_type(
528
+ handler_name, single_metadata_result)
529
+ else:
530
+ handler_name = handler.name
531
+ result_agg[handler_name], is_none[handler_name] = self._convert_metadata_to_correct_type(
532
+ handler_name, handler_result)
529
533
 
530
534
  return result_agg, is_none
531
535
 
code_loader/utils.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import sys
2
2
  from pathlib import Path
3
3
  from types import TracebackType
4
- from typing import List, Union, Tuple, Any, Iterator, Callable
4
+ from typing import List, Union, Tuple, Any, Callable
5
5
  import traceback
6
6
  import numpy as np
7
7
  import numpy.typing as npt
@@ -76,28 +76,3 @@ def rescale_min_max(image: npt.NDArray[np.float32]) -> npt.NDArray[np.float32]:
76
76
  return image
77
77
 
78
78
 
79
- def flatten(
80
- value: Any,
81
- *,
82
- prefix: str = "",
83
- list_token: str = "e",
84
- ) -> Iterator[Tuple[str, Any]]:
85
- """
86
- Recursively walk `value` and yield (flat_key, leaf_value) pairs.
87
-
88
- • Dicts → descend with new_prefix = f"{prefix}_{key}" (or just key if top level)
89
- • Sequences → descend with new_prefix = f"{prefix}_{list_token}{idx}"
90
- • Leaf scalars → yield the accumulated flat key and the scalar itself
91
- """
92
- if isinstance(value, dict):
93
- for k, v in value.items():
94
- new_prefix = f"{prefix}_{k}" if prefix else k
95
- yield from flatten(v, prefix=new_prefix, list_token=list_token)
96
-
97
- elif isinstance(value, (list, tuple)):
98
- for idx, v in enumerate(value):
99
- new_prefix = f"{prefix}_{list_token}{idx}"
100
- yield from flatten(v, prefix=new_prefix, list_token=list_token)
101
-
102
- else: # primitive leaf (str, int, float, bool, None…)
103
- yield prefix, value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: code-loader
3
- Version: 1.0.101.dev0
3
+ Version: 1.0.102.dev1
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
2
2
  code_loader/__init__.py,sha256=6MMWr0ObOU7hkqQKgOqp4Zp3I28L7joGC9iCbQYtAJg,241
3
3
  code_loader/contract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- code_loader/contract/datasetclasses.py,sha256=gJsXu4zVAaiBlq6GJwPxfTD2e0gICTtI_6Ir61MRL48,8838
4
+ code_loader/contract/datasetclasses.py,sha256=6hwzFOtVlAHcDYgz4n-yIQrpqjda-ZoBGeDzH1kogXc,9123
5
5
  code_loader/contract/enums.py,sha256=GEFkvUMXnCNt-GOoz7NJ9ecQZ2PPDettJNOsxsiM0wk,1622
6
6
  code_loader/contract/exceptions.py,sha256=jWqu5i7t-0IG0jGRsKF4DjJdrsdpJjIYpUkN1F4RiyQ,51
7
7
  code_loader/contract/mapping.py,sha256=e11h_sprwOyE32PcqgRq9JvyahQrPzwqgkhmbQLKLQY,1165
@@ -19,15 +19,18 @@ code_loader/experiment_api/experiment_context.py,sha256=kdzUbuzXo1pMVslOC3TKeJwW
19
19
  code_loader/experiment_api/types.py,sha256=MY8xFARHwdVA7p4dxyhD60ShmttgTvb4qdp1oEB_NPg,485
20
20
  code_loader/experiment_api/utils.py,sha256=XZHtxge12TS4H4-8PjV3sKuhp8Ud6ojAiIzTZJEqBqc,3304
21
21
  code_loader/experiment_api/workingspace_config_utils.py,sha256=DLzXQCg4dgTV_YgaSbeTVzq-2ja_SQw4zi7LXwKL9cY,990
22
+ code_loader/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ code_loader/helpers/plot_functions.py,sha256=91wHSewc_y75hdCL-4ghrsGpg0u-IlK_7aoxbu6-jd0,14602
24
+ code_loader/helpers/visualize.py,sha256=RusWyJax9qSkz2JItMb_IxOLskUvfGSWajTJHY4hCuE,565
22
25
  code_loader/inner_leap_binder/__init__.py,sha256=koOlJyMNYzGbEsoIbXathSmQ-L38N_pEXH_HvL7beXU,99
23
- code_loader/inner_leap_binder/leapbinder.py,sha256=mi9wp98iywHedCe2GwrbiqE14zbGo1rR0huodG96ZXY,32508
24
- code_loader/inner_leap_binder/leapbinder_decorators.py,sha256=j38nYWfc6yll1SMggV8gABEvSyQwEBVf5RdFnmQ1aD0,38523
25
- code_loader/leaploader.py,sha256=kCNiLdbmGZBo1a6hE1gDRZyOeJLWH2THweO9AtepO3s,28869
26
+ code_loader/inner_leap_binder/leapbinder.py,sha256=tiWrRBZCuQDeWOP0GGRUvzFHRFKG0uX0mWADdiSP-ho,32570
27
+ code_loader/inner_leap_binder/leapbinder_decorators.py,sha256=0-Itrq_rBzx4InpmcfkSmUX6lOmrzlqGKxtkAMD8H5I,39356
28
+ code_loader/leaploader.py,sha256=vfN92-uoLeo8pojhwzPh4iu3gaoIQNqQklYwOy0kbtM,29225
26
29
  code_loader/leaploaderbase.py,sha256=lKdw2pd6H9hFsxVmc7jJMoZd_vlG5He1ooqT-cR_yq8,4496
27
- code_loader/utils.py,sha256=lzisPgCxMo10dn_VFIlkM1fJaYjwaKXgiMB8zZo7oYw,3664
30
+ code_loader/utils.py,sha256=_j8b60pimoNAvWMRj7hEkkT6C76qES6cZoBFHpXHMxA,2698
28
31
  code_loader/visualizers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
32
  code_loader/visualizers/default_visualizers.py,sha256=onRnLE_TXfgLN4o52hQIOOhUcFexGlqJ3xSpQDVLuZM,2604
30
- code_loader-1.0.101.dev0.dist-info/LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
31
- code_loader-1.0.101.dev0.dist-info/METADATA,sha256=XNQDZDS2yCb-da4qiLyq6WM3ymDBp4e9MbNdZJltUBc,855
32
- code_loader-1.0.101.dev0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
33
- code_loader-1.0.101.dev0.dist-info/RECORD,,
33
+ code_loader-1.0.102.dev1.dist-info/LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
34
+ code_loader-1.0.102.dev1.dist-info/METADATA,sha256=QFOrHLfO7eTASzOF-Cyvu9Nf-pI5Rur-w27OlxES3lc,855
35
+ code_loader-1.0.102.dev1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ code_loader-1.0.102.dev1.dist-info/RECORD,,