lamindb 0.76.8__py3-none-any.whl → 0.76.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 +113 -113
- lamindb/_artifact.py +1205 -1205
- lamindb/_can_validate.py +579 -579
- lamindb/_collection.py +389 -387
- lamindb/_curate.py +1601 -1601
- lamindb/_feature.py +155 -155
- lamindb/_feature_set.py +242 -242
- lamindb/_filter.py +23 -23
- lamindb/_finish.py +256 -256
- lamindb/_from_values.py +382 -382
- lamindb/_is_versioned.py +40 -40
- lamindb/_parents.py +476 -476
- lamindb/_query_manager.py +125 -125
- lamindb/_query_set.py +362 -362
- lamindb/_record.py +649 -649
- lamindb/_run.py +57 -57
- lamindb/_save.py +308 -308
- lamindb/_storage.py +14 -14
- lamindb/_transform.py +127 -127
- lamindb/_ulabel.py +56 -56
- lamindb/_utils.py +9 -9
- lamindb/_view.py +72 -72
- lamindb/core/__init__.py +94 -94
- lamindb/core/_context.py +574 -574
- lamindb/core/_data.py +438 -438
- lamindb/core/_feature_manager.py +867 -867
- lamindb/core/_label_manager.py +253 -253
- lamindb/core/_mapped_collection.py +631 -597
- lamindb/core/_settings.py +187 -187
- lamindb/core/_sync_git.py +138 -138
- lamindb/core/_track_environment.py +27 -27
- lamindb/core/datasets/__init__.py +59 -59
- lamindb/core/datasets/_core.py +581 -571
- lamindb/core/datasets/_fake.py +36 -36
- lamindb/core/exceptions.py +90 -90
- lamindb/core/fields.py +12 -12
- lamindb/core/loaders.py +164 -164
- lamindb/core/schema.py +56 -56
- lamindb/core/storage/__init__.py +25 -25
- lamindb/core/storage/_anndata_accessor.py +740 -740
- lamindb/core/storage/_anndata_sizes.py +41 -41
- lamindb/core/storage/_backed_access.py +98 -98
- lamindb/core/storage/_tiledbsoma.py +204 -204
- lamindb/core/storage/_valid_suffixes.py +21 -21
- lamindb/core/storage/_zarr.py +110 -110
- lamindb/core/storage/objects.py +62 -62
- lamindb/core/storage/paths.py +172 -172
- lamindb/core/subsettings/__init__.py +12 -12
- lamindb/core/subsettings/_creation_settings.py +38 -38
- lamindb/core/subsettings/_transform_settings.py +21 -21
- lamindb/core/types.py +19 -19
- lamindb/core/versioning.py +158 -158
- lamindb/integrations/__init__.py +12 -12
- lamindb/integrations/_vitessce.py +107 -107
- lamindb/setup/__init__.py +14 -14
- lamindb/setup/core/__init__.py +4 -4
- {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/LICENSE +201 -201
- {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/METADATA +4 -4
- lamindb-0.76.9.dist-info/RECORD +60 -0
- {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/WHEEL +1 -1
- lamindb-0.76.8.dist-info/RECORD +0 -60
lamindb/core/storage/objects.py
CHANGED
@@ -1,62 +1,62 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from pathlib import PurePosixPath
|
4
|
-
from typing import TYPE_CHECKING
|
5
|
-
|
6
|
-
from anndata import AnnData
|
7
|
-
from pandas import DataFrame
|
8
|
-
|
9
|
-
if TYPE_CHECKING:
|
10
|
-
from lamindb_setup.core.types import UPathStr
|
11
|
-
|
12
|
-
|
13
|
-
def _mudata_is_installed():
|
14
|
-
try:
|
15
|
-
import mudata
|
16
|
-
except ImportError:
|
17
|
-
return False
|
18
|
-
return True
|
19
|
-
|
20
|
-
|
21
|
-
def infer_suffix(dmem, adata_format: str | None = None):
|
22
|
-
"""Infer LaminDB storage file suffix from a data object."""
|
23
|
-
if isinstance(dmem, AnnData):
|
24
|
-
if adata_format is not None:
|
25
|
-
if adata_format not in {"h5ad", "zarr", "anndata.zarr"}:
|
26
|
-
raise ValueError(
|
27
|
-
"Error when specifying AnnData storage format, it should be"
|
28
|
-
f" 'h5ad', 'zarr', not '{adata_format}'. Check 'format'"
|
29
|
-
" or the suffix of 'key'."
|
30
|
-
)
|
31
|
-
return "." + adata_format
|
32
|
-
return ".h5ad"
|
33
|
-
elif isinstance(dmem, DataFrame):
|
34
|
-
return ".parquet"
|
35
|
-
else:
|
36
|
-
if _mudata_is_installed():
|
37
|
-
from mudata import MuData
|
38
|
-
|
39
|
-
if isinstance(dmem, MuData):
|
40
|
-
return ".h5mu"
|
41
|
-
raise NotImplementedError
|
42
|
-
|
43
|
-
|
44
|
-
def write_to_disk(dmem, filepath: UPathStr):
|
45
|
-
if isinstance(dmem, AnnData):
|
46
|
-
suffix = PurePosixPath(filepath).suffix
|
47
|
-
if suffix == ".h5ad":
|
48
|
-
dmem.write_h5ad(filepath)
|
49
|
-
elif suffix == ".zarr":
|
50
|
-
dmem.write_zarr(filepath)
|
51
|
-
else:
|
52
|
-
raise NotImplementedError
|
53
|
-
elif isinstance(dmem, DataFrame):
|
54
|
-
dmem.to_parquet(filepath)
|
55
|
-
else:
|
56
|
-
if _mudata_is_installed():
|
57
|
-
from mudata import MuData
|
58
|
-
|
59
|
-
if isinstance(dmem, MuData):
|
60
|
-
dmem.write(filepath)
|
61
|
-
return
|
62
|
-
raise NotImplementedError
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from pathlib import PurePosixPath
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
from anndata import AnnData
|
7
|
+
from pandas import DataFrame
|
8
|
+
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from lamindb_setup.core.types import UPathStr
|
11
|
+
|
12
|
+
|
13
|
+
def _mudata_is_installed():
|
14
|
+
try:
|
15
|
+
import mudata
|
16
|
+
except ImportError:
|
17
|
+
return False
|
18
|
+
return True
|
19
|
+
|
20
|
+
|
21
|
+
def infer_suffix(dmem, adata_format: str | None = None):
|
22
|
+
"""Infer LaminDB storage file suffix from a data object."""
|
23
|
+
if isinstance(dmem, AnnData):
|
24
|
+
if adata_format is not None:
|
25
|
+
if adata_format not in {"h5ad", "zarr", "anndata.zarr"}:
|
26
|
+
raise ValueError(
|
27
|
+
"Error when specifying AnnData storage format, it should be"
|
28
|
+
f" 'h5ad', 'zarr', not '{adata_format}'. Check 'format'"
|
29
|
+
" or the suffix of 'key'."
|
30
|
+
)
|
31
|
+
return "." + adata_format
|
32
|
+
return ".h5ad"
|
33
|
+
elif isinstance(dmem, DataFrame):
|
34
|
+
return ".parquet"
|
35
|
+
else:
|
36
|
+
if _mudata_is_installed():
|
37
|
+
from mudata import MuData
|
38
|
+
|
39
|
+
if isinstance(dmem, MuData):
|
40
|
+
return ".h5mu"
|
41
|
+
raise NotImplementedError
|
42
|
+
|
43
|
+
|
44
|
+
def write_to_disk(dmem, filepath: UPathStr):
|
45
|
+
if isinstance(dmem, AnnData):
|
46
|
+
suffix = PurePosixPath(filepath).suffix
|
47
|
+
if suffix == ".h5ad":
|
48
|
+
dmem.write_h5ad(filepath)
|
49
|
+
elif suffix == ".zarr":
|
50
|
+
dmem.write_zarr(filepath)
|
51
|
+
else:
|
52
|
+
raise NotImplementedError
|
53
|
+
elif isinstance(dmem, DataFrame):
|
54
|
+
dmem.to_parquet(filepath)
|
55
|
+
else:
|
56
|
+
if _mudata_is_installed():
|
57
|
+
from mudata import MuData
|
58
|
+
|
59
|
+
if isinstance(dmem, MuData):
|
60
|
+
dmem.write(filepath)
|
61
|
+
return
|
62
|
+
raise NotImplementedError
|
lamindb/core/storage/paths.py
CHANGED
@@ -1,172 +1,172 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import shutil
|
4
|
-
from typing import TYPE_CHECKING
|
5
|
-
|
6
|
-
import anndata as ad
|
7
|
-
import pandas as pd
|
8
|
-
from lamin_utils import logger
|
9
|
-
from lamindb_setup.core import StorageSettings
|
10
|
-
from lamindb_setup.core.upath import (
|
11
|
-
LocalPathClasses,
|
12
|
-
UPath,
|
13
|
-
create_path,
|
14
|
-
infer_filesystem,
|
15
|
-
)
|
16
|
-
from lnschema_core.models import Artifact, Storage
|
17
|
-
|
18
|
-
from lamindb.core._settings import settings
|
19
|
-
|
20
|
-
if TYPE_CHECKING:
|
21
|
-
from pathlib import Path
|
22
|
-
|
23
|
-
from lamindb_setup.core.types import UPathStr
|
24
|
-
|
25
|
-
|
26
|
-
AUTO_KEY_PREFIX = ".lamindb/"
|
27
|
-
|
28
|
-
|
29
|
-
# add type annotations back asap when re-organizing the module
|
30
|
-
def auto_storage_key_from_artifact(artifact: Artifact):
|
31
|
-
if artifact.key is None or artifact._key_is_virtual:
|
32
|
-
is_dir = artifact.n_objects is not None
|
33
|
-
return auto_storage_key_from_artifact_uid(artifact.uid, artifact.suffix, is_dir)
|
34
|
-
else:
|
35
|
-
return artifact.key
|
36
|
-
|
37
|
-
|
38
|
-
def auto_storage_key_from_artifact_uid(uid: str, suffix: str, is_dir: bool) -> str:
|
39
|
-
assert isinstance(suffix, str) # noqa: S101 Suffix cannot be None.
|
40
|
-
if is_dir:
|
41
|
-
uid_storage = uid[:16] # 16 chars, leave 4 chars for versioning
|
42
|
-
else:
|
43
|
-
uid_storage = uid
|
44
|
-
storage_key = f"{AUTO_KEY_PREFIX}{uid_storage}{suffix}"
|
45
|
-
return storage_key
|
46
|
-
|
47
|
-
|
48
|
-
def check_path_is_child_of_root(path: Path | UPath, root: Path | UPath | None) -> bool:
|
49
|
-
# str is needed to eliminate UPath storage_options
|
50
|
-
# from the equality checks below
|
51
|
-
path = UPath(str(path))
|
52
|
-
root = UPath(str(root))
|
53
|
-
return root.resolve() in path.resolve().parents
|
54
|
-
|
55
|
-
|
56
|
-
# returns filepath and root of the storage
|
57
|
-
def attempt_accessing_path(
|
58
|
-
artifact: Artifact,
|
59
|
-
storage_key: str,
|
60
|
-
using_key: str | None = None,
|
61
|
-
access_token: str | None = None,
|
62
|
-
) -> tuple[UPath, StorageSettings]:
|
63
|
-
# check whether the file is in the default db and whether storage
|
64
|
-
# matches default storage
|
65
|
-
if (
|
66
|
-
artifact._state.db in ("default", None)
|
67
|
-
and artifact.storage_id == settings._storage_settings.id
|
68
|
-
):
|
69
|
-
if access_token is None:
|
70
|
-
storage_settings = settings._storage_settings
|
71
|
-
else:
|
72
|
-
storage_settings = StorageSettings(
|
73
|
-
settings.storage.root, access_token=access_token
|
74
|
-
)
|
75
|
-
else:
|
76
|
-
if artifact._state.db not in ("default", None) and using_key is None:
|
77
|
-
storage = Storage.using(artifact._state.db).get(id=artifact.storage_id)
|
78
|
-
else:
|
79
|
-
storage = Storage.objects.using(using_key).get(id=artifact.storage_id)
|
80
|
-
# find a better way than passing None to instance_settings in the future!
|
81
|
-
storage_settings = StorageSettings(storage.root, access_token=access_token)
|
82
|
-
path = storage_settings.key_to_filepath(storage_key)
|
83
|
-
return path, storage_settings
|
84
|
-
|
85
|
-
|
86
|
-
def filepath_from_artifact(
|
87
|
-
artifact: Artifact, using_key: str | None = None
|
88
|
-
) -> tuple[UPath, StorageSettings | None]:
|
89
|
-
if hasattr(artifact, "_local_filepath") and artifact._local_filepath is not None:
|
90
|
-
return artifact._local_filepath.resolve(), None
|
91
|
-
storage_key = auto_storage_key_from_artifact(artifact)
|
92
|
-
path, storage_settings = attempt_accessing_path(
|
93
|
-
artifact, storage_key, using_key=using_key
|
94
|
-
)
|
95
|
-
return path, storage_settings
|
96
|
-
|
97
|
-
|
98
|
-
# virtual key is taken into consideration
|
99
|
-
# only if the version is latest
|
100
|
-
def _cache_key_from_artifact_storage(
|
101
|
-
artifact: Artifact, storage_settings: StorageSettings | None
|
102
|
-
):
|
103
|
-
cache_key = None
|
104
|
-
if (
|
105
|
-
artifact._key_is_virtual
|
106
|
-
and artifact.key is not None
|
107
|
-
and storage_settings is not None
|
108
|
-
and artifact.is_latest
|
109
|
-
):
|
110
|
-
cache_key = (storage_settings.root / artifact.key).path
|
111
|
-
return cache_key
|
112
|
-
|
113
|
-
|
114
|
-
# return filepath and cache_key if needed
|
115
|
-
def filepath_cache_key_from_artifact(
|
116
|
-
artifact: Artifact, using_key: str | None = None
|
117
|
-
) -> tuple[UPath, str | None]:
|
118
|
-
filepath, storage_settings = filepath_from_artifact(artifact, using_key)
|
119
|
-
if isinstance(filepath, LocalPathClasses):
|
120
|
-
return filepath, None
|
121
|
-
cache_key = _cache_key_from_artifact_storage(artifact, storage_settings)
|
122
|
-
return filepath, cache_key
|
123
|
-
|
124
|
-
|
125
|
-
def store_file_or_folder(
|
126
|
-
local_path: UPathStr, storage_path: UPath, print_progress: bool = True
|
127
|
-
) -> None:
|
128
|
-
"""Store file or folder (localpath) at storagepath."""
|
129
|
-
local_path = UPath(local_path)
|
130
|
-
if not isinstance(storage_path, LocalPathClasses):
|
131
|
-
# this uploads files and directories
|
132
|
-
create_folder = False if local_path.is_dir() else None
|
133
|
-
storage_path.upload_from(
|
134
|
-
local_path, create_folder=create_folder, print_progress=print_progress
|
135
|
-
)
|
136
|
-
else: # storage path is local
|
137
|
-
if local_path.resolve().as_posix() == storage_path.resolve().as_posix():
|
138
|
-
return None
|
139
|
-
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
140
|
-
if local_path.is_file():
|
141
|
-
shutil.copyfile(local_path, storage_path)
|
142
|
-
else:
|
143
|
-
if storage_path.exists():
|
144
|
-
shutil.rmtree(storage_path)
|
145
|
-
shutil.copytree(local_path, storage_path)
|
146
|
-
|
147
|
-
|
148
|
-
def delete_storage_using_key(
|
149
|
-
artifact: Artifact, storage_key: str, using_key: str | None
|
150
|
-
):
|
151
|
-
filepath, _ = attempt_accessing_path(artifact, storage_key, using_key=using_key)
|
152
|
-
delete_storage(filepath)
|
153
|
-
|
154
|
-
|
155
|
-
def delete_storage(
|
156
|
-
storagepath: Path, raise_file_not_found_error: bool = True
|
157
|
-
) -> None | str:
|
158
|
-
"""Delete arbitrary artifact."""
|
159
|
-
if storagepath.is_file():
|
160
|
-
storagepath.unlink()
|
161
|
-
elif storagepath.is_dir():
|
162
|
-
if isinstance(storagepath, LocalPathClasses) or not isinstance(
|
163
|
-
storagepath, UPath
|
164
|
-
):
|
165
|
-
shutil.rmtree(storagepath)
|
166
|
-
else:
|
167
|
-
storagepath.rmdir()
|
168
|
-
elif raise_file_not_found_error:
|
169
|
-
raise FileNotFoundError(f"{storagepath} is not an existing path!")
|
170
|
-
else:
|
171
|
-
logger.warning(f"{storagepath} is not an existing path!")
|
172
|
-
return None
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import shutil
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
import anndata as ad
|
7
|
+
import pandas as pd
|
8
|
+
from lamin_utils import logger
|
9
|
+
from lamindb_setup.core import StorageSettings
|
10
|
+
from lamindb_setup.core.upath import (
|
11
|
+
LocalPathClasses,
|
12
|
+
UPath,
|
13
|
+
create_path,
|
14
|
+
infer_filesystem,
|
15
|
+
)
|
16
|
+
from lnschema_core.models import Artifact, Storage
|
17
|
+
|
18
|
+
from lamindb.core._settings import settings
|
19
|
+
|
20
|
+
if TYPE_CHECKING:
|
21
|
+
from pathlib import Path
|
22
|
+
|
23
|
+
from lamindb_setup.core.types import UPathStr
|
24
|
+
|
25
|
+
|
26
|
+
AUTO_KEY_PREFIX = ".lamindb/"
|
27
|
+
|
28
|
+
|
29
|
+
# add type annotations back asap when re-organizing the module
|
30
|
+
def auto_storage_key_from_artifact(artifact: Artifact):
|
31
|
+
if artifact.key is None or artifact._key_is_virtual:
|
32
|
+
is_dir = artifact.n_objects is not None
|
33
|
+
return auto_storage_key_from_artifact_uid(artifact.uid, artifact.suffix, is_dir)
|
34
|
+
else:
|
35
|
+
return artifact.key
|
36
|
+
|
37
|
+
|
38
|
+
def auto_storage_key_from_artifact_uid(uid: str, suffix: str, is_dir: bool) -> str:
|
39
|
+
assert isinstance(suffix, str) # noqa: S101 Suffix cannot be None.
|
40
|
+
if is_dir:
|
41
|
+
uid_storage = uid[:16] # 16 chars, leave 4 chars for versioning
|
42
|
+
else:
|
43
|
+
uid_storage = uid
|
44
|
+
storage_key = f"{AUTO_KEY_PREFIX}{uid_storage}{suffix}"
|
45
|
+
return storage_key
|
46
|
+
|
47
|
+
|
48
|
+
def check_path_is_child_of_root(path: Path | UPath, root: Path | UPath | None) -> bool:
|
49
|
+
# str is needed to eliminate UPath storage_options
|
50
|
+
# from the equality checks below
|
51
|
+
path = UPath(str(path))
|
52
|
+
root = UPath(str(root))
|
53
|
+
return root.resolve() in path.resolve().parents
|
54
|
+
|
55
|
+
|
56
|
+
# returns filepath and root of the storage
|
57
|
+
def attempt_accessing_path(
|
58
|
+
artifact: Artifact,
|
59
|
+
storage_key: str,
|
60
|
+
using_key: str | None = None,
|
61
|
+
access_token: str | None = None,
|
62
|
+
) -> tuple[UPath, StorageSettings]:
|
63
|
+
# check whether the file is in the default db and whether storage
|
64
|
+
# matches default storage
|
65
|
+
if (
|
66
|
+
artifact._state.db in ("default", None)
|
67
|
+
and artifact.storage_id == settings._storage_settings.id
|
68
|
+
):
|
69
|
+
if access_token is None:
|
70
|
+
storage_settings = settings._storage_settings
|
71
|
+
else:
|
72
|
+
storage_settings = StorageSettings(
|
73
|
+
settings.storage.root, access_token=access_token
|
74
|
+
)
|
75
|
+
else:
|
76
|
+
if artifact._state.db not in ("default", None) and using_key is None:
|
77
|
+
storage = Storage.using(artifact._state.db).get(id=artifact.storage_id)
|
78
|
+
else:
|
79
|
+
storage = Storage.objects.using(using_key).get(id=artifact.storage_id)
|
80
|
+
# find a better way than passing None to instance_settings in the future!
|
81
|
+
storage_settings = StorageSettings(storage.root, access_token=access_token)
|
82
|
+
path = storage_settings.key_to_filepath(storage_key)
|
83
|
+
return path, storage_settings
|
84
|
+
|
85
|
+
|
86
|
+
def filepath_from_artifact(
|
87
|
+
artifact: Artifact, using_key: str | None = None
|
88
|
+
) -> tuple[UPath, StorageSettings | None]:
|
89
|
+
if hasattr(artifact, "_local_filepath") and artifact._local_filepath is not None:
|
90
|
+
return artifact._local_filepath.resolve(), None
|
91
|
+
storage_key = auto_storage_key_from_artifact(artifact)
|
92
|
+
path, storage_settings = attempt_accessing_path(
|
93
|
+
artifact, storage_key, using_key=using_key
|
94
|
+
)
|
95
|
+
return path, storage_settings
|
96
|
+
|
97
|
+
|
98
|
+
# virtual key is taken into consideration
|
99
|
+
# only if the version is latest
|
100
|
+
def _cache_key_from_artifact_storage(
|
101
|
+
artifact: Artifact, storage_settings: StorageSettings | None
|
102
|
+
):
|
103
|
+
cache_key = None
|
104
|
+
if (
|
105
|
+
artifact._key_is_virtual
|
106
|
+
and artifact.key is not None
|
107
|
+
and storage_settings is not None
|
108
|
+
and artifact.is_latest
|
109
|
+
):
|
110
|
+
cache_key = (storage_settings.root / artifact.key).path
|
111
|
+
return cache_key
|
112
|
+
|
113
|
+
|
114
|
+
# return filepath and cache_key if needed
|
115
|
+
def filepath_cache_key_from_artifact(
|
116
|
+
artifact: Artifact, using_key: str | None = None
|
117
|
+
) -> tuple[UPath, str | None]:
|
118
|
+
filepath, storage_settings = filepath_from_artifact(artifact, using_key)
|
119
|
+
if isinstance(filepath, LocalPathClasses):
|
120
|
+
return filepath, None
|
121
|
+
cache_key = _cache_key_from_artifact_storage(artifact, storage_settings)
|
122
|
+
return filepath, cache_key
|
123
|
+
|
124
|
+
|
125
|
+
def store_file_or_folder(
|
126
|
+
local_path: UPathStr, storage_path: UPath, print_progress: bool = True
|
127
|
+
) -> None:
|
128
|
+
"""Store file or folder (localpath) at storagepath."""
|
129
|
+
local_path = UPath(local_path)
|
130
|
+
if not isinstance(storage_path, LocalPathClasses):
|
131
|
+
# this uploads files and directories
|
132
|
+
create_folder = False if local_path.is_dir() else None
|
133
|
+
storage_path.upload_from(
|
134
|
+
local_path, create_folder=create_folder, print_progress=print_progress
|
135
|
+
)
|
136
|
+
else: # storage path is local
|
137
|
+
if local_path.resolve().as_posix() == storage_path.resolve().as_posix():
|
138
|
+
return None
|
139
|
+
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
140
|
+
if local_path.is_file():
|
141
|
+
shutil.copyfile(local_path, storage_path)
|
142
|
+
else:
|
143
|
+
if storage_path.exists():
|
144
|
+
shutil.rmtree(storage_path)
|
145
|
+
shutil.copytree(local_path, storage_path)
|
146
|
+
|
147
|
+
|
148
|
+
def delete_storage_using_key(
|
149
|
+
artifact: Artifact, storage_key: str, using_key: str | None
|
150
|
+
):
|
151
|
+
filepath, _ = attempt_accessing_path(artifact, storage_key, using_key=using_key)
|
152
|
+
delete_storage(filepath)
|
153
|
+
|
154
|
+
|
155
|
+
def delete_storage(
|
156
|
+
storagepath: Path, raise_file_not_found_error: bool = True
|
157
|
+
) -> None | str:
|
158
|
+
"""Delete arbitrary artifact."""
|
159
|
+
if storagepath.is_file():
|
160
|
+
storagepath.unlink()
|
161
|
+
elif storagepath.is_dir():
|
162
|
+
if isinstance(storagepath, LocalPathClasses) or not isinstance(
|
163
|
+
storagepath, UPath
|
164
|
+
):
|
165
|
+
shutil.rmtree(storagepath)
|
166
|
+
else:
|
167
|
+
storagepath.rmdir()
|
168
|
+
elif raise_file_not_found_error:
|
169
|
+
raise FileNotFoundError(f"{storagepath} is not an existing path!")
|
170
|
+
else:
|
171
|
+
logger.warning(f"{storagepath} is not an existing path!")
|
172
|
+
return None
|
@@ -1,12 +1,12 @@
|
|
1
|
-
"""Sub settings.
|
2
|
-
|
3
|
-
.. autosummary::
|
4
|
-
:toctree: .
|
5
|
-
|
6
|
-
TransformSettings
|
7
|
-
CreationSettings
|
8
|
-
|
9
|
-
"""
|
10
|
-
|
11
|
-
from ._creation_settings import CreationSettings
|
12
|
-
from ._transform_settings import TransformSettings
|
1
|
+
"""Sub settings.
|
2
|
+
|
3
|
+
.. autosummary::
|
4
|
+
:toctree: .
|
5
|
+
|
6
|
+
TransformSettings
|
7
|
+
CreationSettings
|
8
|
+
|
9
|
+
"""
|
10
|
+
|
11
|
+
from ._creation_settings import CreationSettings
|
12
|
+
from ._transform_settings import TransformSettings
|
@@ -1,38 +1,38 @@
|
|
1
|
-
from typing import Literal
|
2
|
-
|
3
|
-
|
4
|
-
class CreationSettings:
|
5
|
-
artifact_if_hash_exists: Literal[
|
6
|
-
"warn_return_existing", "error", "warn_create_new"
|
7
|
-
] = "warn_return_existing"
|
8
|
-
"""Behavior if file hash exists (default `"warn_return_existing"`).
|
9
|
-
|
10
|
-
One of `["warn_return_existing", "error", "warn_create_new"]`.
|
11
|
-
|
12
|
-
FAQ: :doc:`/faq/idempotency`
|
13
|
-
"""
|
14
|
-
artifact_skip_size_hash: bool = False
|
15
|
-
"""To speed up registering high numbers of files (default `False`).
|
16
|
-
|
17
|
-
This bypasses queries for size and hash to AWS & GCP.
|
18
|
-
|
19
|
-
It speeds up file creation by about a factor 100.
|
20
|
-
"""
|
21
|
-
search_names: bool = True
|
22
|
-
"""To speed up creating records (default `True`).
|
23
|
-
|
24
|
-
If `True`, search for alternative names.
|
25
|
-
|
26
|
-
FAQ: :doc:`/faq/idempotency`
|
27
|
-
"""
|
28
|
-
artifact_silence_missing_run_warning: bool = False
|
29
|
-
"""Silence warning about missing run & transform during artifact creation."""
|
30
|
-
_artifact_use_virtual_keys: bool = True
|
31
|
-
"""Treat `key` parameter in :class:`~lamindb.Artifact` as virtual.
|
32
|
-
|
33
|
-
If `True`, the `key` is **not** used to construct file paths, but file paths are
|
34
|
-
based on the `uid` of artifact.
|
35
|
-
"""
|
36
|
-
|
37
|
-
|
38
|
-
creation_settings = CreationSettings()
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
|
4
|
+
class CreationSettings:
|
5
|
+
artifact_if_hash_exists: Literal[
|
6
|
+
"warn_return_existing", "error", "warn_create_new"
|
7
|
+
] = "warn_return_existing"
|
8
|
+
"""Behavior if file hash exists (default `"warn_return_existing"`).
|
9
|
+
|
10
|
+
One of `["warn_return_existing", "error", "warn_create_new"]`.
|
11
|
+
|
12
|
+
FAQ: :doc:`/faq/idempotency`
|
13
|
+
"""
|
14
|
+
artifact_skip_size_hash: bool = False
|
15
|
+
"""To speed up registering high numbers of files (default `False`).
|
16
|
+
|
17
|
+
This bypasses queries for size and hash to AWS & GCP.
|
18
|
+
|
19
|
+
It speeds up file creation by about a factor 100.
|
20
|
+
"""
|
21
|
+
search_names: bool = True
|
22
|
+
"""To speed up creating records (default `True`).
|
23
|
+
|
24
|
+
If `True`, search for alternative names.
|
25
|
+
|
26
|
+
FAQ: :doc:`/faq/idempotency`
|
27
|
+
"""
|
28
|
+
artifact_silence_missing_run_warning: bool = False
|
29
|
+
"""Silence warning about missing run & transform during artifact creation."""
|
30
|
+
_artifact_use_virtual_keys: bool = True
|
31
|
+
"""Treat `key` parameter in :class:`~lamindb.Artifact` as virtual.
|
32
|
+
|
33
|
+
If `True`, the `key` is **not** used to construct file paths, but file paths are
|
34
|
+
based on the `uid` of artifact.
|
35
|
+
"""
|
36
|
+
|
37
|
+
|
38
|
+
creation_settings = CreationSettings()
|
@@ -1,21 +1,21 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
|
4
|
-
class TransformSettings:
|
5
|
-
stem_uid: str | None = None
|
6
|
-
"""Defines the version family of the transform.
|
7
|
-
|
8
|
-
For example, all notebooks of the same family have a uid that starts with
|
9
|
-
`"FPnfDtJz8qbE"`.
|
10
|
-
|
11
|
-
The full uids of the notebooks in this family are of form
|
12
|
-
`"{stem_uid}{suffix_uid}"` where the `suffix_uid` encodes the semantic
|
13
|
-
`version`.
|
14
|
-
"""
|
15
|
-
version: str | None = None
|
16
|
-
"""The version."""
|
17
|
-
name: str | None = None
|
18
|
-
"""A name like a notebook or script title."""
|
19
|
-
|
20
|
-
|
21
|
-
transform_settings = TransformSettings()
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
|
4
|
+
class TransformSettings:
|
5
|
+
stem_uid: str | None = None
|
6
|
+
"""Defines the version family of the transform.
|
7
|
+
|
8
|
+
For example, all notebooks of the same family have a uid that starts with
|
9
|
+
`"FPnfDtJz8qbE"`.
|
10
|
+
|
11
|
+
The full uids of the notebooks in this family are of form
|
12
|
+
`"{stem_uid}{suffix_uid}"` where the `suffix_uid` encodes the semantic
|
13
|
+
`version`.
|
14
|
+
"""
|
15
|
+
version: str | None = None
|
16
|
+
"""The version."""
|
17
|
+
name: str | None = None
|
18
|
+
"""A name like a notebook or script title."""
|
19
|
+
|
20
|
+
|
21
|
+
transform_settings = TransformSettings()
|
lamindb/core/types.py
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
"""Types.
|
2
|
-
|
3
|
-
.. autosummary::
|
4
|
-
:toctree: .
|
5
|
-
|
6
|
-
UPathStr
|
7
|
-
StrField
|
8
|
-
ListLike
|
9
|
-
TransformType
|
10
|
-
ArtifactType
|
11
|
-
"""
|
12
|
-
|
13
|
-
from lamindb_setup.core.types import UPathStr
|
14
|
-
from lnschema_core.types import (
|
15
|
-
ArtifactType,
|
16
|
-
ListLike,
|
17
|
-
StrField,
|
18
|
-
TransformType,
|
19
|
-
)
|
1
|
+
"""Types.
|
2
|
+
|
3
|
+
.. autosummary::
|
4
|
+
:toctree: .
|
5
|
+
|
6
|
+
UPathStr
|
7
|
+
StrField
|
8
|
+
ListLike
|
9
|
+
TransformType
|
10
|
+
ArtifactType
|
11
|
+
"""
|
12
|
+
|
13
|
+
from lamindb_setup.core.types import UPathStr
|
14
|
+
from lnschema_core.types import (
|
15
|
+
ArtifactType,
|
16
|
+
ListLike,
|
17
|
+
StrField,
|
18
|
+
TransformType,
|
19
|
+
)
|