lamindb 1.1.1__py3-none-any.whl → 1.2a2__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 +28 -25
- lamindb/_tracked.py +1 -1
- lamindb/_view.py +2 -3
- lamindb/base/__init__.py +1 -1
- lamindb/base/ids.py +1 -10
- lamindb/core/__init__.py +7 -65
- lamindb/core/_context.py +34 -8
- lamindb/core/_settings.py +6 -6
- lamindb/core/_sync_git.py +1 -1
- lamindb/core/loaders.py +9 -8
- lamindb/core/storage/_backed_access.py +4 -2
- lamindb/core/storage/_tiledbsoma.py +6 -4
- lamindb/core/storage/_zarr.py +32 -11
- lamindb/core/storage/objects.py +59 -26
- lamindb/core/storage/paths.py +4 -1
- lamindb/curators/__init__.py +97 -81
- lamindb/errors.py +1 -1
- lamindb/integrations/_vitessce.py +4 -4
- lamindb/migrations/0089_subsequent_runs.py +159 -0
- lamindb/migrations/0090_runproject_project_runs.py +73 -0
- lamindb/migrations/{0088_squashed.py → 0090_squashed.py} +245 -177
- lamindb/models/__init__.py +79 -0
- lamindb/{core → models}/_describe.py +3 -3
- lamindb/{core → models}/_django.py +8 -5
- lamindb/{core → models}/_feature_manager.py +103 -87
- lamindb/{_from_values.py → models/_from_values.py} +5 -2
- lamindb/{core/versioning.py → models/_is_versioned.py} +94 -6
- lamindb/{core → models}/_label_manager.py +10 -17
- lamindb/{core/relations.py → models/_relations.py} +8 -1
- lamindb/models/artifact.py +2601 -0
- lamindb/{_can_curate.py → models/can_curate.py} +349 -180
- lamindb/models/collection.py +683 -0
- lamindb/models/core.py +135 -0
- lamindb/models/feature.py +643 -0
- lamindb/models/flextable.py +163 -0
- lamindb/{_parents.py → models/has_parents.py} +55 -49
- lamindb/models/project.py +384 -0
- lamindb/{_query_manager.py → models/query_manager.py} +10 -8
- lamindb/{_query_set.py → models/query_set.py} +28 -24
- lamindb/models/record.py +1757 -0
- lamindb/models/run.py +563 -0
- lamindb/{_save.py → models/save.py} +9 -7
- lamindb/models/schema.py +732 -0
- lamindb/models/transform.py +360 -0
- lamindb/models/ulabel.py +249 -0
- {lamindb-1.1.1.dist-info → lamindb-1.2a2.dist-info}/METADATA +5 -5
- {lamindb-1.1.1.dist-info → lamindb-1.2a2.dist-info}/RECORD +49 -50
- lamindb/_artifact.py +0 -1379
- lamindb/_collection.py +0 -440
- lamindb/_feature.py +0 -316
- lamindb/_is_versioned.py +0 -40
- lamindb/_record.py +0 -1064
- lamindb/_run.py +0 -60
- lamindb/_schema.py +0 -347
- lamindb/_storage.py +0 -15
- lamindb/_transform.py +0 -170
- lamindb/_ulabel.py +0 -56
- lamindb/_utils.py +0 -9
- lamindb/base/validation.py +0 -63
- lamindb/core/_data.py +0 -491
- lamindb/core/fields.py +0 -12
- lamindb/models.py +0 -4475
- {lamindb-1.1.1.dist-info → lamindb-1.2a2.dist-info}/LICENSE +0 -0
- {lamindb-1.1.1.dist-info → lamindb-1.2a2.dist-info}/WHEEL +0 -0
lamindb/core/storage/objects.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from pathlib import PurePosixPath
|
4
|
-
from typing import TYPE_CHECKING
|
4
|
+
from typing import TYPE_CHECKING, TypeAlias, TypeVar
|
5
5
|
|
6
6
|
from anndata import AnnData
|
7
7
|
from pandas import DataFrame
|
@@ -9,54 +9,87 @@ from pandas import DataFrame
|
|
9
9
|
if TYPE_CHECKING:
|
10
10
|
from lamindb_setup.core.types import UPathStr
|
11
11
|
|
12
|
+
SpatialData = TypeVar("SpatialData")
|
13
|
+
MuData = TypeVar("MuData")
|
12
14
|
|
13
|
-
|
14
|
-
try:
|
15
|
-
import mudata # noqa: F401c
|
16
|
-
except ImportError:
|
17
|
-
return False
|
18
|
-
return True
|
15
|
+
SupportedDataTypes: TypeAlias = AnnData | DataFrame | MuData | SpatialData
|
19
16
|
|
20
17
|
|
21
|
-
def
|
18
|
+
def is_package_installed(package_name):
|
19
|
+
import importlib.util
|
20
|
+
|
21
|
+
spec = importlib.util.find_spec(package_name)
|
22
|
+
return spec is not None
|
23
|
+
|
24
|
+
|
25
|
+
def infer_suffix(dmem: SupportedDataTypes, format: str | None = None):
|
22
26
|
"""Infer LaminDB storage file suffix from a data object."""
|
23
27
|
if isinstance(dmem, AnnData):
|
24
|
-
if
|
25
|
-
if
|
28
|
+
if format is not None:
|
29
|
+
if format not in {"h5ad", "zarr", "anndata.zarr"}:
|
26
30
|
raise ValueError(
|
27
31
|
"Error when specifying AnnData storage format, it should be"
|
28
|
-
f" 'h5ad', 'zarr', not '{
|
32
|
+
f" 'h5ad', 'zarr', not '{format}'. Check 'format'"
|
29
33
|
" or the suffix of 'key'."
|
30
34
|
)
|
31
|
-
return "." +
|
35
|
+
return "." + format
|
32
36
|
return ".h5ad"
|
33
|
-
|
37
|
+
|
38
|
+
if isinstance(dmem, DataFrame):
|
34
39
|
return ".parquet"
|
35
|
-
else:
|
36
|
-
if _mudata_is_installed():
|
37
|
-
from mudata import MuData
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
if is_package_installed("mudata"):
|
42
|
+
from mudata import MuData
|
43
|
+
|
44
|
+
if isinstance(dmem, MuData):
|
45
|
+
return ".h5mu"
|
46
|
+
|
47
|
+
if is_package_installed("spatialdata"):
|
48
|
+
from spatialdata import SpatialData
|
49
|
+
|
50
|
+
if isinstance(dmem, SpatialData):
|
51
|
+
if format is not None:
|
52
|
+
if format not in {"spatialdata.zarr"}:
|
53
|
+
raise ValueError(
|
54
|
+
"Error when specifying SpatialData storage format, it should be"
|
55
|
+
f" 'zarr', 'spatialdata.zarr', not '{format}'. Check 'format'"
|
56
|
+
" or the suffix of 'key'."
|
57
|
+
)
|
58
|
+
return "." + format
|
59
|
+
return ".zarr"
|
60
|
+
else:
|
41
61
|
raise NotImplementedError
|
42
62
|
|
43
63
|
|
44
|
-
def write_to_disk(dmem, filepath: UPathStr):
|
64
|
+
def write_to_disk(dmem: SupportedDataTypes, filepath: UPathStr) -> None:
|
65
|
+
"""Writes the passed in memory data to disk to a specified path."""
|
45
66
|
if isinstance(dmem, AnnData):
|
46
67
|
suffix = PurePosixPath(filepath).suffix
|
47
68
|
if suffix == ".h5ad":
|
48
69
|
dmem.write_h5ad(filepath)
|
70
|
+
return
|
49
71
|
elif suffix == ".zarr":
|
50
72
|
dmem.write_zarr(filepath)
|
73
|
+
return
|
51
74
|
else:
|
52
75
|
raise NotImplementedError
|
53
|
-
|
76
|
+
|
77
|
+
if isinstance(dmem, DataFrame):
|
54
78
|
dmem.to_parquet(filepath)
|
55
|
-
|
56
|
-
|
57
|
-
|
79
|
+
return
|
80
|
+
|
81
|
+
if is_package_installed("mudata"):
|
82
|
+
from mudata import MuData
|
58
83
|
|
59
|
-
|
60
|
-
|
61
|
-
|
84
|
+
if isinstance(dmem, MuData):
|
85
|
+
dmem.write(filepath)
|
86
|
+
return
|
87
|
+
|
88
|
+
if is_package_installed("spatialdata"):
|
89
|
+
from spatialdata import SpatialData
|
90
|
+
|
91
|
+
if isinstance(dmem, SpatialData):
|
92
|
+
dmem.write(filepath, overwrite=True)
|
93
|
+
return
|
94
|
+
else:
|
62
95
|
raise NotImplementedError
|
lamindb/core/storage/paths.py
CHANGED
@@ -11,13 +11,14 @@ from lamindb_setup.core.upath import (
|
|
11
11
|
)
|
12
12
|
|
13
13
|
from lamindb.core._settings import settings
|
14
|
-
from lamindb.models import Artifact, Storage
|
15
14
|
|
16
15
|
if TYPE_CHECKING:
|
17
16
|
from pathlib import Path
|
18
17
|
|
19
18
|
from lamindb_setup.core.types import UPathStr
|
20
19
|
|
20
|
+
from lamindb.models.artifact import Artifact
|
21
|
+
|
21
22
|
|
22
23
|
AUTO_KEY_PREFIX = ".lamindb/"
|
23
24
|
|
@@ -70,6 +71,8 @@ def attempt_accessing_path(
|
|
70
71
|
) -> tuple[UPath, StorageSettings]:
|
71
72
|
# check whether the file is in the default db and whether storage
|
72
73
|
# matches default storage
|
74
|
+
from lamindb.models import Storage
|
75
|
+
|
73
76
|
if (
|
74
77
|
artifact._state.db in ("default", None)
|
75
78
|
and artifact.storage_id == settings._storage_settings.id
|
lamindb/curators/__init__.py
CHANGED
@@ -9,12 +9,23 @@
|
|
9
9
|
DataFrameCurator
|
10
10
|
AnnDataCurator
|
11
11
|
|
12
|
+
CatManager:
|
13
|
+
|
14
|
+
.. autosummary::
|
15
|
+
:toctree: .
|
16
|
+
|
17
|
+
CatManager
|
18
|
+
DataFrameCatManager
|
19
|
+
AnnDataCatManager
|
20
|
+
MuDataCatManager
|
21
|
+
TiledbsomaCatManager
|
22
|
+
CurateLookup
|
23
|
+
|
12
24
|
"""
|
13
25
|
|
14
26
|
from __future__ import annotations
|
15
27
|
|
16
28
|
import copy
|
17
|
-
import random
|
18
29
|
import re
|
19
30
|
from importlib import resources
|
20
31
|
from itertools import chain
|
@@ -40,14 +51,10 @@ if TYPE_CHECKING:
|
|
40
51
|
|
41
52
|
from lamindb.base.types import FieldAttr
|
42
53
|
from lamindb.models import Record
|
43
|
-
from lamindb._feature import parse_dtype, parse_dtype_single_cat
|
44
54
|
from lamindb.base.types import FieldAttr # noqa
|
45
|
-
from lamindb.core._data import add_labels
|
46
|
-
from lamindb.core._feature_manager import parse_staged_feature_sets_from_anndata
|
47
55
|
from lamindb.core._settings import settings
|
48
56
|
from lamindb.models import (
|
49
57
|
Artifact,
|
50
|
-
CanCurate,
|
51
58
|
Collection,
|
52
59
|
Feature,
|
53
60
|
Record,
|
@@ -55,9 +62,11 @@ from lamindb.models import (
|
|
55
62
|
Schema,
|
56
63
|
ULabel,
|
57
64
|
)
|
65
|
+
from lamindb.models._feature_manager import parse_staged_feature_sets_from_anndata
|
66
|
+
from lamindb.models.artifact import add_labels, data_is_anndata
|
67
|
+
from lamindb.models.feature import parse_dtype, parse_dtype_single_cat
|
68
|
+
from lamindb.models._from_values import _format_values
|
58
69
|
|
59
|
-
from .._artifact import data_is_anndata
|
60
|
-
from .._from_values import _format_values
|
61
70
|
from ..errors import InvalidArgument, ValidationError
|
62
71
|
|
63
72
|
if TYPE_CHECKING:
|
@@ -68,7 +77,7 @@ if TYPE_CHECKING:
|
|
68
77
|
from mudata import MuData
|
69
78
|
from spatialdata import SpatialData
|
70
79
|
|
71
|
-
from lamindb.
|
80
|
+
from lamindb.models.query_set import RecordList
|
72
81
|
|
73
82
|
|
74
83
|
def strip_ansi_codes(text):
|
@@ -453,24 +462,31 @@ class AnnDataCurator(Curator):
|
|
453
462
|
raise InvalidArgument("dataset must be AnnData-like.")
|
454
463
|
if schema.otype != "AnnData":
|
455
464
|
raise InvalidArgument("Schema otype must be 'AnnData'.")
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
465
|
+
# TODO: also support slots other than obs and var
|
466
|
+
self._slots = {
|
467
|
+
slot: DataFrameCurator(
|
468
|
+
(
|
469
|
+
self._dataset.__getattribute__(slot).T
|
470
|
+
if slot == "var"
|
471
|
+
else self._dataset.__getattribute__(slot)
|
472
|
+
),
|
473
|
+
slot_schema,
|
474
|
+
)
|
475
|
+
for slot, slot_schema in schema.slots.items()
|
476
|
+
if slot in {"obs", "var"}
|
477
|
+
}
|
462
478
|
|
463
479
|
@property
|
464
480
|
@doc_args(SLOTS_DOCSTRING)
|
465
481
|
def slots(self) -> dict[str, DataFrameCurator]:
|
466
482
|
"""{}""" # noqa: D415
|
467
|
-
return
|
483
|
+
return self._slots
|
468
484
|
|
469
485
|
@doc_args(VALIDATE_DOCSTRING)
|
470
486
|
def validate(self) -> None:
|
471
487
|
"""{}""" # noqa: D415
|
472
|
-
self.
|
473
|
-
|
488
|
+
for _, curator in self._slots.items():
|
489
|
+
curator.validate()
|
474
490
|
|
475
491
|
@doc_args(SAVE_ARTIFACT_DOCSTRING)
|
476
492
|
def save_artifact(
|
@@ -483,13 +499,18 @@ class AnnDataCurator(Curator):
|
|
483
499
|
):
|
484
500
|
"""{}""" # noqa: D415
|
485
501
|
if not self._is_validated:
|
486
|
-
self.validate()
|
487
|
-
result = parse_dtype_single_cat(self._var_curator._schema.itype, is_itype=True)
|
502
|
+
self.validate()
|
488
503
|
return save_artifact( # type: ignore
|
489
504
|
self._dataset,
|
490
505
|
description=description,
|
491
|
-
fields=self.
|
492
|
-
columns_field=
|
506
|
+
fields=self.slots["obs"]._cat_manager.categoricals,
|
507
|
+
columns_field=(
|
508
|
+
parse_dtype_single_cat(self.slots["var"]._schema.itype, is_itype=True)[
|
509
|
+
"field"
|
510
|
+
]
|
511
|
+
if "var" in self._slots
|
512
|
+
else None
|
513
|
+
),
|
493
514
|
key=key,
|
494
515
|
artifact=self._artifact,
|
495
516
|
revises=revises,
|
@@ -519,8 +540,8 @@ class CatManager:
|
|
519
540
|
|
520
541
|
If you find non-validated values, you have several options:
|
521
542
|
|
522
|
-
- new values found in the data can be registered using :meth:`~lamindb.
|
523
|
-
- non-validated values can be accessed using :meth:`~lamindb.
|
543
|
+
- new values found in the data can be registered using :meth:`~lamindb.curators.DataFrameCatManager.add_new_from`
|
544
|
+
- non-validated values can be accessed using :meth:`~lamindb.curators.DataFrameCatManager.non_validated` and addressed manually
|
524
545
|
"""
|
525
546
|
|
526
547
|
def __init__(
|
@@ -891,7 +912,7 @@ class AnnDataCatManager(CatManager):
|
|
891
912
|
def __init__(
|
892
913
|
self,
|
893
914
|
data: ad.AnnData | Artifact,
|
894
|
-
var_index: FieldAttr,
|
915
|
+
var_index: FieldAttr | None = None,
|
895
916
|
categoricals: dict[str, FieldAttr] | None = None,
|
896
917
|
obs_columns: FieldAttr = Feature.name,
|
897
918
|
verbosity: str = "hint",
|
@@ -960,15 +981,16 @@ class AnnDataCatManager(CatManager):
|
|
960
981
|
validated_only: bool = True,
|
961
982
|
):
|
962
983
|
"""Save variable records."""
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
984
|
+
if self.var_index is not None:
|
985
|
+
update_registry(
|
986
|
+
values=list(self._adata.var.index),
|
987
|
+
field=self.var_index,
|
988
|
+
key="var_index",
|
989
|
+
validated_only=validated_only,
|
990
|
+
organism=self._organism,
|
991
|
+
source=self._sources.get("var_index"),
|
992
|
+
exclude=self._exclude.get("var_index"),
|
993
|
+
)
|
972
994
|
|
973
995
|
def add_new_from(self, key: str, **kwargs):
|
974
996
|
"""Add validated & new categories.
|
@@ -1004,15 +1026,19 @@ class AnnDataCatManager(CatManager):
|
|
1004
1026
|
|
1005
1027
|
# add all validated records to the current instance
|
1006
1028
|
self._save_from_var_index(validated_only=True)
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1029
|
+
if self.var_index is not None:
|
1030
|
+
validated_var, non_validated_var = validate_categories(
|
1031
|
+
self._adata.var.index,
|
1032
|
+
field=self._var_field,
|
1033
|
+
key="var_index",
|
1034
|
+
source=self._sources.get("var_index"),
|
1035
|
+
hint_print=".add_new_from_var_index()",
|
1036
|
+
exclude=self._exclude.get("var_index"),
|
1037
|
+
organism=self._organism, # type: ignore
|
1038
|
+
)
|
1039
|
+
else:
|
1040
|
+
validated_var = True
|
1041
|
+
non_validated_var = []
|
1016
1042
|
validated_obs = self._obs_df_curator.validate()
|
1017
1043
|
self._non_validated = self._obs_df_curator._non_validated # type: ignore
|
1018
1044
|
if len(non_validated_var) > 0:
|
@@ -1711,7 +1737,7 @@ class TiledbsomaCatManager(CatManager):
|
|
1711
1737
|
Returns:
|
1712
1738
|
A saved artifact record.
|
1713
1739
|
"""
|
1714
|
-
from lamindb.
|
1740
|
+
from lamindb.models.artifact import add_labels
|
1715
1741
|
|
1716
1742
|
if not self._is_validated:
|
1717
1743
|
self.validate()
|
@@ -1853,6 +1879,7 @@ class SpatialDataCatManager(CatManager):
|
|
1853
1879
|
else:
|
1854
1880
|
self._sdata = self._dataset
|
1855
1881
|
self._sample_metadata_key = sample_metadata_key
|
1882
|
+
self._write_path = None
|
1856
1883
|
self._var_fields = var_index
|
1857
1884
|
self._verify_accessor_exists(self._var_fields.keys())
|
1858
1885
|
self._categoricals = categoricals
|
@@ -2134,26 +2161,14 @@ class SpatialDataCatManager(CatManager):
|
|
2134
2161
|
try:
|
2135
2162
|
settings.verbosity = "warning"
|
2136
2163
|
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
# Create the Artifact and associate Artifact metadata
|
2146
|
-
self._artifact = Artifact(
|
2147
|
-
write_path,
|
2148
|
-
description=description,
|
2149
|
-
key=key,
|
2150
|
-
revises=revises,
|
2151
|
-
run=run,
|
2152
|
-
)
|
2153
|
-
# According to Tim it is not easy to calculate the number of observations.
|
2154
|
-
# We would have to write custom code to iterate over labels (which might not even exist at that point)
|
2155
|
-
self._artifact.otype = "spatialdata"
|
2156
|
-
self._artifact.save()
|
2164
|
+
self._artifact = Artifact.from_spatialdata(
|
2165
|
+
self._sdata,
|
2166
|
+
key=key,
|
2167
|
+
description=description,
|
2168
|
+
revises=revises,
|
2169
|
+
run=run,
|
2170
|
+
)
|
2171
|
+
self._artifact.save()
|
2157
2172
|
|
2158
2173
|
# Link schemas
|
2159
2174
|
feature_kwargs = check_registry_organism(
|
@@ -2171,7 +2186,7 @@ class SpatialDataCatManager(CatManager):
|
|
2171
2186
|
"""Add Schemas from SpatialData."""
|
2172
2187
|
if obs_fields is None:
|
2173
2188
|
obs_fields = {}
|
2174
|
-
assert host.otype == "
|
2189
|
+
assert host.otype == "SpatialData" # noqa: S101
|
2175
2190
|
|
2176
2191
|
feature_sets = {}
|
2177
2192
|
|
@@ -2799,7 +2814,7 @@ class DoseHandler:
|
|
2799
2814
|
return cls.UNIT_MAP.get(unit, unit)
|
2800
2815
|
|
2801
2816
|
@classmethod
|
2802
|
-
def validate_values(cls, values: pd.Series) -> list:
|
2817
|
+
def validate_values(cls, values: pd.Series) -> list[str]:
|
2803
2818
|
"""Validate pert_dose values with strict case checking."""
|
2804
2819
|
errors = []
|
2805
2820
|
|
@@ -2843,7 +2858,7 @@ class TimeHandler:
|
|
2843
2858
|
return unit[0].lower()
|
2844
2859
|
|
2845
2860
|
@classmethod
|
2846
|
-
def validate_values(cls, values: pd.Series) -> list:
|
2861
|
+
def validate_values(cls, values: pd.Series) -> list[str]:
|
2847
2862
|
"""Validate pert_time values."""
|
2848
2863
|
errors = []
|
2849
2864
|
|
@@ -3197,8 +3212,8 @@ def validate_categories(
|
|
3197
3212
|
exclude: str | list | None = None,
|
3198
3213
|
hint_print: str | None = None,
|
3199
3214
|
curator: CatManager | None = None,
|
3200
|
-
) -> tuple[bool, list]:
|
3201
|
-
"""Validate ontology terms
|
3215
|
+
) -> tuple[bool, list[str]]:
|
3216
|
+
"""Validate ontology terms using LaminDB registries.
|
3202
3217
|
|
3203
3218
|
Args:
|
3204
3219
|
values: The values to validate.
|
@@ -3210,8 +3225,8 @@ def validate_categories(
|
|
3210
3225
|
standardize: Whether to standardize the values.
|
3211
3226
|
hint_print: The hint to print that suggests fixing non-validated values.
|
3212
3227
|
"""
|
3213
|
-
from lamindb._from_values import _format_values
|
3214
3228
|
from lamindb.core._settings import settings
|
3229
|
+
from lamindb.models._from_values import _format_values
|
3215
3230
|
|
3216
3231
|
model_field = f"{field.field.model.__name__}.{field.field.name}"
|
3217
3232
|
|
@@ -3346,7 +3361,7 @@ def validate_categories_in_df(
|
|
3346
3361
|
def save_artifact(
|
3347
3362
|
data: pd.DataFrame | ad.AnnData | MuData,
|
3348
3363
|
fields: dict[str, FieldAttr] | dict[str, dict[str, FieldAttr]],
|
3349
|
-
columns_field: FieldAttr | dict[str, FieldAttr],
|
3364
|
+
columns_field: FieldAttr | dict[str, FieldAttr] | None = None,
|
3350
3365
|
description: str | None = None,
|
3351
3366
|
organism: str | None = None,
|
3352
3367
|
key: str | None = None,
|
@@ -3372,8 +3387,7 @@ def save_artifact(
|
|
3372
3387
|
Returns:
|
3373
3388
|
The saved Artifact.
|
3374
3389
|
"""
|
3375
|
-
from ..
|
3376
|
-
from ..core._data import add_labels
|
3390
|
+
from ..models.artifact import add_labels, data_is_anndata, data_is_mudata
|
3377
3391
|
|
3378
3392
|
if artifact is None:
|
3379
3393
|
if data_is_anndata(data):
|
@@ -3395,7 +3409,7 @@ def save_artifact(
|
|
3395
3409
|
artifact.schema = schema
|
3396
3410
|
artifact.save()
|
3397
3411
|
|
3398
|
-
if organism is not None:
|
3412
|
+
if organism is not None and columns_field is not None:
|
3399
3413
|
feature_kwargs = check_registry_organism(
|
3400
3414
|
(
|
3401
3415
|
list(columns_field.values())[0].field.model
|
@@ -3532,8 +3546,8 @@ def update_registry(
|
|
3532
3546
|
exclude: Values to exclude from inspect.
|
3533
3547
|
kwargs: Additional keyword arguments to pass to the registry model to create new records.
|
3534
3548
|
"""
|
3535
|
-
from lamindb._save import save as ln_save
|
3536
3549
|
from lamindb.core._settings import settings
|
3550
|
+
from lamindb.models.save import save as ln_save
|
3537
3551
|
|
3538
3552
|
registry = field.field.model
|
3539
3553
|
filter_kwargs = check_registry_organism(registry, organism)
|
@@ -3621,7 +3635,7 @@ def log_saved_labels(
|
|
3621
3635
|
validated_only: bool = True,
|
3622
3636
|
) -> None:
|
3623
3637
|
"""Log the saved labels."""
|
3624
|
-
from .._from_values import _format_values
|
3638
|
+
from ..models._from_values import _format_values
|
3625
3639
|
|
3626
3640
|
model_field = colors.italic(model_field)
|
3627
3641
|
for k, labels in labels_saved.items():
|
@@ -3667,12 +3681,14 @@ def _save_organism(name: str):
|
|
3667
3681
|
return organism
|
3668
3682
|
|
3669
3683
|
|
3670
|
-
def _ref_is_name(field: FieldAttr) -> bool | None:
|
3684
|
+
def _ref_is_name(field: FieldAttr | None) -> bool | None:
|
3671
3685
|
"""Check if the reference field is a name field."""
|
3672
|
-
from ..
|
3686
|
+
from ..models.can_curate import get_name_field
|
3673
3687
|
|
3674
|
-
|
3675
|
-
|
3688
|
+
if field is not None:
|
3689
|
+
name_field = get_name_field(field.field.model)
|
3690
|
+
return field.field.name == name_field
|
3691
|
+
return None
|
3676
3692
|
|
3677
3693
|
|
3678
3694
|
# backward compat constructors ------------------
|
@@ -3721,7 +3737,7 @@ def from_anndata(
|
|
3721
3737
|
@classmethod # type: ignore
|
3722
3738
|
def from_mudata(
|
3723
3739
|
cls,
|
3724
|
-
mdata: MuData,
|
3740
|
+
mdata: MuData | UPathStr,
|
3725
3741
|
var_index: dict[str, dict[str, FieldAttr]],
|
3726
3742
|
categoricals: dict[str, FieldAttr] | None = None,
|
3727
3743
|
verbosity: str = "hint",
|
@@ -3761,7 +3777,7 @@ def from_tiledbsoma(
|
|
3761
3777
|
@classmethod # type: ignore
|
3762
3778
|
def from_spatialdata(
|
3763
3779
|
cls,
|
3764
|
-
sdata,
|
3780
|
+
sdata: SpatialData | UPathStr,
|
3765
3781
|
var_index: dict[str, FieldAttr],
|
3766
3782
|
categoricals: dict[str, dict[str, FieldAttr]] | None = None,
|
3767
3783
|
organism: str | None = None,
|
lamindb/errors.py
CHANGED
@@ -7,10 +7,10 @@ from typing import TYPE_CHECKING
|
|
7
7
|
import lamindb_setup as ln_setup
|
8
8
|
from lamin_utils import logger
|
9
9
|
|
10
|
-
from lamindb.
|
11
|
-
from lamindb.
|
12
|
-
from lamindb.
|
13
|
-
from lamindb.
|
10
|
+
from lamindb.models.artifact import Artifact
|
11
|
+
from lamindb.models.collection import Collection
|
12
|
+
from lamindb.models.run import Run
|
13
|
+
from lamindb.models.transform import Transform
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from vitessce import VitessceConfig
|