lamindb 1.1.0__py3-none-any.whl → 1.2a2__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.
Files changed (72) hide show
  1. lamindb/__init__.py +31 -26
  2. lamindb/_finish.py +9 -1
  3. lamindb/_tracked.py +26 -3
  4. lamindb/_view.py +2 -3
  5. lamindb/base/__init__.py +1 -1
  6. lamindb/base/ids.py +1 -10
  7. lamindb/base/users.py +1 -4
  8. lamindb/core/__init__.py +7 -65
  9. lamindb/core/_context.py +41 -10
  10. lamindb/core/_mapped_collection.py +4 -2
  11. lamindb/core/_settings.py +6 -6
  12. lamindb/core/_sync_git.py +1 -1
  13. lamindb/core/_track_environment.py +2 -1
  14. lamindb/core/datasets/_small.py +3 -3
  15. lamindb/core/loaders.py +22 -9
  16. lamindb/core/storage/_anndata_accessor.py +8 -3
  17. lamindb/core/storage/_backed_access.py +14 -7
  18. lamindb/core/storage/_pyarrow_dataset.py +24 -9
  19. lamindb/core/storage/_tiledbsoma.py +6 -4
  20. lamindb/core/storage/_zarr.py +32 -11
  21. lamindb/core/storage/objects.py +59 -26
  22. lamindb/core/storage/paths.py +16 -13
  23. lamindb/curators/__init__.py +173 -145
  24. lamindb/errors.py +1 -1
  25. lamindb/integrations/_vitessce.py +4 -4
  26. lamindb/migrations/0089_subsequent_runs.py +159 -0
  27. lamindb/migrations/0090_runproject_project_runs.py +73 -0
  28. lamindb/migrations/{0088_squashed.py → 0090_squashed.py} +245 -177
  29. lamindb/models/__init__.py +79 -0
  30. lamindb/{core → models}/_describe.py +3 -3
  31. lamindb/{core → models}/_django.py +8 -5
  32. lamindb/{core → models}/_feature_manager.py +103 -87
  33. lamindb/{_from_values.py → models/_from_values.py} +5 -2
  34. lamindb/{core/versioning.py → models/_is_versioned.py} +94 -6
  35. lamindb/{core → models}/_label_manager.py +10 -17
  36. lamindb/{core/relations.py → models/_relations.py} +8 -1
  37. lamindb/models/artifact.py +2601 -0
  38. lamindb/{_can_curate.py → models/can_curate.py} +349 -180
  39. lamindb/models/collection.py +683 -0
  40. lamindb/models/core.py +135 -0
  41. lamindb/models/feature.py +643 -0
  42. lamindb/models/flextable.py +163 -0
  43. lamindb/{_parents.py → models/has_parents.py} +55 -49
  44. lamindb/models/project.py +384 -0
  45. lamindb/{_query_manager.py → models/query_manager.py} +10 -8
  46. lamindb/{_query_set.py → models/query_set.py} +52 -30
  47. lamindb/models/record.py +1757 -0
  48. lamindb/models/run.py +563 -0
  49. lamindb/{_save.py → models/save.py} +18 -8
  50. lamindb/models/schema.py +732 -0
  51. lamindb/models/transform.py +360 -0
  52. lamindb/models/ulabel.py +249 -0
  53. {lamindb-1.1.0.dist-info → lamindb-1.2a2.dist-info}/METADATA +5 -5
  54. lamindb-1.2a2.dist-info/RECORD +94 -0
  55. lamindb/_artifact.py +0 -1361
  56. lamindb/_collection.py +0 -440
  57. lamindb/_feature.py +0 -316
  58. lamindb/_is_versioned.py +0 -40
  59. lamindb/_record.py +0 -1065
  60. lamindb/_run.py +0 -60
  61. lamindb/_schema.py +0 -347
  62. lamindb/_storage.py +0 -15
  63. lamindb/_transform.py +0 -170
  64. lamindb/_ulabel.py +0 -56
  65. lamindb/_utils.py +0 -9
  66. lamindb/base/validation.py +0 -63
  67. lamindb/core/_data.py +0 -491
  68. lamindb/core/fields.py +0 -12
  69. lamindb/models.py +0 -4435
  70. lamindb-1.1.0.dist-info/RECORD +0 -95
  71. {lamindb-1.1.0.dist-info → lamindb-1.2a2.dist-info}/LICENSE +0 -0
  72. {lamindb-1.1.0.dist-info → lamindb-1.2a2.dist-info}/WHEEL +0 -0
@@ -8,8 +8,6 @@ from lamindb_setup.core._docs import doc_args
8
8
 
9
9
  from lamindb.models import Record
10
10
 
11
- from .core._settings import settings
12
-
13
11
  if TYPE_CHECKING:
14
12
  from lamindb.base.types import StrField
15
13
 
@@ -19,7 +17,7 @@ class QueryManager(models.Manager):
19
17
 
20
18
  See Also:
21
19
 
22
- :class:`lamindb.core.QuerySet`
20
+ :class:`lamindb.models.QuerySet`
23
21
  `django Manager <https://docs.djangoproject.com/en/4.2/topics/db/managers/>`__
24
22
 
25
23
  Examples:
@@ -39,8 +37,12 @@ class QueryManager(models.Manager):
39
37
  self.source_field_name == "collection"
40
38
  and self.target_field_name == "artifact"
41
39
  ):
40
+ from lamindb import settings
42
41
  from lamindb.core._context import context
43
- from lamindb.core._data import WARNING_RUN_TRANSFORM, _track_run_input
42
+ from lamindb.models.artifact import (
43
+ WARNING_RUN_TRANSFORM,
44
+ _track_run_input,
45
+ )
44
46
 
45
47
  if (
46
48
  context.run is None
@@ -71,14 +73,14 @@ class QueryManager(models.Manager):
71
73
  def df(self, **kwargs):
72
74
  """Convert to DataFrame.
73
75
 
74
- For `**kwargs`, see :meth:`lamindb.core.QuerySet.df`.
76
+ For `**kwargs`, see :meth:`lamindb.models.QuerySet.df`.
75
77
  """
76
78
  return self.all().df(**kwargs)
77
79
 
78
80
  def all(self):
79
81
  """Return QuerySet of all.
80
82
 
81
- For `**kwargs`, see :meth:`lamindb.core.QuerySet.df`.
83
+ For `**kwargs`, see :meth:`lamindb.models.QuerySet.df`.
82
84
  """
83
85
  self._track_run_input_manager()
84
86
  return self._all_base_class()
@@ -86,14 +88,14 @@ class QueryManager(models.Manager):
86
88
  @doc_args(Record.search.__doc__)
87
89
  def search(self, string: str, **kwargs):
88
90
  """{}""" # noqa: D415
89
- from ._record import _search
91
+ from .record import _search
90
92
 
91
93
  return _search(cls=self.all(), string=string, **kwargs)
92
94
 
93
95
  @doc_args(Record.lookup.__doc__)
94
96
  def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
95
97
  """{}""" # noqa: D415
96
- from ._record import _lookup
98
+ from .record import _lookup
97
99
 
98
100
  return _lookup(cls=self.all(), field=field, **kwargs)
99
101
 
@@ -5,7 +5,7 @@ import warnings
5
5
  from collections import UserList
6
6
  from collections.abc import Iterable
7
7
  from collections.abc import Iterable as IterableType
8
- from typing import TYPE_CHECKING, Any, Generic, NamedTuple, TypeVar
8
+ from typing import TYPE_CHECKING, Any, Generic, NamedTuple, TypeVar, Union
9
9
 
10
10
  import pandas as pd
11
11
  from django.core.exceptions import FieldError
@@ -15,27 +15,17 @@ from django.db.models.fields.related import ForeignObjectRel
15
15
  from lamin_utils import logger
16
16
  from lamindb_setup.core._docs import doc_args
17
17
 
18
- from lamindb.models import (
19
- Artifact,
20
- CanCurate,
21
- Collection,
22
- Feature,
23
- IsVersioned,
24
- Record,
25
- Run,
26
- Schema,
27
- Transform,
28
- )
18
+ from lamindb.models._is_versioned import IsVersioned
19
+ from lamindb.models.record import Record
29
20
 
30
- from .errors import DoesNotExist
31
-
32
- T = TypeVar("T")
21
+ from ..errors import DoesNotExist
22
+ from .can_curate import CanCurate
33
23
 
34
24
  if TYPE_CHECKING:
35
- from collections.abc import Iterable
36
-
37
25
  from lamindb.base.types import ListLike, StrField
38
26
 
27
+ T = TypeVar("T")
28
+
39
29
 
40
30
  class MultipleResultsFound(Exception):
41
31
  pass
@@ -82,6 +72,13 @@ def one_helper(self):
82
72
 
83
73
 
84
74
  def get_backward_compat_filter_kwargs(queryset, expressions):
75
+ from lamindb.models import (
76
+ Artifact,
77
+ Collection,
78
+ Schema,
79
+ Transform,
80
+ )
81
+
85
82
  if queryset.model in {Collection, Transform}:
86
83
  name_mappings = {
87
84
  "name": "key",
@@ -190,7 +187,7 @@ def process_expressions(queryset: QuerySet, expressions: dict) -> dict:
190
187
 
191
188
 
192
189
  def get(
193
- registry_or_queryset: type[Record] | QuerySet,
190
+ registry_or_queryset: Union[type[Record], QuerySet],
194
191
  idlike: int | str | None = None,
195
192
  **expressions,
196
193
  ) -> Record:
@@ -214,10 +211,27 @@ def get(
214
211
  else:
215
212
  assert idlike is None # noqa: S101
216
213
  expressions = process_expressions(qs, expressions)
214
+ # don't want _branch_code here in .get(), only in .filter()
215
+ expressions.pop("_branch_code", None)
217
216
  # inject is_latest for consistency with idlike
218
- if issubclass(registry, IsVersioned) and "is_latest" not in expressions:
217
+ is_latest_was_not_in_expressions = "is_latest" not in expressions
218
+ if issubclass(registry, IsVersioned) and is_latest_was_not_in_expressions:
219
219
  expressions["is_latest"] = True
220
- return registry.objects.using(qs.db).get(**expressions)
220
+ try:
221
+ return registry.objects.using(qs.db).get(**expressions)
222
+ except registry.DoesNotExist:
223
+ # handle the case in which the is_latest injection led to a missed query
224
+ if "is_latest" in expressions and is_latest_was_not_in_expressions:
225
+ expressions.pop("is_latest")
226
+ result = (
227
+ registry.objects.using(qs.db)
228
+ .filter(**expressions)
229
+ .order_by("-created_at")
230
+ .first()
231
+ )
232
+ if result is not None:
233
+ return result
234
+ raise registry.DoesNotExist from registry.DoesNotExist
221
235
 
222
236
 
223
237
  class RecordList(UserList, Generic[T]):
@@ -240,7 +254,7 @@ class RecordList(UserList, Generic[T]):
240
254
 
241
255
  def save(self) -> RecordList[T]:
242
256
  """Save all records to the database."""
243
- from lamindb._save import save
257
+ from lamindb.models.save import save
244
258
 
245
259
  save(self)
246
260
  return self
@@ -288,6 +302,11 @@ def get_basic_field_names(
288
302
 
289
303
 
290
304
  def get_feature_annotate_kwargs(show_features: bool | list[str]) -> dict[str, Any]:
305
+ from lamindb.models import (
306
+ Artifact,
307
+ Feature,
308
+ )
309
+
291
310
  features = Feature.filter()
292
311
  if isinstance(show_features, list):
293
312
  features.filter(name__in=show_features)
@@ -566,6 +585,8 @@ class QuerySet(models.QuerySet):
566
585
 
567
586
  def delete(self, *args, **kwargs):
568
587
  """Delete all records in the query set."""
588
+ from lamindb.models import Artifact, Collection, Run, Transform
589
+
569
590
  # both Transform & Run might reference artifacts
570
591
  if self.model in {Artifact, Collection, Transform, Run}:
571
592
  for record in self:
@@ -641,11 +662,12 @@ class QuerySet(models.QuerySet):
641
662
  and value.strip("-").isalpha()
642
663
  and "__" not in field
643
664
  and hasattr(self.model, field)
644
- and getattr(self.model, field).field.related_model
645
665
  ):
646
- raise FieldError(
647
- f"Invalid lookup '{value}' for {field}. Did you mean {field}__name?"
648
- )
666
+ field_attr = getattr(self.model, field)
667
+ if hasattr(field_attr, "field") and field_attr.field.related_model:
668
+ raise FieldError(
669
+ f"Invalid lookup '{value}' for {field}. Did you mean {field}__name?"
670
+ )
649
671
 
650
672
  expressions = process_expressions(self, expressions)
651
673
  if len(expressions) > 0:
@@ -689,7 +711,7 @@ class QuerySet(models.QuerySet):
689
711
  @doc_args(Record.search.__doc__)
690
712
  def search(self, string: str, **kwargs):
691
713
  """{}""" # noqa: D415
692
- from ._record import _search
714
+ from .record import _search
693
715
 
694
716
  return _search(cls=self, string=string, **kwargs)
695
717
 
@@ -697,7 +719,7 @@ def search(self, string: str, **kwargs):
697
719
  @doc_args(Record.lookup.__doc__)
698
720
  def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
699
721
  """{}""" # noqa: D415
700
- from ._record import _lookup
722
+ from .record import _lookup
701
723
 
702
724
  return _lookup(cls=self, field=field, **kwargs)
703
725
 
@@ -705,7 +727,7 @@ def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
705
727
  @doc_args(CanCurate.validate.__doc__)
706
728
  def validate(self, values: ListLike, field: str | StrField | None = None, **kwargs):
707
729
  """{}""" # noqa: D415
708
- from ._can_curate import _validate
730
+ from .can_curate import _validate
709
731
 
710
732
  return _validate(cls=self, values=values, field=field, **kwargs)
711
733
 
@@ -713,7 +735,7 @@ def validate(self, values: ListLike, field: str | StrField | None = None, **kwar
713
735
  @doc_args(CanCurate.inspect.__doc__)
714
736
  def inspect(self, values: ListLike, field: str | StrField | None = None, **kwargs):
715
737
  """{}""" # noqa: D415
716
- from ._can_curate import _inspect
738
+ from .can_curate import _inspect
717
739
 
718
740
  return _inspect(cls=self, values=values, field=field, **kwargs)
719
741
 
@@ -721,7 +743,7 @@ def inspect(self, values: ListLike, field: str | StrField | None = None, **kwarg
721
743
  @doc_args(CanCurate.standardize.__doc__)
722
744
  def standardize(self, values: Iterable, field: str | StrField | None = None, **kwargs):
723
745
  """{}""" # noqa: D415
724
- from ._can_curate import _standardize
746
+ from .can_curate import _standardize
725
747
 
726
748
  return _standardize(cls=self, values=values, field=field, **kwargs)
727
749