lamindb 0.69.6__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 +32 -19
- 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.6.dist-info → lamindb-0.69.8.dist-info}/METADATA +6 -5
- lamindb-0.69.8.dist-info/RECORD +54 -0
- lamindb-0.69.6.dist-info/RECORD +0 -54
- {lamindb-0.69.6.dist-info → lamindb-0.69.8.dist-info}/LICENSE +0 -0
- {lamindb-0.69.6.dist-info → lamindb-0.69.8.dist-info}/WHEEL +0 -0
lamindb/_parents.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import builtins
|
2
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING
|
3
5
|
|
4
6
|
import lamindb_setup as ln_setup
|
5
7
|
from lamin_utils import logger
|
@@ -8,7 +10,10 @@ from lnschema_core.models import HasParents, format_field_value
|
|
8
10
|
|
9
11
|
from lamindb._utils import attach_func_to_class_method
|
10
12
|
|
11
|
-
from ._registry import
|
13
|
+
from ._registry import get_default_str_field
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from lnschema_core.types import StrField
|
12
17
|
|
13
18
|
LAMIN_GREEN_LIGHTER = "#10b981"
|
14
19
|
LAMIN_GREEN_DARKER = "#065f46"
|
@@ -47,7 +52,7 @@ def _view(u):
|
|
47
52
|
|
48
53
|
def view_parents(
|
49
54
|
self,
|
50
|
-
field:
|
55
|
+
field: StrField | None = None,
|
51
56
|
with_children: bool = False,
|
52
57
|
distance: int = 5,
|
53
58
|
):
|
@@ -61,7 +66,7 @@ def view_parents(
|
|
61
66
|
)
|
62
67
|
|
63
68
|
|
64
|
-
def view_lineage(data:
|
69
|
+
def view_lineage(data: Artifact | Collection, with_children: bool = True) -> None:
|
65
70
|
"""Graph of data flow.
|
66
71
|
|
67
72
|
Notes:
|
@@ -81,7 +86,7 @@ def view_lineage(data: Union[Artifact, Collection], with_children: bool = True)
|
|
81
86
|
data_label = _record_label(data)
|
82
87
|
|
83
88
|
def add_node(
|
84
|
-
record:
|
89
|
+
record: Run | Artifact | Collection,
|
85
90
|
node_id: str,
|
86
91
|
node_label: str,
|
87
92
|
u: graphviz.Digraph,
|
@@ -256,7 +261,7 @@ def _df_edges_from_parents(
|
|
256
261
|
return df_edges
|
257
262
|
|
258
263
|
|
259
|
-
def _record_label(record: Registry, field:
|
264
|
+
def _record_label(record: Registry, field: str | None = None):
|
260
265
|
if isinstance(record, Artifact):
|
261
266
|
if record.description is None:
|
262
267
|
name = record.key
|
@@ -310,7 +315,7 @@ def _add_emoji(record: Registry, label: str):
|
|
310
315
|
return f"{emoji} {label}"
|
311
316
|
|
312
317
|
|
313
|
-
def _get_all_parent_runs(data:
|
318
|
+
def _get_all_parent_runs(data: Artifact | Collection) -> list:
|
314
319
|
"""Get all input file/collection runs recursively."""
|
315
320
|
name = data._meta.model_name
|
316
321
|
run_inputs_outputs = []
|
@@ -346,10 +351,10 @@ def _get_all_parent_runs(data: Union[Artifact, Collection]) -> List:
|
|
346
351
|
return run_inputs_outputs
|
347
352
|
|
348
353
|
|
349
|
-
def _get_all_child_runs(data:
|
354
|
+
def _get_all_child_runs(data: Artifact | Collection) -> list:
|
350
355
|
"""Get all output file/collection runs recursively."""
|
351
356
|
name = data._meta.model_name
|
352
|
-
all_runs:
|
357
|
+
all_runs: set[Run] = set()
|
353
358
|
run_inputs_outputs = []
|
354
359
|
|
355
360
|
if data.run is not None:
|
@@ -367,7 +372,7 @@ def _get_all_child_runs(data: Union[Artifact, Collection]) -> List:
|
|
367
372
|
)
|
368
373
|
while runs.difference(all_runs):
|
369
374
|
all_runs.update(runs)
|
370
|
-
child_runs:
|
375
|
+
child_runs: set[Run] = set()
|
371
376
|
for r in runs:
|
372
377
|
inputs_run = (
|
373
378
|
r.__getattribute__(f"input_{name}s")
|
@@ -409,7 +414,7 @@ def _get_all_child_runs(data: Union[Artifact, Collection]) -> List:
|
|
409
414
|
return run_inputs_outputs
|
410
415
|
|
411
416
|
|
412
|
-
def _df_edges_from_runs(df_values:
|
417
|
+
def _df_edges_from_runs(df_values: list):
|
413
418
|
import pandas as pd
|
414
419
|
|
415
420
|
df = pd.DataFrame(df_values, columns=["source_record", "target_record"])
|
lamindb/_query_manager.py
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, NamedTuple
|
2
4
|
|
3
5
|
from django.db import models
|
4
6
|
from lamin_utils import logger
|
5
7
|
from lamindb_setup.core._docs import doc_args
|
6
8
|
from lnschema_core.models import Registry
|
7
|
-
from lnschema_core.types import StrField
|
8
9
|
|
9
10
|
from .core._feature_manager import get_feature_set_by_slot
|
10
11
|
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from lnschema_core.types import StrField
|
14
|
+
|
11
15
|
|
12
16
|
class QueryManager(models.Manager):
|
13
17
|
"""Manage queries through fields.
|
@@ -41,7 +45,7 @@ class QueryManager(models.Manager):
|
|
41
45
|
logger.warning(WARNING_RUN_TRANSFORM)
|
42
46
|
_track_run_input(self.instance)
|
43
47
|
|
44
|
-
def list(self, field:
|
48
|
+
def list(self, field: str | None = None):
|
45
49
|
"""Populate a list with the results.
|
46
50
|
|
47
51
|
Examples:
|
@@ -83,7 +87,7 @@ class QueryManager(models.Manager):
|
|
83
87
|
return _search(cls=self.all(), string=string, **kwargs)
|
84
88
|
|
85
89
|
@doc_args(Registry.lookup.__doc__)
|
86
|
-
def lookup(self, field:
|
90
|
+
def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
|
87
91
|
"""{}."""
|
88
92
|
from ._registry import _lookup
|
89
93
|
|
lamindb/_query_set.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from collections import UserList
|
2
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING, Iterable, NamedTuple
|
3
5
|
|
4
6
|
import pandas as pd
|
5
7
|
from django.db import models
|
@@ -15,7 +17,9 @@ from lnschema_core.models import (
|
|
15
17
|
Run,
|
16
18
|
Transform,
|
17
19
|
)
|
18
|
-
|
20
|
+
|
21
|
+
if TYPE_CHECKING:
|
22
|
+
from lnschema_core.types import ListLike, StrField
|
19
23
|
|
20
24
|
|
21
25
|
class NoResultFound(Exception):
|
@@ -32,7 +36,7 @@ class MultipleResultsFound(Exception):
|
|
32
36
|
# return (series + timedelta).dt.strftime("%Y-%m-%d %H:%M:%S %Z")
|
33
37
|
|
34
38
|
|
35
|
-
def get_keys_from_df(data:
|
39
|
+
def get_keys_from_df(data: list, registry: Registry) -> list[str]:
|
36
40
|
if len(data) > 0:
|
37
41
|
if isinstance(data[0], dict):
|
38
42
|
keys = list(data[0].keys())
|
@@ -94,7 +98,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
94
98
|
"""
|
95
99
|
|
96
100
|
@doc_args(Registry.df.__doc__)
|
97
|
-
def df(self, include:
|
101
|
+
def df(self, include: str | list[str] | None = None) -> pd.DataFrame:
|
98
102
|
"""{}."""
|
99
103
|
data = self.values()
|
100
104
|
keys = get_keys_from_df(data, self.model)
|
@@ -173,7 +177,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
173
177
|
else:
|
174
178
|
self._delete_base_class(*args, **kwargs)
|
175
179
|
|
176
|
-
def list(self, field:
|
180
|
+
def list(self, field: str | None = None) -> list[Registry]:
|
177
181
|
"""Populate a list with the results.
|
178
182
|
|
179
183
|
Examples:
|
@@ -185,7 +189,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
185
189
|
else:
|
186
190
|
return list(self.values_list(field, flat=True))
|
187
191
|
|
188
|
-
def first(self) ->
|
192
|
+
def first(self) -> Registry | None:
|
189
193
|
"""If non-empty, the first result in the query set, otherwise ``None``.
|
190
194
|
|
191
195
|
Examples:
|
@@ -203,7 +207,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
203
207
|
"""
|
204
208
|
return one_helper(self)
|
205
209
|
|
206
|
-
def one_or_none(self) ->
|
210
|
+
def one_or_none(self) -> Registry | None:
|
207
211
|
"""At most one result. Returns it if there is one, otherwise returns ``None``.
|
208
212
|
|
209
213
|
Examples:
|
@@ -232,25 +236,21 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
232
236
|
return _search(cls=self, string=string, **kwargs)
|
233
237
|
|
234
238
|
@doc_args(Registry.lookup.__doc__)
|
235
|
-
def lookup(self, field:
|
239
|
+
def lookup(self, field: StrField | None = None, **kwargs) -> NamedTuple:
|
236
240
|
"""{}."""
|
237
241
|
from ._registry import _lookup
|
238
242
|
|
239
243
|
return _lookup(cls=self, field=field, **kwargs)
|
240
244
|
|
241
245
|
@doc_args(CanValidate.validate.__doc__)
|
242
|
-
def validate(
|
243
|
-
self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
|
244
|
-
):
|
246
|
+
def validate(self, values: ListLike, field: str | StrField | None = None, **kwargs):
|
245
247
|
"""{}."""
|
246
248
|
from ._can_validate import _validate
|
247
249
|
|
248
250
|
return _validate(cls=self, values=values, field=field, **kwargs)
|
249
251
|
|
250
252
|
@doc_args(CanValidate.inspect.__doc__)
|
251
|
-
def inspect(
|
252
|
-
self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
|
253
|
-
):
|
253
|
+
def inspect(self, values: ListLike, field: str | StrField | None = None, **kwargs):
|
254
254
|
"""{}."""
|
255
255
|
from ._can_validate import _inspect
|
256
256
|
|
@@ -258,7 +258,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
|
|
258
258
|
|
259
259
|
@doc_args(CanValidate.standardize.__doc__)
|
260
260
|
def standardize(
|
261
|
-
self, values: Iterable, field:
|
261
|
+
self, values: Iterable, field: str | StrField | None = None, **kwargs
|
262
262
|
):
|
263
263
|
"""{}."""
|
264
264
|
from ._can_validate import _standardize
|
lamindb/_registry.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import builtins
|
2
|
-
from typing import Iterable, List, NamedTuple
|
4
|
+
from typing import TYPE_CHECKING, Iterable, List, NamedTuple
|
3
5
|
from uuid import UUID
|
4
6
|
|
5
7
|
import dj_database_url
|
@@ -17,13 +19,15 @@ from lamindb_setup.core._docs import doc_args
|
|
17
19
|
from lamindb_setup.core._hub_core import connect_instance
|
18
20
|
from lamindb_setup.core._settings_storage import StorageSettings
|
19
21
|
from lnschema_core import Registry
|
20
|
-
from lnschema_core.types import ListLike, StrField
|
21
22
|
|
22
23
|
from lamindb._utils import attach_func_to_class_method
|
23
24
|
from lamindb.core._settings import settings
|
24
25
|
|
25
26
|
from ._from_values import get_or_create_records
|
26
27
|
|
28
|
+
if TYPE_CHECKING:
|
29
|
+
from lnschema_core.types import ListLike, StrField
|
30
|
+
|
27
31
|
IPYTHON = getattr(builtins, "__IPYTHON__", False)
|
28
32
|
|
29
33
|
|
@@ -53,7 +57,7 @@ def validate_required_fields(orm: Registry, kwargs):
|
|
53
57
|
raise TypeError(f"{missing_fields} are required.")
|
54
58
|
|
55
59
|
|
56
|
-
def suggest_objects_with_same_name(orm: Registry, kwargs) ->
|
60
|
+
def suggest_objects_with_same_name(orm: Registry, kwargs) -> str | None:
|
57
61
|
if kwargs.get("name") is None:
|
58
62
|
return None
|
59
63
|
else:
|
@@ -125,8 +129,8 @@ def __init__(orm: Registry, *args, **kwargs):
|
|
125
129
|
@classmethod # type:ignore
|
126
130
|
@doc_args(Registry.from_values.__doc__)
|
127
131
|
def from_values(
|
128
|
-
cls, values: ListLike, field:
|
129
|
-
) ->
|
132
|
+
cls, values: ListLike, field: StrField | None = None, **kwargs
|
133
|
+
) -> list[Registry]:
|
130
134
|
"""{}."""
|
131
135
|
from_public = True if cls.__module__.startswith("lnschema_bionty.") else False
|
132
136
|
field_str = get_default_str_field(cls, field=field)
|
@@ -150,21 +154,21 @@ def _search(
|
|
150
154
|
cls,
|
151
155
|
string: str,
|
152
156
|
*,
|
153
|
-
field:
|
154
|
-
limit:
|
157
|
+
field: StrField | list[StrField] | None = None,
|
158
|
+
limit: int | None = 10,
|
155
159
|
return_queryset: bool = False,
|
156
160
|
case_sensitive: bool = False,
|
157
|
-
synonyms_field:
|
158
|
-
using_key:
|
159
|
-
) ->
|
161
|
+
synonyms_field: StrField | None = "synonyms",
|
162
|
+
using_key: str | None = None,
|
163
|
+
) -> pd.DataFrame | QuerySet:
|
160
164
|
queryset = _queryset(cls, using_key=using_key)
|
161
165
|
orm = queryset.model
|
162
166
|
|
163
167
|
def _search_single_field(
|
164
168
|
string: str,
|
165
|
-
field:
|
166
|
-
synonyms_field:
|
167
|
-
) ->
|
169
|
+
field: StrField | None,
|
170
|
+
synonyms_field: StrField | None = "synonyms",
|
171
|
+
) -> pd.DataFrame:
|
168
172
|
field = get_default_str_field(orm=orm, field=field)
|
169
173
|
|
170
174
|
try:
|
@@ -233,12 +237,12 @@ def search(
|
|
233
237
|
cls,
|
234
238
|
string: str,
|
235
239
|
*,
|
236
|
-
field:
|
237
|
-
limit:
|
240
|
+
field: StrField | None = None,
|
241
|
+
limit: int | None = 20,
|
238
242
|
return_queryset: bool = False,
|
239
243
|
case_sensitive: bool = False,
|
240
|
-
synonyms_field:
|
241
|
-
) ->
|
244
|
+
synonyms_field: StrField | None = "synonyms",
|
245
|
+
) -> pd.DataFrame | QuerySet:
|
242
246
|
"""{}."""
|
243
247
|
return _search(
|
244
248
|
cls=cls,
|
@@ -253,9 +257,9 @@ def search(
|
|
253
257
|
|
254
258
|
def _lookup(
|
255
259
|
cls,
|
256
|
-
field:
|
257
|
-
return_field:
|
258
|
-
using_key:
|
260
|
+
field: StrField | None = None,
|
261
|
+
return_field: StrField | None = None,
|
262
|
+
using_key: str | None = None,
|
259
263
|
) -> NamedTuple:
|
260
264
|
"""{}."""
|
261
265
|
queryset = _queryset(cls, using_key=using_key)
|
@@ -279,17 +283,17 @@ def _lookup(
|
|
279
283
|
@doc_args(Registry.lookup.__doc__)
|
280
284
|
def lookup(
|
281
285
|
cls,
|
282
|
-
field:
|
283
|
-
return_field:
|
286
|
+
field: StrField | None = None,
|
287
|
+
return_field: StrField | None = None,
|
284
288
|
) -> NamedTuple:
|
285
289
|
"""{}."""
|
286
290
|
return _lookup(cls=cls, field=field, return_field=return_field)
|
287
291
|
|
288
292
|
|
289
293
|
def get_default_str_field(
|
290
|
-
orm:
|
294
|
+
orm: Registry | QuerySet | Manager,
|
291
295
|
*,
|
292
|
-
field:
|
296
|
+
field: str | StrField | None = None,
|
293
297
|
) -> str:
|
294
298
|
"""Get the 1st char or text field from the orm."""
|
295
299
|
if isinstance(orm, (QuerySet, Manager)):
|
@@ -332,7 +336,7 @@ def get_default_str_field(
|
|
332
336
|
return field
|
333
337
|
|
334
338
|
|
335
|
-
def _queryset(cls:
|
339
|
+
def _queryset(cls: Registry | QuerySet | Manager, using_key: str) -> QuerySet:
|
336
340
|
queryset = (
|
337
341
|
cls.all() if isinstance(cls, QuerySet) else cls.objects.using(using_key).all()
|
338
342
|
)
|
@@ -354,7 +358,7 @@ def add_db_connection(db: str, using: str):
|
|
354
358
|
def using(
|
355
359
|
cls,
|
356
360
|
instance: str,
|
357
|
-
) ->
|
361
|
+
) -> QuerySet:
|
358
362
|
"""{}."""
|
359
363
|
from lamindb_setup._connect_instance import (
|
360
364
|
load_instance_settings,
|
@@ -388,9 +392,9 @@ REGISTRY_UNIQUE_FIELD = {
|
|
388
392
|
|
389
393
|
|
390
394
|
def update_fk_to_default_db(
|
391
|
-
records:
|
395
|
+
records: Registry | list[Registry] | QuerySet,
|
392
396
|
fk: str,
|
393
|
-
using_key:
|
397
|
+
using_key: str | None,
|
394
398
|
):
|
395
399
|
record = records[0] if isinstance(records, (List, QuerySet)) else records
|
396
400
|
if hasattr(record, f"{fk}_id") and getattr(record, f"{fk}_id") is not None:
|
@@ -424,20 +428,18 @@ FKBULK = [
|
|
424
428
|
]
|
425
429
|
|
426
430
|
|
427
|
-
def transfer_fk_to_default_db_bulk(
|
428
|
-
records: Union[List, QuerySet], using_key: Optional[str]
|
429
|
-
):
|
431
|
+
def transfer_fk_to_default_db_bulk(records: list | QuerySet, using_key: str | None):
|
430
432
|
for fk in FKBULK:
|
431
433
|
update_fk_to_default_db(records, fk, using_key)
|
432
434
|
|
433
435
|
|
434
436
|
def transfer_to_default_db(
|
435
437
|
record: Registry,
|
436
|
-
using_key:
|
438
|
+
using_key: str | None,
|
437
439
|
save: bool = False,
|
438
440
|
mute: bool = False,
|
439
441
|
transfer_fk: bool = True,
|
440
|
-
) ->
|
442
|
+
) -> Registry | None:
|
441
443
|
db = record._state.db
|
442
444
|
if db is not None and db != "default" and using_key is None:
|
443
445
|
registry = record.__class__
|
@@ -495,7 +497,7 @@ def save(self, *args, **kwargs) -> None:
|
|
495
497
|
using_key = kwargs["using"]
|
496
498
|
db = self._state.db
|
497
499
|
pk_on_db = self.pk
|
498
|
-
artifacts:
|
500
|
+
artifacts: list = []
|
499
501
|
if self.__class__.__name__ == "Collection" and self.id is not None:
|
500
502
|
# when creating a new collection without being able to access artifacts
|
501
503
|
artifacts = self.artifacts.list()
|
lamindb/_run.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
3
|
from lnschema_core.models import Run, Transform
|
4
4
|
|
@@ -13,10 +13,8 @@ def __init__(run: Run, *args, **kwargs):
|
|
13
13
|
transform: Transform = None
|
14
14
|
if "transform" in kwargs or len(args) == 1:
|
15
15
|
transform = kwargs.pop("transform") if len(args) == 0 else args[0]
|
16
|
-
reference:
|
17
|
-
|
18
|
-
)
|
19
|
-
reference_type: Optional[str] = (
|
16
|
+
reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
|
17
|
+
reference_type: str | None = (
|
20
18
|
kwargs.pop("reference_type") if "reference_type" in kwargs else None
|
21
19
|
)
|
22
20
|
if transform is None:
|
lamindb/_save.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
4
|
import shutil
|
3
5
|
import traceback
|
4
6
|
from collections import defaultdict
|
5
7
|
from datetime import datetime
|
6
8
|
from functools import partial
|
7
|
-
from typing import Iterable,
|
9
|
+
from typing import Iterable, overload
|
8
10
|
|
9
11
|
import lamindb_setup
|
10
12
|
from django.db import transaction
|
@@ -30,7 +32,7 @@ except ImportError:
|
|
30
32
|
|
31
33
|
|
32
34
|
def save(
|
33
|
-
records: Iterable[Registry], ignore_conflicts:
|
35
|
+
records: Iterable[Registry], ignore_conflicts: bool | None = False, **kwargs
|
34
36
|
) -> None:
|
35
37
|
"""Bulk save to registries & storage.
|
36
38
|
|
@@ -123,7 +125,7 @@ def save(
|
|
123
125
|
return None
|
124
126
|
|
125
127
|
|
126
|
-
def bulk_create(records: Iterable[Registry], ignore_conflicts:
|
128
|
+
def bulk_create(records: Iterable[Registry], ignore_conflicts: bool | None = False):
|
127
129
|
records_by_orm = defaultdict(list)
|
128
130
|
for record in records:
|
129
131
|
records_by_orm[record.__class__].append(record)
|
@@ -134,9 +136,9 @@ def bulk_create(records: Iterable[Registry], ignore_conflicts: Optional[bool] =
|
|
134
136
|
# This is also used within Artifact.save()
|
135
137
|
def check_and_attempt_upload(
|
136
138
|
artifact: Artifact,
|
137
|
-
using_key:
|
138
|
-
access_token:
|
139
|
-
) ->
|
139
|
+
using_key: str | None = None,
|
140
|
+
access_token: str | None = None,
|
141
|
+
) -> Exception | None:
|
140
142
|
# if Artifact object is either newly instantiated or replace() was called on
|
141
143
|
# a local env it will have a _local_filepath and needs to be uploaded
|
142
144
|
if hasattr(artifact, "_local_filepath"):
|
@@ -199,8 +201,8 @@ def copy_or_move_to_cache(artifact: Artifact, storage_path: UPath):
|
|
199
201
|
|
200
202
|
# This is also used within Artifact.save()
|
201
203
|
def check_and_attempt_clearing(
|
202
|
-
artifact: Artifact, using_key:
|
203
|
-
) ->
|
204
|
+
artifact: Artifact, using_key: str | None = None
|
205
|
+
) -> Exception | None:
|
204
206
|
# this is a clean-up operation after replace() was called
|
205
207
|
# this will only evaluate to True if replace() was called
|
206
208
|
if hasattr(artifact, "_clear_storagekey"):
|
@@ -220,13 +222,13 @@ def check_and_attempt_clearing(
|
|
220
222
|
|
221
223
|
|
222
224
|
def store_artifacts(
|
223
|
-
artifacts: Iterable[Artifact], using_key:
|
225
|
+
artifacts: Iterable[Artifact], using_key: str | None = None
|
224
226
|
) -> None:
|
225
227
|
"""Upload artifacts in a list of database-committed artifacts to storage.
|
226
228
|
|
227
229
|
If any upload fails, subsequent artifacts are cleaned up from the DB.
|
228
230
|
"""
|
229
|
-
exception:
|
231
|
+
exception: Exception | None = None
|
230
232
|
# because uploads might fail, we need to maintain a new list
|
231
233
|
# of the succeeded uploads
|
232
234
|
stored_artifacts = []
|
@@ -274,7 +276,7 @@ def prepare_error_message(records, stored_artifacts, exception) -> str:
|
|
274
276
|
|
275
277
|
|
276
278
|
def upload_artifact(
|
277
|
-
artifact, using_key:
|
279
|
+
artifact, using_key: str | None = None, access_token: str | None = None
|
278
280
|
) -> UPath:
|
279
281
|
"""Store and add file and its linked entries."""
|
280
282
|
# can't currently use filepath_from_artifact here because it resolves to ._local_filepath
|
lamindb/_transform.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
3
|
from lnschema_core.models import Artifact, Run, Transform
|
4
4
|
from lnschema_core.types import TransformType
|
@@ -11,24 +11,22 @@ def __init__(transform: Transform, *args, **kwargs):
|
|
11
11
|
if len(args) == len(transform._meta.concrete_fields):
|
12
12
|
super(Transform, transform).__init__(*args, **kwargs)
|
13
13
|
return None
|
14
|
-
name:
|
15
|
-
key:
|
16
|
-
is_new_version_of:
|
14
|
+
name: str | None = kwargs.pop("name") if "name" in kwargs else None
|
15
|
+
key: str | None = kwargs.pop("key") if "key" in kwargs else None
|
16
|
+
is_new_version_of: Transform | None = (
|
17
17
|
kwargs.pop("is_new_version_of") if "is_new_version_of" in kwargs else None
|
18
18
|
)
|
19
19
|
(kwargs.pop("initial_version_id") if "initial_version_id" in kwargs else None)
|
20
|
-
version:
|
21
|
-
type:
|
20
|
+
version: str | None = kwargs.pop("version") if "version" in kwargs else None
|
21
|
+
type: TransformType | None = (
|
22
22
|
kwargs.pop("type") if "type" in kwargs else TransformType.pipeline
|
23
23
|
)
|
24
|
-
reference:
|
25
|
-
|
26
|
-
)
|
27
|
-
reference_type: Optional[str] = (
|
24
|
+
reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
|
25
|
+
reference_type: str | None = (
|
28
26
|
kwargs.pop("reference_type") if "reference_type" in kwargs else None
|
29
27
|
)
|
30
28
|
# below is internal use that we'll hopefully be able to eliminate
|
31
|
-
uid:
|
29
|
+
uid: str | None = kwargs.pop("uid") if "uid" in kwargs else None
|
32
30
|
if not len(kwargs) == 0:
|
33
31
|
raise ValueError(
|
34
32
|
"Only name, key, version, type, is_new_version_of, reference, "
|
lamindb/_ulabel.py
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING
|
2
4
|
|
3
5
|
import lamindb_setup as ln_setup
|
4
6
|
from lamindb_setup.core._docs import doc_args
|
5
7
|
from lnschema_core import ULabel
|
6
|
-
from lnschema_core.types import ListLike
|
7
8
|
|
8
9
|
from lamindb._utils import attach_func_to_class_method
|
9
10
|
|
10
11
|
from ._from_values import get_or_create_records
|
11
12
|
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from lnschema_core.types import ListLike
|
15
|
+
|
12
16
|
|
13
17
|
def __init__(self, *args, **kwargs):
|
14
18
|
if len(args) == len(self._meta.concrete_fields):
|
@@ -17,14 +21,12 @@ def __init__(self, *args, **kwargs):
|
|
17
21
|
# now we proceed with the user-facing constructor
|
18
22
|
if len(args) > 0:
|
19
23
|
raise ValueError("Only one non-keyword arg allowed")
|
20
|
-
name:
|
21
|
-
description:
|
24
|
+
name: str | None = kwargs.pop("name") if "name" in kwargs else None
|
25
|
+
description: str | None = (
|
22
26
|
kwargs.pop("description") if "description" in kwargs else None
|
23
27
|
)
|
24
|
-
reference:
|
25
|
-
|
26
|
-
)
|
27
|
-
reference_type: Optional[str] = (
|
28
|
+
reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
|
29
|
+
reference_type: str | None = (
|
28
30
|
kwargs.pop("reference_type") if "reference_type" in kwargs else None
|
29
31
|
)
|
30
32
|
if len(kwargs) > 0:
|
@@ -41,7 +43,7 @@ def __init__(self, *args, **kwargs):
|
|
41
43
|
|
42
44
|
@classmethod # type:ignore
|
43
45
|
@doc_args(ULabel.from_values.__doc__)
|
44
|
-
def from_values(cls, values: ListLike, **kwargs) ->
|
46
|
+
def from_values(cls, values: ListLike, **kwargs) -> list[ULabel]:
|
45
47
|
"""{}."""
|
46
48
|
records = get_or_create_records(
|
47
49
|
iterable=values,
|
lamindb/_view.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import importlib
|
2
4
|
import inspect
|
3
|
-
from typing import List, Optional
|
4
5
|
|
5
6
|
from IPython.display import display
|
6
7
|
from lamin_utils import colors, logger
|
@@ -10,7 +11,7 @@ from lnschema_core import Registry
|
|
10
11
|
|
11
12
|
|
12
13
|
def view(
|
13
|
-
n: int = 7, schema:
|
14
|
+
n: int = 7, schema: str | None = None, registries: list[str] | None = None
|
14
15
|
) -> None:
|
15
16
|
"""View latest metadata state.
|
16
17
|
|