lamindb 0.74.3__py3-none-any.whl → 0.75.1__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 +85 -43
- lamindb/_can_validate.py +100 -35
- lamindb/_collection.py +36 -28
- lamindb/_curate.py +432 -181
- lamindb/_feature_set.py +5 -5
- lamindb/_filter.py +3 -3
- lamindb/_finish.py +29 -23
- lamindb/_from_values.py +47 -66
- lamindb/_is_versioned.py +1 -1
- lamindb/_parents.py +38 -13
- lamindb/_record.py +41 -42
- lamindb/_save.py +7 -7
- lamindb/_transform.py +27 -16
- lamindb/_view.py +13 -11
- lamindb/core/__init__.py +2 -0
- lamindb/core/_data.py +18 -20
- lamindb/core/_feature_manager.py +50 -50
- lamindb/core/_label_manager.py +17 -19
- lamindb/core/_mapped_collection.py +1 -1
- lamindb/core/_run_context.py +6 -8
- lamindb/core/datasets/_core.py +7 -7
- lamindb/core/exceptions.py +11 -0
- lamindb/core/schema.py +5 -5
- lamindb/core/storage/__init__.py +12 -2
- lamindb/core/storage/_anndata_accessor.py +735 -0
- lamindb/core/storage/_backed_access.py +77 -747
- lamindb/core/storage/_valid_suffixes.py +16 -2
- lamindb/core/storage/paths.py +9 -14
- lamindb/core/types.py +3 -0
- lamindb/core/versioning.py +1 -1
- lamindb/integrations/__init__.py +1 -0
- lamindb/integrations/_vitessce.py +68 -31
- {lamindb-0.74.3.dist-info → lamindb-0.75.1.dist-info}/METADATA +5 -5
- lamindb-0.75.1.dist-info/RECORD +58 -0
- lamindb-0.74.3.dist-info/RECORD +0 -57
- {lamindb-0.74.3.dist-info → lamindb-0.75.1.dist-info}/LICENSE +0 -0
- {lamindb-0.74.3.dist-info → lamindb-0.75.1.dist-info}/WHEEL +0 -0
lamindb/_collection.py
CHANGED
@@ -60,7 +60,9 @@ def __init__(
|
|
60
60
|
artifacts: Artifact | Iterable[Artifact] = (
|
61
61
|
kwargs.pop("artifacts") if len(args) == 0 else args[0]
|
62
62
|
)
|
63
|
-
|
63
|
+
meta_artifact: Artifact | None = (
|
64
|
+
kwargs.pop("meta_artifact") if "meta_artifact" in kwargs else None
|
65
|
+
)
|
64
66
|
name: str | None = kwargs.pop("name") if "name" in kwargs else None
|
65
67
|
description: str | None = (
|
66
68
|
kwargs.pop("description") if "description" in kwargs else None
|
@@ -102,16 +104,18 @@ def __init__(
|
|
102
104
|
raise ValueError("Artifact or List[Artifact] is allowed.")
|
103
105
|
assert isinstance(artifacts[0], Artifact) # type: ignore # noqa: S101
|
104
106
|
hash, feature_sets = from_artifacts(artifacts) # type: ignore
|
105
|
-
if
|
106
|
-
if not isinstance(
|
107
|
-
raise ValueError("
|
108
|
-
if isinstance(
|
109
|
-
if
|
110
|
-
raise ValueError(
|
107
|
+
if meta_artifact is not None:
|
108
|
+
if not isinstance(meta_artifact, Artifact):
|
109
|
+
raise ValueError("meta_artifact has to be an Artifact")
|
110
|
+
if isinstance(meta_artifact, Artifact):
|
111
|
+
if meta_artifact._state.adding:
|
112
|
+
raise ValueError(
|
113
|
+
"Save meta_artifact artifact before creating collection!"
|
114
|
+
)
|
111
115
|
if not feature_sets:
|
112
|
-
feature_sets =
|
116
|
+
feature_sets = meta_artifact.features._feature_set_by_slot
|
113
117
|
else:
|
114
|
-
if len(
|
118
|
+
if len(meta_artifact.features._feature_set_by_slot) > 0:
|
115
119
|
logger.info("overwriting feature sets linked to artifact")
|
116
120
|
# we ignore collections in trash containing the same hash
|
117
121
|
if hash is not None:
|
@@ -149,7 +153,7 @@ def __init__(
|
|
149
153
|
description=description,
|
150
154
|
reference=reference,
|
151
155
|
reference_type=reference_type,
|
152
|
-
|
156
|
+
meta_artifact=meta_artifact,
|
153
157
|
hash=hash,
|
154
158
|
run=run,
|
155
159
|
version=version,
|
@@ -176,13 +180,13 @@ def from_artifacts(artifacts: Iterable[Artifact]) -> tuple[str, dict[str, str]]:
|
|
176
180
|
artifact_ids = [artifact.id for artifact in artifacts]
|
177
181
|
# query all feature sets at the same time rather
|
178
182
|
# than making a single query per artifact
|
179
|
-
logger.debug("
|
180
|
-
|
183
|
+
logger.debug("links_feature_set_artifact")
|
184
|
+
links_feature_set_artifact = Artifact.feature_sets.through.objects.filter(
|
181
185
|
artifact_id__in=artifact_ids
|
182
186
|
)
|
183
187
|
feature_sets_by_slots = defaultdict(list)
|
184
188
|
logger.debug("slots")
|
185
|
-
for link in
|
189
|
+
for link in links_feature_set_artifact:
|
186
190
|
feature_sets_by_slots[link.slot].append(link.featureset_id)
|
187
191
|
feature_sets_union = {}
|
188
192
|
logger.debug("union")
|
@@ -240,7 +244,7 @@ def mapped(
|
|
240
244
|
is_run_input: bool | None = None,
|
241
245
|
) -> MappedCollection:
|
242
246
|
path_list = []
|
243
|
-
for artifact in self.
|
247
|
+
for artifact in self.ordered_artifacts.all():
|
244
248
|
if artifact.suffix not in {".h5ad", ".zarr"}:
|
245
249
|
logger.warning(f"Ignoring artifact with suffix {artifact.suffix}")
|
246
250
|
continue
|
@@ -267,10 +271,10 @@ def mapped(
|
|
267
271
|
|
268
272
|
# docstring handled through attach_func_to_class_method
|
269
273
|
def cache(self, is_run_input: bool | None = None) -> list[UPath]:
|
270
|
-
_track_run_input(self, is_run_input)
|
271
274
|
path_list = []
|
272
|
-
for artifact in self.
|
275
|
+
for artifact in self.ordered_artifacts.all():
|
273
276
|
path_list.append(artifact.cache())
|
277
|
+
_track_run_input(self, is_run_input)
|
274
278
|
return path_list
|
275
279
|
|
276
280
|
|
@@ -282,7 +286,7 @@ def load(
|
|
282
286
|
**kwargs,
|
283
287
|
) -> Any:
|
284
288
|
# cannot call _track_run_input here, see comment further down
|
285
|
-
all_artifacts = self.
|
289
|
+
all_artifacts = self.ordered_artifacts.all()
|
286
290
|
suffixes = [artifact.suffix for artifact in all_artifacts]
|
287
291
|
if len(set(suffixes)) != 1:
|
288
292
|
raise RuntimeError(
|
@@ -329,8 +333,8 @@ def delete(self, permanent: bool | None = None) -> None:
|
|
329
333
|
|
330
334
|
# docstring handled through attach_func_to_class_method
|
331
335
|
def save(self, using: str | None = None) -> Collection:
|
332
|
-
if self.
|
333
|
-
self.
|
336
|
+
if self.meta_artifact is not None:
|
337
|
+
self.meta_artifact.save()
|
334
338
|
# we don't need to save feature sets again
|
335
339
|
save_feature_sets(self)
|
336
340
|
super(Collection, self).save()
|
@@ -344,7 +348,7 @@ def save(self, using: str | None = None) -> Collection:
|
|
344
348
|
]
|
345
349
|
# the below seems to preserve the order of the list in the
|
346
350
|
# auto-incrementing integer primary
|
347
|
-
# merely using .
|
351
|
+
# merely using .artifacts.set(*...) doesn't achieve this
|
348
352
|
# we need ignore_conflicts=True so that this won't error if links already exist
|
349
353
|
CollectionArtifact.objects.bulk_create(links, ignore_conflicts=True)
|
350
354
|
save_feature_set_links(self)
|
@@ -357,16 +361,20 @@ def save(self, using: str | None = None) -> Collection:
|
|
357
361
|
def restore(self) -> None:
|
358
362
|
self.visibility = VisibilityChoice.default.value
|
359
363
|
self.save()
|
360
|
-
if self.artifact is not None:
|
361
|
-
self.artifact.visibility = VisibilityChoice.default.value
|
362
|
-
self.artifact.save()
|
363
364
|
|
364
365
|
|
365
366
|
@property # type: ignore
|
366
|
-
@doc_args(Collection.
|
367
|
-
def
|
367
|
+
@doc_args(Collection.ordered_artifacts.__doc__)
|
368
|
+
def ordered_artifacts(self) -> QuerySet:
|
369
|
+
"""{}""" # noqa: D415
|
370
|
+
return self.artifacts.order_by("links_collection__id")
|
371
|
+
|
372
|
+
|
373
|
+
@property # type: ignore
|
374
|
+
@doc_args(Collection.data_artifact.__doc__)
|
375
|
+
def data_artifact(self) -> Artifact | None:
|
368
376
|
"""{}""" # noqa: D415
|
369
|
-
return self.
|
377
|
+
return self.artifacts.first()
|
370
378
|
|
371
379
|
|
372
380
|
METHOD_NAMES = [
|
@@ -391,5 +399,5 @@ if ln_setup._TESTING:
|
|
391
399
|
for name in METHOD_NAMES:
|
392
400
|
attach_func_to_class_method(name, Collection, globals())
|
393
401
|
|
394
|
-
Collection.
|
395
|
-
Collection.
|
402
|
+
Collection.ordered_artifacts = ordered_artifacts
|
403
|
+
Collection.data_artifact = data_artifact
|