lamindb 0.69.7__py3-none-any.whl → 0.69.8__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 +1 -1
- lamindb/_annotate.py +46 -42
- lamindb/_artifact.py +63 -64
- lamindb/_can_validate.py +29 -25
- lamindb/_collection.py +28 -32
- lamindb/_feature.py +10 -8
- lamindb/_feature_set.py +17 -15
- lamindb/_filter.py +2 -2
- lamindb/_finish.py +14 -8
- lamindb/_from_values.py +13 -9
- lamindb/_is_versioned.py +2 -2
- lamindb/_parents.py +16 -11
- lamindb/_query_manager.py +8 -4
- lamindb/_query_set.py +15 -15
- lamindb/_registry.py +36 -34
- lamindb/_run.py +3 -5
- lamindb/_save.py +13 -11
- lamindb/_transform.py +9 -11
- lamindb/_ulabel.py +11 -9
- lamindb/_view.py +3 -2
- lamindb/core/_data.py +21 -17
- lamindb/core/_feature_manager.py +17 -12
- lamindb/core/_label_manager.py +13 -9
- lamindb/core/_mapped_collection.py +16 -12
- lamindb/core/_run_context.py +21 -17
- lamindb/core/_settings.py +19 -16
- lamindb/core/_sync_git.py +4 -5
- lamindb/core/_track_environment.py +6 -1
- lamindb/core/_transform_settings.py +3 -3
- lamindb/core/_view_tree.py +2 -1
- lamindb/core/datasets/_core.py +3 -2
- lamindb/core/datasets/_fake.py +2 -2
- lamindb/core/storage/_anndata_sizes.py +2 -0
- lamindb/core/storage/_backed_access.py +17 -12
- lamindb/core/storage/_zarr.py +7 -3
- lamindb/core/storage/file.py +10 -6
- lamindb/core/storage/object.py +7 -3
- lamindb/core/versioning.py +12 -8
- lamindb/integrations/_vitessce.py +2 -0
- {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/METADATA +4 -4
- lamindb-0.69.8.dist-info/RECORD +54 -0
- lamindb-0.69.7.dist-info/RECORD +0 -54
- {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/LICENSE +0 -0
- {lamindb-0.69.7.dist-info → lamindb-0.69.8.dist-info}/WHEEL +0 -0
lamindb/_can_validate.py
CHANGED
@@ -1,28 +1,32 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Iterable, Literal
|
2
4
|
|
3
5
|
import lamindb_setup as ln_setup
|
4
6
|
import numpy as np
|
5
7
|
import pandas as pd
|
6
8
|
from django.core.exceptions import FieldDoesNotExist
|
7
|
-
from django.db.models import QuerySet
|
8
9
|
from lamin_utils import colors, logger
|
9
|
-
from lamin_utils._inspect import InspectResult
|
10
10
|
from lamindb_setup.core._docs import doc_args
|
11
11
|
from lnschema_core import CanValidate, Registry
|
12
|
-
from lnschema_core.types import ListLike, StrField
|
13
12
|
|
14
13
|
from lamindb._utils import attach_func_to_class_method
|
15
14
|
|
16
15
|
from ._from_values import _has_organism_field, _print_values
|
17
16
|
from ._registry import _queryset, get_default_str_field
|
18
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from django.db.models import QuerySet
|
20
|
+
from lamin_utils._inspect import InspectResult
|
21
|
+
from lnschema_core.types import ListLike, StrField
|
22
|
+
|
19
23
|
|
20
24
|
@classmethod # type: ignore
|
21
25
|
@doc_args(CanValidate.inspect.__doc__)
|
22
26
|
def inspect(
|
23
27
|
cls,
|
24
28
|
values: ListLike,
|
25
|
-
field:
|
29
|
+
field: str | StrField | None = None,
|
26
30
|
*,
|
27
31
|
mute: bool = False,
|
28
32
|
**kwargs,
|
@@ -42,7 +46,7 @@ def inspect(
|
|
42
46
|
def validate(
|
43
47
|
cls,
|
44
48
|
values: ListLike,
|
45
|
-
field:
|
49
|
+
field: str | StrField | None = None,
|
46
50
|
*,
|
47
51
|
mute: bool = False,
|
48
52
|
**kwargs,
|
@@ -54,12 +58,12 @@ def validate(
|
|
54
58
|
def _inspect(
|
55
59
|
cls,
|
56
60
|
values: ListLike,
|
57
|
-
field:
|
61
|
+
field: str | StrField | None = None,
|
58
62
|
*,
|
59
63
|
mute: bool = False,
|
60
|
-
using_key:
|
64
|
+
using_key: str | None = None,
|
61
65
|
**kwargs,
|
62
|
-
) ->
|
66
|
+
) -> pd.DataFrame | dict[str, list[str]]:
|
63
67
|
"""{}."""
|
64
68
|
from lamin_utils._inspect import inspect
|
65
69
|
|
@@ -138,10 +142,10 @@ def _inspect(
|
|
138
142
|
def _validate(
|
139
143
|
cls,
|
140
144
|
values: ListLike,
|
141
|
-
field:
|
145
|
+
field: str | StrField | None = None,
|
142
146
|
*,
|
143
147
|
mute: bool = False,
|
144
|
-
using_key:
|
148
|
+
using_key: str | None = None,
|
145
149
|
**kwargs,
|
146
150
|
) -> np.ndarray:
|
147
151
|
"""{}."""
|
@@ -182,7 +186,7 @@ def _validate(
|
|
182
186
|
def standardize(
|
183
187
|
cls,
|
184
188
|
values: Iterable,
|
185
|
-
field:
|
189
|
+
field: str | StrField | None = None,
|
186
190
|
*,
|
187
191
|
return_field: str = None,
|
188
192
|
return_mapper: bool = False,
|
@@ -192,7 +196,7 @@ def standardize(
|
|
192
196
|
keep: Literal["first", "last", False] = "first",
|
193
197
|
synonyms_field: str = "synonyms",
|
194
198
|
**kwargs,
|
195
|
-
) ->
|
199
|
+
) -> list[str] | dict[str, str]:
|
196
200
|
"""{}."""
|
197
201
|
return _standardize(
|
198
202
|
cls=cls,
|
@@ -226,9 +230,9 @@ def set_abbr(self, value: str):
|
|
226
230
|
|
227
231
|
def add_synonym(
|
228
232
|
self,
|
229
|
-
synonym:
|
233
|
+
synonym: str | ListLike,
|
230
234
|
force: bool = False,
|
231
|
-
save:
|
235
|
+
save: bool | None = None,
|
232
236
|
):
|
233
237
|
_check_synonyms_field_exist(self)
|
234
238
|
_add_or_remove_synonyms(
|
@@ -236,7 +240,7 @@ def add_synonym(
|
|
236
240
|
)
|
237
241
|
|
238
242
|
|
239
|
-
def remove_synonym(self, synonym:
|
243
|
+
def remove_synonym(self, synonym: str | ListLike):
|
240
244
|
_check_synonyms_field_exist(self)
|
241
245
|
_add_or_remove_synonyms(synonym=synonym, record=self, action="remove")
|
242
246
|
|
@@ -244,7 +248,7 @@ def remove_synonym(self, synonym: Union[str, ListLike]):
|
|
244
248
|
def _standardize(
|
245
249
|
cls,
|
246
250
|
values: Iterable,
|
247
|
-
field:
|
251
|
+
field: str | StrField | None = None,
|
248
252
|
*,
|
249
253
|
return_field: str = None,
|
250
254
|
return_mapper: bool = False,
|
@@ -253,9 +257,9 @@ def _standardize(
|
|
253
257
|
public_aware: bool = True,
|
254
258
|
keep: Literal["first", "last", False] = "first",
|
255
259
|
synonyms_field: str = "synonyms",
|
256
|
-
using_key:
|
260
|
+
using_key: str | None = None,
|
257
261
|
**kwargs,
|
258
|
-
) ->
|
262
|
+
) -> list[str] | dict[str, str]:
|
259
263
|
"""{}."""
|
260
264
|
from lamin_utils._standardize import standardize as map_synonyms
|
261
265
|
|
@@ -302,7 +306,7 @@ def _standardize(
|
|
302
306
|
**_kwargs,
|
303
307
|
)
|
304
308
|
|
305
|
-
def _return(result:
|
309
|
+
def _return(result: list, mapper: dict):
|
306
310
|
if return_mapper:
|
307
311
|
return mapper
|
308
312
|
else:
|
@@ -350,15 +354,15 @@ def _standardize(
|
|
350
354
|
|
351
355
|
|
352
356
|
def _add_or_remove_synonyms(
|
353
|
-
synonym:
|
357
|
+
synonym: str | Iterable,
|
354
358
|
record: Registry,
|
355
359
|
action: Literal["add", "remove"],
|
356
360
|
force: bool = False,
|
357
|
-
save:
|
361
|
+
save: bool | None = None,
|
358
362
|
):
|
359
363
|
"""Add or remove synonyms."""
|
360
364
|
|
361
|
-
def check_synonyms_in_all_records(synonyms:
|
365
|
+
def check_synonyms_in_all_records(synonyms: set[str], record: Registry):
|
362
366
|
"""Errors if input synonym is associated with other records in the DB."""
|
363
367
|
import pandas as pd
|
364
368
|
from IPython.display import display
|
@@ -437,8 +441,8 @@ def _check_synonyms_field_exist(record: Registry):
|
|
437
441
|
|
438
442
|
def _filter_query_based_on_organism(
|
439
443
|
queryset: QuerySet,
|
440
|
-
organism:
|
441
|
-
values_list_field:
|
444
|
+
organism: str | Registry | None = None,
|
445
|
+
values_list_field: str | None = None,
|
442
446
|
):
|
443
447
|
"""Filter a queryset based on organism."""
|
444
448
|
import pandas as pd
|
lamindb/_collection.py
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from collections import defaultdict
|
2
4
|
from typing import (
|
3
5
|
TYPE_CHECKING,
|
4
6
|
Any,
|
5
|
-
Dict,
|
6
7
|
Iterable,
|
7
|
-
List,
|
8
8
|
Literal,
|
9
|
-
Optional,
|
10
|
-
Tuple,
|
11
|
-
Union,
|
12
9
|
)
|
13
10
|
|
14
11
|
import anndata as ad
|
@@ -24,12 +21,10 @@ from lnschema_core.types import DataLike, VisibilityChoice
|
|
24
21
|
from lamindb._utils import attach_func_to_class_method
|
25
22
|
from lamindb.core._data import _track_run_input
|
26
23
|
from lamindb.core._mapped_collection import MappedCollection
|
27
|
-
from lamindb.core.storage import UPath
|
28
24
|
from lamindb.core.versioning import get_uid_from_old_version, init_uid
|
29
25
|
|
30
26
|
from . import Artifact, Run
|
31
27
|
from ._artifact import data_is_anndata
|
32
|
-
from ._query_set import QuerySet
|
33
28
|
from ._registry import init_self_from_db
|
34
29
|
from .core._data import (
|
35
30
|
add_transform_to_kwargs,
|
@@ -39,10 +34,13 @@ from .core._data import (
|
|
39
34
|
)
|
40
35
|
|
41
36
|
if TYPE_CHECKING:
|
37
|
+
from lamindb.core.storage import UPath
|
42
38
|
from lamindb.core.storage._backed_access import AnnDataAccessor, BackedAccessor
|
43
39
|
|
40
|
+
from ._query_set import QuerySet
|
41
|
+
|
44
42
|
|
45
|
-
def _check_accessor_collection(data: Any, accessor:
|
43
|
+
def _check_accessor_collection(data: Any, accessor: str | None = None):
|
46
44
|
if accessor is None and isinstance(data, (AnnData, pd.DataFrame)):
|
47
45
|
if isinstance(data, pd.DataFrame):
|
48
46
|
logger.warning("data is a DataFrame, please use .from_df()")
|
@@ -64,31 +62,29 @@ def __init__(
|
|
64
62
|
# now we proceed with the user-facing constructor
|
65
63
|
if len(args) > 1:
|
66
64
|
raise ValueError("Only one non-keyword arg allowed: data")
|
67
|
-
data:
|
65
|
+
data: Artifact | Iterable[Artifact] = (
|
68
66
|
kwargs.pop("data") if len(args) == 0 else args[0]
|
69
67
|
)
|
70
|
-
meta:
|
71
|
-
name:
|
72
|
-
description:
|
68
|
+
meta: str | None = kwargs.pop("meta") if "meta" in kwargs else None
|
69
|
+
name: str | None = kwargs.pop("name") if "name" in kwargs else None
|
70
|
+
description: str | None = (
|
73
71
|
kwargs.pop("description") if "description" in kwargs else None
|
74
72
|
)
|
75
|
-
reference:
|
76
|
-
|
77
|
-
)
|
78
|
-
reference_type: Optional[str] = (
|
73
|
+
reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
|
74
|
+
reference_type: str | None = (
|
79
75
|
kwargs.pop("reference_type") if "reference_type" in kwargs else None
|
80
76
|
)
|
81
|
-
run:
|
82
|
-
is_new_version_of:
|
77
|
+
run: Run | None = kwargs.pop("run") if "run" in kwargs else None
|
78
|
+
is_new_version_of: Collection | None = (
|
83
79
|
kwargs.pop("is_new_version_of") if "is_new_version_of" in kwargs else None
|
84
80
|
)
|
85
|
-
version:
|
86
|
-
visibility:
|
81
|
+
version: str | None = kwargs.pop("version") if "version" in kwargs else None
|
82
|
+
visibility: int | None = (
|
87
83
|
kwargs.pop("visibility")
|
88
84
|
if "visibility" in kwargs
|
89
85
|
else VisibilityChoice.default.value
|
90
86
|
)
|
91
|
-
feature_sets:
|
87
|
+
feature_sets: dict[str, FeatureSet] = (
|
92
88
|
kwargs.pop("feature_sets") if "feature_sets" in kwargs else {}
|
93
89
|
)
|
94
90
|
accessor = kwargs.pop("accessor") if "accessor" in kwargs else None
|
@@ -166,7 +162,7 @@ def __init__(
|
|
166
162
|
|
167
163
|
|
168
164
|
# internal function, not exposed to user
|
169
|
-
def from_artifacts(artifacts: Iterable[Artifact]) ->
|
165
|
+
def from_artifacts(artifacts: Iterable[Artifact]) -> tuple[str, dict[str, str]]:
|
170
166
|
# assert all artifacts are already saved
|
171
167
|
logger.debug("check not saved")
|
172
168
|
saved = not any(artifact._state.adding for artifact in artifacts)
|
@@ -228,16 +224,16 @@ def from_artifacts(artifacts: Iterable[Artifact]) -> Tuple[str, Dict[str, str]]:
|
|
228
224
|
# docstring handled through attach_func_to_class_method
|
229
225
|
def mapped(
|
230
226
|
self,
|
231
|
-
label_keys:
|
232
|
-
join:
|
233
|
-
encode_labels:
|
234
|
-
unknown_label:
|
227
|
+
label_keys: str | list[str] | None = None,
|
228
|
+
join: Literal["inner", "outer"] | None = "inner",
|
229
|
+
encode_labels: bool | list[str] = True,
|
230
|
+
unknown_label: str | dict[str, str] | None = None,
|
235
231
|
cache_categories: bool = True,
|
236
232
|
parallel: bool = False,
|
237
|
-
dtype:
|
233
|
+
dtype: str | None = None,
|
238
234
|
stream: bool = False,
|
239
|
-
is_run_input:
|
240
|
-
) ->
|
235
|
+
is_run_input: bool | None = None,
|
236
|
+
) -> MappedCollection:
|
241
237
|
path_list = []
|
242
238
|
for artifact in self.artifacts.all():
|
243
239
|
if artifact.suffix not in {".h5ad", ".zrad", ".zarr"}:
|
@@ -263,7 +259,7 @@ def mapped(
|
|
263
259
|
|
264
260
|
|
265
261
|
# docstring handled through attach_func_to_class_method
|
266
|
-
def stage(self, is_run_input:
|
262
|
+
def stage(self, is_run_input: bool | None = None) -> list[UPath]:
|
267
263
|
_track_run_input(self, is_run_input)
|
268
264
|
path_list = []
|
269
265
|
for artifact in self.artifacts.all():
|
@@ -275,7 +271,7 @@ def stage(self, is_run_input: Optional[bool] = None) -> List[UPath]:
|
|
275
271
|
def load(
|
276
272
|
self,
|
277
273
|
join: Literal["inner", "outer"] = "outer",
|
278
|
-
is_run_input:
|
274
|
+
is_run_input: bool | None = None,
|
279
275
|
**kwargs,
|
280
276
|
) -> DataLike:
|
281
277
|
# cannot call _track_run_input here, see comment further down
|
@@ -301,7 +297,7 @@ def load(
|
|
301
297
|
|
302
298
|
|
303
299
|
# docstring handled through attach_func_to_class_method
|
304
|
-
def delete(self, permanent:
|
300
|
+
def delete(self, permanent: bool | None = None) -> None:
|
305
301
|
# change visibility to trash
|
306
302
|
trash_visibility = VisibilityChoice.trash.value
|
307
303
|
if self.visibility > trash_visibility and permanent is not True:
|
lamindb/_feature.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, List
|
2
4
|
|
3
5
|
import lamindb_setup as ln_setup
|
4
6
|
import pandas as pd
|
5
7
|
from lamindb_setup.core._docs import doc_args
|
6
8
|
from lnschema_core.models import Feature, Registry
|
7
|
-
from lnschema_core.types import FieldAttr
|
8
9
|
from pandas.api.types import CategoricalDtype, is_string_dtype
|
9
10
|
|
10
11
|
from lamindb._utils import attach_func_to_class_method
|
@@ -12,6 +13,9 @@ from lamindb.core._settings import settings
|
|
12
13
|
|
13
14
|
from ._query_set import RecordsList
|
14
15
|
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from lnschema_core.types import FieldAttr
|
18
|
+
|
15
19
|
FEATURE_TYPES = {
|
16
20
|
"int": "number",
|
17
21
|
"float": "number",
|
@@ -41,7 +45,7 @@ def __init__(self, *args, **kwargs):
|
|
41
45
|
type: Optional[Union[type, str]] = ( # noqa
|
42
46
|
kwargs.pop("type") if "type" in kwargs else None
|
43
47
|
)
|
44
|
-
registries:
|
48
|
+
registries: list[Registry] | None = (
|
45
49
|
kwargs.pop("registries") if "registries" in kwargs else None
|
46
50
|
)
|
47
51
|
# cast type
|
@@ -55,7 +59,7 @@ def __init__(self, *args, **kwargs):
|
|
55
59
|
raise ValueError("type has to be one of 'number', 'category', 'bool'!")
|
56
60
|
kwargs["type"] = type_str
|
57
61
|
# cast registries
|
58
|
-
registries_str:
|
62
|
+
registries_str: str | None = None
|
59
63
|
if registries is not None:
|
60
64
|
if isinstance(registries, str):
|
61
65
|
# TODO: add more validation
|
@@ -73,7 +77,7 @@ def __init__(self, *args, **kwargs):
|
|
73
77
|
super(Feature, self).__init__(*args, **kwargs)
|
74
78
|
|
75
79
|
|
76
|
-
def categoricals_from_df(df:
|
80
|
+
def categoricals_from_df(df: pd.DataFrame) -> dict:
|
77
81
|
"""Returns categorical columns."""
|
78
82
|
string_cols = [col for col in df.columns if is_string_dtype(df[col])]
|
79
83
|
categoricals = {
|
@@ -90,9 +94,7 @@ def categoricals_from_df(df: "pd.DataFrame") -> Dict:
|
|
90
94
|
|
91
95
|
@classmethod # type:ignore
|
92
96
|
@doc_args(Feature.from_df.__doc__)
|
93
|
-
def from_df(
|
94
|
-
cls, df: "pd.DataFrame", field: Optional[FieldAttr] = None
|
95
|
-
) -> "RecordsList":
|
97
|
+
def from_df(cls, df: pd.DataFrame, field: FieldAttr | None = None) -> RecordsList:
|
96
98
|
"""{}."""
|
97
99
|
field = Feature.name if field is None else field
|
98
100
|
categoricals = categoricals_from_df(df)
|
lamindb/_feature_set.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Iterable
|
2
4
|
|
3
5
|
import lamindb_setup as ln_setup
|
4
6
|
import numpy as np
|
@@ -22,7 +24,7 @@ NUMBER_TYPE = "number"
|
|
22
24
|
|
23
25
|
|
24
26
|
def dict_related_model_to_related_name(orm):
|
25
|
-
d:
|
27
|
+
d: dict = {
|
26
28
|
i.related_model.__get_name_with_schema__(): i.related_name
|
27
29
|
for i in orm._meta.related_objects
|
28
30
|
if i.related_name is not None
|
@@ -39,7 +41,7 @@ def dict_related_model_to_related_name(orm):
|
|
39
41
|
|
40
42
|
|
41
43
|
def dict_schema_name_to_model_name(orm):
|
42
|
-
d:
|
44
|
+
d: dict = {
|
43
45
|
i.related_model.__get_name_with_schema__(): i.related_model
|
44
46
|
for i in orm._meta.related_objects
|
45
47
|
if i.related_name is not None
|
@@ -72,7 +74,7 @@ def get_related_name(features_type: Registry):
|
|
72
74
|
return candidates[0]
|
73
75
|
|
74
76
|
|
75
|
-
def validate_features(features:
|
77
|
+
def validate_features(features: list[Registry]) -> Registry:
|
76
78
|
"""Validate and return feature type."""
|
77
79
|
try:
|
78
80
|
if len(features) == 0:
|
@@ -104,8 +106,8 @@ def __init__(self, *args, **kwargs):
|
|
104
106
|
if len(args) > 1:
|
105
107
|
raise ValueError("Only one non-keyword arg allowed: features")
|
106
108
|
features: Iterable[Registry] = kwargs.pop("features") if len(args) == 0 else args[0]
|
107
|
-
type:
|
108
|
-
name:
|
109
|
+
type: str | None = kwargs.pop("type") if "type" in kwargs else None
|
110
|
+
name: str | None = kwargs.pop("name") if "name" in kwargs else None
|
109
111
|
if len(kwargs) > 0:
|
110
112
|
raise ValueError("Only features, type, name are valid keyword arguments")
|
111
113
|
# now code
|
@@ -142,9 +144,9 @@ def save(self, *args, **kwargs) -> None:
|
|
142
144
|
getattr(self, related_name).set(records)
|
143
145
|
|
144
146
|
|
145
|
-
def get_type_str(type:
|
147
|
+
def get_type_str(type: str | None) -> str | None:
|
146
148
|
if type is not None:
|
147
|
-
type_str = type.__name__ if not isinstance(type, str) else type
|
149
|
+
type_str = type.__name__ if not isinstance(type, str) else type # type: ignore
|
148
150
|
else:
|
149
151
|
type_str = None
|
150
152
|
if type == "int" or type == "float":
|
@@ -158,10 +160,10 @@ def from_values(
|
|
158
160
|
cls,
|
159
161
|
values: ListLike,
|
160
162
|
field: FieldAttr = Feature.name,
|
161
|
-
type:
|
162
|
-
name:
|
163
|
+
type: str | None = None,
|
164
|
+
name: str | None = None,
|
163
165
|
**kwargs,
|
164
|
-
) ->
|
166
|
+
) -> FeatureSet | None:
|
165
167
|
"""{}."""
|
166
168
|
if not isinstance(field, FieldAttr):
|
167
169
|
raise TypeError(
|
@@ -192,11 +194,11 @@ def from_values(
|
|
192
194
|
@doc_args(FeatureSet.from_df.__doc__)
|
193
195
|
def from_df(
|
194
196
|
cls,
|
195
|
-
df:
|
197
|
+
df: pd.DataFrame,
|
196
198
|
field: FieldAttr = Feature.name,
|
197
|
-
name:
|
199
|
+
name: str | None = None,
|
198
200
|
**kwargs,
|
199
|
-
) ->
|
201
|
+
) -> FeatureSet | None:
|
200
202
|
"""{}."""
|
201
203
|
registry = field.field.model
|
202
204
|
validated = registry.validate(df.columns, field=field, **kwargs)
|
@@ -225,7 +227,7 @@ def from_df(
|
|
225
227
|
|
226
228
|
@property # type: ignore
|
227
229
|
@doc_args(FeatureSet.members.__doc__)
|
228
|
-
def members(self) ->
|
230
|
+
def members(self) -> QuerySet:
|
229
231
|
"""{}."""
|
230
232
|
if self._state.adding:
|
231
233
|
# this should return a queryset and not a list...
|
lamindb/_filter.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
3
|
from lnschema_core import Artifact, Collection, Registry
|
4
4
|
from lnschema_core.types import VisibilityChoice
|
@@ -7,7 +7,7 @@ from lamindb import settings
|
|
7
7
|
from lamindb._query_set import QuerySet
|
8
8
|
|
9
9
|
|
10
|
-
def filter(Registry:
|
10
|
+
def filter(Registry: type[Registry], **expressions) -> QuerySet:
|
11
11
|
"""See :meth:`~lamindb.core.Registry.filter`."""
|
12
12
|
_using_key = None
|
13
13
|
if "_using_key" in expressions:
|
lamindb/_finish.py
CHANGED
@@ -1,18 +1,24 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
4
|
import shutil
|
3
5
|
import subprocess
|
4
6
|
from datetime import datetime, timezone
|
5
|
-
from
|
6
|
-
from typing import Optional
|
7
|
+
from typing import TYPE_CHECKING
|
7
8
|
|
8
9
|
import lamindb_setup as ln_setup
|
9
10
|
from lamin_utils import logger
|
10
|
-
from lnschema_core import Run, Transform
|
11
11
|
from lnschema_core.types import TransformType
|
12
12
|
|
13
|
-
from ._query_set import QuerySet
|
14
13
|
from .core._run_context import is_run_from_ipython, run_context
|
15
14
|
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from pathlib import Path
|
17
|
+
|
18
|
+
from lnschema_core import Run, Transform
|
19
|
+
|
20
|
+
from ._query_set import QuerySet
|
21
|
+
|
16
22
|
|
17
23
|
class CallFinishInLastCell(SystemExit):
|
18
24
|
pass
|
@@ -34,13 +40,13 @@ def finish(i_saved_the_notebook: bool = False):
|
|
34
40
|
|
35
41
|
if not i_saved_the_notebook and not ln_setup._TESTING:
|
36
42
|
logger.error(
|
37
|
-
"Please
|
43
|
+
"Please pass `i_saved_the_notebook=True` to `ln.finish()`, save the notebook, and re-run this cell."
|
38
44
|
)
|
39
45
|
return None
|
40
46
|
notebook_content = read_notebook(run_context.path) # type: ignore
|
41
47
|
if not check_last_cell(notebook_content, "i_saved_the_notebook"):
|
42
48
|
raise CallFinishInLastCell(
|
43
|
-
"Can only finish() from the last code cell of the notebook."
|
49
|
+
"Can only run `ln.finish(i_saved_the_notebook=True)` from the last code cell of the notebook."
|
44
50
|
)
|
45
51
|
save_run_context_core(
|
46
52
|
run=run_context.run,
|
@@ -61,11 +67,11 @@ def save_run_context_core(
|
|
61
67
|
run: Run,
|
62
68
|
transform: Transform,
|
63
69
|
filepath: Path,
|
64
|
-
transform_family:
|
70
|
+
transform_family: QuerySet | None = None,
|
65
71
|
is_consecutive: bool = True,
|
66
72
|
finished_at: bool = False,
|
67
73
|
notebook_content=None, # nbproject.Notebook
|
68
|
-
) ->
|
74
|
+
) -> str | None:
|
69
75
|
import lamindb as ln
|
70
76
|
|
71
77
|
ln.settings.verbosity = "success"
|
lamindb/_from_values.py
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
2
4
|
|
3
5
|
import pandas as pd
|
4
6
|
from django.core.exceptions import FieldDoesNotExist
|
5
7
|
from lamin_utils import colors, logger
|
6
8
|
from lnschema_core.models import Feature, Registry, ULabel
|
7
|
-
from lnschema_core.types import ListLike, StrField
|
8
9
|
|
9
10
|
from .core._settings import settings
|
10
11
|
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from lnschema_core.types import ListLike, StrField
|
14
|
+
|
11
15
|
|
12
16
|
# The base function for `from_values`
|
13
17
|
def get_or_create_records(
|
@@ -16,7 +20,7 @@ def get_or_create_records(
|
|
16
20
|
*,
|
17
21
|
from_public: bool = False,
|
18
22
|
**kwargs,
|
19
|
-
) ->
|
23
|
+
) -> list[Registry]:
|
20
24
|
"""Get or create records from iterables."""
|
21
25
|
upon_create_search_names = settings.upon_create_search_names
|
22
26
|
settings.upon_create_search_names = False
|
@@ -74,12 +78,12 @@ def get_or_create_records(
|
|
74
78
|
def get_existing_records(
|
75
79
|
iterable_idx: pd.Index,
|
76
80
|
field: StrField,
|
77
|
-
kwargs:
|
81
|
+
kwargs: dict = None,
|
78
82
|
):
|
79
83
|
if kwargs is None:
|
80
84
|
kwargs = {}
|
81
85
|
model = field.field.model
|
82
|
-
condition:
|
86
|
+
condition: dict = {} if len(kwargs) == 0 else kwargs.copy()
|
83
87
|
# existing records matching is agnostic to the bionty source
|
84
88
|
if "public_source" in condition:
|
85
89
|
condition.pop("public_source")
|
@@ -167,7 +171,7 @@ def create_records_from_public(
|
|
167
171
|
**kwargs,
|
168
172
|
):
|
169
173
|
model = field.field.model
|
170
|
-
records:
|
174
|
+
records: list = []
|
171
175
|
# populate additional fields from bionty
|
172
176
|
from lnschema_bionty._bionty import get_public_source_record
|
173
177
|
|
@@ -247,7 +251,7 @@ def index_iterable(iterable: Iterable) -> pd.Index:
|
|
247
251
|
return idx[(idx != "") & (~idx.isnull())]
|
248
252
|
|
249
253
|
|
250
|
-
def _print_values(names:
|
254
|
+
def _print_values(names: list, n: int = 20) -> str:
|
251
255
|
print_values = ", ".join([f"'{name}'" for name in names[:n]])
|
252
256
|
if len(names) > n:
|
253
257
|
print_values += ", ..."
|
@@ -292,8 +296,8 @@ def _filter_bionty_df_columns(model: Registry, public_ontology: Any) -> pd.DataF
|
|
292
296
|
|
293
297
|
|
294
298
|
def _bulk_create_dicts_from_df(
|
295
|
-
keys:
|
296
|
-
) ->
|
299
|
+
keys: set | list, column_name: str, df: pd.DataFrame
|
300
|
+
) -> tuple[dict, str]:
|
297
301
|
"""Get fields from a DataFrame for many rows."""
|
298
302
|
multi_msg = ""
|
299
303
|
if df.index.name != column_name:
|
lamindb/_is_versioned.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
3
|
import lamindb_setup as ln_setup
|
4
4
|
from lamin_utils import logger
|
@@ -12,7 +12,7 @@ from .core.versioning import get_new_path_from_uid, get_uid_from_old_version
|
|
12
12
|
|
13
13
|
# docstring handled through attach_func_to_class_method
|
14
14
|
def add_to_version_family(
|
15
|
-
self, is_new_version_of: IsVersioned, version:
|
15
|
+
self, is_new_version_of: IsVersioned, version: str | None = None
|
16
16
|
):
|
17
17
|
old_uid = self.uid
|
18
18
|
new_uid, version = get_uid_from_old_version(is_new_version_of, version)
|