lamindb 0.69.10__py3-none-any.whl → 0.70.0__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 +23 -11
- lamindb/_collection.py +16 -4
- lamindb/_finish.py +28 -42
- lamindb/_from_values.py +2 -1
- lamindb/core/_data.py +18 -1
- lamindb/core/_feature_manager.py +8 -2
- lamindb/core/_run_context.py +0 -1
- lamindb/core/_settings.py +1 -1
- lamindb/core/datasets/_core.py +1 -1
- lamindb/integrations/_vitessce.py +18 -9
- {lamindb-0.69.10.dist-info → lamindb-0.70.0.dist-info}/METADATA +4 -4
- {lamindb-0.69.10.dist-info → lamindb-0.70.0.dist-info}/RECORD +15 -15
- {lamindb-0.69.10.dist-info → lamindb-0.70.0.dist-info}/LICENSE +0 -0
- {lamindb-0.69.10.dist-info → lamindb-0.70.0.dist-info}/WHEEL +0 -0
lamindb/__init__.py
CHANGED
lamindb/_artifact.py
CHANGED
@@ -238,7 +238,7 @@ def get_stat_or_artifact(
|
|
238
238
|
"💡 you can make this error a warning:\n"
|
239
239
|
" ln.settings.upon_artifact_create_if_hash_exists"
|
240
240
|
)
|
241
|
-
raise
|
241
|
+
raise FileExistsError(f"{msg}\n{hint}")
|
242
242
|
elif settings.upon_artifact_create_if_hash_exists == "warn_create_new":
|
243
243
|
logger.warning(
|
244
244
|
"creating new Artifact object despite existing artifact with same hash:"
|
@@ -246,10 +246,12 @@ def get_stat_or_artifact(
|
|
246
246
|
)
|
247
247
|
return size, hash, hash_type, n_objects
|
248
248
|
else:
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
249
|
+
if result[0].visibility == -1:
|
250
|
+
raise FileExistsError(
|
251
|
+
f"You're trying to re-create this artifact in trash: {result[0]}"
|
252
|
+
"Either permanently delete it with `artifact.delete(permanent=True)` or restore it with `artifact.restore()`"
|
253
|
+
)
|
254
|
+
logger.warning(f"returning existing artifact with same hash: {result[0]}")
|
253
255
|
return result[0]
|
254
256
|
else:
|
255
257
|
return size, hash, hash_type, n_objects
|
@@ -331,6 +333,15 @@ def get_artifact_kwargs_from_data(
|
|
331
333
|
using_key=using_key,
|
332
334
|
)
|
333
335
|
if isinstance(stat_or_artifact, Artifact):
|
336
|
+
# update the run of the existing artifact
|
337
|
+
if run is not None:
|
338
|
+
# save the information that this artifact was previously
|
339
|
+
# produced by another run
|
340
|
+
if stat_or_artifact.run is not None:
|
341
|
+
stat_or_artifact.run.replicated_output_artifacts.add(stat_or_artifact)
|
342
|
+
# update the run of the artifact with the latest run
|
343
|
+
stat_or_artifact.run = run
|
344
|
+
stat_or_artifact.transform = run.transform
|
334
345
|
return stat_or_artifact, None
|
335
346
|
else:
|
336
347
|
size, hash, hash_type, n_objects = stat_or_artifact
|
@@ -854,7 +865,7 @@ def load(self, is_run_input: bool | None = None, stream: bool = False, **kwargs)
|
|
854
865
|
|
855
866
|
|
856
867
|
# docstring handled through attach_func_to_class_method
|
857
|
-
def
|
868
|
+
def cache(self, is_run_input: bool | None = None) -> Path:
|
858
869
|
_track_run_input(self, is_run_input)
|
859
870
|
|
860
871
|
using_key = settings._using_key
|
@@ -932,10 +943,10 @@ def _delete_skip_storage(artifact, *args, **kwargs) -> None:
|
|
932
943
|
|
933
944
|
|
934
945
|
# docstring handled through attach_func_to_class_method
|
935
|
-
def save(self,
|
946
|
+
def save(self, upload: bool | None = None, **kwargs) -> None:
|
936
947
|
access_token = kwargs.pop("access_token", None)
|
937
948
|
|
938
|
-
self._save_skip_storage(
|
949
|
+
self._save_skip_storage(**kwargs)
|
939
950
|
|
940
951
|
from lamindb._save import check_and_attempt_clearing, check_and_attempt_upload
|
941
952
|
|
@@ -951,9 +962,9 @@ def save(self, *args, **kwargs) -> None:
|
|
951
962
|
raise RuntimeError(exception)
|
952
963
|
|
953
964
|
|
954
|
-
def _save_skip_storage(file,
|
965
|
+
def _save_skip_storage(file, **kwargs) -> None:
|
955
966
|
save_feature_sets(file)
|
956
|
-
super(Artifact, file).save(
|
967
|
+
super(Artifact, file).save(**kwargs)
|
957
968
|
save_feature_set_links(file)
|
958
969
|
|
959
970
|
|
@@ -998,7 +1009,7 @@ METHOD_NAMES = [
|
|
998
1009
|
"from_df",
|
999
1010
|
"from_mudata",
|
1000
1011
|
"backed",
|
1001
|
-
"
|
1012
|
+
"cache",
|
1002
1013
|
"load",
|
1003
1014
|
"delete",
|
1004
1015
|
"save",
|
@@ -1024,5 +1035,6 @@ for name in METHOD_NAMES:
|
|
1024
1035
|
Artifact._delete_skip_storage = _delete_skip_storage
|
1025
1036
|
Artifact._save_skip_storage = _save_skip_storage
|
1026
1037
|
Artifact.path = path
|
1038
|
+
Artifact.stage = cache
|
1027
1039
|
# this seems a Django-generated function
|
1028
1040
|
delattr(Artifact, "get_visibility_display")
|
lamindb/_collection.py
CHANGED
@@ -116,6 +116,17 @@ def __init__(
|
|
116
116
|
logger.warning(
|
117
117
|
f"returning existing collection with same hash: {existing_collection}"
|
118
118
|
)
|
119
|
+
# update the run of the existing artifact
|
120
|
+
if run is not None:
|
121
|
+
# save the information that this artifact was previously
|
122
|
+
# produced by another run
|
123
|
+
if existing_collection.run is not None:
|
124
|
+
existing_collection.run.replicated_output_collections.add(
|
125
|
+
existing_collection
|
126
|
+
)
|
127
|
+
# update the run of the artifact with the latest run
|
128
|
+
existing_collection.run = run
|
129
|
+
existing_collection.transform = run.transform
|
119
130
|
init_self_from_db(collection, existing_collection)
|
120
131
|
for slot, feature_set in collection.features._feature_set_by_slot.items():
|
121
132
|
if slot in feature_sets:
|
@@ -227,7 +238,7 @@ def mapped(
|
|
227
238
|
logger.warning(f"Ignoring artifact with suffix {artifact.suffix}")
|
228
239
|
continue
|
229
240
|
elif not stream:
|
230
|
-
path_list.append(artifact.
|
241
|
+
path_list.append(artifact.cache())
|
231
242
|
else:
|
232
243
|
path_list.append(artifact.path)
|
233
244
|
ds = MappedCollection(
|
@@ -248,11 +259,11 @@ def mapped(
|
|
248
259
|
|
249
260
|
|
250
261
|
# docstring handled through attach_func_to_class_method
|
251
|
-
def
|
262
|
+
def cache(self, is_run_input: bool | None = None) -> list[UPath]:
|
252
263
|
_track_run_input(self, is_run_input)
|
253
264
|
path_list = []
|
254
265
|
for artifact in self.artifacts.all():
|
255
|
-
path_list.append(artifact.
|
266
|
+
path_list.append(artifact.cache())
|
256
267
|
return path_list
|
257
268
|
|
258
269
|
|
@@ -355,7 +366,7 @@ def artifacts(self) -> QuerySet:
|
|
355
366
|
METHOD_NAMES = [
|
356
367
|
"__init__",
|
357
368
|
"mapped",
|
358
|
-
"
|
369
|
+
"cache",
|
359
370
|
"load",
|
360
371
|
"delete",
|
361
372
|
"save",
|
@@ -377,3 +388,4 @@ for name in METHOD_NAMES:
|
|
377
388
|
# this seems a Django-generated function
|
378
389
|
delattr(Collection, "get_visibility_display")
|
379
390
|
Collection.artifacts = artifacts
|
391
|
+
Collection.stage = cache
|
lamindb/_finish.py
CHANGED
@@ -43,39 +43,35 @@ def finish(i_saved_the_notebook: bool = False):
|
|
43
43
|
"Please pass `i_saved_the_notebook=True` to `ln.finish()`, save the notebook, and re-run this cell."
|
44
44
|
)
|
45
45
|
return None
|
46
|
-
notebook_content = read_notebook(run_context.path) # type: ignore
|
47
|
-
if not check_last_cell(notebook_content, "i_saved_the_notebook"):
|
48
|
-
raise CallFinishInLastCell(
|
49
|
-
"Can only run `ln.finish(i_saved_the_notebook=True)` from the last code cell of the notebook."
|
50
|
-
)
|
51
46
|
save_run_context_core(
|
52
47
|
run=run_context.run,
|
53
48
|
transform=run_context.transform,
|
54
49
|
filepath=run_context.path,
|
55
50
|
finished_at=True,
|
56
|
-
notebook_content=notebook_content,
|
57
51
|
)
|
58
52
|
else:
|
59
53
|
# scripts
|
54
|
+
# save_run_context_core was already called during ln.track()
|
60
55
|
run_context.run.finished_at = datetime.now(timezone.utc) # update run time
|
61
56
|
run_context.run.save()
|
62
57
|
|
63
58
|
|
64
|
-
# do not type because we need to be aware of lnschema_core import order
|
65
59
|
def save_run_context_core(
|
66
60
|
*,
|
67
61
|
run: Run,
|
68
62
|
transform: Transform,
|
69
63
|
filepath: Path,
|
70
64
|
transform_family: QuerySet | None = None,
|
71
|
-
is_consecutive: bool = True,
|
72
65
|
finished_at: bool = False,
|
73
|
-
notebook_content=None, # nbproject.Notebook
|
74
66
|
) -> str | None:
|
75
67
|
import lamindb as ln
|
76
68
|
|
77
69
|
ln.settings.verbosity = "success"
|
78
70
|
|
71
|
+
# for scripts, things are easy
|
72
|
+
is_consecutive = True
|
73
|
+
source_code_path = filepath
|
74
|
+
# for notebooks, we need more work
|
79
75
|
if transform.type == TransformType.notebook:
|
80
76
|
try:
|
81
77
|
import nbstripout
|
@@ -88,62 +84,52 @@ def save_run_context_core(
|
|
88
84
|
"install nbproject & nbstripout: pip install nbproject nbstripout"
|
89
85
|
)
|
90
86
|
return None
|
91
|
-
|
92
|
-
notebook_content = read_notebook(filepath) # type: ignore
|
87
|
+
notebook_content = read_notebook(filepath) # type: ignore
|
93
88
|
is_consecutive = check_consecutiveness(notebook_content)
|
94
89
|
if not is_consecutive:
|
90
|
+
msg = " Do you still want to proceed with finishing? (y/n) "
|
95
91
|
if os.getenv("LAMIN_TESTING") is None:
|
96
|
-
|
97
|
-
" Do you still want to proceed with publishing? (y/n) "
|
98
|
-
)
|
92
|
+
response = input(msg)
|
99
93
|
else:
|
100
|
-
|
101
|
-
if
|
102
|
-
logger.error("Aborted (non-consecutive)!")
|
94
|
+
response = "n"
|
95
|
+
if response != "y":
|
103
96
|
return "aborted-non-consecutive"
|
104
|
-
|
105
97
|
# convert the notebook file to html
|
106
98
|
# log_level is set to 40 to silence the nbconvert logging
|
107
|
-
|
99
|
+
subprocess.run(
|
108
100
|
"jupyter nbconvert --to html"
|
109
101
|
f" {filepath.as_posix()} --Application.log_level=40",
|
110
102
|
shell=True,
|
103
|
+
check=True,
|
111
104
|
)
|
112
105
|
# move the temporary file into the cache dir in case it's accidentally
|
113
106
|
# in an existing storage location -> we want to move associated
|
114
107
|
# artifacts into default storage and not register them in an existing
|
115
108
|
# location
|
116
|
-
|
109
|
+
filepath_html_orig = filepath.with_suffix(".html") # current location
|
110
|
+
filepath_html = ln_setup.settings.storage.cache_dir / filepath_html_orig.name
|
111
|
+
# don't use Path.rename here because of cross-device link error
|
112
|
+
# https://laminlabs.slack.com/archives/C04A0RMA0SC/p1710259102686969
|
117
113
|
shutil.move(
|
118
|
-
|
119
|
-
|
120
|
-
)
|
121
|
-
#
|
122
|
-
|
123
|
-
ln_setup.settings.storage.cache_dir / filepath_html.name
|
124
|
-
) # adjust location
|
125
|
-
assert result.returncode == 0
|
126
|
-
# copy the notebook file to a temporary file
|
114
|
+
filepath_html_orig, # type: ignore
|
115
|
+
filepath_html,
|
116
|
+
)
|
117
|
+
# strip the output from the notebook to create the source code file
|
118
|
+
# first, copy the notebook file to a temporary file in the cache
|
127
119
|
source_code_path = ln_setup.settings.storage.cache_dir / filepath.name
|
128
120
|
shutil.copy2(filepath, source_code_path) # copy
|
129
|
-
|
130
|
-
assert result.returncode == 0
|
131
|
-
else:
|
132
|
-
source_code_path = filepath
|
121
|
+
subprocess.run(f"nbstripout {source_code_path}", shell=True, check=True)
|
133
122
|
# find initial versions of source codes and html reports
|
134
|
-
|
135
|
-
|
123
|
+
prev_report = None
|
124
|
+
prev_source = None
|
136
125
|
if transform_family is None:
|
137
126
|
transform_family = transform.versions
|
138
127
|
if len(transform_family) > 0:
|
139
128
|
for prev_transform in transform_family.order_by("-created_at"):
|
140
|
-
# check for id to avoid query
|
141
129
|
if prev_transform.latest_report_id is not None:
|
142
|
-
|
143
|
-
initial_report = prev_transform.latest_report
|
130
|
+
prev_report = prev_transform.latest_report
|
144
131
|
if prev_transform.source_code_id is not None:
|
145
|
-
|
146
|
-
initial_source = prev_transform.source_code
|
132
|
+
prev_source = prev_transform.source_code
|
147
133
|
ln.settings.silence_file_run_transform_warning = True
|
148
134
|
# register the source code
|
149
135
|
if transform.source_code is not None:
|
@@ -173,7 +159,7 @@ def save_run_context_core(
|
|
173
159
|
source_code_path,
|
174
160
|
description=f"Source of transform {transform.uid}",
|
175
161
|
version=transform.version,
|
176
|
-
is_new_version_of=
|
162
|
+
is_new_version_of=prev_source,
|
177
163
|
visibility=0, # hidden file
|
178
164
|
run=False,
|
179
165
|
)
|
@@ -207,7 +193,7 @@ def save_run_context_core(
|
|
207
193
|
report_file = ln.Artifact(
|
208
194
|
filepath_html,
|
209
195
|
description=f"Report of run {run.uid}",
|
210
|
-
is_new_version_of=
|
196
|
+
is_new_version_of=prev_report,
|
211
197
|
visibility=0, # hidden file
|
212
198
|
run=False,
|
213
199
|
)
|
lamindb/_from_values.py
CHANGED
@@ -247,7 +247,8 @@ def index_iterable(iterable: Iterable) -> pd.Index:
|
|
247
247
|
|
248
248
|
|
249
249
|
def _print_values(names: list, n: int = 20) -> str:
|
250
|
-
|
250
|
+
names = list(set(names))
|
251
|
+
print_values = ", ".join([f"'{name}'" for name in names[:n] if name != "None"])
|
251
252
|
if len(names) > n:
|
252
253
|
print_values += ", ..."
|
253
254
|
return print_values
|
lamindb/core/_data.py
CHANGED
@@ -94,6 +94,23 @@ def save_feature_set_links(self: Artifact | Collection) -> None:
|
|
94
94
|
bulk_create(links, ignore_conflicts=True)
|
95
95
|
|
96
96
|
|
97
|
+
def format_repr(value: Registry, exclude: list[str] | str | None = None) -> str:
|
98
|
+
if isinstance(exclude, str):
|
99
|
+
exclude = [exclude]
|
100
|
+
exclude_fields = set() if exclude is None else set(exclude)
|
101
|
+
exclude_fields.update(["created_at", "updated_at"])
|
102
|
+
|
103
|
+
fields = [
|
104
|
+
f
|
105
|
+
for f in value.__repr__(include_foreign_keys=False).split(", ")
|
106
|
+
if not any(f"{excluded_field}=" in f for excluded_field in exclude_fields)
|
107
|
+
]
|
108
|
+
repr = ", ".join(fields)
|
109
|
+
if not repr.endswith(")"):
|
110
|
+
repr += ")"
|
111
|
+
return repr
|
112
|
+
|
113
|
+
|
97
114
|
@doc_args(Data.describe.__doc__)
|
98
115
|
def describe(self: Data):
|
99
116
|
"""{}."""
|
@@ -117,7 +134,7 @@ def describe(self: Data):
|
|
117
134
|
msg += f"{colors.green('Provenance')}:\n "
|
118
135
|
related_msg = "".join(
|
119
136
|
[
|
120
|
-
f"📎 {field}: {self.__getattribute__(field)}\n "
|
137
|
+
f"📎 {field}: {format_repr(self.__getattribute__(field))}\n "
|
121
138
|
for field in foreign_key_fields
|
122
139
|
if self.__getattribute__(field) is not None
|
123
140
|
]
|
lamindb/core/_feature_manager.py
CHANGED
@@ -91,6 +91,8 @@ def get_feature_set_links(host: Artifact | Collection) -> QuerySet:
|
|
91
91
|
def print_features(self: Data) -> str:
|
92
92
|
from lamindb._from_values import _print_values
|
93
93
|
|
94
|
+
from ._data import format_repr
|
95
|
+
|
94
96
|
msg = ""
|
95
97
|
features_lookup = Feature.objects.using(self._state.db).lookup().dict()
|
96
98
|
for slot, feature_set in self.features._feature_set_by_slot.items():
|
@@ -98,12 +100,16 @@ def print_features(self: Data) -> str:
|
|
98
100
|
features = feature_set.members
|
99
101
|
name_field = get_default_str_field(features[0])
|
100
102
|
feature_names = [getattr(feature, name_field) for feature in features]
|
101
|
-
msg +=
|
103
|
+
msg += (
|
104
|
+
f" {colors.bold(slot)}: {format_repr(feature_set, exclude='hash')}\n"
|
105
|
+
)
|
102
106
|
print_values = _print_values(feature_names, n=20)
|
103
107
|
msg += f" {print_values}\n"
|
104
108
|
else:
|
105
109
|
df_slot = feature_set.features.df()
|
106
|
-
msg +=
|
110
|
+
msg += (
|
111
|
+
f" {colors.bold(slot)}: {format_repr(feature_set, exclude='hash')}\n"
|
112
|
+
)
|
107
113
|
for _, row in df_slot.iterrows():
|
108
114
|
if row["type"] == "category" and row["registries"] is not None:
|
109
115
|
labels = self.labels.get(
|
lamindb/core/_run_context.py
CHANGED
lamindb/core/_settings.py
CHANGED
@@ -64,7 +64,7 @@ class Settings:
|
|
64
64
|
FAQ: :doc:`/faq/idempotency`
|
65
65
|
"""
|
66
66
|
track_run_inputs: bool = True
|
67
|
-
"""Track files as input upon `.load()`, `.
|
67
|
+
"""Track files as input upon `.load()`, `.cache()` and `.backed()`.
|
68
68
|
|
69
69
|
Requires a global run context with :func:`~lamindb.track` was created!
|
70
70
|
|
lamindb/core/datasets/_core.py
CHANGED
@@ -299,7 +299,7 @@ def anndata_human_immune_cells(
|
|
299
299
|
adata = sc.read('Global.h5ad')
|
300
300
|
adata.obs = adata.obs[['donor_id', 'tissue', 'cell_type', 'assay', 'tissue_ontology_term_id', 'cell_type_ontology_term_id', 'assay_ontology_term_id']].copy()
|
301
301
|
sc.pp.subsample(adata, fraction=0.005)
|
302
|
-
del adata.uns["
|
302
|
+
del adata.uns["development_cache_ontology_term_id_colors"]
|
303
303
|
del adata.uns["sex_ontology_term_id_colors"]
|
304
304
|
adata.write('human_immune.h5ad')
|
305
305
|
"""
|
@@ -2,39 +2,48 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import json
|
4
4
|
from datetime import datetime, timezone
|
5
|
+
from typing import TYPE_CHECKING
|
5
6
|
|
6
7
|
import lamindb_setup as ln_setup
|
7
8
|
from lamin_utils import logger
|
8
9
|
|
9
10
|
from lamindb._artifact import Artifact
|
10
11
|
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from vitessce import VitessceConfig
|
14
|
+
|
11
15
|
|
12
|
-
# tested in lamin-spatial
|
13
|
-
|
14
|
-
def save_vitessce_config(vitessce_config, description: str) -> Artifact:
|
16
|
+
# tested & context in https://github.com/laminlabs/lamin-spatial
|
17
|
+
def save_vitessce_config(vitessce_config: VitessceConfig, description: str) -> Artifact:
|
15
18
|
"""Takes a ``VitessceConfig`` object and saves it as an artifact.
|
16
19
|
|
17
20
|
Args:
|
18
21
|
vitessce_config (``VitessceConfig``): A VitessceConfig object.
|
19
22
|
description: A description for the artifact.
|
20
23
|
"""
|
24
|
+
# can't assume vitessce is installed
|
21
25
|
from vitessce import VitessceConfig
|
22
26
|
|
23
|
-
|
27
|
+
# create a local _data export_ in a folder
|
24
28
|
timestamp = datetime.now(timezone.utc).isoformat().split(".")[0]
|
25
|
-
|
26
|
-
vitessce_config.export(to="files", base_url="", out_dir=
|
27
|
-
logger.important(f"local export: {
|
28
|
-
artifact
|
29
|
+
vitesse_export_folder = f"./vitessce_export_{timestamp}.vitessce"
|
30
|
+
vitessce_config.export(to="files", base_url="", out_dir=vitesse_export_folder)
|
31
|
+
logger.important(f"local export: {vitesse_export_folder}")
|
32
|
+
# create an artifact and store the local export in th cloud
|
33
|
+
artifact = Artifact(vitesse_export_folder, description=description)
|
29
34
|
artifact.save()
|
35
|
+
# create a JSON export that points to the data in the cloud
|
30
36
|
config_dict = vitessce_config.to_dict(base_url=artifact.path.to_url())
|
31
37
|
logger.important(f"base url: {artifact.path.to_url()}")
|
38
|
+
# manually place that JSON export into the local data export folder
|
32
39
|
config_filename = "vitessce_config.json"
|
33
|
-
config_file_local_path = f"{
|
40
|
+
config_file_local_path = f"{vitesse_export_folder}/{config_filename}"
|
34
41
|
with open(config_file_local_path, "w") as file:
|
35
42
|
json.dump(config_dict, file)
|
43
|
+
# manually place that JSON export into the previously registered artifact folder
|
36
44
|
config_file_path = artifact.path / config_filename
|
37
45
|
config_file_path.upload_from(config_file_local_path)
|
46
|
+
# log the the URLs
|
38
47
|
logger.important(f"config url: {config_file_path.to_url()}")
|
39
48
|
slug = ln_setup.settings.instance.slug
|
40
49
|
logger.important(f"go to: https://lamin.ai/{slug}/artifact/{artifact.uid}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lamindb
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.70.0
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
6
|
Requires-Python: >=3.8
|
@@ -9,10 +9,10 @@ Classifier: Programming Language :: Python :: 3.8
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.9
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
|
-
Requires-Dist: lnschema_core==0.
|
13
|
-
Requires-Dist: lamindb_setup==0.69.
|
12
|
+
Requires-Dist: lnschema_core==0.65.0
|
13
|
+
Requires-Dist: lamindb_setup==0.69.2
|
14
14
|
Requires-Dist: lamin_utils==0.13.1
|
15
|
-
Requires-Dist: lamin_cli==0.12.
|
15
|
+
Requires-Dist: lamin_cli==0.12.3
|
16
16
|
Requires-Dist: rapidfuzz
|
17
17
|
Requires-Dist: pyarrow
|
18
18
|
Requires-Dist: typing_extensions!=4.6.0
|
@@ -1,13 +1,13 @@
|
|
1
|
-
lamindb/__init__.py,sha256=
|
1
|
+
lamindb/__init__.py,sha256=BT6UZlIvg7VG1sTaQ_k81e1b2ATVgR3eTSMjFitNerA,2163
|
2
2
|
lamindb/_annotate.py,sha256=BXYWFATifbfRVmLFIgE4cZ4Fls4lkH2WXAEL2o7v-XM,43035
|
3
|
-
lamindb/_artifact.py,sha256=
|
3
|
+
lamindb/_artifact.py,sha256=eUh0_dCD_wLMUL7HxWTKjk7WGeyFh1olJVMkQETzLUU,37193
|
4
4
|
lamindb/_can_validate.py,sha256=qA6Ni9scObcIeYzuudVymgOjQVLLxnGNofBSDNDaqfY,14557
|
5
|
-
lamindb/_collection.py,sha256=
|
5
|
+
lamindb/_collection.py,sha256=Yo72YdmAKP4O6awoJAFhRKKzM6rKelS0inII8sKk0ls,14545
|
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=
|
10
|
-
lamindb/_from_values.py,sha256=
|
9
|
+
lamindb/_finish.py,sha256=SIPIIMAXM2d00L6VHMf2qFiOHuTyAlLy-5qRJ-BYaIQ,8107
|
10
|
+
lamindb/_from_values.py,sha256=Mupz-mW_aftlhSktH1cgSD4hVaQJW93VehoFJhD15h4,12207
|
11
11
|
lamindb/_is_versioned.py,sha256=0PgRCmxEmYDcAjllLSOYZm132B1lW6QgmBBERhRyFt0,1341
|
12
12
|
lamindb/_parents.py,sha256=N9T8jbd3eaoHDLE9TD1y1QgGcO81E6Brapy8LILzRCQ,14790
|
13
13
|
lamindb/_query_manager.py,sha256=3zokXqxgj9vTJBnN2sbYKS-q69fyDDPF_aGq_rFHzXU,4066
|
@@ -21,12 +21,12 @@ lamindb/_ulabel.py,sha256=e5dw9h1tR0_u-DMn7Gzx0WhUhV5w7j4v3QbnLWQV7eI,1941
|
|
21
21
|
lamindb/_utils.py,sha256=LGdiW4k3GClLz65vKAVRkL6Tw-Gkx9DWAdez1jyA5bE,428
|
22
22
|
lamindb/_view.py,sha256=GV1FrqIMmdooEkA-5zvcTWgV1nqx1sehi6WdWEaFpxM,2171
|
23
23
|
lamindb/core/__init__.py,sha256=MB1gEMKUf0GBQrI3dH8WRZOZQmWR4HIojXK_hXXVdqA,1235
|
24
|
-
lamindb/core/_data.py,sha256=
|
25
|
-
lamindb/core/_feature_manager.py,sha256=
|
24
|
+
lamindb/core/_data.py,sha256=En3v29eiJARy5l7nSsttAsDsqDLTZ4-xM8fCNyVzExI,17465
|
25
|
+
lamindb/core/_feature_manager.py,sha256=LlYgU71AoTnrseWFCq-oZkUAYWITtRR7BNFm0AhHe-c,15773
|
26
26
|
lamindb/core/_label_manager.py,sha256=0RtegYnK3zIisOnd970EobOrHMpp7OCH-mEoPrPXw2c,9075
|
27
27
|
lamindb/core/_mapped_collection.py,sha256=_OwFZh5SePDUD70XIK5kngv3we_Z5-YdGHNfpUSatSQ,19469
|
28
|
-
lamindb/core/_run_context.py,sha256=
|
29
|
-
lamindb/core/_settings.py,sha256=
|
28
|
+
lamindb/core/_run_context.py,sha256=xcsPhpabm2a-PnwH-vDJ4Mx4qQLdFsn4ZUpWMWKZgoM,17472
|
29
|
+
lamindb/core/_settings.py,sha256=r9si7wJb31tI4vfz9dUN4iXe6QQU7FjnqAEsHy2UDzM,5727
|
30
30
|
lamindb/core/_sync_git.py,sha256=IlTqw55inPp_RZbN_YScaCeKza7LeF9mClQw55W3_d4,3921
|
31
31
|
lamindb/core/_track_environment.py,sha256=xLZ6kgzxWS6MWZ5LQ_wkbJX99vmYOT8iQ-Fz4OHCgWw,754
|
32
32
|
lamindb/core/_transform_settings.py,sha256=eV96QKX9jOojjzF-a0oo0wXQsMXN2F6QV7orE06oFC8,161
|
@@ -36,7 +36,7 @@ lamindb/core/fields.py,sha256=Jgi_XI-iTe6cT7oD8FV_JqEpjN1Q9rZWwL8VLtj4jkA,164
|
|
36
36
|
lamindb/core/types.py,sha256=xeQF2x40p2pR9eIVQrXT74RrS810z2fbjmTRTSQUqPM,230
|
37
37
|
lamindb/core/versioning.py,sha256=DsEHpCueNwhRiIaRH5-O8H_1fJVNtWslCRx30YiIS5o,3080
|
38
38
|
lamindb/core/datasets/__init__.py,sha256=zRP98oqUAaXhqWyKMiH0s_ImVIuNeziQQ2kQ_t0f-DI,1353
|
39
|
-
lamindb/core/datasets/_core.py,sha256=
|
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
41
|
lamindb/core/storage/__init__.py,sha256=9alBNtyH59VnoWJS-IdjLwFKlK-kgeCGl6jXk0_wGeQ,369
|
42
42
|
lamindb/core/storage/_anndata_sizes.py,sha256=aXO3OB--tF5MChenSsigW6Q-RuE8YJJOUTVukkLrv9A,1029
|
@@ -45,10 +45,10 @@ lamindb/core/storage/_zarr.py,sha256=0i9-cJPjieIsp5UpK-IyRPkHAF-iKkWgpkWviSni2MM
|
|
45
45
|
lamindb/core/storage/file.py,sha256=AEMbrC6oWoIp3vs4F2bgm50EVBxkCGbN9R4na7Wanaw,7754
|
46
46
|
lamindb/core/storage/object.py,sha256=37p8CSlfSlWPVuuD3MFcwQRj1n_kovLKVImh9SCR4Eg,1601
|
47
47
|
lamindb/integrations/__init__.py,sha256=aH2PmO2m4-vwIifMYTB0Fyyr_gZWtVnV71jT0tVWSw0,123
|
48
|
-
lamindb/integrations/_vitessce.py,sha256=
|
48
|
+
lamindb/integrations/_vitessce.py,sha256=l3GPkzQXcwnMypbm8vDkITjognELjX8ucLaiqy99Jgg,2131
|
49
49
|
lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
|
50
50
|
lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
|
51
|
-
lamindb-0.
|
52
|
-
lamindb-0.
|
53
|
-
lamindb-0.
|
54
|
-
lamindb-0.
|
51
|
+
lamindb-0.70.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
52
|
+
lamindb-0.70.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
53
|
+
lamindb-0.70.0.dist-info/METADATA,sha256=Mj16sNRVTgeMpFSL9mNUzF9HBaGo1RzERYp2ejiW8Xk,2835
|
54
|
+
lamindb-0.70.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|