lamindb 1.2a2__py3-none-any.whl → 1.3.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.
- lamindb/__init__.py +3 -1
- lamindb/core/_compat.py +60 -0
- lamindb/core/_context.py +15 -12
- lamindb/core/datasets/__init__.py +1 -0
- lamindb/core/datasets/_core.py +23 -0
- lamindb/core/datasets/_small.py +16 -2
- lamindb/core/loaders.py +22 -12
- lamindb/core/storage/_tiledbsoma.py +2 -2
- lamindb/core/storage/_zarr.py +84 -26
- lamindb/core/storage/objects.py +45 -44
- lamindb/core/types.py +10 -0
- lamindb/curators/__init__.py +1272 -1517
- lamindb/curators/_cellxgene_schemas/__init__.py +190 -18
- lamindb/curators/_cellxgene_schemas/schema_versions.csv +43 -0
- lamindb/models/_feature_manager.py +65 -14
- lamindb/models/_from_values.py +113 -78
- lamindb/models/artifact.py +142 -98
- lamindb/models/can_curate.py +185 -216
- lamindb/models/feature.py +32 -2
- lamindb/models/project.py +69 -7
- lamindb/models/query_set.py +12 -2
- lamindb/models/record.py +48 -25
- lamindb/models/run.py +18 -1
- lamindb/models/schema.py +0 -8
- {lamindb-1.2a2.dist-info → lamindb-1.3.0.dist-info}/METADATA +7 -6
- {lamindb-1.2a2.dist-info → lamindb-1.3.0.dist-info}/RECORD +28 -27
- lamindb/curators/_cellxgene_schemas/schema_versions.yml +0 -104
- {lamindb-1.2a2.dist-info → lamindb-1.3.0.dist-info}/LICENSE +0 -0
- {lamindb-1.2a2.dist-info → lamindb-1.3.0.dist-info}/WHEEL +0 -0
lamindb/models/feature.py
CHANGED
@@ -47,7 +47,8 @@ def parse_dtype_single_cat(
|
|
47
47
|
dtype_str: str,
|
48
48
|
related_registries: dict[str, Record] | None = None,
|
49
49
|
is_itype: bool = False,
|
50
|
-
) -> dict:
|
50
|
+
) -> dict[str, Any]:
|
51
|
+
"""Parses a categorical data type string into its components (registry, field, subtypes)."""
|
51
52
|
from .artifact import Artifact
|
52
53
|
|
53
54
|
assert isinstance(dtype_str, str) # noqa: S101
|
@@ -116,6 +117,7 @@ def parse_dtype_single_cat(
|
|
116
117
|
|
117
118
|
|
118
119
|
def parse_dtype(dtype_str: str, is_param: bool = False) -> list[dict[str, str]]:
|
120
|
+
"""Parses feature data type string into a structured list of components."""
|
119
121
|
from .artifact import Artifact
|
120
122
|
|
121
123
|
allowed_dtypes = FEATURE_DTYPES
|
@@ -140,7 +142,10 @@ def parse_dtype(dtype_str: str, is_param: bool = False) -> list[dict[str, str]]:
|
|
140
142
|
return result
|
141
143
|
|
142
144
|
|
143
|
-
def get_dtype_str_from_dtype(
|
145
|
+
def get_dtype_str_from_dtype(
|
146
|
+
dtype: Record | FieldAttr | list[Record], is_itype: bool = False
|
147
|
+
) -> str:
|
148
|
+
"""Converts a data type object into its string representation."""
|
144
149
|
if (
|
145
150
|
not isinstance(dtype, list)
|
146
151
|
and hasattr(dtype, "__name__")
|
@@ -255,6 +260,8 @@ class Feature(Record, CanCurate, TracksRun, TracksUpdates):
|
|
255
260
|
synonyms: `str | None = None` Bar-separated synonyms.
|
256
261
|
nullable: `bool = True` Whether the feature can have null-like values (`None`, `pd.NA`, `NaN`, etc.), see :attr:`~lamindb.Feature.nullable`.
|
257
262
|
default_value: `Any | None = None` Default value for the feature.
|
263
|
+
coerce_dtype: `bool = False` When True, attempts to coerce values to the specified dtype
|
264
|
+
during validation, see :attr:`~lamindb.Feature.coerce_dtype`.
|
258
265
|
cat_filters: `dict[str, str] | None = None` Subset a registry by additional filters to define valid categories.
|
259
266
|
|
260
267
|
Note:
|
@@ -323,6 +330,7 @@ class Feature(Record, CanCurate, TracksRun, TracksUpdates):
|
|
323
330
|
_aux_fields: dict[str, tuple[str, type]] = {
|
324
331
|
"0": ("default_value", bool),
|
325
332
|
"1": ("nullable", bool),
|
333
|
+
"2": ("coerce_dtype", bool),
|
326
334
|
}
|
327
335
|
|
328
336
|
id: int = models.AutoField(primary_key=True)
|
@@ -419,6 +427,7 @@ class Feature(Record, CanCurate, TracksRun, TracksUpdates):
|
|
419
427
|
synonyms: str | None = None,
|
420
428
|
nullable: bool = True,
|
421
429
|
default_value: str | None = None,
|
430
|
+
coerce_dtype: bool = False,
|
422
431
|
cat_filters: dict[str, str] | None = None,
|
423
432
|
): ...
|
424
433
|
|
@@ -440,10 +449,12 @@ class Feature(Record, CanCurate, TracksRun, TracksUpdates):
|
|
440
449
|
default_value = kwargs.pop("default_value", None)
|
441
450
|
nullable = kwargs.pop("nullable", True) # default value of nullable
|
442
451
|
cat_filters = kwargs.pop("cat_filters", None)
|
452
|
+
coerce_dtype = kwargs.pop("coerce_dtype", False)
|
443
453
|
kwargs = process_init_feature_param(args, kwargs)
|
444
454
|
super().__init__(*args, **kwargs)
|
445
455
|
self.default_value = default_value
|
446
456
|
self.nullable = nullable
|
457
|
+
self.coerce_dtype = coerce_dtype
|
447
458
|
dtype_str = kwargs.pop("dtype", None)
|
448
459
|
if cat_filters:
|
449
460
|
assert "|" not in dtype_str # noqa: S101
|
@@ -489,6 +500,25 @@ class Feature(Record, CanCurate, TracksRun, TracksUpdates):
|
|
489
500
|
super().save(*args, **kwargs)
|
490
501
|
return self
|
491
502
|
|
503
|
+
@property
|
504
|
+
def coerce_dtype(self) -> bool:
|
505
|
+
"""Whether dtypes should be coerced during validation.
|
506
|
+
|
507
|
+
For example, a `objects`-dtyped pandas column can be coerced to `categorical` and would pass validation if this is true.
|
508
|
+
"""
|
509
|
+
if self._aux is not None and "af" in self._aux and "2" in self._aux["af"]: # type: ignore
|
510
|
+
return self._aux["af"]["2"] # type: ignore
|
511
|
+
else:
|
512
|
+
return False
|
513
|
+
|
514
|
+
@coerce_dtype.setter
|
515
|
+
def coerce_dtype(self, value: bool) -> None:
|
516
|
+
if self._aux is None: # type: ignore
|
517
|
+
self._aux = {} # type: ignore
|
518
|
+
if "af" not in self._aux:
|
519
|
+
self._aux["af"] = {}
|
520
|
+
self._aux["af"]["2"] = value
|
521
|
+
|
492
522
|
@property
|
493
523
|
def default_value(self) -> Any:
|
494
524
|
"""A default value that overwrites missing values (default `None`).
|
lamindb/models/project.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING
|
3
|
+
from typing import TYPE_CHECKING, overload
|
4
4
|
|
5
5
|
from django.core.validators import RegexValidator
|
6
6
|
from django.db import models
|
@@ -66,6 +66,23 @@ class Person(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
|
66
66
|
external: bool = BooleanField(default=True, db_index=True)
|
67
67
|
"""Whether the person is external to the organization."""
|
68
68
|
|
69
|
+
@overload
|
70
|
+
def __init__(
|
71
|
+
self,
|
72
|
+
name: str,
|
73
|
+
email: str | None = None,
|
74
|
+
external: bool = True,
|
75
|
+
): ...
|
76
|
+
|
77
|
+
@overload
|
78
|
+
def __init__(
|
79
|
+
self,
|
80
|
+
*db_args,
|
81
|
+
): ...
|
82
|
+
|
83
|
+
def __init__(self, *args, **kwargs):
|
84
|
+
super().__init__(*args, **kwargs)
|
85
|
+
|
69
86
|
|
70
87
|
class Reference(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
71
88
|
"""References such as internal studies, papers, documents, or URLs.
|
@@ -94,12 +111,6 @@ class Reference(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
|
94
111
|
"""Universal id, valid across DB instances."""
|
95
112
|
name: str = CharField(db_index=True)
|
96
113
|
"""Title or name of the reference document."""
|
97
|
-
abbr: str | None = CharField(
|
98
|
-
max_length=32,
|
99
|
-
db_index=True,
|
100
|
-
null=True,
|
101
|
-
)
|
102
|
-
"""An abbreviation for the reference."""
|
103
114
|
type: Reference | None = ForeignKey(
|
104
115
|
"self", PROTECT, null=True, related_name="records"
|
105
116
|
)
|
@@ -111,6 +122,12 @@ class Reference(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
|
111
122
|
"""Records of this type."""
|
112
123
|
is_type: bool = BooleanField(default=False, db_index=True, null=True)
|
113
124
|
"""Distinguish types from instances of the type."""
|
125
|
+
abbr: str | None = CharField(
|
126
|
+
max_length=32,
|
127
|
+
db_index=True,
|
128
|
+
null=True,
|
129
|
+
)
|
130
|
+
"""An abbreviation for the reference."""
|
114
131
|
url: str | None = URLField(null=True)
|
115
132
|
"""URL linking to the reference."""
|
116
133
|
pubmed_id: int | None = BigIntegerField(null=True, db_index=True)
|
@@ -147,6 +164,30 @@ class Reference(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
|
147
164
|
)
|
148
165
|
"""Collections associated with this reference."""
|
149
166
|
|
167
|
+
@overload
|
168
|
+
def __init__(
|
169
|
+
self,
|
170
|
+
name: str,
|
171
|
+
type: Reference | None = None,
|
172
|
+
is_type: bool = False,
|
173
|
+
abbr: str | None = None,
|
174
|
+
url: str | None = None,
|
175
|
+
pubmed_id: int | None = None,
|
176
|
+
doi: str | None = None,
|
177
|
+
description: str | None = None,
|
178
|
+
text: str | None = None,
|
179
|
+
date: DateType | None = None,
|
180
|
+
): ...
|
181
|
+
|
182
|
+
@overload
|
183
|
+
def __init__(
|
184
|
+
self,
|
185
|
+
*db_args,
|
186
|
+
): ...
|
187
|
+
|
188
|
+
def __init__(self, *args, **kwargs):
|
189
|
+
super().__init__(*args, **kwargs)
|
190
|
+
|
150
191
|
|
151
192
|
class Project(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
152
193
|
"""Projects.
|
@@ -241,6 +282,27 @@ class Project(Record, CanCurate, TracksRun, TracksUpdates, ValidateFields):
|
|
241
282
|
_status_code: int = models.SmallIntegerField(default=0, db_index=True)
|
242
283
|
"""Status code."""
|
243
284
|
|
285
|
+
@overload
|
286
|
+
def __init__(
|
287
|
+
self,
|
288
|
+
name: str,
|
289
|
+
type: Project | None = None,
|
290
|
+
is_type: bool = False,
|
291
|
+
abbr: str | None = None,
|
292
|
+
url: str | None = None,
|
293
|
+
start_date: DateType | None = None,
|
294
|
+
end_date: DateType | None = None,
|
295
|
+
): ...
|
296
|
+
|
297
|
+
@overload
|
298
|
+
def __init__(
|
299
|
+
self,
|
300
|
+
*db_args,
|
301
|
+
): ...
|
302
|
+
|
303
|
+
def __init__(self, *args, **kwargs):
|
304
|
+
super().__init__(*args, **kwargs)
|
305
|
+
|
244
306
|
|
245
307
|
class ArtifactProject(BasicRecord, LinkORM, TracksRun):
|
246
308
|
id: int = models.BigAutoField(primary_key=True)
|
lamindb/models/query_set.py
CHANGED
@@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Any, Generic, NamedTuple, TypeVar, Union
|
|
10
10
|
import pandas as pd
|
11
11
|
from django.core.exceptions import FieldError
|
12
12
|
from django.db import models
|
13
|
-
from django.db.models import F, ForeignKey, ManyToManyField
|
13
|
+
from django.db.models import F, ForeignKey, ManyToManyField, Subquery
|
14
14
|
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
|
@@ -567,7 +567,17 @@ class QuerySet(models.QuerySet):
|
|
567
567
|
include_kwargs = {s: F(s) for s in include if s not in field_names}
|
568
568
|
annotate_kwargs.update(include_kwargs)
|
569
569
|
if annotate_kwargs:
|
570
|
-
|
570
|
+
id_subquery = self.values("id")
|
571
|
+
# for annotate, we want the queryset without filters so that joins don't affect the annotations
|
572
|
+
query_set_without_filters = self.model.objects.filter(
|
573
|
+
id__in=Subquery(id_subquery)
|
574
|
+
)
|
575
|
+
if self.query.order_by:
|
576
|
+
# Apply the same ordering to the new queryset
|
577
|
+
query_set_without_filters = query_set_without_filters.order_by(
|
578
|
+
*self.query.order_by
|
579
|
+
)
|
580
|
+
queryset = query_set_without_filters.annotate(**annotate_kwargs)
|
571
581
|
else:
|
572
582
|
queryset = self
|
573
583
|
|
lamindb/models/record.py
CHANGED
@@ -13,7 +13,9 @@ from typing import (
|
|
13
13
|
Any,
|
14
14
|
Literal,
|
15
15
|
NamedTuple,
|
16
|
+
TypeVar,
|
16
17
|
Union,
|
18
|
+
overload,
|
17
19
|
)
|
18
20
|
|
19
21
|
import dj_database_url
|
@@ -49,6 +51,7 @@ from django.db.models.lookups import (
|
|
49
51
|
)
|
50
52
|
from lamin_utils import colors, logger
|
51
53
|
from lamin_utils._lookup import Lookup
|
54
|
+
from lamindb_setup import settings as setup_settings
|
52
55
|
from lamindb_setup._connect_instance import (
|
53
56
|
get_owner_name_from_identifier,
|
54
57
|
load_instance_settings,
|
@@ -87,6 +90,7 @@ if TYPE_CHECKING:
|
|
87
90
|
from .transform import Transform
|
88
91
|
|
89
92
|
|
93
|
+
T = TypeVar("T", bound="Record")
|
90
94
|
IPYTHON = getattr(builtins, "__IPYTHON__", False)
|
91
95
|
|
92
96
|
|
@@ -466,19 +470,16 @@ class Registry(ModelBase):
|
|
466
470
|
return QuerySet(model=cls, using=_using_key).filter(*queries, **expressions)
|
467
471
|
|
468
472
|
def get(
|
469
|
-
cls,
|
473
|
+
cls: type[T],
|
470
474
|
idlike: int | str | None = None,
|
471
475
|
**expressions,
|
472
|
-
) ->
|
476
|
+
) -> T:
|
473
477
|
"""Get a single record.
|
474
478
|
|
475
479
|
Args:
|
476
480
|
idlike: Either a uid stub, uid or an integer id.
|
477
481
|
expressions: Fields and values passed as Django query expressions.
|
478
482
|
|
479
|
-
Returns:
|
480
|
-
A record.
|
481
|
-
|
482
483
|
Raises:
|
483
484
|
:exc:`docs:lamindb.errors.DoesNotExist`: In case no matching record is found.
|
484
485
|
|
@@ -486,9 +487,10 @@ class Registry(ModelBase):
|
|
486
487
|
- Guide: :doc:`docs:registries`
|
487
488
|
- Django documentation: `Queries <https://docs.djangoproject.com/en/stable/topics/db/queries/>`__
|
488
489
|
|
489
|
-
Examples
|
490
|
-
|
491
|
-
|
490
|
+
Examples::
|
491
|
+
|
492
|
+
ulabel = ln.ULabel.get("FvtpPJLJ")
|
493
|
+
ulabel = ln.ULabel.get(name="my-label")
|
492
494
|
"""
|
493
495
|
from .query_set import QuerySet
|
494
496
|
|
@@ -594,7 +596,11 @@ class Registry(ModelBase):
|
|
594
596
|
|
595
597
|
if instance is None:
|
596
598
|
return QuerySet(model=cls, using=None)
|
599
|
+
|
597
600
|
owner, name = get_owner_name_from_identifier(instance)
|
601
|
+
if f"{owner}/{name}" == setup_settings.instance.slug:
|
602
|
+
return QuerySet(model=cls, using=None)
|
603
|
+
|
598
604
|
settings_file = instance_settings_file(name, owner)
|
599
605
|
cache_filepath = (
|
600
606
|
ln_setup.settings.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
@@ -875,7 +881,13 @@ class BasicRecord(models.Model, metaclass=Registry):
|
|
875
881
|
|
876
882
|
|
877
883
|
class Space(BasicRecord):
|
878
|
-
"""Spaces.
|
884
|
+
"""Spaces.
|
885
|
+
|
886
|
+
You can use spaces to restrict access to records within an instance.
|
887
|
+
|
888
|
+
All data in this registry is synced from `lamin.ai` to enable re-using spaces across instances.
|
889
|
+
There is no need to manually create records.
|
890
|
+
"""
|
879
891
|
|
880
892
|
id: int = models.SmallAutoField(primary_key=True)
|
881
893
|
"""Internal id, valid only in one DB instance."""
|
@@ -901,6 +913,26 @@ class Space(BasicRecord):
|
|
901
913
|
)
|
902
914
|
"""Creator of run."""
|
903
915
|
|
916
|
+
@overload
|
917
|
+
def __init__(
|
918
|
+
self,
|
919
|
+
name: str,
|
920
|
+
description: str | None = None,
|
921
|
+
): ...
|
922
|
+
|
923
|
+
@overload
|
924
|
+
def __init__(
|
925
|
+
self,
|
926
|
+
*db_args,
|
927
|
+
): ...
|
928
|
+
|
929
|
+
def __init__(
|
930
|
+
self,
|
931
|
+
*args,
|
932
|
+
**kwargs,
|
933
|
+
):
|
934
|
+
super().__init__(*args, **kwargs)
|
935
|
+
|
904
936
|
|
905
937
|
@doc_args(RECORD_REGISTRY_EXAMPLE)
|
906
938
|
class Record(BasicRecord, metaclass=Registry):
|
@@ -989,8 +1021,8 @@ def _get_record_kwargs(record_class) -> list[tuple[str, str]]:
|
|
989
1021
|
pattern = r"@overload\s+def __init__\s*\(([\s\S]*?)\):\s*\.{3}"
|
990
1022
|
overloads = re.finditer(pattern, source)
|
991
1023
|
|
992
|
-
for
|
993
|
-
params_block =
|
1024
|
+
for single_overload in overloads:
|
1025
|
+
params_block = single_overload.group(1)
|
994
1026
|
# This is an additional safety measure if the overloaded signature that we're
|
995
1027
|
# looking for is not at the top but a "db_args" constructor
|
996
1028
|
if "*db_args" in params_block:
|
@@ -1037,13 +1069,14 @@ def _search(
|
|
1037
1069
|
field: StrField | list[StrField] | None = None,
|
1038
1070
|
limit: int | None = 20,
|
1039
1071
|
case_sensitive: bool = False,
|
1040
|
-
using_key: str | None = None,
|
1041
1072
|
truncate_string: bool = False,
|
1042
1073
|
) -> QuerySet:
|
1043
1074
|
if string is None:
|
1044
1075
|
raise ValueError("Cannot search for None value! Please pass a valid string.")
|
1045
1076
|
|
1046
|
-
input_queryset =
|
1077
|
+
input_queryset = (
|
1078
|
+
cls.all() if isinstance(cls, (QuerySet, Manager)) else cls.objects.all()
|
1079
|
+
)
|
1047
1080
|
registry = input_queryset.model
|
1048
1081
|
name_field = getattr(registry, "_name_field", "name")
|
1049
1082
|
if field is None:
|
@@ -1152,7 +1185,7 @@ def _lookup(
|
|
1152
1185
|
using_key: str | None = None,
|
1153
1186
|
) -> NamedTuple:
|
1154
1187
|
"""{}""" # noqa: D415
|
1155
|
-
queryset =
|
1188
|
+
queryset = cls.all() if isinstance(cls, (QuerySet, Manager)) else cls.objects.all()
|
1156
1189
|
field = get_name_field(registry=queryset.model, field=field)
|
1157
1190
|
|
1158
1191
|
return Lookup(
|
@@ -1172,7 +1205,7 @@ def _lookup(
|
|
1172
1205
|
def get_name_field(
|
1173
1206
|
registry: type[Record] | QuerySet | Manager,
|
1174
1207
|
*,
|
1175
|
-
field:
|
1208
|
+
field: StrField | None = None,
|
1176
1209
|
) -> str:
|
1177
1210
|
"""Get the 1st char or text field from the registry."""
|
1178
1211
|
if isinstance(registry, (QuerySet, Manager)):
|
@@ -1212,16 +1245,6 @@ def get_name_field(
|
|
1212
1245
|
return field
|
1213
1246
|
|
1214
1247
|
|
1215
|
-
def _queryset(cls: Record | QuerySet | Manager, using_key: str) -> QuerySet:
|
1216
|
-
if isinstance(cls, (QuerySet, Manager)):
|
1217
|
-
return cls.all()
|
1218
|
-
elif using_key is None or using_key == "default":
|
1219
|
-
return cls.objects.all()
|
1220
|
-
else:
|
1221
|
-
# using must be called on cls, otherwise the connection isn't found
|
1222
|
-
return cls.using(using_key).all()
|
1223
|
-
|
1224
|
-
|
1225
1248
|
def add_db_connection(db: str, using: str):
|
1226
1249
|
db_config = dj_database_url.config(
|
1227
1250
|
default=db, conn_max_age=600, conn_health_checks=True
|
lamindb/models/run.py
CHANGED
@@ -23,11 +23,13 @@ from lamindb.errors import ValidationError
|
|
23
23
|
|
24
24
|
from ..base.ids import base62_20
|
25
25
|
from .can_curate import CanCurate
|
26
|
-
from .record import BasicRecord, LinkORM, Record
|
26
|
+
from .record import BasicRecord, LinkORM, Record, Registry
|
27
27
|
|
28
28
|
if TYPE_CHECKING:
|
29
29
|
from datetime import datetime
|
30
30
|
|
31
|
+
from lamindb.base.types import FeatureDtype, FieldAttr
|
32
|
+
|
31
33
|
from .artifact import Artifact
|
32
34
|
from .collection import Collection
|
33
35
|
from .project import Project
|
@@ -235,6 +237,21 @@ class Param(Record, CanCurate, TracksRun, TracksUpdates):
|
|
235
237
|
values: ParamValue
|
236
238
|
"""Values for this parameter."""
|
237
239
|
|
240
|
+
@overload
|
241
|
+
def __init__(
|
242
|
+
self,
|
243
|
+
name: str,
|
244
|
+
dtype: FeatureDtype | Registry | list[Registry] | FieldAttr,
|
245
|
+
type: Param | None = None,
|
246
|
+
is_type: bool = False,
|
247
|
+
): ...
|
248
|
+
|
249
|
+
@overload
|
250
|
+
def __init__(
|
251
|
+
self,
|
252
|
+
*db_args,
|
253
|
+
): ...
|
254
|
+
|
238
255
|
def __init__(self, *args, **kwargs):
|
239
256
|
from .feature import process_init_feature_param
|
240
257
|
|
lamindb/models/schema.py
CHANGED
@@ -585,14 +585,6 @@ class Schema(Record, CanCurate, TracksRun):
|
|
585
585
|
self._aux["af"] = {}
|
586
586
|
self._aux["af"]["0"] = value
|
587
587
|
|
588
|
-
@coerce_dtype.setter
|
589
|
-
def coerce_dtype(self, value: bool) -> None:
|
590
|
-
if self._aux is None:
|
591
|
-
self._aux = {}
|
592
|
-
if "af" not in self._aux:
|
593
|
-
self._aux["af"] = {}
|
594
|
-
self._aux["af"]["0"] = value
|
595
|
-
|
596
588
|
# @property
|
597
589
|
# def index_feature(self) -> None | Feature:
|
598
590
|
# # index_feature: `Record | None = None` A :class:`~lamindb.Feature` to validate the index of a `DataFrame`.
|
@@ -1,16 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: lamindb
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.0
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
|
-
Requires-Python: >=3.10,<3.
|
6
|
+
Requires-Python: >=3.10,<3.14
|
7
7
|
Description-Content-Type: text/markdown
|
8
8
|
Classifier: Programming Language :: Python :: 3.10
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
11
|
-
|
12
|
-
Requires-Dist:
|
13
|
-
Requires-Dist:
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
12
|
+
Requires-Dist: lamin_utils==0.13.11
|
13
|
+
Requires-Dist: lamin_cli==1.2.0
|
14
|
+
Requires-Dist: lamindb_setup[aws]==1.3.2
|
14
15
|
Requires-Dist: pyyaml
|
15
16
|
Requires-Dist: pyarrow
|
16
17
|
Requires-Dist: pandera
|
@@ -39,7 +40,7 @@ Requires-Dist: faker-biology ; extra == "dev"
|
|
39
40
|
Requires-Dist: django-schema-graph ; extra == "erdiagram"
|
40
41
|
Requires-Dist: readfcs>=2.0.1 ; extra == "fcs"
|
41
42
|
Requires-Dist: lamindb_setup[gcp] ; extra == "gcp"
|
42
|
-
Requires-Dist: nbproject==0.10.
|
43
|
+
Requires-Dist: nbproject==0.10.6 ; extra == "jupyter"
|
43
44
|
Requires-Dist: jupytext ; extra == "jupyter"
|
44
45
|
Requires-Dist: nbconvert>=7.2.1 ; extra == "jupyter"
|
45
46
|
Requires-Dist: mistune!=3.1.0 ; extra == "jupyter"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
lamindb/__init__.py,sha256=
|
1
|
+
lamindb/__init__.py,sha256=G2uKSFYRVQni9rx_TyWNVsqG2tdv65RjmDm188hP8Xo,2468
|
2
2
|
lamindb/_finish.py,sha256=UK9XW1qZCd32Nqz0cdKYmpX9ilFU0nGyNb6Urwfx_Nw,19612
|
3
3
|
lamindb/_tracked.py,sha256=JKzYEpqVojklTms0VpP-tU34AHVZG8a13dSl3CfIzwQ,4472
|
4
4
|
lamindb/_view.py,sha256=O9qvwLmgKKsuFMoJ9YjV12cdOUjG6Ez1cQyLGCywm8Y,4964
|
@@ -9,33 +9,34 @@ lamindb/base/ids.py,sha256=OOgD5vxry6s2vSslb8-E9zEykDMpyhnungfT844DhSU,1547
|
|
9
9
|
lamindb/base/types.py,sha256=JfZk0xmhLsWusU0s4SNjhRnQ52mn-cSiG5Gf4SsACBs,1227
|
10
10
|
lamindb/base/users.py,sha256=8MSmAvCKoUF15YsDE6BGLBXsFWpfoEEg8iDTKZ7kD48,848
|
11
11
|
lamindb/core/__init__.py,sha256=aaBq0UVjNolMynbT1V5hB6UrJm1tK0M6WHu_r6em9_4,604
|
12
|
-
lamindb/core/
|
12
|
+
lamindb/core/_compat.py,sha256=NLnKk1qk4xdgMV-QwFDnBnbio02ujjlF86icvhpdv4c,2029
|
13
|
+
lamindb/core/_context.py,sha256=0JqPGrMsri8XhFwg7ugV-7xBJMF5czR2S610bCpLdZM,30411
|
13
14
|
lamindb/core/_mapped_collection.py,sha256=dxyZ1ZHFn5SBl1xILqN9N6TTUJP0PptVBV-2O0EdZww,25751
|
14
15
|
lamindb/core/_settings.py,sha256=WLjFn9XunEZ9zMy2Qvmc3aJqWMXw2hcG0EBNX9wjkfU,5706
|
15
16
|
lamindb/core/_sync_git.py,sha256=Z7keuyS5X7CAj285sEbZIFExZF9mtjGH8DzKwz3xhHw,5881
|
16
17
|
lamindb/core/_track_environment.py,sha256=gKmXiL2meqJT65X-66p_GlonoxzBZXNwNm-G9gk0fS4,847
|
17
18
|
lamindb/core/exceptions.py,sha256=FMEoSvT3FvtLkxQAt2oDXPeaPem8V5x5UBbTsPFYU5w,53
|
18
|
-
lamindb/core/loaders.py,sha256=
|
19
|
-
lamindb/core/types.py,sha256=
|
20
|
-
lamindb/core/datasets/__init__.py,sha256=
|
21
|
-
lamindb/core/datasets/_core.py,sha256=
|
19
|
+
lamindb/core/loaders.py,sha256=1JHLr4e-gbh8QXiy5duOPsiKo7TKjo74vmvolqhkhgs,5458
|
20
|
+
lamindb/core/types.py,sha256=7QmFnXe7lnr0tyJ0NzzAyvtVZtm9W4Yv0lMmq__CT3E,390
|
21
|
+
lamindb/core/datasets/__init__.py,sha256=g6cSgJmlkLuI6CoxB-Lbg70cpkVZWDuPv-2kcFb0uYs,1745
|
22
|
+
lamindb/core/datasets/_core.py,sha256=_PrZSr_rRpfScdzU216YMUR6TxihqA2hffRXmjD5Azw,20344
|
22
23
|
lamindb/core/datasets/_fake.py,sha256=BZF9R_1iF0HDnvtZNqL2FtsjSMuqDIfuFxnw_LJYIh4,953
|
23
|
-
lamindb/core/datasets/_small.py,sha256=
|
24
|
+
lamindb/core/datasets/_small.py,sha256=NuovAoA1oMpknQUASErdZgRz4byRQvT4ZgfQRX3GaHY,5597
|
24
25
|
lamindb/core/storage/__init__.py,sha256=JOIMu_7unbyhndtH1j0Q-9AvY8knSuc1IJO9sQnyBAQ,498
|
25
26
|
lamindb/core/storage/_anndata_accessor.py,sha256=oq2e4vlBnGhIeGR5a_8traOV3tKklZJUqcgKt0pEO8c,26187
|
26
27
|
lamindb/core/storage/_anndata_sizes.py,sha256=aXO3OB--tF5MChenSsigW6Q-RuE8YJJOUTVukkLrv9A,1029
|
27
28
|
lamindb/core/storage/_backed_access.py,sha256=98KdO0Qw6ZrYHAnHG-zUzjxr8Jb-ujIWtGWjg_Wdk9c,3854
|
28
29
|
lamindb/core/storage/_pyarrow_dataset.py,sha256=Kvrwuw1-44WpyI7iuKWV5XU3u-wI9-hz0FiXPzxErmI,1892
|
29
|
-
lamindb/core/storage/_tiledbsoma.py,sha256=
|
30
|
+
lamindb/core/storage/_tiledbsoma.py,sha256=gOcfgMHToI142KqyOYWJMOzmFMLos660k6ZFaAooYPc,10308
|
30
31
|
lamindb/core/storage/_valid_suffixes.py,sha256=vUSeQ4s01rdhD_vSd6wKmFBsgMJAKkBMnL_T9Y1znMg,501
|
31
|
-
lamindb/core/storage/_zarr.py,sha256=
|
32
|
-
lamindb/core/storage/objects.py,sha256=
|
32
|
+
lamindb/core/storage/_zarr.py,sha256=cisYXU4_QXMF_ZY2pV52Incus6365mMxRphLaHO76W0,6801
|
33
|
+
lamindb/core/storage/objects.py,sha256=l2JTHI7oLMH7JJqxwpyIgMXZJ3gaGv7xl_Jr21wWFAs,2809
|
33
34
|
lamindb/core/storage/paths.py,sha256=wJTD7qza87Xx7ZMo9HFHKgZWaVnst6qc4F2SzqvBMrE,7118
|
34
35
|
lamindb/core/subsettings/__init__.py,sha256=j6G9WAJLK-x9FzPSFw-HJUmOseZKGTbK-oLTKI_X_zs,126
|
35
36
|
lamindb/core/subsettings/_creation_settings.py,sha256=NGHWKqCFSzVNBxAr2VnmdYguiFdW29XUK7T9wRsVshg,906
|
36
|
-
lamindb/curators/__init__.py,sha256=
|
37
|
-
lamindb/curators/_cellxgene_schemas/__init__.py,sha256=
|
38
|
-
lamindb/curators/_cellxgene_schemas/schema_versions.
|
37
|
+
lamindb/curators/__init__.py,sha256=djRLi1YABJPwKz3wwSGhdRkuy3EC7wJy4pI_Yn6TQRQ,130500
|
38
|
+
lamindb/curators/_cellxgene_schemas/__init__.py,sha256=sOlwEBuYrUb8s-_NO0f2tM9cvW6FURLs91FKtTBeKSM,7541
|
39
|
+
lamindb/curators/_cellxgene_schemas/schema_versions.csv,sha256=X9rmO88TW1Fht1f5mJs0JdW-VPvyKSajpf8lHNeECj4,1680
|
39
40
|
lamindb/integrations/__init__.py,sha256=RWGMYYIzr8zvmNPyVB4m-p4gMDhxdRbjES2Ed23OItw,215
|
40
41
|
lamindb/integrations/_vitessce.py,sha256=VgO9zAlTSIKDo1wEef_Q4BudTAVtRSZmuzRdCGwBvJk,4016
|
41
42
|
lamindb/migrations/0069_squashed.py,sha256=gMWv65ErtjJZyWWo1b4uFHXWa6MSuBcmqz4ElZ6GPf4,62639
|
@@ -65,30 +66,30 @@ lamindb/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
65
66
|
lamindb/models/__init__.py,sha256=NlnrPiBSv93PttHDrAYnF3RTfiIhgC7QOE_mP0M9Ddc,1934
|
66
67
|
lamindb/models/_describe.py,sha256=B-lmzc8AYaeuKwwRRsF0q8qT6P1i93sEjYkfl0NuyWQ,4926
|
67
68
|
lamindb/models/_django.py,sha256=2LFaTvIPtxIV8_T6Kx0cvquTetj7C3OcnKukUyC9msY,7705
|
68
|
-
lamindb/models/_feature_manager.py,sha256=
|
69
|
-
lamindb/models/_from_values.py,sha256
|
69
|
+
lamindb/models/_feature_manager.py,sha256=SoprmJeUGyrEBTWq16gEQoxcaXFKnALdN2IJnnolWCM,50240
|
70
|
+
lamindb/models/_from_values.py,sha256=K9iTNJnCo9nKDkulmJ0OgI6_y13By4lOm-NZL8HotN0,14875
|
70
71
|
lamindb/models/_is_versioned.py,sha256=ivtC0t96YI6eaMFqg0ctWY3ert96I_2R-DI5O0Zx7kU,8011
|
71
72
|
lamindb/models/_label_manager.py,sha256=iDmCO6SNJAaskM43wfOoyVweCDuXXXIVhD9fnFdv2Vk,11650
|
72
73
|
lamindb/models/_relations.py,sha256=ONjHPiWIa_Ur7zMNTa_9Uw7K-366GORyPvGoVjf4EQs,3681
|
73
|
-
lamindb/models/artifact.py,sha256=
|
74
|
-
lamindb/models/can_curate.py,sha256
|
74
|
+
lamindb/models/artifact.py,sha256=TycwzkelBkJYh_282efbDLilNczJac2fRhKh7NyKqfM,102869
|
75
|
+
lamindb/models/can_curate.py,sha256=-A1WCO9a8Lf21TsYE58otv-4NVfXV9ajwv6UcM2tCRo,29052
|
75
76
|
lamindb/models/collection.py,sha256=P1E4olaqaPsVYdcQe8AgH_yUUdeQBa6QcyD1Y6Gedjo,26311
|
76
77
|
lamindb/models/core.py,sha256=cjQGk5r0Rzf3zTeC0gn_GB29UfKq34l4hThsNNVhi3o,3965
|
77
|
-
lamindb/models/feature.py,sha256
|
78
|
+
lamindb/models/feature.py,sha256=-ZoU4Ec6DsGwE1eavUrQC-cPbh2NYB2IunEDCmHCZcM,26274
|
78
79
|
lamindb/models/flextable.py,sha256=ET9j0fTFYQIdXOZfwCnosXOag7nYD1DUV6_wZNqhvOs,5400
|
79
80
|
lamindb/models/has_parents.py,sha256=PEGDiNTK7ikHBHAGsiHK4e6TA9jqUFRom1HSQuyReyE,17942
|
80
|
-
lamindb/models/project.py,sha256=
|
81
|
+
lamindb/models/project.py,sha256=WSOtM6-hKPeDNOCR6Frq1bJxc27j0HJWhCmFh5L3CiM,15174
|
81
82
|
lamindb/models/query_manager.py,sha256=RqF842cqloAv5z4zLDlWAZfVkLQbhCPry6WQW3CaznI,3713
|
82
|
-
lamindb/models/query_set.py,sha256=
|
83
|
-
lamindb/models/record.py,sha256=
|
84
|
-
lamindb/models/run.py,sha256=
|
83
|
+
lamindb/models/query_set.py,sha256=buJ-zuua5MTqeEE8WD3lOBZXs19k_r4DuRWPB8Bai5Y,27060
|
84
|
+
lamindb/models/record.py,sha256=Xkr37P60MqmOQgBCgw4H7sLwHi70zLDIJ06ZQt4Q8pk,64893
|
85
|
+
lamindb/models/run.py,sha256=VXWzxKZQGKh9UeZTLW3L3zSXn1UvHE5ObT_L9XdjDDU,18877
|
85
86
|
lamindb/models/save.py,sha256=VEq4kmDyDiw9zTQY6meA9c5yT_YU5ldFzRDgKqCX59M,13031
|
86
|
-
lamindb/models/schema.py,sha256=
|
87
|
+
lamindb/models/schema.py,sha256=nfS_efk35ULXWM6fkF4GPfBaLwYD4WHPCoPUSpIn7Lw,28735
|
87
88
|
lamindb/models/transform.py,sha256=PbtjakPWmw0iuCG0HPEbysISVX_CoIE2KAPF7L18Vak,13064
|
88
89
|
lamindb/models/ulabel.py,sha256=A8zJcRiGNmq24njLJv7_FuVZJmdtSkN-MSKw5c1QJMo,8605
|
89
90
|
lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
|
90
91
|
lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
|
91
|
-
lamindb-1.
|
92
|
-
lamindb-1.
|
93
|
-
lamindb-1.
|
94
|
-
lamindb-1.
|
92
|
+
lamindb-1.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
93
|
+
lamindb-1.3.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
94
|
+
lamindb-1.3.0.dist-info/METADATA,sha256=CEM_-5XfZuNgGALPTHPZvvdPJQwxDhVjjKbUNTSdsgI,2726
|
95
|
+
lamindb-1.3.0.dist-info/RECORD,,
|