lamindb 0.77.3__py3-none-any.whl → 1.0rc1__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 (89) hide show
  1. lamindb/__init__.py +39 -32
  2. lamindb/_artifact.py +95 -64
  3. lamindb/_can_curate.py +13 -6
  4. lamindb/_collection.py +51 -49
  5. lamindb/_feature.py +9 -9
  6. lamindb/_finish.py +92 -79
  7. lamindb/_from_values.py +13 -10
  8. lamindb/_is_versioned.py +2 -1
  9. lamindb/_parents.py +23 -16
  10. lamindb/_query_manager.py +3 -3
  11. lamindb/_query_set.py +85 -18
  12. lamindb/_record.py +114 -41
  13. lamindb/_run.py +3 -3
  14. lamindb/_save.py +5 -6
  15. lamindb/{_feature_set.py → _schema.py} +34 -31
  16. lamindb/_storage.py +2 -1
  17. lamindb/_transform.py +51 -23
  18. lamindb/_ulabel.py +17 -8
  19. lamindb/_view.py +13 -13
  20. lamindb/base/__init__.py +24 -0
  21. lamindb/base/fields.py +281 -0
  22. lamindb/base/ids.py +103 -0
  23. lamindb/base/types.py +51 -0
  24. lamindb/base/users.py +30 -0
  25. lamindb/base/validation.py +67 -0
  26. lamindb/core/__init__.py +18 -15
  27. lamindb/core/_context.py +295 -224
  28. lamindb/core/_data.py +44 -49
  29. lamindb/core/_describe.py +41 -31
  30. lamindb/core/_django.py +29 -27
  31. lamindb/core/_feature_manager.py +130 -129
  32. lamindb/core/_label_manager.py +7 -8
  33. lamindb/core/_mapped_collection.py +17 -14
  34. lamindb/core/_settings.py +1 -12
  35. lamindb/core/_sync_git.py +56 -9
  36. lamindb/core/_track_environment.py +1 -1
  37. lamindb/core/datasets/_core.py +5 -6
  38. lamindb/core/exceptions.py +0 -7
  39. lamindb/core/fields.py +1 -1
  40. lamindb/core/loaders.py +0 -1
  41. lamindb/core/{schema.py → relations.py} +22 -19
  42. lamindb/core/storage/_anndata_accessor.py +1 -2
  43. lamindb/core/storage/_backed_access.py +2 -1
  44. lamindb/core/storage/_tiledbsoma.py +38 -13
  45. lamindb/core/storage/objects.py +1 -1
  46. lamindb/core/storage/paths.py +13 -8
  47. lamindb/core/subsettings/__init__.py +0 -2
  48. lamindb/core/types.py +2 -23
  49. lamindb/core/versioning.py +11 -7
  50. lamindb/{_curate.py → curators/__init__.py} +122 -23
  51. lamindb/curators/_spatial.py +528 -0
  52. lamindb/integrations/_vitessce.py +1 -3
  53. lamindb/migrations/0052_squashed.py +1261 -0
  54. lamindb/migrations/0053_alter_featureset_hash_alter_paramvalue_created_by_and_more.py +57 -0
  55. lamindb/migrations/0054_alter_feature_previous_runs_and_more.py +35 -0
  56. lamindb/migrations/0055_artifact_type_artifactparamvalue_and_more.py +61 -0
  57. lamindb/migrations/0056_rename_ulabel_ref_is_name_artifactulabel_label_ref_is_name_and_more.py +22 -0
  58. lamindb/migrations/0057_link_models_latest_report_and_others.py +356 -0
  59. lamindb/migrations/0058_artifact__actions_collection__actions.py +22 -0
  60. lamindb/migrations/0059_alter_artifact__accessor_alter_artifact__hash_type_and_more.py +31 -0
  61. lamindb/migrations/0060_alter_artifact__actions.py +22 -0
  62. lamindb/migrations/0061_alter_collection_meta_artifact_alter_run_environment_and_more.py +45 -0
  63. lamindb/migrations/0062_add_is_latest_field.py +32 -0
  64. lamindb/migrations/0063_populate_latest_field.py +45 -0
  65. lamindb/migrations/0064_alter_artifact_version_alter_collection_version_and_more.py +33 -0
  66. lamindb/migrations/0065_remove_collection_feature_sets_and_more.py +22 -0
  67. lamindb/migrations/0066_alter_artifact__feature_values_and_more.py +352 -0
  68. lamindb/migrations/0067_alter_featurevalue_unique_together_and_more.py +20 -0
  69. lamindb/migrations/0068_alter_artifactulabel_unique_together_and_more.py +20 -0
  70. lamindb/migrations/0069_alter_artifact__accessor_alter_artifact__hash_type_and_more.py +1294 -0
  71. lamindb/migrations/0069_squashed.py +1770 -0
  72. lamindb/migrations/0070_lamindbv1_migrate_data.py +78 -0
  73. lamindb/migrations/0071_lamindbv1_migrate_schema.py +741 -0
  74. lamindb/migrations/0072_remove_user__branch_code_remove_user_aux_and_more.py +148 -0
  75. lamindb/migrations/0073_merge_ourprojects.py +945 -0
  76. lamindb/migrations/0074_lamindbv1_part4.py +374 -0
  77. lamindb/migrations/0075_lamindbv1_part5.py +276 -0
  78. lamindb/migrations/0076_lamindbv1_part6.py +621 -0
  79. lamindb/migrations/0077_lamindbv1_part6b.py +228 -0
  80. lamindb/migrations/0078_lamindbv1_part6c.py +468 -0
  81. lamindb/migrations/0079_alter_rundata_value_json_and_more.py +36 -0
  82. lamindb/migrations/__init__.py +0 -0
  83. lamindb/models.py +4064 -0
  84. {lamindb-0.77.3.dist-info → lamindb-1.0rc1.dist-info}/METADATA +13 -19
  85. lamindb-1.0rc1.dist-info/RECORD +100 -0
  86. {lamindb-0.77.3.dist-info → lamindb-1.0rc1.dist-info}/WHEEL +1 -1
  87. lamindb/core/subsettings/_transform_settings.py +0 -21
  88. lamindb-0.77.3.dist-info/RECORD +0 -63
  89. {lamindb-0.77.3.dist-info → lamindb-1.0rc1.dist-info}/LICENSE +0 -0
lamindb/base/fields.py ADDED
@@ -0,0 +1,281 @@
1
+ from django.db import models
2
+
3
+
4
+ class CharField(models.CharField):
5
+ """Custom `CharField` with default values for `blank`, `default`, and `max_length`.
6
+
7
+ Django default values for `CharField` are `blank=False`, `default=""`, undefined `max_length`.
8
+ """
9
+
10
+ def __init__(self, max_length: int = 255, **kwargs):
11
+ kwargs["max_length"] = max_length # Set max_length in kwargs
12
+ kwargs.setdefault("blank", True)
13
+ kwargs.setdefault("default", None)
14
+ super().__init__(**kwargs) # Pass all arguments as kwargs
15
+
16
+
17
+ class TextField(models.TextField):
18
+ """Custom `TextField` with default values for `blank` and `default`.
19
+
20
+ Django default values for `TextField` are `blank=False`, `default=''`.
21
+ """
22
+
23
+ def __init__(self, *args, **kwargs):
24
+ kwargs.setdefault("blank", True)
25
+ kwargs.setdefault("default", None)
26
+ super().__init__(*args, **kwargs)
27
+
28
+
29
+ class ForeignKey(models.ForeignKey):
30
+ """Custom `ForeignKey` with default values for `blank`.
31
+
32
+ Django default value for `ForeignKey` `blank=False`.
33
+ """
34
+
35
+ def __init__(self, *args, **kwargs):
36
+ kwargs.setdefault("blank", True)
37
+ super().__init__(*args, **kwargs)
38
+
39
+
40
+ class BooleanField(models.BooleanField):
41
+ """Custom `BooleanField` with default values for `blank` and `default`.
42
+
43
+ Django default values for `BooleanField` are `blank=False`, `default=False`.
44
+ """
45
+
46
+ def __init__(self, *args, **kwargs):
47
+ kwargs.setdefault("blank", True)
48
+ kwargs.setdefault("default", None)
49
+ super().__init__(*args, **kwargs)
50
+
51
+
52
+ class DateField(models.DateField):
53
+ """Custom `DateField` with default values for `blank`.
54
+
55
+ Django default values for `DateField` are `blank=False`.
56
+ """
57
+
58
+ def __init__(self, *args, **kwargs):
59
+ kwargs.setdefault("blank", True)
60
+ super().__init__(*args, **kwargs)
61
+
62
+
63
+ class DateTimeField(models.DateTimeField):
64
+ """Custom `DateTimeField` with default values for `blank`.
65
+
66
+ Django default values for `DateTimeField` are `blank=False`.
67
+ """
68
+
69
+ def __init__(self, *args, **kwargs):
70
+ kwargs.setdefault("blank", True)
71
+ super().__init__(*args, **kwargs)
72
+
73
+
74
+ class BigIntegerField(models.BigIntegerField):
75
+ """Custom `BigIntegerField` with default values for `blank`.
76
+
77
+ Django default values for `BigIntegerField` are `blank=False`.
78
+ """
79
+
80
+ def __init__(self, *args, **kwargs):
81
+ kwargs.setdefault("blank", True)
82
+ kwargs.setdefault("default", None)
83
+ super().__init__(*args, **kwargs)
84
+
85
+
86
+ class IntegerField(models.IntegerField):
87
+ """Custom `IntegerField` with default values for `blank`.
88
+
89
+ Django default values for `IntegerField` are `blank=False`.
90
+ """
91
+
92
+ def __init__(self, *args, **kwargs):
93
+ kwargs.setdefault("blank", True)
94
+ super().__init__(*args, **kwargs)
95
+
96
+
97
+ class OneToOneField(models.OneToOneField):
98
+ """Custom `OneToOneField` with default values for `blank`.
99
+
100
+ Django default values for `OneToOneField` are `blank=False`.
101
+ """
102
+
103
+ def __init__(self, *args, **kwargs):
104
+ kwargs.setdefault("blank", True)
105
+ super().__init__(*args, **kwargs)
106
+
107
+
108
+ class FloatField(models.FloatField):
109
+ """Custom `FloatField` with default values for `blank`.
110
+
111
+ Django default values for `FloatField` are `blank=False`.
112
+ """
113
+
114
+ def __init__(self, *args, **kwargs):
115
+ kwargs.setdefault("blank", True)
116
+ super().__init__(*args, **kwargs)
117
+
118
+
119
+ class DecimalField(models.DecimalField):
120
+ """Custom `DecimalField` with default values for `blank`.
121
+
122
+ Django default values for `DecimalField` are `blank=False`.
123
+ """
124
+
125
+ def __init__(self, *args, **kwargs):
126
+ kwargs.setdefault("blank", True)
127
+ super().__init__(*args, **kwargs)
128
+
129
+
130
+ class JSONField(models.JSONField):
131
+ """Custom `JSONField` with default values for `blank`.
132
+
133
+ Django default values for `JSONField` are `blank=False`.
134
+ """
135
+
136
+ def __init__(self, *args, **kwargs):
137
+ kwargs.setdefault("blank", True)
138
+ super().__init__(*args, **kwargs)
139
+
140
+
141
+ class DurationField(models.DurationField):
142
+ """Custom `DurationField` with default values for `blank`.
143
+
144
+ Django default values for `DurationField` are `blank=False`.
145
+ """
146
+
147
+ def __init__(self, *args, **kwargs):
148
+ kwargs.setdefault("blank", True)
149
+ super().__init__(*args, **kwargs)
150
+
151
+
152
+ class URLField(models.URLField):
153
+ """Custom `URLField` with default values for `blank`.
154
+
155
+ Django default values for `URLField` are `blank=False`.
156
+ """
157
+
158
+ def __init__(self, *args, **kwargs):
159
+ kwargs.setdefault("blank", True)
160
+ super().__init__(*args, **kwargs)
161
+
162
+
163
+ class EmailField(models.EmailField):
164
+ """Custom `EmailField` with default values for `blank`.
165
+
166
+ Django default values for `EmailField` are `blank=False`.
167
+ """
168
+
169
+ def __init__(self, *args, **kwargs):
170
+ kwargs.setdefault("blank", True)
171
+ super().__init__(*args, **kwargs)
172
+
173
+
174
+ class TimeField(models.TimeField):
175
+ """Custom `TimeField` with default values for `blank`.
176
+
177
+ Django default values for `TimeField` are `blank=False`.
178
+ """
179
+
180
+ def __init__(self, *args, **kwargs):
181
+ kwargs.setdefault("blank", True)
182
+ super().__init__(*args, **kwargs)
183
+
184
+
185
+ class SlugField(models.SlugField):
186
+ """Custom `SlugField` with default values for `blank`.
187
+
188
+ Django default values for `SlugField` are `blank=False`.
189
+ """
190
+
191
+ def __init__(self, *args, **kwargs):
192
+ kwargs.setdefault("blank", True)
193
+ super().__init__(*args, **kwargs)
194
+
195
+
196
+ class UUIDField(models.UUIDField):
197
+ """Custom `UUIDField` with default values for `blank`.
198
+
199
+ Django default values for `UUIDField` are `blank=False`.
200
+ """
201
+
202
+ def __init__(self, *args, **kwargs):
203
+ kwargs.setdefault("blank", True)
204
+ super().__init__(*args, **kwargs)
205
+
206
+
207
+ class PositiveIntegerField(models.PositiveIntegerField):
208
+ """Custom `PositiveIntegerField` with default values for `blank`.
209
+
210
+ Django default values for `PositiveIntegerField` are `blank=False`.
211
+ """
212
+
213
+ def __init__(self, *args, **kwargs):
214
+ kwargs.setdefault("blank", True)
215
+ super().__init__(*args, **kwargs)
216
+
217
+
218
+ class PositiveSmallIntegerField(models.PositiveSmallIntegerField):
219
+ """Custom `PositiveSmallIntegerField` with default values for `blank`.
220
+
221
+ Django default values for `PositiveSmallIntegerField` are `blank=False`.
222
+ """
223
+
224
+ def __init__(self, *args, **kwargs):
225
+ kwargs.setdefault("blank", True)
226
+ super().__init__(*args, **kwargs)
227
+
228
+
229
+ class SmallIntegerField(models.SmallIntegerField):
230
+ """Custom `SmallIntegerField` with default values for `blank`.
231
+
232
+ Django default values for `SmallIntegerField` are `blank=False`.
233
+ """
234
+
235
+ def __init__(self, *args, **kwargs):
236
+ kwargs.setdefault("blank", True)
237
+ super().__init__(*args, **kwargs)
238
+
239
+
240
+ class BinaryField(models.BinaryField):
241
+ """Custom `BinaryField` with default values for `blank`.
242
+
243
+ Django default values for `BinaryField` are `blank=False`.
244
+ """
245
+
246
+ def __init__(self, *args, **kwargs):
247
+ kwargs.setdefault("blank", True)
248
+ super().__init__(*args, **kwargs)
249
+
250
+
251
+ class GenericIPAddressField(models.GenericIPAddressField):
252
+ """Custom `GenericIPAddressField` with default values for `blank`.
253
+
254
+ Django default values for `GenericIPAddressField` are `blank=False`.
255
+ """
256
+
257
+ def __init__(self, *args, **kwargs):
258
+ kwargs.setdefault("blank", True)
259
+ super().__init__(*args, **kwargs)
260
+
261
+
262
+ class FileField(models.FileField):
263
+ """Custom `FileField` with default values for `blank`.
264
+
265
+ Django default values for `FileField` are `blank=False`.
266
+ """
267
+
268
+ def __init__(self, *args, **kwargs):
269
+ kwargs.setdefault("blank", True)
270
+ super().__init__(*args, **kwargs)
271
+
272
+
273
+ class ImageField(models.ImageField):
274
+ """Custom `ImageField` with default values for `blank`.
275
+
276
+ Django default values for `ImageField` are `blank=False`.
277
+ """
278
+
279
+ def __init__(self, *args, **kwargs):
280
+ kwargs.setdefault("blank", True)
281
+ super().__init__(*args, **kwargs)
lamindb/base/ids.py ADDED
@@ -0,0 +1,103 @@
1
+ """IDs.
2
+
3
+ Base generators:
4
+
5
+ .. autosummary::
6
+ :toctree: .
7
+
8
+ base26
9
+ base62
10
+ base64
11
+
12
+ 8 base62 characters:
13
+
14
+ ======= ===========
15
+ n p_collision
16
+ ======= ===========
17
+ 100k 2e-05
18
+ 1M 2e-03
19
+ ======= ===========
20
+
21
+ 12 base62 characters:
22
+
23
+ ======= ===========
24
+ n p_collision
25
+ ======= ===========
26
+ 100M 2e-06
27
+ 1B 2e-04
28
+ ======= ===========
29
+
30
+ 20 base62 characters (62**20=7e+35) roughly matches UUID (2*122=5e+36):
31
+
32
+ ======= ===========
33
+ n p_collision
34
+ ======= ===========
35
+ 3e15 1e-6
36
+ ======= ===========
37
+
38
+ """
39
+
40
+ import secrets
41
+ import string
42
+
43
+
44
+ def base64(n_char: int) -> str:
45
+ """Random Base64 string."""
46
+ alphabet = string.digits + string.ascii_letters.swapcase() + "_" + "-"
47
+ id = "".join(secrets.choice(alphabet) for i in range(n_char))
48
+ return id
49
+
50
+
51
+ def base62(n_char: int) -> str:
52
+ """Random Base62 string."""
53
+ alphabet = string.digits + string.ascii_letters.swapcase()
54
+ id = "".join(secrets.choice(alphabet) for i in range(n_char))
55
+ return id
56
+
57
+
58
+ # the following cannot be serialized by Django
59
+ # class Base62:
60
+ # def __init__(self, n_char: int):
61
+ # self.n_char = n_char
62
+
63
+ # def __call__(self):
64
+ # return base62(self.n_char)
65
+
66
+
67
+ def base26(n_char: int):
68
+ """ASCII lowercase."""
69
+ alphabet = string.ascii_lowercase
70
+ id = "".join(secrets.choice(alphabet) for i in range(n_char))
71
+ return id
72
+
73
+
74
+ def base62_4() -> str:
75
+ return base62(4)
76
+
77
+
78
+ def base62_8() -> str:
79
+ return base62(8)
80
+
81
+
82
+ def base62_12() -> str:
83
+ return base62(12)
84
+
85
+
86
+ def base62_14() -> str:
87
+ return base62(14)
88
+
89
+
90
+ def base62_16() -> str:
91
+ return base62(16)
92
+
93
+
94
+ def base62_18() -> str:
95
+ return base62(18)
96
+
97
+
98
+ def base62_20() -> str:
99
+ return base62(20)
100
+
101
+
102
+ def base62_24() -> str:
103
+ return base62(24)
lamindb/base/types.py ADDED
@@ -0,0 +1,51 @@
1
+ """Types.
2
+
3
+ Central object types.
4
+
5
+ .. autosummary::
6
+ :toctree: .
7
+
8
+ ArtifactKind
9
+ TransformType
10
+ FeatureDtype
11
+
12
+ Basic types.
13
+
14
+ .. autosummary::
15
+ :toctree: .
16
+
17
+ UPathStr
18
+ StrField
19
+ ListLike
20
+ FieldAttr
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from typing import Literal, Union
26
+
27
+ import numpy as np
28
+ import pandas as pd
29
+ from django.db.models.query_utils import DeferredAttribute as FieldAttr
30
+ from lamindb_setup.core.types import UPathStr # noqa: F401
31
+
32
+ # need to use Union because __future__.annotations doesn't do the job here <3.10
33
+ # typing.TypeAlias, >3.10 on but already deprecated
34
+ ListLike = Union[list[str], pd.Series, np.array]
35
+ StrField = Union[str, FieldAttr] # typing.TypeAlias
36
+
37
+ TransformType = Literal[
38
+ "pipeline", "notebook", "upload", "script", "function", "linker"
39
+ ]
40
+ ArtifactKind = Literal["dataset", "model"]
41
+ FeatureDtype = Literal[
42
+ "cat", # categorical variables
43
+ "num", # numerical variables
44
+ "str", # string variables
45
+ "int", # integer variables
46
+ "float", # float variables
47
+ "bool", # boolean variables
48
+ "date", # date variables
49
+ "datetime", # datetime variables
50
+ "object", # this is a pandas type, we're only using it for complicated types, not for strings
51
+ ]
lamindb/base/users.py ADDED
@@ -0,0 +1,30 @@
1
+ user_id_cache = {}
2
+
3
+
4
+ def current_user_id() -> int:
5
+ import lamindb_setup as ln_setup
6
+ from lamindb_setup import settings
7
+ from lamindb_setup._init_instance import register_user
8
+
9
+ from lamindb.models import User
10
+
11
+ def query_user_id():
12
+ if ln_setup.core.django.IS_MIGRATING:
13
+ return 1
14
+ else:
15
+ exc_attr = (
16
+ "DoesNotExist" if hasattr(User, "DoesNotExist") else "_DoesNotExist"
17
+ )
18
+ try:
19
+ user_id = User.objects.get(uid=settings.user.uid).id
20
+ except getattr(User, exc_attr):
21
+ register_user(settings.user)
22
+ user_id = User.objects.get(uid=settings.user.uid).id
23
+ return user_id
24
+
25
+ if settings._instance_exists:
26
+ if settings.instance.slug not in user_id_cache:
27
+ user_id_cache[settings.instance.slug] = query_user_id()
28
+ return user_id_cache[settings.instance.slug]
29
+ else:
30
+ return query_user_id()
@@ -0,0 +1,67 @@
1
+ from typing import TYPE_CHECKING, Literal, Union, get_args, get_origin, get_type_hints
2
+
3
+ from lamin_utils import colors
4
+
5
+ if TYPE_CHECKING:
6
+ from .models import Record
7
+
8
+
9
+ class FieldValidationError(SystemExit):
10
+ """Field validation error."""
11
+
12
+ pass
13
+
14
+
15
+ def validate_literal_fields(record: "Record", kwargs) -> None:
16
+ """Validate all Literal type fields in a record.
17
+
18
+ Args:
19
+ record: record being validated
20
+
21
+ Raises:
22
+ ValidationError: If any field value is not in its Literal's allowed values
23
+ """
24
+ # check is based on string to avoid circular imports
25
+ if record.__class__.__name__ == "Feature":
26
+ # the FeatureDtype is more complicated than a simple literal
27
+ # because it allows constructs like cat[ULabel] etc.
28
+ # the User model is used at startup and throws a datetime-related error otherwise
29
+ # simmilar for Storage & Source
30
+ return None
31
+ try:
32
+ type_hints = get_type_hints(record.__class__)
33
+ except TypeError:
34
+ # for 3.9, get_type_hints errors with | in type hints
35
+ return
36
+ errors = {}
37
+
38
+ for field_name, field_type in type_hints.items():
39
+ # Handle both plain Literal and Union/Optional Literal types
40
+ origin = get_origin(field_type)
41
+ if origin is Union:
42
+ # For Optional/Union types, find the Literal type if it exists
43
+ literal_type = next(
44
+ (t for t in get_args(field_type) if get_origin(t) is Literal), None
45
+ )
46
+ else:
47
+ # For plain types, check if it's a Literal
48
+ literal_type = field_type if origin is Literal else None
49
+
50
+ # Skip if no Literal type found
51
+ if literal_type is None:
52
+ continue
53
+
54
+ value = kwargs.get(field_name)
55
+ if value is not None:
56
+ valid_values = set(get_args(literal_type))
57
+ if value not in valid_values:
58
+ errors[field_name] = (
59
+ f"{field_name}: {colors.yellow(value)} is not a valid value"
60
+ f"\n → Valid values are: {colors.green(', '.join(sorted(valid_values)))}"
61
+ )
62
+
63
+ if errors:
64
+ message = "\n "
65
+ for _, error in errors.items():
66
+ message += error + "\n "
67
+ raise FieldValidationError(message)
lamindb/core/__init__.py CHANGED
@@ -5,10 +5,12 @@ Registries:
5
5
  .. autosummary::
6
6
  :toctree: .
7
7
 
8
+ BasicRecord
8
9
  Record
9
10
  Registry
10
11
  QuerySet
11
12
  QueryManager
13
+ Schema
12
14
  RecordList
13
15
  FeatureManager
14
16
  ParamManager
@@ -59,7 +61,6 @@ Modules:
59
61
  loaders
60
62
  datasets
61
63
  storage
62
- types
63
64
  exceptions
64
65
  subsettings
65
66
  logger
@@ -68,7 +69,21 @@ Modules:
68
69
 
69
70
  from lamin_utils import logger
70
71
  from lamin_utils._inspect import InspectResult
71
- from lnschema_core.models import (
72
+
73
+ from lamindb._query_manager import QueryManager
74
+ from lamindb._query_set import QuerySet, RecordList
75
+ from lamindb.core._feature_manager import FeatureManager, ParamManager
76
+ from lamindb.core._label_manager import LabelManager
77
+ from lamindb.curators import (
78
+ AnnDataCurator,
79
+ BaseCurator,
80
+ CurateLookup,
81
+ DataFrameCurator,
82
+ MuDataCurator,
83
+ SOMACurator,
84
+ )
85
+ from lamindb.models import (
86
+ BasicRecord,
72
87
  CanCurate,
73
88
  FeatureValue,
74
89
  HasParents,
@@ -76,24 +91,12 @@ from lnschema_core.models import (
76
91
  ParamValue,
77
92
  Record,
78
93
  Registry,
94
+ Schema,
79
95
  TracksRun,
80
96
  TracksUpdates,
81
97
  ValidateFields,
82
98
  )
83
99
 
84
- from lamindb._curate import (
85
- AnnDataCurator,
86
- BaseCurator,
87
- CurateLookup,
88
- DataFrameCurator,
89
- MuDataCurator,
90
- SOMACurator,
91
- )
92
- from lamindb._query_manager import QueryManager
93
- from lamindb._query_set import QuerySet, RecordList
94
- from lamindb.core._feature_manager import FeatureManager, ParamManager
95
- from lamindb.core._label_manager import LabelManager
96
-
97
100
  from . import _data, datasets, exceptions, fields, loaders, subsettings, types
98
101
  from ._context import Context
99
102
  from ._mapped_collection import MappedCollection