lamindb 0.70.1__py3-none-any.whl → 0.70.2__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 +4 -4
- lamindb/_finish.py +31 -29
- lamindb/core/storage/__init__.py +1 -0
- lamindb/core/storage/_backed_access.py +3 -3
- lamindb/core/storage/_valid_suffixes.py +3 -0
- lamindb/integrations/_vitessce.py +44 -24
- {lamindb-0.70.1.dist-info → lamindb-0.70.2.dist-info}/METADATA +3 -3
- {lamindb-0.70.1.dist-info → lamindb-0.70.2.dist-info}/RECORD +11 -10
- {lamindb-0.70.1.dist-info → lamindb-0.70.2.dist-info}/LICENSE +0 -0
- {lamindb-0.70.1.dist-info → lamindb-0.70.2.dist-info}/WHEEL +0 -0
lamindb/__init__.py
CHANGED
lamindb/_annotate.py
CHANGED
@@ -351,7 +351,7 @@ class AnnDataAnnotator(DataFrameAnnotator):
|
|
351
351
|
self,
|
352
352
|
adata: ad.AnnData,
|
353
353
|
var_index: FieldAttr,
|
354
|
-
categoricals: dict[str, FieldAttr],
|
354
|
+
categoricals: dict[str, FieldAttr] | None = None,
|
355
355
|
using: str = "default",
|
356
356
|
verbosity: str = "hint",
|
357
357
|
organism: str | None = None,
|
@@ -494,7 +494,7 @@ class MuDataAnnotator:
|
|
494
494
|
self,
|
495
495
|
mdata: MuData,
|
496
496
|
var_index: dict[str, dict[str, FieldAttr]],
|
497
|
-
categoricals: dict[str, FieldAttr],
|
497
|
+
categoricals: dict[str, FieldAttr] | None = None,
|
498
498
|
using: str = "default",
|
499
499
|
verbosity: str = "hint",
|
500
500
|
organism: str | None = None,
|
@@ -751,7 +751,7 @@ class Annotate:
|
|
751
751
|
cls,
|
752
752
|
adata: ad.AnnData,
|
753
753
|
var_index: FieldAttr,
|
754
|
-
categoricals: dict[str, FieldAttr],
|
754
|
+
categoricals: dict[str, FieldAttr] | None = None,
|
755
755
|
using: str = "default",
|
756
756
|
verbosity: str = "hint",
|
757
757
|
organism: str | None = None,
|
@@ -772,7 +772,7 @@ class Annotate:
|
|
772
772
|
cls,
|
773
773
|
mdata: MuData,
|
774
774
|
var_index: dict[str, dict[str, FieldAttr]],
|
775
|
-
categoricals: dict[str,
|
775
|
+
categoricals: dict[str, FieldAttr] | None = None,
|
776
776
|
using: str = "default",
|
777
777
|
verbosity: str = "hint",
|
778
778
|
organism: str | None = None,
|
lamindb/_finish.py
CHANGED
@@ -20,37 +20,40 @@ if TYPE_CHECKING:
|
|
20
20
|
from ._query_set import QuerySet
|
21
21
|
|
22
22
|
|
23
|
-
class
|
23
|
+
class TrackNotCalled(SystemExit):
|
24
24
|
pass
|
25
25
|
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
class NotebookNotSaved(SystemExit):
|
28
|
+
pass
|
29
29
|
|
30
|
-
When run in notebooks, save the run report to your default storage location.
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
editor (JupyterLab, VSCode, etc.).
|
35
|
-
"""
|
36
|
-
if is_run_from_ipython:
|
37
|
-
# notebooks
|
38
|
-
from nbproject.dev import read_notebook
|
39
|
-
from nbproject.dev._check_last_cell import check_last_cell
|
31
|
+
def get_seconds_since_modified(filepath) -> float:
|
32
|
+
return datetime.now().timestamp() - filepath.stat().st_mtime
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
|
35
|
+
def finish():
|
36
|
+
"""Mark a tracked run as finished.
|
37
|
+
|
38
|
+
If run in a notebook, it saves the run report & source code to your default storage location.
|
39
|
+
"""
|
40
|
+
if run_context.path is None:
|
41
|
+
raise TrackNotCalled("Please run `ln.track()` before `ln.finish()`")
|
42
|
+
if is_run_from_ipython: # notebooks
|
43
|
+
if (
|
44
|
+
get_seconds_since_modified(run_context.path) > 3
|
45
|
+
and os.getenv("LAMIN_TESTING") is None
|
46
|
+
):
|
47
|
+
raise NotebookNotSaved(
|
48
|
+
"Please save the notebook in your editor right before running `ln.finish()`"
|
44
49
|
)
|
45
|
-
return None
|
46
50
|
save_run_context_core(
|
47
51
|
run=run_context.run,
|
48
52
|
transform=run_context.transform,
|
49
53
|
filepath=run_context.path,
|
50
54
|
finished_at=True,
|
51
55
|
)
|
52
|
-
else:
|
53
|
-
# scripts
|
56
|
+
else: # scripts
|
54
57
|
# save_run_context_core was already called during ln.track()
|
55
58
|
run_context.run.finished_at = datetime.now(timezone.utc) # update run time
|
56
59
|
run_context.run.save()
|
@@ -98,7 +101,7 @@ def save_run_context_core(
|
|
98
101
|
# log_level is set to 40 to silence the nbconvert logging
|
99
102
|
subprocess.run(
|
100
103
|
"jupyter nbconvert --to html"
|
101
|
-
f" {filepath.as_posix()} --Application.log_level=40",
|
104
|
+
f" '{filepath.as_posix()}' --Application.log_level=40",
|
102
105
|
shell=True,
|
103
106
|
check=True,
|
104
107
|
)
|
@@ -118,7 +121,7 @@ def save_run_context_core(
|
|
118
121
|
# first, copy the notebook file to a temporary file in the cache
|
119
122
|
source_code_path = ln_setup.settings.storage.cache_dir / filepath.name
|
120
123
|
shutil.copy2(filepath, source_code_path) # copy
|
121
|
-
subprocess.run(f"nbstripout {source_code_path}", shell=True, check=True)
|
124
|
+
subprocess.run(f"nbstripout '{source_code_path}'", shell=True, check=True)
|
122
125
|
# find initial versions of source codes and html reports
|
123
126
|
prev_report = None
|
124
127
|
prev_source = None
|
@@ -139,9 +142,8 @@ def save_run_context_core(
|
|
139
142
|
if os.getenv("LAMIN_TESTING") is None:
|
140
143
|
# in test, auto-confirm overwrite
|
141
144
|
response = input(
|
142
|
-
"You
|
143
|
-
f" '{transform.version}'
|
144
|
-
f" existing source code {transform.source_code}? (y/n)"
|
145
|
+
f"You are about to overwrite existing source code (hash {transform.source_code.hash}) for transform version"
|
146
|
+
f" '{transform.version}'. Proceed? (y/n)"
|
145
147
|
)
|
146
148
|
else:
|
147
149
|
response = "y"
|
@@ -149,10 +151,7 @@ def save_run_context_core(
|
|
149
151
|
transform.source_code.replace(source_code_path)
|
150
152
|
transform.source_code.save()
|
151
153
|
else:
|
152
|
-
logger.warning(
|
153
|
-
"Please create a new version of the notebook via `lamin track"
|
154
|
-
" <filepath>` and re-run the notebook"
|
155
|
-
)
|
154
|
+
logger.warning("Please re-run `ln.track()` to make a new version")
|
156
155
|
return "rerun-the-notebook"
|
157
156
|
else:
|
158
157
|
source_code = ln.Artifact(
|
@@ -207,8 +206,11 @@ def save_run_context_core(
|
|
207
206
|
transform.save()
|
208
207
|
if transform.type == TransformType.notebook:
|
209
208
|
logger.success(f"saved transform.latest_report: {transform.latest_report}")
|
210
|
-
|
211
|
-
|
209
|
+
if ln_setup.settings.instance.is_remote:
|
210
|
+
identifier = ln_setup.settings.instance.slug
|
211
|
+
logger.success(
|
212
|
+
f"go to: https://lamin.ai/{identifier}/transform/{transform.uid}"
|
213
|
+
)
|
212
214
|
# because run & transform changed, update the global run_context
|
213
215
|
run_context.run = run
|
214
216
|
run_context.transform = transform
|
lamindb/core/storage/__init__.py
CHANGED
@@ -10,5 +10,6 @@ from lamindb_setup.core.upath import LocalPathClasses, UPath, infer_filesystem
|
|
10
10
|
|
11
11
|
from ._anndata_sizes import size_adata
|
12
12
|
from ._backed_access import AnnDataAccessor, BackedAccessor
|
13
|
+
from ._valid_suffixes import VALID_SUFFIXES
|
13
14
|
from .objects import infer_suffix, write_to_file
|
14
15
|
from .paths import delete_storage, load_to_memory
|
@@ -733,7 +733,7 @@ class BackedAccessor:
|
|
733
733
|
|
734
734
|
|
735
735
|
def backed_access(
|
736
|
-
artifact_or_filepath: Artifact | Path, using_key: str | None
|
736
|
+
artifact_or_filepath: Artifact | Path, using_key: str | None = None
|
737
737
|
) -> AnnDataAccessor | BackedAccessor:
|
738
738
|
if isinstance(artifact_or_filepath, Artifact):
|
739
739
|
filepath = filepath_from_artifact(artifact_or_filepath, using_key=using_key)
|
@@ -747,11 +747,11 @@ def backed_access(
|
|
747
747
|
conn, storage = registry.open("zarr", filepath)
|
748
748
|
else:
|
749
749
|
raise ValueError(
|
750
|
-
"
|
750
|
+
"object should have .h5, .hdf5, .h5ad, .zarr suffix, not"
|
751
751
|
f" {filepath.suffix}."
|
752
752
|
)
|
753
753
|
|
754
|
-
if filepath.suffix
|
754
|
+
if filepath.suffix == ".h5ad":
|
755
755
|
return AnnDataAccessor(conn, storage, name)
|
756
756
|
else:
|
757
757
|
if get_spec(storage).encoding_type == "anndata":
|
@@ -8,6 +8,8 @@ import lamindb_setup as ln_setup
|
|
8
8
|
from lamin_utils import logger
|
9
9
|
|
10
10
|
from lamindb._artifact import Artifact
|
11
|
+
from lamindb._run import Run
|
12
|
+
from lamindb._transform import Transform
|
11
13
|
|
12
14
|
if TYPE_CHECKING:
|
13
15
|
from vitessce import VitessceConfig
|
@@ -15,36 +17,54 @@ if TYPE_CHECKING:
|
|
15
17
|
|
16
18
|
# tested & context in https://github.com/laminlabs/lamin-spatial
|
17
19
|
def save_vitessce_config(vitessce_config: VitessceConfig, description: str) -> Artifact:
|
18
|
-
"""
|
20
|
+
"""Validates and saves a ``VitessceConfig`` object.
|
21
|
+
|
22
|
+
Example: :doc:`docs:vitessce`.
|
19
23
|
|
20
24
|
Args:
|
21
25
|
vitessce_config (``VitessceConfig``): A VitessceConfig object.
|
22
26
|
description: A description for the artifact.
|
23
|
-
"""
|
24
|
-
# can't assume vitessce is installed
|
25
|
-
from vitessce import VitessceConfig
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
vitessce_config.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
28
|
+
.. versionchanged:: 0.70.2
|
29
|
+
This function no longer saves the dataset. It only saves the VitessceConfig object.
|
30
|
+
"""
|
31
|
+
vc_dict = vitessce_config.to_dict()
|
32
|
+
# validate
|
33
|
+
datasets = vc_dict["datasets"]
|
34
|
+
input_artifacts = []
|
35
|
+
for dataset in datasets:
|
36
|
+
if "files" not in dataset:
|
37
|
+
raise ValueError("Each dataset must have a 'files' key.")
|
38
|
+
for file in dataset["files"]:
|
39
|
+
if "url" not in file:
|
40
|
+
raise ValueError("Each file must have a 'url' key.")
|
41
|
+
filename = file["url"].split("/")[-1]
|
42
|
+
assert filename.endswith((".anndata.zarr", ".spatialdata.zarr", ".zarr"))
|
43
|
+
filestem = (
|
44
|
+
filename.replace(".anndata.zarr", "")
|
45
|
+
.replace(".spatialdata.zarr", "")
|
46
|
+
.replace(".zarr", "")
|
47
|
+
)
|
48
|
+
artifact = Artifact.filter(uid__startswith=filestem).one_or_none()
|
49
|
+
if artifact is None:
|
50
|
+
logger.warning(f"could not find dataset in lamindb: {dataset}")
|
51
|
+
else:
|
52
|
+
input_artifacts.append(artifact)
|
53
|
+
# link inputs
|
54
|
+
with logger.mute():
|
55
|
+
transform = Transform(name="save_vitessce_config", type="function", version="1")
|
56
|
+
transform.save()
|
57
|
+
run = Run(transform=transform)
|
58
|
+
run.save()
|
59
|
+
run.input_artifacts.set(input_artifacts)
|
60
|
+
# create a JSON export
|
61
|
+
config_file_local_path = (
|
62
|
+
ln_setup.settings.storage.cache_dir / "config.vitessce.json"
|
63
|
+
)
|
41
64
|
with open(config_file_local_path, "w") as file:
|
42
|
-
json.dump(
|
43
|
-
|
44
|
-
|
45
|
-
config_file_path.upload_from(config_file_local_path)
|
46
|
-
# log the the URLs
|
47
|
-
logger.important(f"config url: {config_file_path.to_url()}")
|
65
|
+
json.dump(vc_dict, file)
|
66
|
+
artifact = Artifact(config_file_local_path, description=description, run=run)
|
67
|
+
artifact.save()
|
48
68
|
slug = ln_setup.settings.instance.slug
|
49
69
|
logger.important(f"go to: https://lamin.ai/{slug}/artifact/{artifact.uid}")
|
50
70
|
return artifact
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lamindb
|
3
|
-
Version: 0.70.
|
3
|
+
Version: 0.70.2
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
6
|
Requires-Python: >=3.8
|
@@ -10,8 +10,8 @@ Classifier: Programming Language :: Python :: 3.9
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
12
|
Requires-Dist: lnschema_core==0.65.1
|
13
|
-
Requires-Dist: lamindb_setup==0.69.
|
14
|
-
Requires-Dist: lamin_utils==0.13.
|
13
|
+
Requires-Dist: lamindb_setup==0.69.4
|
14
|
+
Requires-Dist: lamin_utils==0.13.2
|
15
15
|
Requires-Dist: lamin_cli==0.12.3
|
16
16
|
Requires-Dist: rapidfuzz
|
17
17
|
Requires-Dist: pyarrow
|
@@ -1,12 +1,12 @@
|
|
1
|
-
lamindb/__init__.py,sha256=
|
2
|
-
lamindb/_annotate.py,sha256=
|
1
|
+
lamindb/__init__.py,sha256=JHrhBHkihUcLRbreh9xyafsWang75NJxz9CVIWx6Bc0,2163
|
2
|
+
lamindb/_annotate.py,sha256=B0KSvo5S2kJPeMMqy2SSFkqRJCS2QRC4NtI0_vWEZMs,43080
|
3
3
|
lamindb/_artifact.py,sha256=BUl_3WYwrZ28P93Pb9AiwriVFBSLvBUEQjYEyYCrkZ0,37307
|
4
4
|
lamindb/_can_validate.py,sha256=nvoZG-35n3HofkY4Xc6hBv9AV54_RDan7Hzp5TuqY9I,14709
|
5
5
|
lamindb/_collection.py,sha256=wf7ClfiD3vsetts_iSUk4UihWsHq0IdOF8LdIIHS7JU,14536
|
6
6
|
lamindb/_feature.py,sha256=srAKchY7gqD-h-cWlEiAWuHlpFKFwv0PWIA-JX0Go8c,6758
|
7
7
|
lamindb/_feature_set.py,sha256=AzjOcHzQajpeikPOAic-aj0z_C5b7VpHVegg3ThRSLw,9045
|
8
8
|
lamindb/_filter.py,sha256=xnjJzjF3Zj4dK_Kfymvhgczk27MhhXz5ZYc7XINbgHY,1331
|
9
|
-
lamindb/_finish.py,sha256=
|
9
|
+
lamindb/_finish.py,sha256=oR7oe6By3vEhF0twDBqSdT1EF28MPhyiS_cfZP0CcCw,8040
|
10
10
|
lamindb/_from_values.py,sha256=DVXjnQ2wwNw-2bFzy0uXLdVlqoprrn95hTnrXwn-KqM,12638
|
11
11
|
lamindb/_is_versioned.py,sha256=0PgRCmxEmYDcAjllLSOYZm132B1lW6QgmBBERhRyFt0,1341
|
12
12
|
lamindb/_parents.py,sha256=N9T8jbd3eaoHDLE9TD1y1QgGcO81E6Brapy8LILzRCQ,14790
|
@@ -38,17 +38,18 @@ lamindb/core/versioning.py,sha256=DsEHpCueNwhRiIaRH5-O8H_1fJVNtWslCRx30YiIS5o,30
|
|
38
38
|
lamindb/core/datasets/__init__.py,sha256=zRP98oqUAaXhqWyKMiH0s_ImVIuNeziQQ2kQ_t0f-DI,1353
|
39
39
|
lamindb/core/datasets/_core.py,sha256=36vUOYFkX_4hBAnM_BujV5BRARMI5b9iI_SM9qS7wGc,20191
|
40
40
|
lamindb/core/datasets/_fake.py,sha256=BZF9R_1iF0HDnvtZNqL2FtsjSMuqDIfuFxnw_LJYIh4,953
|
41
|
-
lamindb/core/storage/__init__.py,sha256=
|
41
|
+
lamindb/core/storage/__init__.py,sha256=6jnbFj-eBV3xZt04qP-kTsMWoP8YwpM50wlnnxDYsZU,415
|
42
42
|
lamindb/core/storage/_anndata_sizes.py,sha256=aXO3OB--tF5MChenSsigW6Q-RuE8YJJOUTVukkLrv9A,1029
|
43
|
-
lamindb/core/storage/_backed_access.py,sha256=
|
43
|
+
lamindb/core/storage/_backed_access.py,sha256=eManrLsu3pSSQAyAKy47FDBm-iHgjaNfHA-zLy59uDs,24536
|
44
|
+
lamindb/core/storage/_valid_suffixes.py,sha256=sewRRU3I6fJ-Jd5ACNcco_o3hic9zmqTs8BuZui-450,133
|
44
45
|
lamindb/core/storage/_zarr.py,sha256=0i9-cJPjieIsp5UpK-IyRPkHAF-iKkWgpkWviSni2MM,2900
|
45
46
|
lamindb/core/storage/objects.py,sha256=5LbBeZVKuOOB8DceSE-PN8elKY0N9OhFXZPQJE4lK48,1538
|
46
47
|
lamindb/core/storage/paths.py,sha256=XWfSHK5b3_TFiK-IMvH-srvxO0bZStzA_rwjNaTxQU4,7725
|
47
48
|
lamindb/integrations/__init__.py,sha256=aH2PmO2m4-vwIifMYTB0Fyyr_gZWtVnV71jT0tVWSw0,123
|
48
|
-
lamindb/integrations/_vitessce.py,sha256=
|
49
|
+
lamindb/integrations/_vitessce.py,sha256=Ii2YhGwXH_tNDS9MXzxNekthWoDmDGpgGxAOVcTIbB4,2550
|
49
50
|
lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
|
50
51
|
lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
|
51
|
-
lamindb-0.70.
|
52
|
-
lamindb-0.70.
|
53
|
-
lamindb-0.70.
|
54
|
-
lamindb-0.70.
|
52
|
+
lamindb-0.70.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
53
|
+
lamindb-0.70.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
54
|
+
lamindb-0.70.2.dist-info/METADATA,sha256=KqXBjKMhKMBbx7VYeaWWfP0Xot_OyRRjpFO9vZotb7c,2835
|
55
|
+
lamindb-0.70.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|