lamindb 0.76.10__py3-none-any.whl → 0.76.12__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/_artifact.py +4 -8
- lamindb/_filter.py +0 -2
- lamindb/_finish.py +11 -4
- lamindb/_query_set.py +2 -2
- lamindb/_record.py +4 -8
- lamindb/_save.py +1 -1
- lamindb/core/_context.py +16 -10
- lamindb/core/_feature_manager.py +39 -8
- lamindb/core/_label_manager.py +1 -2
- lamindb/core/_settings.py +5 -0
- lamindb/core/_sync_git.py +2 -2
- lamindb/core/_track_environment.py +1 -1
- lamindb/core/exceptions.py +1 -1
- lamindb/integrations/_vitessce.py +45 -51
- {lamindb-0.76.10.dist-info → lamindb-0.76.12.dist-info}/METADATA +5 -5
- {lamindb-0.76.10.dist-info → lamindb-0.76.12.dist-info}/RECORD +19 -19
- {lamindb-0.76.10.dist-info → lamindb-0.76.12.dist-info}/LICENSE +0 -0
- {lamindb-0.76.10.dist-info → lamindb-0.76.12.dist-info}/WHEEL +0 -0
lamindb/__init__.py
CHANGED
lamindb/_artifact.py
CHANGED
@@ -10,7 +10,7 @@ import fsspec
|
|
10
10
|
import lamindb_setup as ln_setup
|
11
11
|
import pandas as pd
|
12
12
|
from anndata import AnnData
|
13
|
-
from django.db.models import Q
|
13
|
+
from django.db.models import Q
|
14
14
|
from lamin_utils import colors, logger
|
15
15
|
from lamindb_setup import settings as setup_settings
|
16
16
|
from lamindb_setup._init_instance import register_storage_in_instance
|
@@ -180,7 +180,7 @@ def process_data(
|
|
180
180
|
f" be '{suffix}'."
|
181
181
|
)
|
182
182
|
cache_name = f"{provisional_uid}{suffix}"
|
183
|
-
path = settings.
|
183
|
+
path = settings.cache_dir / cache_name
|
184
184
|
# Alex: I don't understand the line below
|
185
185
|
if path.suffixes == []:
|
186
186
|
path = path.with_suffix(suffix)
|
@@ -344,7 +344,7 @@ def get_artifact_kwargs_from_data(
|
|
344
344
|
|
345
345
|
if revises is not None: # update provisional_uid
|
346
346
|
provisional_uid, revises = create_uid(revises=revises, version=version)
|
347
|
-
if settings.
|
347
|
+
if settings.cache_dir in path.parents:
|
348
348
|
path = path.rename(path.with_name(f"{provisional_uid}{suffix}"))
|
349
349
|
|
350
350
|
check_path_in_storage = False
|
@@ -749,10 +749,6 @@ def from_dir(
|
|
749
749
|
run: Run | None = None,
|
750
750
|
) -> list[Artifact]:
|
751
751
|
"""{}""" # noqa: D415
|
752
|
-
logger.warning(
|
753
|
-
"this creates one artifact per file in the directory - consider"
|
754
|
-
" ln.Artifact(dir_path) to get one artifact for the entire directory"
|
755
|
-
)
|
756
752
|
folderpath: UPath = create_path(path) # returns Path for local
|
757
753
|
default_storage = settings.storage.record
|
758
754
|
using_key = settings._using_key
|
@@ -1125,7 +1121,7 @@ def save(self, upload: bool | None = None, **kwargs) -> Artifact:
|
|
1125
1121
|
raise RuntimeError(exception)
|
1126
1122
|
if local_path is not None and not state_was_adding:
|
1127
1123
|
# only move the local artifact to cache if it was not newly created
|
1128
|
-
local_path_cache = ln_setup.settings.
|
1124
|
+
local_path_cache = ln_setup.settings.cache_dir / local_path.name
|
1129
1125
|
# don't use Path.rename here because of cross-device link error
|
1130
1126
|
# https://laminlabs.slack.com/archives/C04A0RMA0SC/p1710259102686969
|
1131
1127
|
shutil.move(
|
lamindb/_filter.py
CHANGED
lamindb/_finish.py
CHANGED
@@ -35,6 +35,13 @@ def prepare_notebook(
|
|
35
35
|
if strip_title:
|
36
36
|
lines.pop(i)
|
37
37
|
cell["source"] = "\n".join(lines)
|
38
|
+
# strip resaved finish error if present
|
39
|
+
# this is normally the last cell
|
40
|
+
if cell["cell_type"] == "code" and ".finish(" in cell["source"]:
|
41
|
+
for output in cell["outputs"]:
|
42
|
+
if output.get("ename", None) == "NotebookNotSaved":
|
43
|
+
cell["outputs"] = []
|
44
|
+
break
|
38
45
|
return None
|
39
46
|
|
40
47
|
|
@@ -112,7 +119,7 @@ def save_context_core(
|
|
112
119
|
notebook_content = read_notebook(filepath) # type: ignore
|
113
120
|
if not ignore_non_consecutive: # ignore_non_consecutive is None or False
|
114
121
|
is_consecutive = check_consecutiveness(
|
115
|
-
notebook_content, calling_statement=".finish(
|
122
|
+
notebook_content, calling_statement=".finish("
|
116
123
|
)
|
117
124
|
if not is_consecutive:
|
118
125
|
response = "n" # ignore_non_consecutive == False
|
@@ -123,12 +130,12 @@ def save_context_core(
|
|
123
130
|
if response != "y":
|
124
131
|
return "aborted-non-consecutive"
|
125
132
|
# write the report
|
126
|
-
report_path = ln_setup.settings.
|
133
|
+
report_path = ln_setup.settings.cache_dir / filepath.name.replace(
|
127
134
|
".ipynb", ".html"
|
128
135
|
)
|
129
136
|
notebook_to_report(filepath, report_path)
|
130
137
|
# write the source code
|
131
|
-
source_code_path = ln_setup.settings.
|
138
|
+
source_code_path = ln_setup.settings.cache_dir / filepath.name.replace(
|
132
139
|
".ipynb", ".py"
|
133
140
|
)
|
134
141
|
notebook_to_script(transform, filepath, source_code_path)
|
@@ -164,7 +171,7 @@ def save_context_core(
|
|
164
171
|
transform.hash = hash
|
165
172
|
|
166
173
|
# track environment
|
167
|
-
env_path = ln_setup.settings.
|
174
|
+
env_path = ln_setup.settings.cache_dir / f"run_env_pip_{run.uid}.txt"
|
168
175
|
if env_path.exists():
|
169
176
|
overwrite_env = True
|
170
177
|
if run.environment_id is not None and from_cli:
|
lamindb/_query_set.py
CHANGED
@@ -139,7 +139,7 @@ class QuerySet(models.QuerySet):
|
|
139
139
|
|
140
140
|
See Also:
|
141
141
|
|
142
|
-
`django QuerySet <https://docs.djangoproject.com/en/4.2/ref/models/querysets/>`__
|
142
|
+
`django QuerySet <https://docs.djangoproject.com/en/4.2/ref/models/querysets/>`__
|
143
143
|
|
144
144
|
Examples:
|
145
145
|
|
@@ -154,7 +154,7 @@ class QuerySet(models.QuerySet):
|
|
154
154
|
) -> pd.DataFrame:
|
155
155
|
"""{}""" # noqa: D415
|
156
156
|
# re-order the columns
|
157
|
-
exclude_field_names = ["
|
157
|
+
exclude_field_names = ["updated_at"]
|
158
158
|
field_names = [
|
159
159
|
field.name
|
160
160
|
for field in self.model._meta.fields
|
lamindb/_record.py
CHANGED
@@ -15,7 +15,7 @@ from lamindb_setup._connect_instance import (
|
|
15
15
|
update_db_using_local,
|
16
16
|
)
|
17
17
|
from lamindb_setup.core._docs import doc_args
|
18
|
-
from lamindb_setup.core._hub_core import
|
18
|
+
from lamindb_setup.core._hub_core import connect_instance_hub
|
19
19
|
from lamindb_setup.core._settings_store import instance_settings_file
|
20
20
|
from lnschema_core.models import IsVersioned, Record, Run, Transform
|
21
21
|
|
@@ -380,11 +380,9 @@ def using(
|
|
380
380
|
return QuerySet(model=cls, using=None)
|
381
381
|
owner, name = get_owner_name_from_identifier(instance)
|
382
382
|
settings_file = instance_settings_file(name, owner)
|
383
|
-
cache_filepath =
|
384
|
-
ln_setup.settings.storage.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
385
|
-
)
|
383
|
+
cache_filepath = ln_setup.settings.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
386
384
|
if not settings_file.exists():
|
387
|
-
result =
|
385
|
+
result = connect_instance_hub(owner=owner, name=name)
|
388
386
|
if isinstance(result, str):
|
389
387
|
raise RuntimeError(
|
390
388
|
f"Failed to load instance {instance}, please check your permissions!"
|
@@ -469,9 +467,7 @@ def get_transfer_run(record) -> Run:
|
|
469
467
|
|
470
468
|
slug = record._state.db
|
471
469
|
owner, name = get_owner_name_from_identifier(slug)
|
472
|
-
cache_filepath =
|
473
|
-
ln_setup.settings.storage.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
474
|
-
)
|
470
|
+
cache_filepath = ln_setup.settings.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
475
471
|
if not cache_filepath.exists():
|
476
472
|
raise SystemExit("Need to call .using() before")
|
477
473
|
instance_uid = cache_filepath.read_text()
|
lamindb/_save.py
CHANGED
@@ -168,7 +168,7 @@ def copy_or_move_to_cache(
|
|
168
168
|
|
169
169
|
local_path = local_path.resolve()
|
170
170
|
is_dir = local_path.is_dir()
|
171
|
-
cache_dir = settings.
|
171
|
+
cache_dir = settings.cache_dir
|
172
172
|
|
173
173
|
# just delete from the cache dir if storage_path is local
|
174
174
|
if cache_path is None:
|
lamindb/core/_context.py
CHANGED
@@ -562,26 +562,32 @@ class Context:
|
|
562
562
|
|
563
563
|
return "CMD + s" if platform.system() == "Darwin" else "CTRL + s"
|
564
564
|
|
565
|
-
if
|
565
|
+
if self.run is None:
|
566
566
|
raise TrackNotCalled("Please run `ln.track()` before `ln.finish()`")
|
567
|
-
if
|
568
|
-
if
|
567
|
+
if self._path is None:
|
568
|
+
if self.run.transform.type in {"script", "notebook"}:
|
569
569
|
raise ValueError(
|
570
|
-
|
570
|
+
"Transform type is not allowed to be 'script' or 'notebook' because `context._path` is `None`."
|
571
571
|
)
|
572
|
-
|
573
|
-
|
572
|
+
self.run.finished_at = datetime.now(timezone.utc)
|
573
|
+
self.run.save()
|
574
574
|
# nothing else to do
|
575
575
|
return None
|
576
576
|
if is_run_from_ipython: # notebooks
|
577
|
-
|
577
|
+
import nbproject
|
578
|
+
|
579
|
+
# it might be that the user modifies the title just before ln.finish()
|
580
|
+
if (nbproject_title := nbproject.meta.live.title) != self.transform.name:
|
581
|
+
self.transform.name = nbproject_title
|
582
|
+
self.transform.save()
|
583
|
+
if get_seconds_since_modified(self._path) > 2 and not ln_setup._TESTING:
|
578
584
|
raise NotebookNotSaved(
|
579
585
|
f"Please save the notebook in your editor (shortcut `{get_shortcut()}`) right before calling `ln.finish()`"
|
580
586
|
)
|
581
587
|
save_context_core(
|
582
|
-
run=
|
583
|
-
transform=
|
584
|
-
filepath=
|
588
|
+
run=self.run,
|
589
|
+
transform=self.run.transform,
|
590
|
+
filepath=self._path,
|
585
591
|
finished_at=True,
|
586
592
|
ignore_non_consecutive=ignore_non_consecutive,
|
587
593
|
)
|
lamindb/core/_feature_manager.py
CHANGED
@@ -40,7 +40,7 @@ from lamindb._record import (
|
|
40
40
|
transfer_to_default_db,
|
41
41
|
)
|
42
42
|
from lamindb._save import save
|
43
|
-
from lamindb.core.exceptions import ValidationError
|
43
|
+
from lamindb.core.exceptions import DoesNotExist, ValidationError
|
44
44
|
from lamindb.core.storage import LocalPathClasses
|
45
45
|
|
46
46
|
from ._django import get_artifact_with_related
|
@@ -509,18 +509,49 @@ def filter_base(cls, **expression):
|
|
509
509
|
expression = {feature_param: feature, f"value{comparator}": value}
|
510
510
|
feature_value = value_model.filter(**expression)
|
511
511
|
new_expression[f"_{feature_param}_values__in"] = feature_value
|
512
|
-
|
512
|
+
elif isinstance(value, (str, Record)):
|
513
|
+
# because SQL is sensitive to whether querying with __in or not
|
514
|
+
# and might return multiple equivalent records for the latter
|
515
|
+
# we distinguish cases in which we have multiple label matches vs. one
|
516
|
+
label = None
|
517
|
+
labels = None
|
513
518
|
if isinstance(value, str):
|
519
|
+
# we need the comparator here because users might query like so
|
520
|
+
# ln.Artifact.features.filter(experiment__contains="Experi")
|
514
521
|
expression = {f"name{comparator}": value}
|
515
|
-
|
516
|
-
|
522
|
+
labels = ULabel.filter(**expression).all()
|
523
|
+
if len(labels) == 0:
|
524
|
+
raise DoesNotExist(
|
525
|
+
f"Did not find a ULabel matching `name{comparator}={value}`"
|
526
|
+
)
|
527
|
+
elif len(labels) == 1:
|
528
|
+
label = labels[0]
|
529
|
+
elif isinstance(value, Record):
|
530
|
+
label = value
|
531
|
+
label_registry = (
|
532
|
+
label.__class__ if label is not None else labels[0].__class__
|
533
|
+
)
|
534
|
+
accessor_name = (
|
535
|
+
label_registry.artifacts.through.artifact.field._related_name
|
536
|
+
)
|
537
|
+
new_expression[f"{accessor_name}__feature"] = feature
|
538
|
+
if label is not None:
|
539
|
+
# simplified query if we have exactly one label
|
540
|
+
new_expression[
|
541
|
+
f"{accessor_name}__{label_registry.__name__.lower()}"
|
542
|
+
] = label
|
517
543
|
else:
|
518
|
-
|
544
|
+
new_expression[
|
545
|
+
f"{accessor_name}__{label_registry.__name__.lower()}__in"
|
546
|
+
] = labels
|
547
|
+
else:
|
548
|
+
# if passing a list of records, we want to
|
549
|
+
# find artifacts that are annotated by all of them at the same
|
550
|
+
# time; hence, we don't want the __in construct that we use to match strings
|
551
|
+
# https://laminlabs.slack.com/archives/C04FPE8V01W/p1688328084810609
|
552
|
+
raise NotImplementedError
|
519
553
|
if cls == FeatureManager or cls == ParamManagerArtifact:
|
520
554
|
return Artifact.filter(**new_expression)
|
521
|
-
# might renable something similar in the future
|
522
|
-
# elif cls == FeatureManagerCollection:
|
523
|
-
# return Collection.filter(**new_expression)
|
524
555
|
elif cls == ParamManagerRun:
|
525
556
|
return Run.filter(**new_expression)
|
526
557
|
|
lamindb/core/_label_manager.py
CHANGED
@@ -90,10 +90,9 @@ def print_labels(
|
|
90
90
|
# there is a try except block here to deal with schema inconsistencies
|
91
91
|
# during transfer between instances
|
92
92
|
try:
|
93
|
-
field = get_name_field(
|
93
|
+
field = get_name_field(labels)
|
94
94
|
labels_list = list(labels.values_list(field, flat=True))
|
95
95
|
if len(labels_list) > 0:
|
96
|
-
get_name_field(labels)
|
97
96
|
print_values = _print_values(labels_list, n=10)
|
98
97
|
type_str = f": {related_model}" if print_types else ""
|
99
98
|
labels_msg += f" .{related_name}{type_str} = {print_values}\n"
|
lamindb/core/_settings.py
CHANGED
@@ -143,6 +143,11 @@ class Settings:
|
|
143
143
|
path, kwargs = path_kwargs, {}
|
144
144
|
set_managed_storage(path, **kwargs)
|
145
145
|
|
146
|
+
@property
|
147
|
+
def cache_dir(self) -> UPath:
|
148
|
+
"""Cache root, a local directory to cache cloud files."""
|
149
|
+
return ln_setup.settings.cache_dir
|
150
|
+
|
146
151
|
@property
|
147
152
|
def storage_local(self) -> StorageSettings:
|
148
153
|
"""An additional local default storage (a path to its root).
|
lamindb/core/_sync_git.py
CHANGED
@@ -16,7 +16,7 @@ class BlobHashNotFound(SystemExit):
|
|
16
16
|
|
17
17
|
def get_git_repo_from_remote() -> Path:
|
18
18
|
repo_url = settings.sync_git_repo
|
19
|
-
repo_dir = setup_settings.
|
19
|
+
repo_dir = setup_settings.cache_dir / repo_url.split("/")[-1]
|
20
20
|
if repo_dir.exists():
|
21
21
|
logger.warning(f"git repo {repo_dir} already exists locally")
|
22
22
|
return repo_dir
|
@@ -26,7 +26,7 @@ def get_git_repo_from_remote() -> Path:
|
|
26
26
|
result = subprocess.run(
|
27
27
|
["git", "clone", "--depth", "10", f"{repo_url}.git"],
|
28
28
|
capture_output=True,
|
29
|
-
cwd=setup_settings.
|
29
|
+
cwd=setup_settings.cache_dir,
|
30
30
|
)
|
31
31
|
if result.returncode != 0 or not repo_dir.exists():
|
32
32
|
raise RuntimeError(result.stderr.decode())
|
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|
11
11
|
|
12
12
|
|
13
13
|
def track_environment(run: Run) -> None:
|
14
|
-
filepath = ln_setup.settings.
|
14
|
+
filepath = ln_setup.settings.cache_dir / f"run_env_pip_{run.uid}.txt"
|
15
15
|
# create a requirements.txt
|
16
16
|
# we don't create a conda environment.yml mostly for its slowness
|
17
17
|
try:
|
lamindb/core/exceptions.py
CHANGED
@@ -8,6 +8,7 @@ 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._collection import Collection
|
11
12
|
from lamindb._run import Run
|
12
13
|
from lamindb._transform import Transform
|
13
14
|
|
@@ -20,14 +21,21 @@ if TYPE_CHECKING:
|
|
20
21
|
def save_vitessce_config(
|
21
22
|
vitessce_config: VitessceConfig, description: str | None = None
|
22
23
|
) -> Artifact:
|
23
|
-
"""Validates and saves a
|
24
|
+
"""Validates and saves a `VitessceConfig` object.
|
25
|
+
|
26
|
+
If the `VitessceConfig` object references multiple artifacts, automatically
|
27
|
+
creates a `Collection` and displays the "Vitessce button" next to it.
|
24
28
|
|
25
29
|
Guide: :doc:`docs:vitessce`.
|
26
30
|
|
27
31
|
Args:
|
28
|
-
vitessce_config
|
29
|
-
description: A description for the `VitessceConfig`
|
32
|
+
vitessce_config: A `VitessceConfig` object.
|
33
|
+
description: A description for the `VitessceConfig` object. Is used as
|
34
|
+
`name` for a `Collection` in case the `VitessceConfig` object
|
35
|
+
references multiple artifacts.
|
30
36
|
|
37
|
+
.. versionchanged:: 0.76.12
|
38
|
+
Now assumes `vitessce-python >= 3.4.0`, which allows passing artifacts within `VitessceConfig`.
|
31
39
|
.. versionchanged:: 0.75.1
|
32
40
|
Now displays the "Vitessce button" on the hub next to the dataset. It additionally keeps displaying it next to the configuration file.
|
33
41
|
.. versionchanged:: 0.70.2
|
@@ -40,68 +48,54 @@ def save_vitessce_config(
|
|
40
48
|
|
41
49
|
assert isinstance(vitessce_config, VitessceConfig) # noqa: S101
|
42
50
|
vc_dict = vitessce_config.to_dict()
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
for file in vitessce_dataset["files"]:
|
55
|
-
if "url" not in file:
|
56
|
-
raise ValueError("Each file must have a 'url' key.")
|
57
|
-
s3_path = file["url"]
|
58
|
-
s3_path_last_element = s3_path.split("/")[-1]
|
59
|
-
# now start with attempting to strip the composite suffix candidates
|
60
|
-
for suffix in valid_composite_zarr_suffixes:
|
61
|
-
s3_path_last_element = s3_path_last_element.replace(suffix, "")
|
62
|
-
# in case there was no hit, strip plain ".zarr"
|
63
|
-
artifact_stem_uid = s3_path_last_element.replace(".zarr", "")
|
64
|
-
# if there is still a "." in string, raise an error
|
65
|
-
if "." in artifact_stem_uid:
|
66
|
-
raise ValueError(
|
67
|
-
f"Suffix should be '.zarr' or one of {valid_composite_zarr_suffixes}. Inspect your path {s3_path}"
|
68
|
-
)
|
69
|
-
artifact = Artifact.filter(uid__startswith=artifact_stem_uid).one_or_none()
|
70
|
-
if artifact is None:
|
71
|
-
raise ValueError(
|
72
|
-
f"Could not find dataset with stem uid '{artifact_stem_uid}' in lamindb: {vitessce_dataset}. Did you follow https://docs.lamin.ai/vitessce? It appears the AWS S3 path doesn't encode a lamindb uid."
|
73
|
-
)
|
74
|
-
else:
|
75
|
-
dataset_artifacts.append(artifact)
|
51
|
+
try:
|
52
|
+
url_to_artifact_dict = vitessce_config.get_artifacts()
|
53
|
+
except AttributeError as e:
|
54
|
+
raise SystemExit(
|
55
|
+
"save_vitessce_config() requires vitessce>=3.4.0: pip install vitessce>=3.4.0"
|
56
|
+
) from e
|
57
|
+
dataset_artifacts = list(url_to_artifact_dict.values())
|
58
|
+
message = "\n".join([artifact.__repr__() for artifact in dataset_artifacts])
|
59
|
+
logger.important(f"VitessceConfig references these artifacts:\n{message}")
|
60
|
+
assert len(dataset_artifacts) > 0 # noqa: S101
|
61
|
+
|
76
62
|
# the below will be replaced with a `ln.tracked()` decorator soon
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
).save()
|
63
|
+
transform = Transform(
|
64
|
+
uid="kup03MJBsIVa0002",
|
65
|
+
name="save_vitessce_config",
|
66
|
+
type="function",
|
67
|
+
version="3",
|
68
|
+
).save()
|
84
69
|
run = Run(transform=transform).save()
|
70
|
+
run.input_artifacts.set(dataset_artifacts)
|
71
|
+
collection = None
|
85
72
|
if len(dataset_artifacts) > 1:
|
86
73
|
# if we have more datasets, we should create a collection
|
87
74
|
# and attach an action to the collection
|
88
|
-
|
89
|
-
|
75
|
+
collection = Collection(dataset_artifacts, name=description).save()
|
76
|
+
|
90
77
|
# create a JSON export
|
91
|
-
config_file_local_path =
|
92
|
-
ln_setup.settings.storage.cache_dir / "config.vitessce.json"
|
93
|
-
)
|
78
|
+
config_file_local_path = ln_setup.settings.cache_dir / "config.vitessce.json"
|
94
79
|
with open(config_file_local_path, "w") as file:
|
95
80
|
json.dump(vc_dict, file)
|
96
81
|
vitessce_config_artifact = Artifact(
|
97
82
|
config_file_local_path, description=description, run=run
|
98
83
|
).save()
|
99
|
-
# we have one and only one dataset artifact, hence the following line is OK
|
100
|
-
dataset_artifacts[0]._actions.add(vitessce_config_artifact)
|
101
84
|
slug = ln_setup.settings.instance.slug
|
102
85
|
logger.important(
|
103
|
-
f"
|
86
|
+
f"VitessceConfig: https://lamin.ai/{slug}/artifact/{vitessce_config_artifact.uid}"
|
104
87
|
)
|
88
|
+
if collection is None:
|
89
|
+
# we have one and only one dataset artifact, hence the following line is OK
|
90
|
+
dataset_artifacts[0]._actions.add(vitessce_config_artifact)
|
91
|
+
logger.important(
|
92
|
+
f"Dataset: https://lamin.ai/{slug}/artifact/{dataset_artifacts[0].uid}"
|
93
|
+
)
|
94
|
+
else:
|
95
|
+
collection._actions.add(vitessce_config_artifact)
|
96
|
+
logger.important(
|
97
|
+
f"Collection: https://lamin.ai/{slug}/collection/{collection.uid}"
|
98
|
+
)
|
105
99
|
run.finished_at = datetime.now(timezone.utc)
|
106
100
|
run.save()
|
107
101
|
return vitessce_config_artifact
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lamindb
|
3
|
-
Version: 0.76.
|
3
|
+
Version: 0.76.12
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
6
|
Requires-Python: >=3.9
|
@@ -8,10 +8,10 @@ Description-Content-Type: text/markdown
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.9
|
9
9
|
Classifier: Programming Language :: Python :: 3.10
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
11
|
-
Requires-Dist: lnschema_core==0.
|
12
|
-
Requires-Dist: lamindb_setup==0.77.6
|
11
|
+
Requires-Dist: lnschema_core==0.75.0
|
13
12
|
Requires-Dist: lamin_utils==0.13.6
|
14
|
-
Requires-Dist: lamin_cli==0.
|
13
|
+
Requires-Dist: lamin_cli==0.18.0
|
14
|
+
Requires-Dist: lamindb_setup
|
15
15
|
Requires-Dist: rapidfuzz
|
16
16
|
Requires-Dist: pyarrow
|
17
17
|
Requires-Dist: typing_extensions!=4.6.0
|
@@ -23,7 +23,7 @@ Requires-Dist: pandas
|
|
23
23
|
Requires-Dist: graphviz
|
24
24
|
Requires-Dist: psycopg2-binary
|
25
25
|
Requires-Dist: lamindb_setup[aws] ; extra == "aws"
|
26
|
-
Requires-Dist: bionty==0.51.
|
26
|
+
Requires-Dist: bionty==0.51.2 ; extra == "bionty"
|
27
27
|
Requires-Dist: line_profiler ; extra == "dev"
|
28
28
|
Requires-Dist: pre-commit ; extra == "dev"
|
29
29
|
Requires-Dist: nox ; extra == "dev"
|
@@ -1,36 +1,36 @@
|
|
1
|
-
lamindb/__init__.py,sha256=
|
2
|
-
lamindb/_artifact.py,sha256=
|
1
|
+
lamindb/__init__.py,sha256=IriWYyrDC6JejjCZBDmycpYNGj9hiGgJZ7vAFBCcq9w,2278
|
2
|
+
lamindb/_artifact.py,sha256=Q0fCuD2nDQdqtQIxA9I4dTOY6R-12fv4ImeoNYEgL5I,44800
|
3
3
|
lamindb/_can_validate.py,sha256=1pUavLwZ_yPAtbVYKOGYUHaPxlJGZ246qZ0e-4ZUDSc,19552
|
4
4
|
lamindb/_collection.py,sha256=TSkJ3z0axRAFrV2PvZf1YMz7NXWLX3hYoNQ48l4NoyM,14129
|
5
5
|
lamindb/_curate.py,sha256=KpEP0-9nQUmiRn6z7fiGs6BmQdpqSg3QPlAgV-S9_wA,58839
|
6
6
|
lamindb/_feature.py,sha256=nZhtrH0ssoNls-hV-dkwfK9sKypg2El59R9qfarxfUE,5340
|
7
7
|
lamindb/_feature_set.py,sha256=lHKATvs8NagaaHwsWqi4XMTPTNKsGdM-6ZRctTHHSNc,8130
|
8
|
-
lamindb/_filter.py,sha256=
|
9
|
-
lamindb/_finish.py,sha256=
|
8
|
+
lamindb/_filter.py,sha256=Pf9NHV4gm7NOC0Frtvx4W7nvwt2EowOP74DwppyXAZs,635
|
9
|
+
lamindb/_finish.py,sha256=VMAmxCUFmTKIMSCx7LEh4QAnWDeue6MeUAAzkMVEYMU,9546
|
10
10
|
lamindb/_from_values.py,sha256=iqcR8T8i9VZpnn09W441zW-djhWMh8EZj7XFJq9jP2k,14211
|
11
11
|
lamindb/_is_versioned.py,sha256=5lAnhTboltFkZCKVRV1uxkm0OCjJz_HKi3yQq_vEuMs,1306
|
12
12
|
lamindb/_parents.py,sha256=eMavdd6IO6STOVJSlR2TzdRtx6sKYDKsMOtlR3DZlgQ,15599
|
13
13
|
lamindb/_query_manager.py,sha256=Ipe85HL31DDwMbC8CN_1Svbwk48a_DUh_INGQdZL08I,4222
|
14
|
-
lamindb/_query_set.py,sha256=
|
15
|
-
lamindb/_record.py,sha256=
|
14
|
+
lamindb/_query_set.py,sha256=jPW7vUm_lMtL3qhLJ16nJxZkf184mM0Ny1OM1uaztto,12717
|
15
|
+
lamindb/_record.py,sha256=OUW0xr2s7I2iML2GoFjdZ3nNc0q9RKMLUXnTU5cwBs8,23260
|
16
16
|
lamindb/_run.py,sha256=K_5drpLn3D7y3XtZ3vtAw35rG5RCSvB4bXQZx4ESSI0,1964
|
17
|
-
lamindb/_save.py,sha256=
|
17
|
+
lamindb/_save.py,sha256=BCaSFnANYPxTqL5gw7Hrh_9kz7SDyOxrJV2KW6rXqts,11366
|
18
18
|
lamindb/_storage.py,sha256=GBVChv-DHVMNEBJL5l_JT6B4RDhZ6NnwgzmUICphYKk,413
|
19
19
|
lamindb/_transform.py,sha256=wZDkY8lp4d_OsO5a7rLs1RamkDzBXZSLaWJU34zRnmA,4728
|
20
20
|
lamindb/_ulabel.py,sha256=XDSdZBXX_ki5s1vOths3MjF2x5DPggBR_PV_KF4SGyg,1611
|
21
21
|
lamindb/_utils.py,sha256=LGdiW4k3GClLz65vKAVRkL6Tw-Gkx9DWAdez1jyA5bE,428
|
22
22
|
lamindb/_view.py,sha256=4Ln2ItTb3857PAI-70O8eJYqoTJ_NNFc7E_wds6OGns,2412
|
23
23
|
lamindb/core/__init__.py,sha256=57AXQ286eOX2_o5HUeqIFJrfqN-OZ_E7FVHd3Xm5oOk,1483
|
24
|
-
lamindb/core/_context.py,sha256=
|
24
|
+
lamindb/core/_context.py,sha256=6N8SlTRJyVwhm0kLmd_ToHvT4BhQI977PUhUv8e8KN4,22900
|
25
25
|
lamindb/core/_data.py,sha256=P0vlbw_UQp9UDNMmUo9YFxqurcWtMaKPWCT12IRA2C0,19672
|
26
26
|
lamindb/core/_django.py,sha256=mqZ0WhTakLDrGVp3MVI6RNfu8kZ2L5BiEnMwXnkfsG0,6760
|
27
|
-
lamindb/core/_feature_manager.py,sha256=
|
28
|
-
lamindb/core/_label_manager.py,sha256=
|
27
|
+
lamindb/core/_feature_manager.py,sha256=f7pO3RQ0ojYvofLYqioE4CV2t8nXTkQcXvJDuMB_XaY,38941
|
28
|
+
lamindb/core/_label_manager.py,sha256=GoluSFk_z1c1fZw8OGKkaIURWgognEsOHCo9mzigd-A,11108
|
29
29
|
lamindb/core/_mapped_collection.py,sha256=M50haewVAFONeF71QQbzD09L8lVZCL1hyf0W87jKE5U,24575
|
30
|
-
lamindb/core/_settings.py,sha256=
|
31
|
-
lamindb/core/_sync_git.py,sha256=
|
32
|
-
lamindb/core/_track_environment.py,sha256=
|
33
|
-
lamindb/core/exceptions.py,sha256=
|
30
|
+
lamindb/core/_settings.py,sha256=6jNadlQdimxCsKR2ZyUD0YJYzOdubTnKktki-MqEWqQ,6137
|
31
|
+
lamindb/core/_sync_git.py,sha256=lIgl6YfpH4rCFT1WILAp7zlemZfxog1d0zp3cX0KIZw,4531
|
32
|
+
lamindb/core/_track_environment.py,sha256=Ywzg_sJ7guI1dcsN7h5orce9VdYl8VGVE3OLITlHBXQ,820
|
33
|
+
lamindb/core/exceptions.py,sha256=0B36kOVo-Dik5KbSKvy5GPuMjUfhVb99dJwXl_J0ldo,1636
|
34
34
|
lamindb/core/fields.py,sha256=47Jmh3efUr5ZscgimR_yckY-I3cNf8ScLutbwKCK3j4,162
|
35
35
|
lamindb/core/loaders.py,sha256=KMTkDa73jkRVvI9uc5Fgr0t6mq22cAxBwhSlUZKUaBg,4016
|
36
36
|
lamindb/core/schema.py,sha256=KiYQn_8fokSMztTNDe6qUocZzKXWxU32H-YChNJv51A,1877
|
@@ -52,10 +52,10 @@ lamindb/core/subsettings/__init__.py,sha256=KFHPzIE7f7Bj4RgMjGQF4CjTdHVG_VNFBrCn
|
|
52
52
|
lamindb/core/subsettings/_creation_settings.py,sha256=54mfMH_osC753hpxcl7Dq1rwBD2LHnWveXtQpkLBITE,1194
|
53
53
|
lamindb/core/subsettings/_transform_settings.py,sha256=4YbCuZtJo6zdytl6UQR4GvdDkTtT6SRBqVzofGzNOt8,583
|
54
54
|
lamindb/integrations/__init__.py,sha256=RWGMYYIzr8zvmNPyVB4m-p4gMDhxdRbjES2Ed23OItw,215
|
55
|
-
lamindb/integrations/_vitessce.py,sha256=
|
55
|
+
lamindb/integrations/_vitessce.py,sha256=uPl45_w4Uu9_BhpBDDVonC1nDOuAnB7DAnzi5w5bZAE,4032
|
56
56
|
lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
|
57
57
|
lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
|
58
|
-
lamindb-0.76.
|
59
|
-
lamindb-0.76.
|
60
|
-
lamindb-0.76.
|
61
|
-
lamindb-0.76.
|
58
|
+
lamindb-0.76.12.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
59
|
+
lamindb-0.76.12.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
60
|
+
lamindb-0.76.12.dist-info/METADATA,sha256=1R8hfPpe0viZZHFgDGyRrq-myQ71euhBbXdB9LH2kD4,2361
|
61
|
+
lamindb-0.76.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|