lamindb 0.69.7__py3-none-any.whl → 0.69.9__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 +66 -70
- lamindb/_can_validate.py +29 -25
- lamindb/_collection.py +30 -34
- 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 +18 -13
- 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 +13 -6
- lamindb/core/storage/object.py +7 -3
- lamindb/core/types.py +0 -2
- lamindb/core/versioning.py +12 -8
- lamindb/integrations/_vitessce.py +2 -0
- lamindb/setup/core/__init__.py +3 -14
- {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/METADATA +5 -5
- lamindb-0.69.9.dist-info/RECORD +54 -0
- lamindb-0.69.7.dist-info/RECORD +0 -54
- {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/LICENSE +0 -0
- {lamindb-0.69.7.dist-info → lamindb-0.69.9.dist-info}/WHEEL +0 -0
lamindb/core/_data.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from collections import defaultdict
|
2
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING, Any, Iterable, List
|
3
5
|
|
4
6
|
from lamin_utils import colors, logger
|
5
7
|
from lamindb_setup.core._docs import doc_args
|
@@ -15,7 +17,6 @@ from lnschema_core.models import (
|
|
15
17
|
__repr__,
|
16
18
|
format_field_value,
|
17
19
|
)
|
18
|
-
from lnschema_core.types import StrField
|
19
20
|
|
20
21
|
from lamindb._feature_set import (
|
21
22
|
dict_related_model_to_related_name,
|
@@ -36,10 +37,13 @@ from ._label_manager import LabelManager, print_labels
|
|
36
37
|
from ._run_context import run_context
|
37
38
|
from .exceptions import ValidationError
|
38
39
|
|
40
|
+
if TYPE_CHECKING:
|
41
|
+
from lnschema_core.types import StrField
|
42
|
+
|
39
43
|
WARNING_RUN_TRANSFORM = "no run & transform get linked, consider calling ln.track()"
|
40
44
|
|
41
45
|
|
42
|
-
def get_run(run:
|
46
|
+
def get_run(run: Run | None) -> Run | None:
|
43
47
|
if run is None:
|
44
48
|
run = run_context.run
|
45
49
|
if run is None and not settings.silence_file_run_transform_warning:
|
@@ -50,12 +54,12 @@ def get_run(run: Optional[Run]) -> Optional[Run]:
|
|
50
54
|
return run
|
51
55
|
|
52
56
|
|
53
|
-
def add_transform_to_kwargs(kwargs:
|
57
|
+
def add_transform_to_kwargs(kwargs: dict[str, Any], run: Run):
|
54
58
|
if run is not None:
|
55
59
|
kwargs["transform"] = run.transform
|
56
60
|
|
57
61
|
|
58
|
-
def save_feature_sets(self:
|
62
|
+
def save_feature_sets(self: Artifact | Collection) -> None:
|
59
63
|
if hasattr(self, "_feature_sets"):
|
60
64
|
saved_feature_sets = {}
|
61
65
|
for key, feature_set in self._feature_sets.items():
|
@@ -73,7 +77,7 @@ def save_feature_sets(self: Union[Artifact, Collection]) -> None:
|
|
73
77
|
)
|
74
78
|
|
75
79
|
|
76
|
-
def save_feature_set_links(self:
|
80
|
+
def save_feature_set_links(self: Artifact | Collection) -> None:
|
77
81
|
from lamindb._save import bulk_create
|
78
82
|
|
79
83
|
Data = self.__class__
|
@@ -141,7 +145,7 @@ def describe(self: Data):
|
|
141
145
|
logger.print(msg)
|
142
146
|
|
143
147
|
|
144
|
-
def validate_feature(feature: Feature, records:
|
148
|
+
def validate_feature(feature: Feature, records: list[Registry]) -> None:
|
145
149
|
"""Validate feature record, set feature.registries based on labels records."""
|
146
150
|
if not isinstance(feature, Feature):
|
147
151
|
raise TypeError("feature has to be of type Feature")
|
@@ -160,7 +164,7 @@ def get_labels(
|
|
160
164
|
feature: Feature,
|
161
165
|
mute: bool = False,
|
162
166
|
flat_names: bool = False,
|
163
|
-
) ->
|
167
|
+
) -> QuerySet | dict[str, QuerySet] | list:
|
164
168
|
"""{}."""
|
165
169
|
if not isinstance(feature, Feature):
|
166
170
|
raise TypeError("feature has to be of type Feature")
|
@@ -202,10 +206,10 @@ def get_labels(
|
|
202
206
|
|
203
207
|
def add_labels(
|
204
208
|
self,
|
205
|
-
records:
|
206
|
-
feature:
|
209
|
+
records: Registry | list[Registry] | QuerySet | Iterable,
|
210
|
+
feature: Feature | None = None,
|
207
211
|
*,
|
208
|
-
field:
|
212
|
+
field: StrField | None = None,
|
209
213
|
) -> None:
|
210
214
|
"""{}."""
|
211
215
|
if self._state.adding:
|
@@ -253,7 +257,7 @@ def add_labels(
|
|
253
257
|
if feature is None:
|
254
258
|
d = dict_related_model_to_related_name(self.__class__)
|
255
259
|
# strategy: group records by registry to reduce number of transactions
|
256
|
-
records_by_related_name:
|
260
|
+
records_by_related_name: dict = {}
|
257
261
|
for record in records:
|
258
262
|
related_name = d.get(record.__class__.__get_name_with_schema__())
|
259
263
|
if related_name is None:
|
@@ -343,9 +347,9 @@ def add_labels(
|
|
343
347
|
|
344
348
|
|
345
349
|
def _track_run_input(
|
346
|
-
data:
|
347
|
-
is_run_input:
|
348
|
-
run:
|
350
|
+
data: Data | Iterable[Data],
|
351
|
+
is_run_input: bool | None = None,
|
352
|
+
run: Run | None = None,
|
349
353
|
):
|
350
354
|
if run is None:
|
351
355
|
run = run_context.run
|
@@ -430,7 +434,7 @@ def _track_run_input(
|
|
430
434
|
|
431
435
|
@property # type: ignore
|
432
436
|
@doc_args(Data.features.__doc__)
|
433
|
-
def features(self) ->
|
437
|
+
def features(self) -> FeatureManager:
|
434
438
|
"""{}."""
|
435
439
|
from lamindb.core._feature_manager import FeatureManager
|
436
440
|
|
@@ -439,7 +443,7 @@ def features(self) -> "FeatureManager":
|
|
439
443
|
|
440
444
|
@property # type: ignore
|
441
445
|
@doc_args(Data.labels.__doc__)
|
442
|
-
def labels(self) ->
|
446
|
+
def labels(self) -> LabelManager:
|
443
447
|
"""{}."""
|
444
448
|
from lamindb.core._label_manager import LabelManager
|
445
449
|
|
lamindb/core/_feature_manager.py
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from itertools import compress
|
2
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING, Iterable
|
3
5
|
|
4
6
|
import anndata as ad
|
5
7
|
from anndata import AnnData
|
6
8
|
from lamin_utils import colors, logger
|
7
9
|
from lamindb_setup.core.upath import create_path
|
8
10
|
from lnschema_core.models import Artifact, Collection, Data, Feature, Registry
|
9
|
-
from lnschema_core.types import AnnDataLike, FieldAttr
|
10
11
|
|
11
12
|
from lamindb._feature import convert_numpy_dtype_to_lamin_feature_type
|
12
13
|
from lamindb._feature_set import FeatureSet
|
13
|
-
from lamindb._query_set import QuerySet
|
14
14
|
from lamindb._registry import (
|
15
15
|
REGISTRY_UNIQUE_FIELD,
|
16
16
|
get_default_str_field,
|
@@ -22,8 +22,13 @@ from lamindb.core.storage import LocalPathClasses
|
|
22
22
|
|
23
23
|
from ._settings import settings
|
24
24
|
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from lnschema_core.types import FieldAttr
|
27
|
+
|
28
|
+
from lamindb._query_set import QuerySet
|
29
|
+
|
25
30
|
|
26
|
-
def get_host_id_field(host:
|
31
|
+
def get_host_id_field(host: Artifact | Collection) -> str:
|
27
32
|
if isinstance(host, Artifact):
|
28
33
|
host_id_field = "artifact_id"
|
29
34
|
else:
|
@@ -31,7 +36,7 @@ def get_host_id_field(host: Union[Artifact, Collection]) -> str:
|
|
31
36
|
return host_id_field
|
32
37
|
|
33
38
|
|
34
|
-
def get_accessor_by_orm(host:
|
39
|
+
def get_accessor_by_orm(host: Artifact | Collection) -> dict:
|
35
40
|
dictionary = {
|
36
41
|
field.related_model.__get_name_with_schema__(): field.name
|
37
42
|
for field in host._meta.related_objects
|
@@ -41,7 +46,7 @@ def get_accessor_by_orm(host: Union[Artifact, Collection]) -> Dict:
|
|
41
46
|
return dictionary
|
42
47
|
|
43
48
|
|
44
|
-
def get_feature_set_by_slot(host) ->
|
49
|
+
def get_feature_set_by_slot(host) -> dict:
|
45
50
|
# if the host is not yet saved
|
46
51
|
if host._state.adding:
|
47
52
|
if hasattr(host, "_feature_sets"):
|
@@ -64,7 +69,7 @@ def get_feature_set_by_slot(host) -> Dict:
|
|
64
69
|
|
65
70
|
|
66
71
|
def get_label_links(
|
67
|
-
host:
|
72
|
+
host: Artifact | Collection, registry: str, feature: Feature
|
68
73
|
) -> QuerySet:
|
69
74
|
host_id_field = get_host_id_field(host)
|
70
75
|
kwargs = {host_id_field: host.id, "feature_id": feature.id}
|
@@ -76,7 +81,7 @@ def get_label_links(
|
|
76
81
|
return link_records
|
77
82
|
|
78
83
|
|
79
|
-
def get_feature_set_links(host:
|
84
|
+
def get_feature_set_links(host: Artifact | Collection) -> QuerySet:
|
80
85
|
host_id_field = get_host_id_field(host)
|
81
86
|
kwargs = {host_id_field: host.id}
|
82
87
|
feature_set_links = host.feature_sets.through.objects.filter(**kwargs)
|
@@ -127,11 +132,11 @@ def print_features(self: Data) -> str:
|
|
127
132
|
|
128
133
|
|
129
134
|
def parse_feature_sets_from_anndata(
|
130
|
-
adata:
|
135
|
+
adata: AnnData,
|
131
136
|
var_field: FieldAttr,
|
132
137
|
obs_field: FieldAttr = Feature.name,
|
133
138
|
**kwargs,
|
134
|
-
) ->
|
139
|
+
) -> dict:
|
135
140
|
data_parse = adata
|
136
141
|
if not isinstance(adata, AnnData): # is a path
|
137
142
|
filepath = create_path(adata) # returns Path for local
|
@@ -183,7 +188,7 @@ class FeatureManager:
|
|
183
188
|
See :class:`~lamindb.core.Data` for more information.
|
184
189
|
"""
|
185
190
|
|
186
|
-
def __init__(self, host:
|
191
|
+
def __init__(self, host: Artifact | Collection):
|
187
192
|
self._host = host
|
188
193
|
self._feature_set_by_slot = get_feature_set_by_slot(host)
|
189
194
|
self._accessor_by_orm = get_accessor_by_orm(host)
|
@@ -210,7 +215,7 @@ class FeatureManager:
|
|
210
215
|
else:
|
211
216
|
return getattr(feature_set, self._accessor_by_orm[orm_name]).all()
|
212
217
|
|
213
|
-
def add(self, features: Iterable[Registry], slot:
|
218
|
+
def add(self, features: Iterable[Registry], slot: str | None = None):
|
214
219
|
"""Add features stratified by slot."""
|
215
220
|
if (hasattr(self._host, "accessor") and self._host.accessor == "DataFrame") or (
|
216
221
|
hasattr(self._host, "artifact")
|
@@ -246,7 +251,7 @@ class FeatureManager:
|
|
246
251
|
def add_from_anndata(
|
247
252
|
self,
|
248
253
|
var_field: FieldAttr,
|
249
|
-
obs_field:
|
254
|
+
obs_field: FieldAttr | None = Feature.name,
|
250
255
|
**kwargs,
|
251
256
|
):
|
252
257
|
"""Add features from AnnData."""
|
lamindb/core/_label_manager.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Dict
|
2
4
|
|
3
5
|
import numpy as np
|
4
6
|
from lamin_utils import colors, logger
|
@@ -6,7 +8,6 @@ from lnschema_core.models import Artifact, Collection, Data, Feature, Registry
|
|
6
8
|
|
7
9
|
from lamindb._feature_set import dict_related_model_to_related_name
|
8
10
|
from lamindb._from_values import _print_values
|
9
|
-
from lamindb._query_set import QuerySet
|
10
11
|
from lamindb._registry import (
|
11
12
|
REGISTRY_UNIQUE_FIELD,
|
12
13
|
get_default_str_field,
|
@@ -17,6 +18,9 @@ from lamindb._save import save
|
|
17
18
|
|
18
19
|
from ._settings import settings
|
19
20
|
|
21
|
+
if TYPE_CHECKING:
|
22
|
+
from lamindb._query_set import QuerySet
|
23
|
+
|
20
24
|
|
21
25
|
def get_labels_as_dict(self: Data):
|
22
26
|
labels = {}
|
@@ -80,10 +84,10 @@ def transfer_add_labels(labels, features_lookup_self, self, row, parents: bool =
|
|
80
84
|
transfer_single_registry(*result)
|
81
85
|
|
82
86
|
|
83
|
-
def validate_labels(labels:
|
87
|
+
def validate_labels(labels: QuerySet | list | dict, parents: bool = True):
|
84
88
|
def validate_labels_registry(
|
85
|
-
labels:
|
86
|
-
) ->
|
89
|
+
labels: QuerySet | list | dict, parents: bool = True
|
90
|
+
) -> tuple[list[str], list[str]]:
|
87
91
|
if len(labels) == 0:
|
88
92
|
return [], []
|
89
93
|
registry = labels[0].__class__
|
@@ -134,7 +138,7 @@ class LabelManager:
|
|
134
138
|
See :class:`~lamindb.core.Data` for more information.
|
135
139
|
"""
|
136
140
|
|
137
|
-
def __init__(self, host:
|
141
|
+
def __init__(self, host: Artifact | Collection):
|
138
142
|
self._host = host
|
139
143
|
|
140
144
|
def __repr__(self) -> str:
|
@@ -146,8 +150,8 @@ class LabelManager:
|
|
146
150
|
|
147
151
|
def add(
|
148
152
|
self,
|
149
|
-
records:
|
150
|
-
feature:
|
153
|
+
records: Registry | list[Registry] | QuerySet,
|
154
|
+
feature: Feature | None = None,
|
151
155
|
) -> None:
|
152
156
|
"""Add one or several labels and associate them with a feature.
|
153
157
|
|
@@ -165,7 +169,7 @@ class LabelManager:
|
|
165
169
|
feature: Feature,
|
166
170
|
mute: bool = False,
|
167
171
|
flat_names: bool = False,
|
168
|
-
) ->
|
172
|
+
) -> QuerySet | dict[str, QuerySet] | list:
|
169
173
|
"""Get labels given a feature.
|
170
174
|
|
171
175
|
Args:
|
@@ -1,12 +1,13 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from collections import Counter
|
2
4
|
from functools import reduce
|
3
5
|
from pathlib import Path
|
4
|
-
from typing import Dict, List, Literal, Optional, Union
|
6
|
+
from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
|
5
7
|
|
6
8
|
import numpy as np
|
7
9
|
import pandas as pd
|
8
10
|
from lamin_utils import logger
|
9
|
-
from lamindb_setup.core.types import UPathStr
|
10
11
|
from lamindb_setup.core.upath import UPath
|
11
12
|
|
12
13
|
from .storage._backed_access import (
|
@@ -17,6 +18,9 @@ from .storage._backed_access import (
|
|
17
18
|
registry,
|
18
19
|
)
|
19
20
|
|
21
|
+
if TYPE_CHECKING:
|
22
|
+
from lamindb_setup.core.types import UPathStr
|
23
|
+
|
20
24
|
|
21
25
|
class _Connect:
|
22
26
|
def __init__(self, storage):
|
@@ -81,14 +85,14 @@ class MappedCollection:
|
|
81
85
|
|
82
86
|
def __init__(
|
83
87
|
self,
|
84
|
-
path_list:
|
85
|
-
label_keys:
|
86
|
-
join:
|
87
|
-
encode_labels:
|
88
|
-
unknown_label:
|
88
|
+
path_list: list[UPathStr],
|
89
|
+
label_keys: str | list[str] | None = None,
|
90
|
+
join: Literal["inner", "outer"] | None = "inner",
|
91
|
+
encode_labels: bool | list[str] = True,
|
92
|
+
unknown_label: str | dict[str, str] | None = None,
|
89
93
|
cache_categories: bool = True,
|
90
94
|
parallel: bool = False,
|
91
|
-
dtype:
|
95
|
+
dtype: str | None = None,
|
92
96
|
):
|
93
97
|
assert join in {None, "inner", "outer"}
|
94
98
|
|
@@ -248,8 +252,8 @@ class MappedCollection:
|
|
248
252
|
self,
|
249
253
|
storage: StorageType, # type: ignore
|
250
254
|
idx: int,
|
251
|
-
var_idxs_join:
|
252
|
-
layer_key:
|
255
|
+
var_idxs_join: list | None = None,
|
256
|
+
layer_key: str | None = None,
|
253
257
|
):
|
254
258
|
"""Get the index for the data."""
|
255
259
|
layer = storage["X"] if layer_key is None else storage["layers"][layer_key] # type: ignore
|
@@ -290,7 +294,7 @@ class MappedCollection:
|
|
290
294
|
storage: StorageType,
|
291
295
|
idx: int,
|
292
296
|
label_key: str,
|
293
|
-
categories:
|
297
|
+
categories: list | None = None,
|
294
298
|
):
|
295
299
|
"""Get the index for the label by key."""
|
296
300
|
obs = storage["obs"] # type: ignore
|
@@ -313,7 +317,7 @@ class MappedCollection:
|
|
313
317
|
label = label.decode("utf-8")
|
314
318
|
return label
|
315
319
|
|
316
|
-
def get_label_weights(self, label_keys:
|
320
|
+
def get_label_weights(self, label_keys: str | list[str]):
|
317
321
|
"""Get all weights for the given label keys."""
|
318
322
|
if isinstance(label_keys, str):
|
319
323
|
label_keys = [label_keys]
|
lamindb/core/_run_context.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import builtins
|
2
4
|
import hashlib
|
3
5
|
import os
|
@@ -6,12 +8,11 @@ import subprocess
|
|
6
8
|
import sys
|
7
9
|
from datetime import datetime, timezone
|
8
10
|
from pathlib import Path, PurePath
|
9
|
-
from typing import
|
11
|
+
from typing import TYPE_CHECKING, Any
|
10
12
|
|
11
13
|
from lamin_utils import logger
|
12
14
|
from lamindb_setup import settings as setup_settings
|
13
15
|
from lamindb_setup.core import InstanceSettings
|
14
|
-
from lamindb_setup.core.types import UPathStr
|
15
16
|
from lnschema_core import Run, Transform, ids
|
16
17
|
from lnschema_core.types import TransformType
|
17
18
|
from lnschema_core.users import current_user_id
|
@@ -21,6 +22,9 @@ from lamindb.core._transform_settings import transform as transform_settings
|
|
21
22
|
from ._settings import settings
|
22
23
|
from ._sync_git import get_transform_reference_from_git_repo
|
23
24
|
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from lamindb_setup.core.types import UPathStr
|
27
|
+
|
24
28
|
is_run_from_ipython = getattr(builtins, "__IPYTHON__", False)
|
25
29
|
|
26
30
|
msg_path_failed = (
|
@@ -55,7 +59,7 @@ def get_uid_ext(version: str) -> str:
|
|
55
59
|
return encodebytes(hashlib.md5(version.encode()).digest())[:4]
|
56
60
|
|
57
61
|
|
58
|
-
def get_stem_uid_and_version_from_file(file_path: Path) ->
|
62
|
+
def get_stem_uid_and_version_from_file(file_path: Path) -> tuple[str, str]:
|
59
63
|
# line-by-line matching might be faster, but let's go with this for now
|
60
64
|
with open(file_path) as file:
|
61
65
|
content = file.read()
|
@@ -215,20 +219,20 @@ def raise_transform_settings_error() -> None:
|
|
215
219
|
class run_context:
|
216
220
|
"""Global run context."""
|
217
221
|
|
218
|
-
transform:
|
222
|
+
transform: Transform | None = None
|
219
223
|
"""Current transform."""
|
220
|
-
run:
|
224
|
+
run: Run | None = None
|
221
225
|
"""Current run."""
|
222
|
-
path:
|
226
|
+
path: Path | None = None
|
223
227
|
"""A local path to the script that's running."""
|
224
228
|
|
225
229
|
@classmethod
|
226
230
|
def _track(
|
227
231
|
cls,
|
228
232
|
*,
|
229
|
-
transform:
|
230
|
-
new_run:
|
231
|
-
path:
|
233
|
+
transform: Transform | None = None,
|
234
|
+
new_run: bool | None = None,
|
235
|
+
path: str | None = None,
|
232
236
|
) -> None:
|
233
237
|
"""Track notebook or script run.
|
234
238
|
|
@@ -364,8 +368,8 @@ class run_context:
|
|
364
368
|
def _track_script(
|
365
369
|
cls,
|
366
370
|
*,
|
367
|
-
path:
|
368
|
-
) ->
|
371
|
+
path: UPathStr | None,
|
372
|
+
) -> tuple[str, str, str, str]:
|
369
373
|
if path is None:
|
370
374
|
import inspect
|
371
375
|
|
@@ -387,7 +391,7 @@ class run_context:
|
|
387
391
|
def _track_notebook(
|
388
392
|
cls,
|
389
393
|
*,
|
390
|
-
path:
|
394
|
+
path: str | None,
|
391
395
|
):
|
392
396
|
if path is None:
|
393
397
|
path = get_notebook_path()
|
@@ -442,13 +446,13 @@ class run_context:
|
|
442
446
|
cls,
|
443
447
|
*,
|
444
448
|
stem_uid: str,
|
445
|
-
version:
|
449
|
+
version: str | None,
|
446
450
|
name: str,
|
447
|
-
transform_ref:
|
448
|
-
transform_ref_type:
|
449
|
-
key:
|
451
|
+
transform_ref: str | None = None,
|
452
|
+
transform_ref_type: str | None = None,
|
453
|
+
key: str | None = None,
|
450
454
|
transform_type: TransformType = None,
|
451
|
-
transform:
|
455
|
+
transform: Transform | None = None,
|
452
456
|
):
|
453
457
|
# make a new transform record
|
454
458
|
if transform is None:
|
lamindb/core/_settings.py
CHANGED
@@ -1,16 +1,21 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
|
-
from
|
3
|
-
from typing import Dict, Literal, Mapping, Optional, Tuple, Union
|
4
|
+
from typing import TYPE_CHECKING, Literal, Mapping
|
4
5
|
|
5
6
|
import lamindb_setup as ln_setup
|
6
7
|
from lamin_utils import logger
|
7
8
|
from lamindb_setup._add_remote_storage import switch_default_storage
|
8
9
|
from lamindb_setup.core._settings import settings as setup_settings
|
9
10
|
from lamindb_setup.core._settings_instance import sanitize_git_repo_url
|
10
|
-
from upath import UPath
|
11
11
|
|
12
12
|
from ._transform_settings import TransformSettings, transform
|
13
13
|
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from pathlib import Path
|
16
|
+
|
17
|
+
from upath import UPath
|
18
|
+
|
14
19
|
VERBOSITY_TO_INT = {
|
15
20
|
"error": 0, # 40
|
16
21
|
"warning": 1, # 30
|
@@ -19,7 +24,7 @@ VERBOSITY_TO_INT = {
|
|
19
24
|
"hint": 4, # 15
|
20
25
|
"debug": 5, # 10
|
21
26
|
}
|
22
|
-
VERBOSITY_TO_STR:
|
27
|
+
VERBOSITY_TO_STR: dict[int, str] = dict(
|
23
28
|
[reversed(i) for i in VERBOSITY_TO_INT.items()] # type: ignore
|
24
29
|
)
|
25
30
|
|
@@ -30,10 +35,10 @@ class Settings:
|
|
30
35
|
Use ``lamindb.settings`` instead of instantiating this class yourself.
|
31
36
|
"""
|
32
37
|
|
33
|
-
def __init__(self, git_repo:
|
38
|
+
def __init__(self, git_repo: str | None):
|
34
39
|
self._verbosity_int: int = 1 # warning-level logging
|
35
40
|
logger.set_verbosity(self._verbosity_int)
|
36
|
-
self._sync_git_repo:
|
41
|
+
self._sync_git_repo: str | None = git_repo
|
37
42
|
|
38
43
|
upon_artifact_create_if_hash_exists: Literal[
|
39
44
|
"warn_return_existing", "error", "warn_create_new"
|
@@ -73,16 +78,16 @@ class Settings:
|
|
73
78
|
If `True`, the `key` is **not** used to construct file paths, but file paths are
|
74
79
|
based on the `uid` of artifact.
|
75
80
|
"""
|
76
|
-
__using_key:
|
77
|
-
_using_storage:
|
81
|
+
__using_key: str | None = None
|
82
|
+
_using_storage: str | None = None
|
78
83
|
|
79
84
|
@property
|
80
|
-
def _using_key(self) ->
|
85
|
+
def _using_key(self) -> str | None:
|
81
86
|
"""Key for Django database settings."""
|
82
87
|
return self.__using_key
|
83
88
|
|
84
89
|
@_using_key.setter
|
85
|
-
def _using_key(self, value:
|
90
|
+
def _using_key(self, value: str | None):
|
86
91
|
ln_setup.settings._using_key = value
|
87
92
|
self.__using_key = value
|
88
93
|
|
@@ -100,7 +105,7 @@ class Settings:
|
|
100
105
|
return transform
|
101
106
|
|
102
107
|
@property
|
103
|
-
def sync_git_repo(self) ->
|
108
|
+
def sync_git_repo(self) -> str | None:
|
104
109
|
"""Sync transforms with scripts in git repository.
|
105
110
|
|
106
111
|
Provide the full git repo URL.
|
@@ -117,7 +122,7 @@ class Settings:
|
|
117
122
|
assert self._sync_git_repo.startswith("https://")
|
118
123
|
|
119
124
|
@property
|
120
|
-
def storage(self) ->
|
125
|
+
def storage(self) -> Path | UPath:
|
121
126
|
"""Default storage location (a path to its root).
|
122
127
|
|
123
128
|
Examples:
|
@@ -137,9 +142,7 @@ class Settings:
|
|
137
142
|
return self._storage_settings.root
|
138
143
|
|
139
144
|
@storage.setter
|
140
|
-
def storage(
|
141
|
-
self, path_kwargs: Union[str, Path, UPath, Tuple[Union[str, UPath], Mapping]]
|
142
|
-
):
|
145
|
+
def storage(self, path_kwargs: str | Path | UPath | tuple[str | UPath, Mapping]):
|
143
146
|
logger.warning(
|
144
147
|
"you'll no longer be able to set arbitrary storage locations soon"
|
145
148
|
)
|
@@ -165,7 +168,7 @@ class Settings:
|
|
165
168
|
return VERBOSITY_TO_STR[self._verbosity_int]
|
166
169
|
|
167
170
|
@verbosity.setter
|
168
|
-
def verbosity(self, verbosity:
|
171
|
+
def verbosity(self, verbosity: str | int):
|
169
172
|
if isinstance(verbosity, str):
|
170
173
|
verbosity_int = VERBOSITY_TO_INT[verbosity]
|
171
174
|
else:
|
lamindb/core/_sync_git.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import subprocess
|
2
4
|
from pathlib import Path
|
3
|
-
from typing import Optional
|
4
5
|
|
5
6
|
from lamin_utils import logger
|
6
7
|
from lamindb_setup import settings as setup_settings
|
@@ -52,9 +53,7 @@ def check_local_git_repo() -> bool:
|
|
52
53
|
return False
|
53
54
|
|
54
55
|
|
55
|
-
def get_git_commit_hash(
|
56
|
-
blob_hash: str, repo_dir: Optional[Path] = None
|
57
|
-
) -> Optional[str]:
|
56
|
+
def get_git_commit_hash(blob_hash: str, repo_dir: Path | None = None) -> str | None:
|
58
57
|
command = f"git log --find-object={blob_hash} --pretty=format:%H"
|
59
58
|
result = subprocess.run(
|
60
59
|
command,
|
@@ -71,7 +70,7 @@ def get_git_commit_hash(
|
|
71
70
|
|
72
71
|
|
73
72
|
def get_filepath_within_git_repo(
|
74
|
-
commit_hash: str, blob_hash: str, repo_dir:
|
73
|
+
commit_hash: str, blob_hash: str, repo_dir: Path | None
|
75
74
|
) -> str:
|
76
75
|
# repo_dir might not point to the root of the
|
77
76
|
# the git repository because git log --find-object works
|
@@ -1,8 +1,13 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import subprocess
|
4
|
+
from typing import TYPE_CHECKING
|
2
5
|
|
3
6
|
import lamindb_setup as ln_setup
|
4
7
|
from lamin_utils import logger
|
5
|
-
|
8
|
+
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from lnschema_core.models import Run
|
6
11
|
|
7
12
|
|
8
13
|
def track_environment(run: Run) -> None:
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
3
|
|
4
4
|
class TransformSettings:
|
5
|
-
stem_uid:
|
6
|
-
version:
|
5
|
+
stem_uid: None | None = None
|
6
|
+
version: None | None = None
|
7
7
|
|
8
8
|
|
9
9
|
transform = TransformSettings()
|
lamindb/core/_view_tree.py
CHANGED
lamindb/core/datasets/_core.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from pathlib import Path
|
2
|
-
from typing import Union
|
3
4
|
from urllib.request import urlretrieve
|
4
5
|
|
5
6
|
import anndata as ad
|
@@ -448,7 +449,7 @@ def df_iris_in_meter_study2() -> pd.DataFrame:
|
|
448
449
|
|
449
450
|
|
450
451
|
def dir_scrnaseq_cellranger(
|
451
|
-
sample_name: str, basedir:
|
452
|
+
sample_name: str, basedir: str | Path = "./", output_only: bool = True
|
452
453
|
): # pragma: no cover
|
453
454
|
"""Generate mock cell ranger outputs.
|
454
455
|
|
lamindb/core/datasets/_fake.py
CHANGED