code-loader 1.0.214.dev2__tar.gz → 1.0.215.dev1__tar.gz

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.
Files changed (37) hide show
  1. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/PKG-INFO +1 -1
  2. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/datasetclasses.py +32 -12
  3. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/inner_leap_binder/leapbinder.py +3 -3
  4. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/inner_leap_binder/leapbinder_decorators.py +6 -5
  5. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/utils.py +3 -3
  6. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/pyproject.toml +5 -1
  7. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/LICENSE +0 -0
  8. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/README.md +0 -0
  9. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/__init__.py +0 -0
  10. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/__init__.py +0 -0
  11. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/enums.py +0 -0
  12. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/exceptions.py +0 -0
  13. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/mapping.py +0 -0
  14. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/responsedataclasses.py +0 -0
  15. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/sim_config.py +0 -0
  16. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/contract/visualizer_classes.py +0 -0
  17. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/default_losses.py +0 -0
  18. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/default_metrics.py +0 -0
  19. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/__init__.py +0 -0
  20. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/api.py +0 -0
  21. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/cli_config_utils.py +0 -0
  22. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/client.py +0 -0
  23. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/epoch.py +0 -0
  24. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/experiment.py +0 -0
  25. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/experiment_context.py +0 -0
  26. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/types.py +0 -0
  27. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/utils.py +0 -0
  28. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  29. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/inner_leap_binder/__init__.py +0 -0
  30. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/leaploader.py +0 -0
  31. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/leaploaderbase.py +0 -0
  32. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/mixpanel_tracker.py +0 -0
  33. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/plot_functions/__init__.py +0 -0
  34. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/plot_functions/plot_functions.py +0 -0
  35. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/plot_functions/visualize.py +0 -0
  36. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/visualizers/__init__.py +0 -0
  37. {code_loader-1.0.214.dev2 → code_loader-1.0.215.dev1}/code_loader/visualizers/default_visualizers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: code-loader
3
- Version: 1.0.214.dev2
3
+ Version: 1.0.215.dev1
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -25,6 +25,17 @@ _simulation_context: Dict[str, bool] = {"active": False}
25
25
 
26
26
  SampleId = Union[int, str]
27
27
 
28
+ SUPPORTED_SAMPLE_IDS_CONTAINERS = (list, tuple, range)
29
+ SUPPORTED_SAMPLE_IDS = ("a list of str, a list of int (with sample_id_type=int), "
30
+ "or a list of non-empty lists of str or int for grouped samples "
31
+ "(a tuple or range can be used instead of the outer list)")
32
+
33
+ _SAMPLE_ID_TYPES: Dict[type, Tuple[type, ...]] = {str: (str, np.str_), int: (int,)}
34
+
35
+
36
+ def is_sample_id_of_type(sample_id: Any, sample_id_type: type) -> bool:
37
+ return type(sample_id) in _SAMPLE_ID_TYPES.get(sample_id_type, ())
38
+
28
39
 
29
40
  @dataclass
30
41
  class PreprocessResponse:
@@ -69,19 +80,24 @@ class PreprocessResponse:
69
80
  self._grouped = False
70
81
  elif self.sample_ids is not None:
71
82
  given_length = self.length
83
+ assert type(self.sample_ids) in SUPPORTED_SAMPLE_IDS_CONTAINERS, \
84
+ (f"PreprocessResponse.sample_ids should be a list. Got: {type(self.sample_ids).__name__}. "
85
+ f"Supported: {SUPPORTED_SAMPLE_IDS}. Convert it with .tolist() or list(...), "
86
+ f"e.g. sample_ids=df.index.tolist().")
72
87
  self._grouped = len(self.sample_ids) > 0 and isinstance(self.sample_ids[0], list)
73
88
  if self._grouped:
74
89
  groups = cast(List[List[SampleId]], self.sample_ids)
75
90
  assert len(groups) >= 1, "Grouped PreprocessResponse must have at least one group."
76
91
  for group in groups:
77
- assert isinstance(group, list) and len(group) > 0, \
78
- "Each group in a grouped PreprocessResponse must be a non-empty list."
79
- self.sample_id_type = type(groups[0][0])
80
- assert issubclass(self.sample_id_type, (str, int)), \
81
- f"Sample id should be of type str or int. Got: {self.sample_id_type.__name__}"
92
+ assert type(group) is list and len(group) > 0, \
93
+ f"Each group in a grouped PreprocessResponse must be a non-empty list. Got: {type(group).__name__}"
94
+ first_type = type(groups[0][0])
95
+ assert first_type in (str, np.str_, int), \
96
+ f"Sample id should be of type str or int. Got: {first_type.__name__}"
97
+ self.sample_id_type = int if first_type is int else str
82
98
  for group in groups:
83
99
  for sample_id in group:
84
- assert isinstance(sample_id, self.sample_id_type), \
100
+ assert is_sample_id_of_type(sample_id, self.sample_id_type), \
85
101
  f"Sample id should be of type {self.sample_id_type.__name__}. Got: {type(sample_id)}"
86
102
  self.length = sum(len(group) for group in groups)
87
103
  else:
@@ -89,9 +105,13 @@ class PreprocessResponse:
89
105
  self.length = len(flat_ids)
90
106
  if self.sample_id_type is None:
91
107
  self.sample_id_type = str
92
- if self.sample_id_type == str:
93
- for sample_id in flat_ids:
94
- assert isinstance(sample_id, str), f"Sample id should be of type str. Got: {type(sample_id)}"
108
+ assert self.sample_id_type in (str, int), \
109
+ f"PreprocessResponse.sample_id_type should be str or int. Got: {self.sample_id_type}"
110
+ for sample_id in flat_ids:
111
+ assert is_sample_id_of_type(sample_id, self.sample_id_type), \
112
+ (f"Sample id should be of type {self.sample_id_type.__name__}. Got: {type(sample_id)}. "
113
+ f"Supported: {SUPPORTED_SAMPLE_IDS}. Convert NumPy values with .tolist(), "
114
+ f"or pass sample_id_type=int for int ids.")
95
115
  # dataclasses.replace() re-invokes __init__ with both fields already populated
96
116
  # (length previously derived from sample_ids); only reject a genuine mismatch.
97
117
  if given_length is not None:
@@ -313,7 +333,7 @@ class ElementInstanceMasksHandler:
313
333
  @dataclass
314
334
  class FalsePositiveInstancesHandler:
315
335
  name: str
316
- function: Callable
336
+ function: Callable[..., Any]
317
337
 
318
338
  @dataclass
319
339
  class GroundTruthHandler(DatasetBaseHandler):
@@ -414,8 +434,8 @@ class DatasetIntegrationSetup:
414
434
  inputs: List[InputHandler] = field(default_factory=list)
415
435
  instance_masks: List[ElementInstanceMasksHandler] = field(default_factory=list)
416
436
  false_positive_instances: Optional[FalsePositiveInstancesHandler] = None
417
- false_positive_empty_gt: Dict[str, Callable] = field(default_factory=dict)
418
- false_positive_custom_latent_spaces: Dict[str, Callable] = field(default_factory=dict)
437
+ false_positive_empty_gt: Dict[str, Callable[..., Any]] = field(default_factory=dict)
438
+ false_positive_custom_latent_spaces: Dict[str, Callable[..., Any]] = field(default_factory=dict)
419
439
  ground_truths: List[GroundTruthHandler] = field(default_factory=list)
420
440
  metadata: List[MetadataHandler] = field(default_factory=list)
421
441
  prediction_types: List[PredictionTypeHandler] = field(default_factory=list)
@@ -341,7 +341,7 @@ class LeapBinder:
341
341
  self.setup_container.instance_masks.append(ElementInstanceMasksHandler(name, function))
342
342
 
343
343
 
344
- def set_false_positive_instances(self, function: Callable, name: str) -> None:
344
+ def set_false_positive_instances(self, function: Callable[..., Any], name: str) -> None:
345
345
  """
346
346
  Set the false-positive instances handler. It receives (sample_id, preprocess, predictions)
347
347
  and returns a list of ElementInstance, one per false-positive prediction.
@@ -351,7 +351,7 @@ class LeapBinder:
351
351
  function = to_numpy_return_fp_masks_wrapper(function)
352
352
  self.setup_container.false_positive_instances = FalsePositiveInstancesHandler(name, function)
353
353
 
354
- def set_false_positive_empty_gt(self, function: Callable, gt_name: str) -> None:
354
+ def set_false_positive_empty_gt(self, function: Callable[..., Any], gt_name: str) -> None:
355
355
  """
356
356
  Set the empty ground truth for false-positive instance rows of the given GT encoder.
357
357
  It receives (sample_id, preprocess) and returns an array shaped like the GT encoder's output.
@@ -392,7 +392,7 @@ class LeapBinder:
392
392
  f"tensorleap_false_positive_empty_gt for '{name}' returned dtype {empty.dtype}, "
393
393
  f"which cannot be cast to float32.")
394
394
 
395
- def set_false_positive_custom_latent_space(self, function: Callable, name: str) -> None:
395
+ def set_false_positive_custom_latent_space(self, function: Callable[..., Any], name: str) -> None:
396
396
  """
397
397
  Set the custom latent space hook for false-positive instance rows. It receives
398
398
  (sample_id, preprocess, fp_instance) and returns a 1-D vector for the instance-aware
@@ -27,6 +27,7 @@ from code_loader.contract.datasetclasses import CustomCallableInterfaceMultiArgs
27
27
  CustomMultipleReturnCallableInterfaceMultiArgs, ConfusionMatrixCallableInterfaceMultiArgs, CustomCallableInterface, \
28
28
  VisualizerCallableInterface, MetadataSectionCallableInterface, PreprocessResponse, SectionCallableInterface, \
29
29
  ConfusionMatrixElement, SamplePreprocessResponse, PredictionTypeHandler, InstanceCallableInterface, ElementInstance, \
30
+ is_sample_id_of_type, \
30
31
  InstanceLengthCallableInterface, InstanceSectionCallableInterface, AutoregressiveStepCallableInterface, \
31
32
  MAX_CUSTOM_LATENT_SPACE_DIM, CUSTOM_LATENT_SPACE_WARN_DIM
32
33
  from code_loader.contract.enums import MetricDirection, LeapDataType, DatasetMetadataType, DataStateType, \
@@ -236,7 +237,7 @@ def _validate_id_or_group(sample_id, preprocess_response, func_name):
236
237
  f'is grouped. Pass a group (list of sample ids) for a grouped dataset.')
237
238
  ids = sample_id if is_group else [sample_id]
238
239
  for sid in ids:
239
- assert type(sid) == preprocess_response.sample_id_type, \
240
+ assert is_sample_id_of_type(sid, preprocess_response.sample_id_type), \
240
241
  (f'{func_name}() validation failed: '
241
242
  f'Argument sample_id should be as the same type as defined in the preprocess response '
242
243
  f'{preprocess_response.sample_id_type}. Got {type(sid)}.')
@@ -2491,7 +2492,7 @@ def tensorleap_autoregressive_step(latent_space_aggregation: str = 'last_step'):
2491
2492
  (f'{user_function.__name__}() validation failed: '
2492
2493
  f'the first call (prev_inputs=None, prev_outputs=None) must pass state=None. '
2493
2494
  f'Got state of type {type(state).__name__}.')
2494
- assert type(sample_id) == preprocess_response.sample_id_type, \
2495
+ assert is_sample_id_of_type(sample_id, preprocess_response.sample_id_type), \
2495
2496
  (f'{user_function.__name__}() validation failed: '
2496
2497
  f'Argument sample_id should be as the same type as defined in the preprocess response '
2497
2498
  f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
@@ -3360,7 +3361,7 @@ def tensorleap_element_instance_preprocess(
3360
3361
  "Remove the instance encoders or don't group this dataset.")
3361
3362
  sample_ids_to_instance_mappings = {}
3362
3363
  instance_to_sample_ids_mappings = {}
3363
- all_sample_ids = preprocess_response.sample_ids.copy()
3364
+ all_sample_ids = list(preprocess_response.sample_ids)
3364
3365
  for sample_id in preprocess_response.sample_ids:
3365
3366
  instances_length = instance_length_encoder(sample_id, preprocess_response)
3366
3367
  instances_ids = [f'{sample_id}_{instance_id}' for instance_id in range(instances_length)]
@@ -3458,7 +3459,7 @@ def tensorleap_instances_masks_encoder(name: str):
3458
3459
  assert isinstance(preprocess_response, PreprocessResponse), \
3459
3460
  (f'tensorleap_instances_masks_encoder validation failed: '
3460
3461
  f'Argument preprocess_response should be a PreprocessResponse. Got {type(preprocess_response)}.')
3461
- assert type(sample_id) == preprocess_response.sample_id_type, \
3462
+ assert is_sample_id_of_type(sample_id, preprocess_response.sample_id_type), \
3462
3463
  (f'tensorleap_instances_masks_encoder validation failed: '
3463
3464
  f'Argument sample_id should be as the same type as defined in the preprocess response '
3464
3465
  f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
@@ -3660,7 +3661,7 @@ def tensorleap_instances_length_encoder(name: str):
3660
3661
  assert isinstance(preprocess_response, PreprocessResponse), \
3661
3662
  (f'tensorleap_instances_length_encoder validation failed: '
3662
3663
  f'Argument preprocess_response should be a PreprocessResponse. Got {type(preprocess_response)}.')
3663
- assert type(sample_id) == preprocess_response.sample_id_type, \
3664
+ assert is_sample_id_of_type(sample_id, preprocess_response.sample_id_type), \
3664
3665
  (f'tensorleap_instances_length_encoder validation failed: '
3665
3666
  f'Argument sample_id should be as the same type as defined in the preprocess response '
3666
3667
  f'{preprocess_response.sample_id_type}. Got {type(sample_id)}.')
@@ -6,7 +6,7 @@ import pickle
6
6
  import sys
7
7
  from pathlib import Path
8
8
  from types import TracebackType
9
- from typing import List, Union, Tuple, Any, Callable, Dict, Optional
9
+ from typing import List, Union, Tuple, Any, Callable, Dict, Optional, cast
10
10
  import traceback
11
11
  import numpy as np
12
12
  import numpy.typing as npt
@@ -53,11 +53,11 @@ def to_numpy_return_masks_wrapper(encoder_function: InstanceCallableInterface) -
53
53
  return numpy_encoder_function
54
54
 
55
55
 
56
- def to_numpy_return_fp_masks_wrapper(encoder_function: Callable) -> Callable:
56
+ def to_numpy_return_fp_masks_wrapper(encoder_function: Callable[..., Any]) -> Callable[..., List[ElementInstance]]:
57
57
  def numpy_encoder_function(idx: Union[int, str], samples: PreprocessResponse, predictions: Dict[str, Any]) -> List[ElementInstance]:
58
58
  result = encoder_function(idx, samples, predictions)
59
59
  if not isinstance(result, list):
60
- return result # malformed: the loader reports it with a clear message
60
+ return cast(List[ElementInstance], result) # malformed: the loader reports it with a clear message
61
61
  for instance in result:
62
62
  if not isinstance(instance, ElementInstance):
63
63
  continue
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
- version = "1.0.214.dev2"
3
+ version = "1.0.215.dev1"
4
4
  description = ""
5
5
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
6
6
  license = "MIT"
@@ -30,6 +30,10 @@ pytest-watch = "^4.2.0"
30
30
  mypy = "1.3.0"
31
31
  onnxruntime = {version = ">=1.0.0", python = ">=3.10"}
32
32
  onnx = {version = ">=1.0.0", python = ">=3.10"}
33
+ pandas = [
34
+ { version = "^2.0.3", python = ">=3.8,<3.11" },
35
+ { version = "^2.2.3", python = ">=3.11,<3.13" }
36
+ ]
33
37
 
34
38
  [build-system]
35
39
  requires = ["poetry-core>=1.0.0"]