lamindb 0.76.13__py3-none-any.whl → 0.76.14__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.
lamindb/_from_values.py CHANGED
@@ -64,11 +64,7 @@ def get_or_create_records(
64
64
  if source_record:
65
65
  from bionty.core._add_ontology import check_source_in_db
66
66
 
67
- check_source_in_db(
68
- registry=registry,
69
- source=source_record,
70
- update=True,
71
- )
67
+ check_source_in_db(registry=registry, source=source_record)
72
68
 
73
69
  from_source = not source_record.in_db
74
70
  elif hasattr(registry, "source_id"):
lamindb/_query_set.py CHANGED
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, NamedTuple
6
6
  import pandas as pd
7
7
  from django.db import models
8
8
  from django.db.models import F
9
- from lamin_utils import logger
9
+ from lamin_utils import colors, logger
10
10
  from lamindb_setup.core._docs import doc_args
11
11
  from lnschema_core.models import (
12
12
  Artifact,
@@ -186,6 +186,7 @@ class QuerySet(models.QuerySet):
186
186
  if pk_column_name in df.columns:
187
187
  df = df.set_index(pk_column_name)
188
188
  if len(df) == 0:
189
+ logger.warning(colors.yellow("No records found"))
189
190
  return df
190
191
  if include is not None:
191
192
  if isinstance(include, str):
@@ -218,12 +219,15 @@ class QuerySet(models.QuerySet):
218
219
  f"{related_ORM.__name__.lower()}__{lookup_str}"
219
220
  )
220
221
  link_df = pd.DataFrame(
221
- field.through.objects.values(
222
+ field.through.objects.using(self.db).values(
222
223
  left_side_link_model, values_expression
223
224
  )
224
225
  )
225
226
  if link_df.shape[0] == 0:
226
- return df
227
+ logger.warning(
228
+ f"{colors.yellow(expression)} is not shown because no values are found"
229
+ )
230
+ continue
227
231
  link_groupby = link_df.groupby(left_side_link_model)[
228
232
  values_expression
229
233
  ].apply(list)
lamindb/_record.py CHANGED
@@ -7,7 +7,7 @@ import dj_database_url
7
7
  import lamindb_setup as ln_setup
8
8
  from django.db import connections, transaction
9
9
  from django.db.models import IntegerField, Manager, Q, QuerySet, Value
10
- from lamin_utils import logger
10
+ from lamin_utils import colors, logger
11
11
  from lamin_utils._lookup import Lookup
12
12
  from lamindb_setup._connect_instance import (
13
13
  get_owner_name_from_identifier,
@@ -17,10 +17,11 @@ from lamindb_setup._connect_instance import (
17
17
  from lamindb_setup.core._docs import doc_args
18
18
  from lamindb_setup.core._hub_core import connect_instance_hub
19
19
  from lamindb_setup.core._settings_store import instance_settings_file
20
- from lnschema_core.models import IsVersioned, Record, Run, Transform
20
+ from lnschema_core.models import Artifact, Feature, IsVersioned, Record, Run, Transform
21
21
 
22
22
  from lamindb._utils import attach_func_to_class_method
23
23
  from lamindb.core._settings import settings
24
+ from lamindb.core.exceptions import RecordNameChangeIntegrityError
24
25
 
25
26
  if TYPE_CHECKING:
26
27
  import pandas as pd
@@ -129,6 +130,7 @@ def __init__(record: Record, *args, **kwargs):
129
130
  else:
130
131
  # object is loaded from DB (**kwargs could be omitted below, I believe)
131
132
  super(Record, record).__init__(*args, **kwargs)
133
+ _store_record_old_name(record)
132
134
 
133
135
 
134
136
  @classmethod # type:ignore
@@ -584,11 +586,15 @@ def save(self, *args, **kwargs) -> Record:
584
586
  with transaction.atomic():
585
587
  revises._revises = None # ensure we don't start a recursion
586
588
  revises.save()
589
+ check_name_change(self)
587
590
  super(Record, self).save(*args, **kwargs)
591
+ _store_record_old_name(self)
588
592
  self._revises = None
589
593
  # save unversioned record
590
594
  else:
595
+ check_name_change(self)
591
596
  super(Record, self).save(*args, **kwargs)
597
+ _store_record_old_name(self)
592
598
  # perform transfer of many-to-many fields
593
599
  # only supported for Artifact and Collection records
594
600
  if db is not None and db != "default" and using_key is None:
@@ -616,6 +622,74 @@ def save(self, *args, **kwargs) -> Record:
616
622
  return self
617
623
 
618
624
 
625
+ def _store_record_old_name(record: Record):
626
+ # writes the name to the _name attribute, so we can detect renaming upon save
627
+ if hasattr(record, "_name_field"):
628
+ record._name = getattr(record, record._name_field)
629
+
630
+
631
+ def check_name_change(record: Record):
632
+ """Warns if a record's name has changed."""
633
+ if (
634
+ not record.pk
635
+ or not hasattr(record, "_name")
636
+ or not hasattr(record, "_name_field")
637
+ ):
638
+ return
639
+
640
+ old_name = record._name
641
+ new_name = getattr(record, record._name_field)
642
+ registry = record.__class__.__name__
643
+
644
+ if old_name != new_name:
645
+ # when a label is renamed, only raise a warning if it has a feature
646
+ if hasattr(record, "artifacts"):
647
+ linked_records = (
648
+ record.artifacts.through.filter(
649
+ label_ref_is_name=True, **{f"{registry.lower()}_id": record.pk}
650
+ )
651
+ .exclude(feature_id=None) # must have a feature
652
+ .exclude(
653
+ feature_ref_is_name=None
654
+ ) # must be linked via Curator and therefore part of a featureset
655
+ .distinct()
656
+ )
657
+ artifact_ids = linked_records.list("artifact__uid")
658
+ n = len(artifact_ids)
659
+ s = "s" if n > 1 else ""
660
+ if n > 0:
661
+ logger.error(
662
+ f"You are trying to {colors.red('rename label')} from '{old_name}' to '{new_name}'!\n"
663
+ f" → The following {n} artifact{s} {colors.red('will no longer be validated')}: {artifact_ids}\n\n"
664
+ f"{colors.bold('To rename this label')}, make it external:\n"
665
+ f" → run `artifact.labels.make_external(label)`\n\n"
666
+ f"After renaming, consider re-curating the above artifact{s}:\n"
667
+ f' → in each dataset, manually modify label "{old_name}" to "{new_name}"\n'
668
+ f" → run `ln.Curator`\n"
669
+ )
670
+ raise RecordNameChangeIntegrityError
671
+
672
+ # when a feature is renamed
673
+ elif isinstance(record, Feature):
674
+ # only internal features are associated with featuresets
675
+ linked_artifacts = Artifact.filter(feature_sets__features=record).list(
676
+ "uid"
677
+ )
678
+ n = len(linked_artifacts)
679
+ s = "s" if n > 1 else ""
680
+ if n > 0:
681
+ logger.error(
682
+ f"You are trying to {colors.red('rename feature')} from '{old_name}' to '{new_name}'!\n"
683
+ f" → The following {n} artifact{s} {colors.red('will no longer be validated')}: {linked_artifacts}\n\n"
684
+ f"{colors.bold('To rename this feature')}, make it external:\n"
685
+ " → run `artifact.features.make_external(feature)`\n\n"
686
+ f"After renaming, consider re-curating the above artifact{s}:\n"
687
+ f" → in each dataset, manually modify feature '{old_name}' to '{new_name}'\n"
688
+ f" → run `ln.Curator`\n"
689
+ )
690
+ raise RecordNameChangeIntegrityError
691
+
692
+
619
693
  def delete(self) -> None:
620
694
  """Delete the record."""
621
695
  # note that the logic below does not fire if a record is moved to the trash
lamindb/core/__init__.py CHANGED
@@ -60,9 +60,11 @@ Modules:
60
60
  types
61
61
  exceptions
62
62
  subsettings
63
+ logger
63
64
 
64
65
  """
65
66
 
67
+ from lamin_utils import logger
66
68
  from lamin_utils._inspect import InspectResult
67
69
  from lnschema_core.models import (
68
70
  CanValidate,
lamindb/core/_data.py CHANGED
@@ -26,6 +26,7 @@ from lamindb.core._settings import settings
26
26
  from ._context import context
27
27
  from ._django import get_artifact_with_related, get_related_model
28
28
  from ._feature_manager import (
29
+ add_label_feature_links,
29
30
  get_feature_set_links,
30
31
  get_host_id_field,
31
32
  get_label_links,
@@ -67,11 +68,17 @@ def add_transform_to_kwargs(kwargs: dict[str, Any], run: Run):
67
68
 
68
69
  def save_feature_sets(self: Artifact | Collection) -> None:
69
70
  if hasattr(self, "_feature_sets"):
71
+ from lamindb.core._feature_manager import get_feature_set_by_slot_
72
+
73
+ existing_feature_sets = get_feature_set_by_slot_(self)
70
74
  saved_feature_sets = {}
71
75
  for key, feature_set in self._feature_sets.items():
72
76
  if isinstance(feature_set, FeatureSet) and feature_set._state.adding:
73
77
  feature_set.save()
74
78
  saved_feature_sets[key] = feature_set
79
+ if key in existing_feature_sets:
80
+ # remove existing feature set on the same slot
81
+ self.feature_sets.remove(existing_feature_sets[key])
75
82
  if len(saved_feature_sets) > 0:
76
83
  s = "s" if len(saved_feature_sets) > 1 else ""
77
84
  display_feature_set_keys = ",".join(
@@ -305,6 +312,8 @@ def add_labels(
305
312
  feature: Feature | None = None,
306
313
  *,
307
314
  field: StrField | None = None,
315
+ feature_ref_is_name: bool | None = None,
316
+ label_ref_is_name: bool | None = None,
308
317
  ) -> None:
309
318
  """{}""" # noqa: D415
310
319
  if self._state.adding:
@@ -373,14 +382,17 @@ def add_labels(
373
382
  if registry_name not in self.features._accessor_by_registry:
374
383
  logger.warning(f"skipping {registry_name}")
375
384
  continue
376
- labels_accessor = getattr(
377
- self, self.features._accessor_by_registry[registry_name]
385
+ if len(records) == 0:
386
+ continue
387
+ features_labels = {
388
+ registry_name: [(feature, label_record) for label_record in records]
389
+ }
390
+ add_label_feature_links(
391
+ self.features,
392
+ features_labels,
393
+ feature_ref_is_name=feature_ref_is_name,
394
+ label_ref_is_name=label_ref_is_name,
378
395
  )
379
- # remove labels that are already linked as add doesn't perform update
380
- linked_labels = [r for r in records if r in labels_accessor.filter()]
381
- if len(linked_labels) > 0:
382
- labels_accessor.remove(*linked_labels)
383
- labels_accessor.add(*records, through_defaults={"feature_id": feature.id})
384
396
  links_feature_set = get_feature_set_links(self)
385
397
  feature_set_ids = [link.featureset_id for link in links_feature_set.all()]
386
398
  # get all linked features of type Feature
@@ -13,6 +13,7 @@ from django.contrib.postgres.aggregates import ArrayAgg
13
13
  from django.db import connections
14
14
  from django.db.models import Aggregate
15
15
  from lamin_utils import colors, logger
16
+ from lamindb_setup.core.hashing import hash_set
16
17
  from lamindb_setup.core.upath import create_path
17
18
  from lnschema_core.models import (
18
19
  Artifact,
@@ -586,6 +587,48 @@ def _accessor_by_registry(self):
586
587
  return self._accessor_by_registry_
587
588
 
588
589
 
590
+ def add_label_feature_links(
591
+ self,
592
+ features_labels,
593
+ *,
594
+ label_ref_is_name: bool | None = None,
595
+ feature_ref_is_name: bool | None = None,
596
+ ):
597
+ if list(features_labels.keys()) != ["ULabel"]:
598
+ related_names = dict_related_model_to_related_name(self._host.__class__)
599
+ else:
600
+ related_names = {"ULabel": "ulabels"}
601
+ for class_name, registry_features_labels in features_labels.items():
602
+ related_name = related_names[class_name] # e.g., "ulabels"
603
+ LinkORM = getattr(self._host, related_name).through
604
+ field_name = f"{get_link_attr(LinkORM, self._host)}_id" # e.g., ulabel_id
605
+ links = [
606
+ LinkORM(
607
+ **{
608
+ "artifact_id": self._host.id,
609
+ "feature_id": feature.id,
610
+ field_name: label.id,
611
+ "feature_ref_is_name": feature_ref_is_name,
612
+ "label_ref_is_name": label_ref_is_name,
613
+ }
614
+ )
615
+ for (feature, label) in registry_features_labels
616
+ ]
617
+ # a link might already exist
618
+ try:
619
+ save(links, ignore_conflicts=False)
620
+ except Exception:
621
+ save(links, ignore_conflicts=True)
622
+ # now delete links that were previously saved without a feature
623
+ LinkORM.filter(
624
+ **{
625
+ "artifact_id": self._host.id,
626
+ "feature_id": None,
627
+ f"{field_name}__in": [l.id for _, l in registry_features_labels],
628
+ }
629
+ ).all().delete()
630
+
631
+
589
632
  def _add_values(
590
633
  self,
591
634
  values: dict[str, str | int | float | bool],
@@ -717,49 +760,9 @@ def _add_values(
717
760
  f"Here is how to create ulabels for them:\n\n{hint}"
718
761
  )
719
762
  raise ValidationError(msg)
720
- # bulk add all links to ArtifactULabel
763
+ # bulk add all links
721
764
  if features_labels:
722
- if list(features_labels.keys()) != ["ULabel"]:
723
- related_names = dict_related_model_to_related_name(self._host.__class__)
724
- else:
725
- related_names = {"ULabel": "ulabels"}
726
- for class_name, registry_features_labels in features_labels.items():
727
- related_name = related_names[class_name] # e.g., "ulabels"
728
- LinkORM = getattr(self._host, related_name).through
729
- field_name = f"{get_link_attr(LinkORM, self._host)}_id" # e.g., ulabel_id
730
- links = [
731
- LinkORM(
732
- **{
733
- "artifact_id": self._host.id,
734
- "feature_id": feature.id,
735
- field_name: label.id,
736
- }
737
- )
738
- for (feature, label) in registry_features_labels
739
- ]
740
- # a link might already exist
741
- try:
742
- save(links, ignore_conflicts=False)
743
- except Exception:
744
- save(links, ignore_conflicts=True)
745
- # now deal with links that were previously saved without a feature_id
746
- links_saved = LinkORM.filter(
747
- **{
748
- "artifact_id": self._host.id,
749
- f"{field_name}__in": [
750
- l.id for _, l in registry_features_labels
751
- ],
752
- }
753
- )
754
- for link in links_saved.all():
755
- # TODO: also check for inconsistent features
756
- if link.feature_id is None:
757
- link.feature_id = [
758
- f.id
759
- for f, l in registry_features_labels
760
- if l.id == getattr(link, field_name)
761
- ][0]
762
- link.save()
765
+ add_label_feature_links(self, features_labels)
763
766
  if _feature_values:
764
767
  save(_feature_values)
765
768
  if is_param:
@@ -1006,6 +1009,36 @@ def _add_from(self, data: Artifact | Collection, transfer_logs: dict = None):
1006
1009
  self._host.features.add_feature_set(feature_set_self, slot)
1007
1010
 
1008
1011
 
1012
+ def make_external(self, feature: Feature) -> None:
1013
+ """Make a feature external, aka, remove feature from feature sets.
1014
+
1015
+ Args:
1016
+ feature: `Feature` A feature record.
1017
+
1018
+ """
1019
+ if not isinstance(feature, Feature):
1020
+ raise TypeError("feature must be a Feature record!")
1021
+ feature_sets = FeatureSet.filter(features=feature).all()
1022
+ for fs in feature_sets:
1023
+ f = Feature.filter(uid=feature.uid).all()
1024
+ features_updated = fs.members.difference(f)
1025
+ if len(features_updated) > 0:
1026
+ # re-compute the hash of feature sets based on the updated members
1027
+ features_hash = hash_set({feature.uid for feature in features_updated})
1028
+ fs.hash = features_hash
1029
+ fs.n = len(features_updated)
1030
+ fs.save()
1031
+ # delete the link between the feature and the feature set
1032
+ FeatureSet.features.through.objects.filter(
1033
+ feature_id=feature.id, featureset_id=fs.id
1034
+ ).delete()
1035
+ # if no members are left in the featureset, delete it
1036
+ if len(features_updated) == 0:
1037
+ logger.warning(f"deleting empty feature set: {fs}")
1038
+ fs.artifacts.set([])
1039
+ fs.delete()
1040
+
1041
+
1009
1042
  FeatureManager.__init__ = __init__
1010
1043
  ParamManager.__init__ = __init__
1011
1044
  FeatureManager.__repr__ = __repr__
@@ -1022,6 +1055,7 @@ FeatureManager._add_set_from_mudata = _add_set_from_mudata
1022
1055
  FeatureManager._add_from = _add_from
1023
1056
  FeatureManager.filter = filter
1024
1057
  FeatureManager.get = get
1058
+ FeatureManager.make_external = make_external
1025
1059
  ParamManager.add_values = add_values_params
1026
1060
  ParamManager.get_values = get_values
1027
1061
  ParamManager.filter = filter
@@ -263,3 +263,24 @@ class LabelManager:
263
263
  getattr(self._host, related_name).add(
264
264
  *labels, through_defaults={"feature_id": feature_id}
265
265
  )
266
+
267
+ def make_external(self, label: Record):
268
+ """Make a label external, aka dissociate label from internal features.
269
+
270
+ Args:
271
+ label: Label record to make external.
272
+ """
273
+ d = dict_related_model_to_related_name(self._host)
274
+ registry = label.__class__
275
+ related_name = d.get(registry.__get_name_with_schema__())
276
+ link_model = getattr(self._host, related_name).through
277
+ link_records = link_model.filter(
278
+ artifact_id=self._host.id, **{f"{registry.__name__.lower()}_id": label.id}
279
+ )
280
+ features = link_records.values_list("feature__name", flat=True).distinct()
281
+ s = "s" if len(features) > 1 else ""
282
+ link_records.update(feature_id=None, feature_ref_is_name=None)
283
+ logger.warning(
284
+ f'{registry.__name__} "{getattr(label, label._name_field)}" is no longer associated with the following feature{s}:\n'
285
+ f"{list(features)}"
286
+ )
@@ -11,6 +11,7 @@
11
11
  MissingContextUID
12
12
  UpdateContext
13
13
  IntegrityError
14
+ RecordNameChangeIntegrityError
14
15
 
15
16
  """
16
17
 
@@ -57,6 +58,12 @@ class InconsistentKey(Exception):
57
58
  pass
58
59
 
59
60
 
61
+ class RecordNameChangeIntegrityError(SystemExit):
62
+ """Custom exception for name change errors."""
63
+
64
+ pass
65
+
66
+
60
67
  # -------------------------------------------------------------------------------------
61
68
  # run context
62
69
  # -------------------------------------------------------------------------------------
lamindb/core/types.py CHANGED
@@ -13,6 +13,7 @@
13
13
  from lamindb_setup.core.types import UPathStr
14
14
  from lnschema_core.types import (
15
15
  ArtifactType,
16
+ FieldAttr,
16
17
  ListLike,
17
18
  StrField,
18
19
  TransformType,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamindb
3
- Version: 0.76.13
3
+ Version: 0.76.14
4
4
  Summary: A data framework for biology.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Requires-Python: >=3.9
@@ -8,9 +8,9 @@ Description-Content-Type: text/markdown
8
8
  Classifier: Programming Language :: Python :: 3.9
9
9
  Classifier: Programming Language :: Python :: 3.10
10
10
  Classifier: Programming Language :: Python :: 3.11
11
- Requires-Dist: lnschema_core==0.75.0
12
- Requires-Dist: lamin_utils==0.13.6
13
- Requires-Dist: lamin_cli==0.19.0
11
+ Requires-Dist: lnschema_core==0.76.0
12
+ Requires-Dist: lamin_utils==0.13.7
13
+ Requires-Dist: lamin_cli==0.20.1
14
14
  Requires-Dist: lamindb_setup
15
15
  Requires-Dist: rapidfuzz
16
16
  Requires-Dist: pyarrow
@@ -23,7 +23,7 @@ Requires-Dist: pandas
23
23
  Requires-Dist: graphviz
24
24
  Requires-Dist: psycopg2-binary
25
25
  Requires-Dist: lamindb_setup[aws] ; extra == "aws"
26
- Requires-Dist: bionty==0.51.2 ; extra == "bionty"
26
+ Requires-Dist: bionty==0.52.0 ; extra == "bionty"
27
27
  Requires-Dist: line_profiler ; extra == "dev"
28
28
  Requires-Dist: pre-commit ; extra == "dev"
29
29
  Requires-Dist: nox ; extra == "dev"
@@ -37,7 +37,7 @@ Requires-Dist: faker-biology ; extra == "dev"
37
37
  Requires-Dist: django-schema-graph ; extra == "erdiagram"
38
38
  Requires-Dist: readfcs>=1.1.8 ; extra == "fcs"
39
39
  Requires-Dist: lamindb_setup[gcp] ; extra == "gcp"
40
- Requires-Dist: nbproject==0.10.4 ; extra == "jupyter"
40
+ Requires-Dist: nbproject==0.10.5 ; extra == "jupyter"
41
41
  Requires-Dist: jupytext ; extra == "jupyter"
42
42
  Requires-Dist: nbconvert ; extra == "jupyter"
43
43
  Requires-Dist: zarr>=2.16.0 ; extra == "zarr"
@@ -1,18 +1,18 @@
1
- lamindb/__init__.py,sha256=h_byT1s_9NrqH157lvPgG336CTBqGzIIJNlNU7MKWQE,2278
2
- lamindb/_artifact.py,sha256=AHyKZ_D_qMGtywAklo42je8BZB-VBqQ-ZTaI9AB_Yxs,44905
1
+ lamindb/__init__.py,sha256=PelFCbUaNuz_1rnpOqj-mDCMqCfT2hJ27M3C-VkGJl0,2278
2
+ lamindb/_artifact.py,sha256=9soXXT3g9tG1BTwX4DCRPurbFFcpHKOT8W7SsoLiNbo,44847
3
3
  lamindb/_can_validate.py,sha256=1pUavLwZ_yPAtbVYKOGYUHaPxlJGZ246qZ0e-4ZUDSc,19552
4
- lamindb/_collection.py,sha256=ZQ45_9n0komz1y8l_vzZ-cRn-ghinE0Izl889Mk-TSA,14249
5
- lamindb/_curate.py,sha256=KpEP0-9nQUmiRn6z7fiGs6BmQdpqSg3QPlAgV-S9_wA,58839
4
+ lamindb/_collection.py,sha256=vt604fUjkmOYCGR4Sq_NTwnPywATfjUAdkQjuJJ17y0,14613
5
+ lamindb/_curate.py,sha256=rFbPEoD-E-5s3QPIcUuedUO6a2c8QfpTrBfVX9gUVpE,63120
6
6
  lamindb/_feature.py,sha256=nZhtrH0ssoNls-hV-dkwfK9sKypg2El59R9qfarxfUE,5340
7
7
  lamindb/_feature_set.py,sha256=JQSP-YLam1KW-rDzly5Dm4IYVL2A6ec7ufIf6iCc2W8,8169
8
8
  lamindb/_filter.py,sha256=Pf9NHV4gm7NOC0Frtvx4W7nvwt2EowOP74DwppyXAZs,635
9
9
  lamindb/_finish.py,sha256=VMAmxCUFmTKIMSCx7LEh4QAnWDeue6MeUAAzkMVEYMU,9546
10
- lamindb/_from_values.py,sha256=iqcR8T8i9VZpnn09W441zW-djhWMh8EZj7XFJq9jP2k,14211
10
+ lamindb/_from_values.py,sha256=uRtZLaMWKoANMMXm1hrADHfckRCTiK8_d02Yp07nLkw,14119
11
11
  lamindb/_is_versioned.py,sha256=5lAnhTboltFkZCKVRV1uxkm0OCjJz_HKi3yQq_vEuMs,1306
12
12
  lamindb/_parents.py,sha256=KMBUfCLNqjmFzOdZIXaUFqDPeEpWP28MCkHHPq887h8,16341
13
13
  lamindb/_query_manager.py,sha256=pmPhJQ85-7XeAU9TFv6LPGi9F7dBgztZgZcXz33HYJM,3710
14
- lamindb/_query_set.py,sha256=81y1c-Y-PGCmqc64WizlCiGTbsrApsajtX2xj7xrsMo,12730
15
- lamindb/_record.py,sha256=LkKtDxqlTq43UlAiJ96_nbpjj9eQbU4N3HpfBVfImJo,23395
14
+ lamindb/_query_set.py,sha256=AyWvFZ-Vnd_1dhbDLkiyEh2-2XiIR_OpEk72xoQ2JVg,12980
15
+ lamindb/_record.py,sha256=FkU7G1OUl0HPQO6wh8EkPh4T_ogxcy6QGkrVz_I4WUw,26840
16
16
  lamindb/_run.py,sha256=K_5drpLn3D7y3XtZ3vtAw35rG5RCSvB4bXQZx4ESSI0,1964
17
17
  lamindb/_save.py,sha256=BCaSFnANYPxTqL5gw7Hrh_9kz7SDyOxrJV2KW6rXqts,11366
18
18
  lamindb/_storage.py,sha256=GBVChv-DHVMNEBJL5l_JT6B4RDhZ6NnwgzmUICphYKk,413
@@ -20,21 +20,21 @@ lamindb/_transform.py,sha256=wZDkY8lp4d_OsO5a7rLs1RamkDzBXZSLaWJU34zRnmA,4728
20
20
  lamindb/_ulabel.py,sha256=XDSdZBXX_ki5s1vOths3MjF2x5DPggBR_PV_KF4SGyg,1611
21
21
  lamindb/_utils.py,sha256=LGdiW4k3GClLz65vKAVRkL6Tw-Gkx9DWAdez1jyA5bE,428
22
22
  lamindb/_view.py,sha256=4Ln2ItTb3857PAI-70O8eJYqoTJ_NNFc7E_wds6OGns,2412
23
- lamindb/core/__init__.py,sha256=57AXQ286eOX2_o5HUeqIFJrfqN-OZ_E7FVHd3Xm5oOk,1483
23
+ lamindb/core/__init__.py,sha256=y87MCP1BEC2qHNVDIOwqVteIP_2hPCdIoa9JXr0EG8U,1524
24
24
  lamindb/core/_context.py,sha256=dI3z7fCMRPC3IMb7-EIaQYhacSZBA4HfLVFyoJtVL7I,22900
25
- lamindb/core/_data.py,sha256=P0vlbw_UQp9UDNMmUo9YFxqurcWtMaKPWCT12IRA2C0,19672
25
+ lamindb/core/_data.py,sha256=BVZkxK8aloSecH25LivbwnjcG1fz7Gs2UDceO5pWd3I,20049
26
26
  lamindb/core/_django.py,sha256=yeMPp1n9WrFmEjVRdavfpVqAolPLd24RseTQlvsK67w,7157
27
- lamindb/core/_feature_manager.py,sha256=yH6HGF_c0NwIE6hxcMUZdZrokx75Kz-54d_3JhyCglQ,39020
28
- lamindb/core/_label_manager.py,sha256=bhD6krOrf0SWXfCzhFsEA-7h0ZLJ59YSPxWnlq7DZiE,9991
27
+ lamindb/core/_feature_manager.py,sha256=q4WmzJvFLL_fAs-vNRgV2klanAoU6Wu8_g0O2dyIjVg,40027
28
+ lamindb/core/_label_manager.py,sha256=yh-r4KbtOArMUKPJL75yOxJc8HUKqsik8pExBVKyDlA,10949
29
29
  lamindb/core/_mapped_collection.py,sha256=M50haewVAFONeF71QQbzD09L8lVZCL1hyf0W87jKE5U,24575
30
30
  lamindb/core/_settings.py,sha256=6jNadlQdimxCsKR2ZyUD0YJYzOdubTnKktki-MqEWqQ,6137
31
31
  lamindb/core/_sync_git.py,sha256=lIgl6YfpH4rCFT1WILAp7zlemZfxog1d0zp3cX0KIZw,4531
32
32
  lamindb/core/_track_environment.py,sha256=Ywzg_sJ7guI1dcsN7h5orce9VdYl8VGVE3OLITlHBXQ,820
33
- lamindb/core/exceptions.py,sha256=0B36kOVo-Dik5KbSKvy5GPuMjUfhVb99dJwXl_J0ldo,1636
33
+ lamindb/core/exceptions.py,sha256=Y1XQGbv9MgNLVvoClpcwN4NugrLW3Xgy1up15wZK740,1783
34
34
  lamindb/core/fields.py,sha256=47Jmh3efUr5ZscgimR_yckY-I3cNf8ScLutbwKCK3j4,162
35
35
  lamindb/core/loaders.py,sha256=KMTkDa73jkRVvI9uc5Fgr0t6mq22cAxBwhSlUZKUaBg,4016
36
36
  lamindb/core/schema.py,sha256=Y1tGn93B236PtnYZkpgTNFgTXBcVujPM1qh1kNG6Nbs,3441
37
- lamindb/core/types.py,sha256=uVBqSVLoQaTkqP9nqsJhwU6yYnx8H5e6-ZxrB6vpOOw,265
37
+ lamindb/core/types.py,sha256=cL4cmJFA1xfxAIFOQqoa_fvVzdUM3A5blHStVwRNtk4,280
38
38
  lamindb/core/versioning.py,sha256=KUpd94F5QpbDxx9eKgZwrpPyQpm9YeHVedrTEO2a_mI,4839
39
39
  lamindb/core/datasets/__init__.py,sha256=zRP98oqUAaXhqWyKMiH0s_ImVIuNeziQQ2kQ_t0f-DI,1353
40
40
  lamindb/core/datasets/_core.py,sha256=JGP_q-OQibDCEaI54jZ2F6fSbSW9Yg6oYOqgOCXM0v4,20414
@@ -55,7 +55,7 @@ lamindb/integrations/__init__.py,sha256=RWGMYYIzr8zvmNPyVB4m-p4gMDhxdRbjES2Ed23O
55
55
  lamindb/integrations/_vitessce.py,sha256=uPl45_w4Uu9_BhpBDDVonC1nDOuAnB7DAnzi5w5bZAE,4032
56
56
  lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
57
57
  lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
58
- lamindb-0.76.13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
59
- lamindb-0.76.13.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
60
- lamindb-0.76.13.dist-info/METADATA,sha256=Vo8AcZfSEBwW3NJsFndztG1b2fAVSquWw2OENmncc8M,2361
61
- lamindb-0.76.13.dist-info/RECORD,,
58
+ lamindb-0.76.14.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
59
+ lamindb-0.76.14.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
60
+ lamindb-0.76.14.dist-info/METADATA,sha256=j7r4goc9s3ANslQ7-pT7WIct1uDLJK3DGuN3kPsixYs,2361
61
+ lamindb-0.76.14.dist-info/RECORD,,