lamindb_setup 1.15.2__py3-none-any.whl → 1.16.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_setup/__init__.py +1 -1
- lamindb_setup/_schema_metadata.py +9 -11
- lamindb_setup/_setup_user.py +20 -2
- lamindb_setup/core/_clone.py +1 -1
- lamindb_setup/core/_private_django_api.py +0 -1
- lamindb_setup/core/_settings_storage.py +3 -1
- lamindb_setup/core/django.py +2 -0
- lamindb_setup/core/upath.py +19 -7
- lamindb_setup/io.py +55 -30
- {lamindb_setup-1.15.2.dist-info → lamindb_setup-1.16.0.dist-info}/METADATA +2 -1
- {lamindb_setup-1.15.2.dist-info → lamindb_setup-1.16.0.dist-info}/RECORD +13 -13
- {lamindb_setup-1.15.2.dist-info → lamindb_setup-1.16.0.dist-info}/LICENSE +0 -0
- {lamindb_setup-1.15.2.dist-info → lamindb_setup-1.16.0.dist-info}/WHEEL +0 -0
lamindb_setup/__init__.py
CHANGED
|
@@ -172,7 +172,8 @@ class _ModelHandler:
|
|
|
172
172
|
self.table_name = model._meta.db_table
|
|
173
173
|
self.included_modules = included_modules
|
|
174
174
|
self.fields = self._get_fields_metadata(self.model)
|
|
175
|
-
self.
|
|
175
|
+
self.is_auto_created = bool(model._meta.auto_created)
|
|
176
|
+
self.is_link_table = issubclass(model, IsLink) or self.is_auto_created
|
|
176
177
|
self.name_field = model._name_field if hasattr(model, "_name_field") else None
|
|
177
178
|
self.ontology_id_field = (
|
|
178
179
|
model._ontology_id_field if hasattr(model, "_ontology_id_field") else None
|
|
@@ -183,6 +184,7 @@ class _ModelHandler:
|
|
|
183
184
|
"fields": self.fields.copy(),
|
|
184
185
|
"class_name": self.class_name,
|
|
185
186
|
"table_name": self.table_name,
|
|
187
|
+
"is_auto_created": self.is_auto_created,
|
|
186
188
|
"is_link_table": self.is_link_table,
|
|
187
189
|
"name_field": self.name_field,
|
|
188
190
|
"ontology_id_field": self.ontology_id_field,
|
|
@@ -249,13 +251,13 @@ class _ModelHandler:
|
|
|
249
251
|
return related_fields
|
|
250
252
|
|
|
251
253
|
def _get_field_metadata(self, model, field: Field):
|
|
252
|
-
from lamindb.models import IsLink
|
|
254
|
+
from lamindb.models import IsLink, Registry
|
|
253
255
|
|
|
254
256
|
internal_type = field.get_internal_type()
|
|
255
257
|
model_name = field.model._meta.model_name
|
|
256
258
|
relation_type = self._get_relation_type(model, field)
|
|
257
259
|
|
|
258
|
-
schema_name = field.model
|
|
260
|
+
schema_name = Registry.__get_module_name__(field.model)
|
|
259
261
|
|
|
260
262
|
if field.related_model is None:
|
|
261
263
|
related_model_name = None
|
|
@@ -265,7 +267,7 @@ class _ModelHandler:
|
|
|
265
267
|
max_length = field.max_length
|
|
266
268
|
else:
|
|
267
269
|
related_model_name = field.related_model._meta.model_name
|
|
268
|
-
related_schema_name = field.related_model
|
|
270
|
+
related_schema_name = Registry.__get_module_name__(field.related_model)
|
|
269
271
|
related_field_name = field.remote_field.name
|
|
270
272
|
is_editable = False
|
|
271
273
|
max_length = None
|
|
@@ -418,14 +420,10 @@ class _SchemaHandler:
|
|
|
418
420
|
all_models = {module_name: {} for module_name in self.included_modules}
|
|
419
421
|
|
|
420
422
|
# Iterate through all registered Django models
|
|
421
|
-
for model in apps.get_models():
|
|
423
|
+
for model in apps.get_models(include_auto_created=True):
|
|
422
424
|
# Check if model meets the criteria
|
|
423
|
-
if
|
|
424
|
-
|
|
425
|
-
and model is not SQLRecord
|
|
426
|
-
and not model._meta.abstract
|
|
427
|
-
):
|
|
428
|
-
module_name = model.__get_module_name__()
|
|
425
|
+
if model is not SQLRecord and not model._meta.abstract:
|
|
426
|
+
module_name = Registry.__get_module_name__(model)
|
|
429
427
|
# Only include if module is in our included list
|
|
430
428
|
if module_name in self.included_modules:
|
|
431
429
|
model_name = model._meta.model_name
|
lamindb_setup/_setup_user.py
CHANGED
|
@@ -43,6 +43,14 @@ def load_user(email: str | None = None, handle: str | None = None) -> UserSettin
|
|
|
43
43
|
return user_settings
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def current_user_uid() -> str:
|
|
47
|
+
current_user_settings = current_user_settings_file()
|
|
48
|
+
if current_user_settings.exists():
|
|
49
|
+
return load_user_settings(current_user_settings).uid
|
|
50
|
+
|
|
51
|
+
return "00000000" # anonymous
|
|
52
|
+
|
|
53
|
+
|
|
46
54
|
def login(
|
|
47
55
|
user: str | None = None, *, api_key: str | None = None, **kwargs
|
|
48
56
|
) -> UserSettings:
|
|
@@ -90,6 +98,9 @@ def login(
|
|
|
90
98
|
"the legacy API key is deprecated and will likely be removed in a future version"
|
|
91
99
|
)
|
|
92
100
|
|
|
101
|
+
# do this here because load_user overwrites current_user_settings_file
|
|
102
|
+
previous_user_uid = current_user_uid()
|
|
103
|
+
|
|
93
104
|
if api_key is None:
|
|
94
105
|
if "@" in user: # type: ignore
|
|
95
106
|
email, handle = user, None
|
|
@@ -144,8 +155,15 @@ def login(
|
|
|
144
155
|
user_settings.api_key = api_key
|
|
145
156
|
save_user_settings(user_settings)
|
|
146
157
|
|
|
147
|
-
if settings._instance_exists
|
|
148
|
-
|
|
158
|
+
if settings._instance_exists:
|
|
159
|
+
if (
|
|
160
|
+
isettings := settings.instance
|
|
161
|
+
).is_on_hub and previous_user_uid != user_settings.uid:
|
|
162
|
+
logger.important_hint(
|
|
163
|
+
f"consider re-connecting to update permissions: lamin connect {isettings.slug}"
|
|
164
|
+
)
|
|
165
|
+
if _check_instance_setup():
|
|
166
|
+
register_user(user_settings)
|
|
149
167
|
|
|
150
168
|
settings._user_settings = None
|
|
151
169
|
# aws s3 credentials are scoped to the user
|
lamindb_setup/core/_clone.py
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
init_local_sqlite
|
|
7
7
|
connect_local_sqlite
|
|
8
|
+
connect_remote_sqlite
|
|
8
9
|
upload_sqlite_clone
|
|
9
10
|
"""
|
|
10
11
|
|
|
@@ -13,7 +14,6 @@ import os
|
|
|
13
14
|
import shutil
|
|
14
15
|
from pathlib import Path
|
|
15
16
|
|
|
16
|
-
from lamindb_setup.core._settings_instance import InstanceSettings
|
|
17
17
|
from lamindb_setup.core._settings_load import load_instance_settings
|
|
18
18
|
from lamindb_setup.core._settings_store import instance_settings_file
|
|
19
19
|
from lamindb_setup.core.django import reset_django
|
|
@@ -122,6 +122,7 @@ def init_storage(
|
|
|
122
122
|
access_token: str | None = None,
|
|
123
123
|
region: str | None = None,
|
|
124
124
|
space_uuid: UUID | None = None,
|
|
125
|
+
skip_mark_storage_root: bool = False,
|
|
125
126
|
) -> tuple[
|
|
126
127
|
StorageSettings,
|
|
127
128
|
Literal["hub-record-not-created", "hub-record-retrieved", "hub-record-created"],
|
|
@@ -181,7 +182,8 @@ def init_storage(
|
|
|
181
182
|
space_id=space_uuid,
|
|
182
183
|
)
|
|
183
184
|
# we check the write access here if the storage record has not been retrieved from the hub
|
|
184
|
-
if hub_record_status
|
|
185
|
+
# Sergei: should it in fact still go through if hub_record_status == "hub-record-not-created"?
|
|
186
|
+
if hub_record_status != "hub-record-retrieved" and not skip_mark_storage_root:
|
|
185
187
|
try:
|
|
186
188
|
# (federated) credentials for AWS access are provisioned under-the-hood
|
|
187
189
|
# discussion: https://laminlabs.slack.com/archives/C04FPE8V01W/p1719260587167489
|
lamindb_setup/core/django.py
CHANGED
|
@@ -238,6 +238,8 @@ def setup_django(
|
|
|
238
238
|
if view_schema:
|
|
239
239
|
installed_apps = installed_apps[::-1] # to fix how apps appear
|
|
240
240
|
installed_apps += ["schema_graph", "django.contrib.staticfiles"]
|
|
241
|
+
if isettings.dialect == "postgresql":
|
|
242
|
+
installed_apps.insert(0, "pgtrigger")
|
|
241
243
|
|
|
242
244
|
kwargs = dict(
|
|
243
245
|
INSTALLED_APPS=installed_apps,
|
lamindb_setup/core/upath.py
CHANGED
|
@@ -93,10 +93,12 @@ def extract_suffix_from_path(path: Path, arg_name: str | None = None) -> str:
|
|
|
93
93
|
else:
|
|
94
94
|
return suffix
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
suffixes = path.suffixes
|
|
97
|
+
|
|
98
|
+
if len(suffixes) <= 1:
|
|
97
99
|
return process_digits(path.suffix)
|
|
98
100
|
|
|
99
|
-
total_suffix = "".join(
|
|
101
|
+
total_suffix = "".join(suffixes)
|
|
100
102
|
if total_suffix in VALID_SIMPLE_SUFFIXES:
|
|
101
103
|
return total_suffix
|
|
102
104
|
elif total_suffix.endswith(tuple(VALID_COMPOSITE_SUFFIXES)):
|
|
@@ -115,14 +117,24 @@ def extract_suffix_from_path(path: Path, arg_name: str | None = None) -> str:
|
|
|
115
117
|
# in COMPRESSION_SUFFIXES to detect something like .random.gz and then
|
|
116
118
|
# add ".random.gz" but concluded it's too dangerous it's safer to just
|
|
117
119
|
# use ".gz" in such a case
|
|
118
|
-
if
|
|
119
|
-
suffix = "".join(
|
|
120
|
-
|
|
120
|
+
if suffixes[-2] in VALID_SIMPLE_SUFFIXES:
|
|
121
|
+
suffix = "".join(suffixes[-2:])
|
|
122
|
+
# if the suffix preceding the compression suffixes is a valid suffix,
|
|
123
|
+
# we account for it; otherwise we don't.
|
|
124
|
+
# i.e. we should have .h5ad.tar.gz or .csv.tar.gz, not just .tar.gz
|
|
125
|
+
if (
|
|
126
|
+
suffix == ".tar.gz"
|
|
127
|
+
and len(suffixes) > 2
|
|
128
|
+
and (suffix_3 := suffixes[-3]) in VALID_SIMPLE_SUFFIXES
|
|
129
|
+
):
|
|
130
|
+
suffix = suffix_3 + suffix
|
|
121
131
|
# do not print a warning for things like .tar.gz, .fastq.gz
|
|
122
|
-
if
|
|
132
|
+
if suffixes[-1] == ".gz":
|
|
123
133
|
print_hint = False
|
|
134
|
+
else:
|
|
135
|
+
msg += f"inferring: '{suffix}'"
|
|
124
136
|
else:
|
|
125
|
-
suffix =
|
|
137
|
+
suffix = suffixes[-1] # this is equivalent to path.suffix
|
|
126
138
|
msg += (
|
|
127
139
|
f"using only last suffix: '{suffix}' - if you want your composite"
|
|
128
140
|
" suffix to be recognized add it to"
|
lamindb_setup/io.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import io
|
|
4
4
|
import json
|
|
5
5
|
import warnings
|
|
6
|
-
from concurrent.futures import
|
|
6
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
7
7
|
from importlib import import_module
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
@@ -14,24 +14,13 @@ from django.db import models, transaction
|
|
|
14
14
|
from rich.progress import Progress
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
|
-
from collections.abc import Sequence
|
|
17
|
+
from collections.abc import Iterable, Sequence
|
|
18
18
|
from typing import Literal
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def _get_registries(module_name: str) -> list[str]:
|
|
22
22
|
"""Get registry class names from a module."""
|
|
23
23
|
schema_module = import_module(module_name)
|
|
24
|
-
exclude = {"SQLRecord", "BaseSQLRecord"}
|
|
25
|
-
|
|
26
|
-
if module_name == "lamindb":
|
|
27
|
-
module_filter = lambda cls, name: cls.__module__.startswith(
|
|
28
|
-
f"{module_name}.models."
|
|
29
|
-
) and name in dir(schema_module)
|
|
30
|
-
else:
|
|
31
|
-
module_filter = (
|
|
32
|
-
lambda cls, name: cls.__module__ == f"{module_name}.models"
|
|
33
|
-
and name in dir(schema_module)
|
|
34
|
-
)
|
|
35
24
|
|
|
36
25
|
return [
|
|
37
26
|
name
|
|
@@ -40,8 +29,8 @@ def _get_registries(module_name: str) -> list[str]:
|
|
|
40
29
|
name[0].isupper()
|
|
41
30
|
and isinstance(cls := getattr(schema_module.models, name, None), type)
|
|
42
31
|
and issubclass(cls, models.Model)
|
|
43
|
-
|
|
44
|
-
and
|
|
32
|
+
# Table names starting with `None_` are abstract base classes or Django mixins
|
|
33
|
+
and not cls._meta.db_table.startswith("None_") # type: ignore
|
|
45
34
|
)
|
|
46
35
|
]
|
|
47
36
|
|
|
@@ -59,7 +48,7 @@ def _export_full_table(
|
|
|
59
48
|
For SQLite with large tables, reads in chunks to avoid memory issues when tables exceed available RAM.
|
|
60
49
|
|
|
61
50
|
Args:
|
|
62
|
-
registry_info: Tuple of (module_name, model_name, field_name) where field_name
|
|
51
|
+
registry_info: Tuple of (module_name, model_name, field_name) where `field_name`
|
|
63
52
|
is None for regular tables or the field name for M2M link tables.
|
|
64
53
|
directory: Output directory for parquet files.
|
|
65
54
|
chunk_size: Maximum rows per chunk for SQLite large tables.
|
|
@@ -73,7 +62,7 @@ def _export_full_table(
|
|
|
73
62
|
|
|
74
63
|
module_name, model_name, field_name = registry_info
|
|
75
64
|
schema_module = import_module(module_name)
|
|
76
|
-
registry = getattr(schema_module, model_name)
|
|
65
|
+
registry = getattr(schema_module.models, model_name)
|
|
77
66
|
|
|
78
67
|
if field_name:
|
|
79
68
|
registry = getattr(registry, field_name).through
|
|
@@ -84,12 +73,19 @@ def _export_full_table(
|
|
|
84
73
|
if ln_setup.settings.instance.dialect == "postgresql":
|
|
85
74
|
buffer = io.StringIO()
|
|
86
75
|
with connection.cursor() as cursor:
|
|
76
|
+
cursor.execute("SET statement_timeout = 0")
|
|
87
77
|
cursor.copy_expert(
|
|
88
78
|
f'COPY "{table_name}" TO STDOUT WITH (FORMAT CSV, HEADER TRUE)',
|
|
89
79
|
buffer,
|
|
90
80
|
)
|
|
91
81
|
buffer.seek(0)
|
|
92
|
-
|
|
82
|
+
# Prevent pandas from converting empty strings to float NaN (which PyArrow rejects)
|
|
83
|
+
df = pd.read_csv(buffer, keep_default_na=False)
|
|
84
|
+
# Convert object columns to string to handle mixed types from data corruption,
|
|
85
|
+
# schema migrations, or manual SQL inserts. PyArrow rejects mixed-type objects.
|
|
86
|
+
df = df.astype(
|
|
87
|
+
{col: str for col in df.columns if df[col].dtype == "object"}
|
|
88
|
+
)
|
|
93
89
|
df.to_parquet(directory / f"{table_name}.parquet", compression=None)
|
|
94
90
|
return (
|
|
95
91
|
f"{module_name}.{model_name}.{field_name}"
|
|
@@ -118,11 +114,21 @@ def _export_full_table(
|
|
|
118
114
|
chunk_file = (
|
|
119
115
|
directory / f"{table_name}_chunk_{chunk_id}.parquet"
|
|
120
116
|
)
|
|
117
|
+
df = df.astype(
|
|
118
|
+
{
|
|
119
|
+
col: str
|
|
120
|
+
for col in df.columns
|
|
121
|
+
if df[col].dtype == "object"
|
|
122
|
+
}
|
|
123
|
+
)
|
|
121
124
|
df.to_parquet(chunk_file, compression=None)
|
|
122
125
|
chunk_files.append((table_name, chunk_file))
|
|
123
126
|
return chunk_files
|
|
124
127
|
else:
|
|
125
128
|
df = pd.read_sql_table(table_name, ln_setup.settings.instance.db)
|
|
129
|
+
df = df.astype(
|
|
130
|
+
{col: str for col in df.columns if df[col].dtype == "object"}
|
|
131
|
+
)
|
|
126
132
|
df.to_parquet(directory / f"{table_name}.parquet", compression=None)
|
|
127
133
|
return (
|
|
128
134
|
f"{module_name}.{model_name}.{field_name}"
|
|
@@ -163,7 +169,7 @@ def export_db(
|
|
|
163
169
|
for module_name, model_names in modules.items():
|
|
164
170
|
schema_module = import_module(module_name)
|
|
165
171
|
for model_name in model_names:
|
|
166
|
-
registry = getattr(schema_module, model_name)
|
|
172
|
+
registry = getattr(schema_module.models, model_name)
|
|
167
173
|
tasks.append((module_name, model_name, None))
|
|
168
174
|
for field in registry._meta.many_to_many:
|
|
169
175
|
tasks.append((module_name, model_name, field.name))
|
|
@@ -173,13 +179,8 @@ def export_db(
|
|
|
173
179
|
with Progress() as progress:
|
|
174
180
|
task_id = progress.add_task("Exporting", total=len(tasks))
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
mp_context = multiprocessing.get_context("spawn")
|
|
179
|
-
|
|
180
|
-
with ProcessPoolExecutor(
|
|
181
|
-
max_workers=max_workers, mp_context=mp_context
|
|
182
|
-
) as executor:
|
|
182
|
+
# This must be a ThreadPoolExecutor and not a ProcessPoolExecutor to inherit JWTs
|
|
183
|
+
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
183
184
|
futures = {
|
|
184
185
|
executor.submit(_export_full_table, task, directory, chunk_size): task
|
|
185
186
|
for task in tasks
|
|
@@ -229,7 +230,6 @@ def _import_registry(
|
|
|
229
230
|
parquet_file = directory / f"{table_name}.parquet"
|
|
230
231
|
|
|
231
232
|
if not parquet_file.exists():
|
|
232
|
-
print(f"Skipped {table_name} (file not found)")
|
|
233
233
|
return
|
|
234
234
|
|
|
235
235
|
df = pd.read_parquet(parquet_file)
|
|
@@ -244,12 +244,37 @@ def _import_registry(
|
|
|
244
244
|
if mask.any():
|
|
245
245
|
df.loc[mask, col] = df.loc[mask, col].map(_serialize_value)
|
|
246
246
|
|
|
247
|
+
for field in registry._meta.fields:
|
|
248
|
+
# Convert PostgreSQL boolean string literals ('t'/'f') to Python booleans for SQLite compatibility
|
|
249
|
+
if field.get_internal_type() == "BooleanField" and field.column in df.columns:
|
|
250
|
+
df[field.column] = df[field.column].map(
|
|
251
|
+
{"t": True, "f": False, True: True, False: False, None: None}
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# PostgreSQL CSV export writes NULL as empty string; convert back to None for nullable fields
|
|
255
|
+
if field.null and field.column in df.columns:
|
|
256
|
+
df[field.column] = df[field.column].replace("", None)
|
|
257
|
+
|
|
258
|
+
# Convert numeric fields from strings to proper types for SQLite
|
|
259
|
+
if (
|
|
260
|
+
field.get_internal_type()
|
|
261
|
+
in (
|
|
262
|
+
"IntegerField",
|
|
263
|
+
"BigIntegerField",
|
|
264
|
+
"PositiveIntegerField",
|
|
265
|
+
"FloatField",
|
|
266
|
+
"DecimalField",
|
|
267
|
+
)
|
|
268
|
+
and field.column in df.columns
|
|
269
|
+
):
|
|
270
|
+
df[field.column] = pd.to_numeric(df[field.column], errors="coerce")
|
|
271
|
+
|
|
247
272
|
if if_exists == "append":
|
|
248
273
|
# Fill NULL values in NOT NULL columns to handle schema mismatches between postgres source and SQLite target
|
|
249
274
|
# This allows importing data where fields were nullable
|
|
250
275
|
for field in registry._meta.fields:
|
|
251
276
|
if field.column in df.columns and not field.null:
|
|
252
|
-
df[field.column] = df[field.column].fillna("")
|
|
277
|
+
df[field.column] = df[field.column].fillna("").infer_objects(copy=False)
|
|
253
278
|
|
|
254
279
|
if df.empty:
|
|
255
280
|
return
|
|
@@ -297,7 +322,7 @@ def _import_registry(
|
|
|
297
322
|
|
|
298
323
|
|
|
299
324
|
def import_db(
|
|
300
|
-
module_names:
|
|
325
|
+
module_names: Iterable[str] | None = None,
|
|
301
326
|
*,
|
|
302
327
|
input_dir: str | Path = "./lamindb_export/",
|
|
303
328
|
if_exists: Literal["fail", "replace", "append"] = "replace",
|
|
@@ -362,7 +387,7 @@ def import_db(
|
|
|
362
387
|
progress.update(
|
|
363
388
|
task, description=f"[cyan]{module_name}.{model_name}"
|
|
364
389
|
)
|
|
365
|
-
registry = getattr(schema_module, model_name)
|
|
390
|
+
registry = getattr(schema_module.models, model_name)
|
|
366
391
|
_import_registry(registry, directory, if_exists=if_exists)
|
|
367
392
|
for field in registry._meta.many_to_many:
|
|
368
393
|
link_orm = getattr(registry, field.name).through
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: lamindb_setup
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.0
|
|
4
4
|
Summary: Setup & configure LaminDB.
|
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -8,6 +8,7 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
Requires-Dist: lamin_utils>=0.3.3
|
|
9
9
|
Requires-Dist: django>=5.2,<5.3
|
|
10
10
|
Requires-Dist: dj_database_url>=1.3.0,<3.0.0
|
|
11
|
+
Requires-Dist: django-pgtrigger
|
|
11
12
|
Requires-Dist: pydantic-settings
|
|
12
13
|
Requires-Dist: platformdirs<5.0.0
|
|
13
14
|
Requires-Dist: httpx_retries<1.0.0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
lamindb_setup/__init__.py,sha256=
|
|
1
|
+
lamindb_setup/__init__.py,sha256=zAgDC8o3cyH4eXcM60mbulFPECs5XZbqFRxLfGpgpc8,3215
|
|
2
2
|
lamindb_setup/_cache.py,sha256=pGvDNVHGx4HWr_6w5ajqEJOdysmaGc6F221qFnXkT-k,2747
|
|
3
3
|
lamindb_setup/_check.py,sha256=28PcG8Kp6OpjSLSi1r2boL2Ryeh6xkaCL87HFbjs6GA,129
|
|
4
4
|
lamindb_setup/_check_setup.py,sha256=ToKMxsUq8dQBQh8baOrNVlSb1iC8h4zTg5dV8wMu0W4,6760
|
|
@@ -11,40 +11,40 @@ lamindb_setup/_init_instance.py,sha256=zNXmZPUHYda1CfLGtsvo4gNhHprK9QVPfffUIfBlT
|
|
|
11
11
|
lamindb_setup/_migrate.py,sha256=SN8uphuQX-8XShH5odLyzV8-eyXATDxB5hWoxwxmgBU,11264
|
|
12
12
|
lamindb_setup/_register_instance.py,sha256=RdUZxZWHLdbvdNZWpF8e0UWROb_T0cStWbzc5yUw34I,1047
|
|
13
13
|
lamindb_setup/_schema.py,sha256=b3uzhhWpV5mQtDwhMINc2MabGCnGLESy51ito3yl6Wc,679
|
|
14
|
-
lamindb_setup/_schema_metadata.py,sha256=
|
|
14
|
+
lamindb_setup/_schema_metadata.py,sha256=Whs-e4ZMnA1niZ2l5Eu8il-33IxI4Hr5ylGEgPxx8wk,15628
|
|
15
15
|
lamindb_setup/_set_managed_storage.py,sha256=xQe5DXCRiQ5VseAjVC2Bki0wB0n0tSTchvVKSx9I6eo,3094
|
|
16
|
-
lamindb_setup/_setup_user.py,sha256=
|
|
16
|
+
lamindb_setup/_setup_user.py,sha256=cjQ-Md-FkP04PnBxocbHW6wCsZsNtD2T2NB52vAOnHI,6730
|
|
17
17
|
lamindb_setup/_silence_loggers.py,sha256=AKF_YcHvX32eGXdsYK8MJlxEaZ-Uo2f6QDRzjKFCtws,1568
|
|
18
18
|
lamindb_setup/errors.py,sha256=lccF3X3M2mcbHVG_0HxfuJRFFpUE-42paccIxFOfefQ,1958
|
|
19
|
-
lamindb_setup/io.py,sha256=
|
|
19
|
+
lamindb_setup/io.py,sha256=9s4Itt4rrHzsUATY79r4nhGp9zVAm-9uBhiQgg60l6U,16708
|
|
20
20
|
lamindb_setup/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
lamindb_setup/types.py,sha256=fuQxZJnrGYe7a_Ju9n1RqO-HhkOAr1l1xjpAg9dmBu8,605
|
|
22
22
|
lamindb_setup/core/__init__.py,sha256=adZtacDwG2C0tgx-ypp9yOAqw9qaR-IRWkgLurKpXVE,668
|
|
23
23
|
lamindb_setup/core/_aws_options.py,sha256=9kQ5BB-cuJQrlJRGNqMRe1m48dP67xMbefOJP2c9OQw,9674
|
|
24
24
|
lamindb_setup/core/_aws_storage.py,sha256=QEtV-riQrwfivcwqHnXBbkJ-9YyNEXL4fLoCmOHZ1BI,2003
|
|
25
|
-
lamindb_setup/core/_clone.py,sha256=
|
|
25
|
+
lamindb_setup/core/_clone.py,sha256=oLTMItGxRQB1THSDP-RG2eH1qPTVcuZ7_-eElttJ518,6451
|
|
26
26
|
lamindb_setup/core/_deprecated.py,sha256=M3vpM4fZPOncxY2qsXQAPeaEph28xWdv7tYaueaUyAA,2554
|
|
27
27
|
lamindb_setup/core/_docs.py,sha256=3k-YY-oVaJd_9UIY-LfBg_u8raKOCNfkZQPA73KsUhs,276
|
|
28
28
|
lamindb_setup/core/_hub_client.py,sha256=vem145S5ppRPcWob7iclGhos8k-BfwJi9AI-l5PteDs,10481
|
|
29
29
|
lamindb_setup/core/_hub_core.py,sha256=GAQK5XkHROIuqA-H8sOQZVlxvN4QIH_cmHY0TENnq2U,29090
|
|
30
30
|
lamindb_setup/core/_hub_crud.py,sha256=j6516H82kLjFUNPqFGUINbDw9YbofMgjxadGzYb0OS4,6362
|
|
31
31
|
lamindb_setup/core/_hub_utils.py,sha256=6dyDGyzYFgVfR_lE3VN3CP1jGp98gxPtr-T91PAP05U,2687
|
|
32
|
-
lamindb_setup/core/_private_django_api.py,sha256=
|
|
32
|
+
lamindb_setup/core/_private_django_api.py,sha256=Z9uGL4CK0OX58rc8R_qarg9rIBp1DgjsjfP9Vj2vJHI,2629
|
|
33
33
|
lamindb_setup/core/_settings.py,sha256=QbTrSkkdx0u685NJ4neNtWzhdHoaGMKcIvrfFnctTQ4,15450
|
|
34
34
|
lamindb_setup/core/_settings_instance.py,sha256=eDkueLK5JZOGFhZRbGa-OffS9iBFlxMp47vF_MfmCYI,24301
|
|
35
35
|
lamindb_setup/core/_settings_load.py,sha256=NQDOln8e3qyGphk8ucU7mm3HVkCv4QV4rDZro3TIwfo,5183
|
|
36
36
|
lamindb_setup/core/_settings_save.py,sha256=96mWdYLyfvbnG_ok_vK4x7jm-rtqcWCD1OHEt2QSAms,3328
|
|
37
|
-
lamindb_setup/core/_settings_storage.py,sha256=
|
|
37
|
+
lamindb_setup/core/_settings_storage.py,sha256=22EBagIr5qOZr9pqVkJsTcQtgE14en-Wh0y9rgF4FEQ,15677
|
|
38
38
|
lamindb_setup/core/_settings_store.py,sha256=auZssUBb6qE5oSqdGiHhqI2B46qSpegX89VwObPQksk,2601
|
|
39
39
|
lamindb_setup/core/_settings_user.py,sha256=gFfyMf-738onbh1Mf4wsmLlenQJPtjQfpUgKnOlqc2o,1453
|
|
40
40
|
lamindb_setup/core/_setup_bionty_sources.py,sha256=ox3X-SHiHa2lNPSWjwZhINypbLacX6kGwH6hVVrSFZc,1505
|
|
41
41
|
lamindb_setup/core/cloud_sqlite_locker.py,sha256=H_CTUCjURFXwD1cCtV_Jn0_60iztZTkaesLLXIBgIxc,7204
|
|
42
|
-
lamindb_setup/core/django.py,sha256=
|
|
42
|
+
lamindb_setup/core/django.py,sha256=aBdIN07ZCD8PGT04sjF1rruwlppx0cEobBnjk2Due70,12525
|
|
43
43
|
lamindb_setup/core/exceptions.py,sha256=qjMzqy_uzPA7mCOdnoWnS_fdA6OWbdZGftz-YYplrY0,84
|
|
44
44
|
lamindb_setup/core/hashing.py,sha256=Y8Uc5uSGTfU6L2R_gb5w8DdHhGRog7RnkK-e9FEMjPY,3680
|
|
45
45
|
lamindb_setup/core/types.py,sha256=T7NwspfRHgIIpYsXDcApks8jkOlGeGRW-YbVLB7jNIo,67
|
|
46
|
-
lamindb_setup/core/upath.py,sha256=
|
|
47
|
-
lamindb_setup-1.
|
|
48
|
-
lamindb_setup-1.
|
|
49
|
-
lamindb_setup-1.
|
|
50
|
-
lamindb_setup-1.
|
|
46
|
+
lamindb_setup/core/upath.py,sha256=_xs6CgqQezOe6h8oQURjpOl1WT_1ctROzH3yzesVceE,36188
|
|
47
|
+
lamindb_setup-1.16.0.dist-info/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
|
|
48
|
+
lamindb_setup-1.16.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
49
|
+
lamindb_setup-1.16.0.dist-info/METADATA,sha256=mkCWug_dpZRqU6Y0ajukECuIC8kezhh4bTYAIuDLAao,1830
|
|
50
|
+
lamindb_setup-1.16.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|