lamindb 1.3.2__py3-none-any.whl → 1.4.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.
@@ -21,6 +21,7 @@
21
21
  FeatureValue
22
22
  InspectResult
23
23
  ValidateFields
24
+ SchemaOptionals
24
25
 
25
26
  """
26
27
 
@@ -75,5 +76,11 @@ from .project import (
75
76
  )
76
77
  from .record import Migration
77
78
  from .run import RunParamValue
78
- from .schema import SchemaFeature, SchemaParam, ArtifactSchema, SchemaComponent
79
+ from .schema import (
80
+ SchemaFeature,
81
+ SchemaParam,
82
+ ArtifactSchema,
83
+ SchemaComponent,
84
+ SchemaOptionals,
85
+ )
79
86
  from .ulabel import ArtifactULabel, TransformULabel, RunULabel, CollectionULabel
@@ -313,6 +313,9 @@ def describe_features(
313
313
  fs_data = _get_schemas_postgres(self, related_data=related_data)
314
314
  for fs_id, (slot, data) in fs_data.items():
315
315
  for registry_str, feature_names in data.items():
316
+ # prevent projects show up as features
317
+ if registry_str == "Project":
318
+ continue
316
319
  schema = Schema.objects.using(self._state.db).get(id=fs_id)
317
320
  schema_data[slot] = (schema, feature_names)
318
321
  for feature_name in feature_names:
@@ -446,8 +449,6 @@ def describe_features(
446
449
  dataset_tree = tree.add(
447
450
  Text.assemble(
448
451
  ("Dataset features", "bold bright_magenta"),
449
- ("/", "dim"),
450
- (".feature_sets", "dim bold"),
451
452
  )
452
453
  )
453
454
  for child in int_features_tree_children:
@@ -648,7 +649,7 @@ def __getitem__(self, slot) -> QuerySet:
648
649
  return getattr(schema, self._accessor_by_registry[orm_name]).all()
649
650
 
650
651
 
651
- def filter_base(cls, **expression):
652
+ def filter_base(cls, _skip_validation: bool = True, **expression) -> QuerySet:
652
653
  from .artifact import Artifact
653
654
 
654
655
  if cls is FeatureManager:
@@ -658,11 +659,12 @@ def filter_base(cls, **expression):
658
659
  model = Param
659
660
  value_model = ParamValue
660
661
  keys_normalized = [key.split("__")[0] for key in expression]
661
- validated = model.validate(keys_normalized, field="name", mute=True)
662
- if sum(validated) != len(keys_normalized):
663
- raise ValidationError(
664
- f"Some keys in the filter expression are not registered as features: {np.array(keys_normalized)[~validated]}"
665
- )
662
+ if not _skip_validation:
663
+ validated = model.validate(keys_normalized, field="name", mute=True)
664
+ if sum(validated) != len(keys_normalized):
665
+ raise ValidationError(
666
+ f"Some keys in the filter expression are not registered as features: {np.array(keys_normalized)[~validated]}"
667
+ )
666
668
  new_expression = {}
667
669
  features = model.filter(name__in=keys_normalized).all().distinct()
668
670
  feature_param = "param" if model is Param else "feature"
@@ -719,31 +721,33 @@ def filter_base(cls, **expression):
719
721
  # https://laminlabs.slack.com/archives/C04FPE8V01W/p1688328084810609
720
722
  raise NotImplementedError
721
723
  if cls == FeatureManager or cls == ParamManagerArtifact:
722
- return Artifact.filter(**new_expression)
724
+ return Artifact.objects.filter(**new_expression)
723
725
  elif cls == ParamManagerRun:
724
- return Run.filter(**new_expression)
726
+ return Run.objects.filter(**new_expression)
725
727
 
726
728
 
727
729
  @classmethod # type: ignore
730
+ @deprecated("the filter() registry classmethod")
728
731
  def filter(cls, **expression) -> QuerySet:
729
732
  """Query artifacts by features."""
730
- return filter_base(cls, **expression)
733
+ return filter_base(cls, _skip_validation=False, **expression)
731
734
 
732
735
 
733
736
  @classmethod # type: ignore
737
+ @deprecated("the filter() registry classmethod")
734
738
  def get(cls, **expression) -> Record:
735
739
  """Query a single artifact by feature."""
736
- return filter_base(cls, **expression).one()
740
+ return filter_base(cls, _skip_validation=False, **expression).one()
737
741
 
738
742
 
739
743
  @property # type: ignore
740
744
  def slots(self) -> dict[str, Schema]:
741
745
  """Schema by slot.
742
746
 
743
- Example:
747
+ Example::
744
748
 
745
- >>> artifact.features.slots
746
- {'var': <Schema: var>, 'obs': <Schema: obs>}
749
+ artifact.features.slots
750
+ #> {'var': <Schema: var>, 'obs': <Schema: obs>}
747
751
  """
748
752
  if self._slots is None:
749
753
  self._slots = get_schema_by_slot_(self._host)
@@ -1096,7 +1100,7 @@ def _add_set_from_df(
1096
1100
  ):
1097
1101
  """Add feature set corresponding to column names of DataFrame."""
1098
1102
  assert self._host.otype == "DataFrame" # noqa: S101
1099
- df = self._host.load()
1103
+ df = self._host.load(is_run_input=False)
1100
1104
  schema = Schema.from_df(
1101
1105
  df=df,
1102
1106
  field=field,
@@ -1119,7 +1123,7 @@ def _add_set_from_anndata(
1119
1123
  assert self._host.otype == "AnnData" # noqa: S101
1120
1124
 
1121
1125
  # parse and register features
1122
- adata = self._host.load()
1126
+ adata = self._host.load(is_run_input=False)
1123
1127
  feature_sets = parse_staged_feature_sets_from_anndata(
1124
1128
  adata,
1125
1129
  var_field=var_field,
@@ -1162,7 +1166,7 @@ def _add_set_from_mudata(
1162
1166
  assert self._host.otype == "MuData" # noqa: S101
1163
1167
 
1164
1168
  # parse and register features
1165
- mdata = self._host.load()
1169
+ mdata = self._host.load(is_run_input=False)
1166
1170
  feature_sets = {}
1167
1171
 
1168
1172
  obs_features = Feature.from_values(mdata.obs.columns) # type: ignore
@@ -1198,7 +1202,7 @@ def _add_set_from_spatialdata(
1198
1202
  assert self._host.otype == "SpatialData" # noqa: S101
1199
1203
 
1200
1204
  # parse and register features
1201
- sdata = self._host.load()
1205
+ sdata = self._host.load(is_run_input=False)
1202
1206
  feature_sets = {}
1203
1207
 
1204
1208
  # sample features
@@ -85,7 +85,7 @@ def _from_values(
85
85
  print_values = colors.yellow(_format_values(unmapped_values))
86
86
  n_nonval = colors.yellow(f"{len(unmapped_values)} non-validated")
87
87
  if not mute:
88
- logger.warning(
88
+ logger.info(
89
89
  f"{colors.red('did not create')} {registry.__name__} record{s} for "
90
90
  f"{n_nonval} {colors.italic(f'{field.field.name}{s}')}: {print_values}" # type: ignore
91
91
  )
@@ -73,11 +73,11 @@ class IsVersioned(models.Model):
73
73
  >>> new_artifact = ln.Artifact(df2, revises=artifact).save()
74
74
  >>> new_artifact.versions()
75
75
  """
76
- db = self._state.db
77
- if db is not None and db != "default":
78
- return self.__class__.using(db).filter(uid__startswith=self.stem_uid) # type: ignore
79
- else:
80
- return self.__class__.filter(uid__startswith=self.stem_uid) # type: ignore
76
+ return (
77
+ self.__class__.using(self._state.db)
78
+ .filter(uid__startswith=self.stem_uid)
79
+ .order_by("-created_at")
80
+ )
81
81
 
82
82
  def _add_to_version_family(self, revises: IsVersioned, version: str | None = None):
83
83
  """Add current record to a version family.
@@ -101,16 +101,6 @@ class IsVersioned(models.Model):
101
101
  logger.success(f"updated uid from {old_uid} to {new_uid}!")
102
102
 
103
103
 
104
- def message_update_key_in_version_family(
105
- *,
106
- suid: str,
107
- existing_key: str,
108
- registry: str,
109
- new_key: str,
110
- ) -> str:
111
- return f'Or update key "{existing_key}" to "{new_key}" for all previous versions:\n\nln.{registry}.filter(uid__startswith="{suid}").update(key="{new_key}")\n'
112
-
113
-
114
104
  def bump_version(
115
105
  version: str,
116
106
  bump_type: str = "minor",