lamindb_setup 1.18.1__py3-none-any.whl → 1.19.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 +4 -19
- lamindb_setup/_connect_instance.py +7 -4
- lamindb_setup/_delete.py +7 -3
- lamindb_setup/_init_instance.py +1 -7
- lamindb_setup/_migrate.py +6 -2
- lamindb_setup/_set_managed_storage.py +2 -1
- lamindb_setup/core/_aws_options.py +10 -0
- lamindb_setup/core/_aws_storage.py +3 -1
- lamindb_setup/core/_hub_client.py +6 -12
- lamindb_setup/core/_hub_core.py +0 -2
- lamindb_setup/core/_settings_instance.py +10 -6
- lamindb_setup/core/_settings_load.py +11 -8
- lamindb_setup/core/_settings_save.py +17 -5
- lamindb_setup/core/_settings_store.py +87 -17
- lamindb_setup/core/django.py +21 -0
- lamindb_setup/errors.py +7 -5
- lamindb_setup/io.py +12 -5
- {lamindb_setup-1.18.1.dist-info → lamindb_setup-1.19.0.dist-info}/METADATA +2 -1
- {lamindb_setup-1.18.1.dist-info → lamindb_setup-1.19.0.dist-info}/RECORD +21 -21
- {lamindb_setup-1.18.1.dist-info → lamindb_setup-1.19.0.dist-info}/LICENSE +0 -0
- {lamindb_setup-1.18.1.dist-info → lamindb_setup-1.19.0.dist-info}/WHEEL +0 -0
lamindb_setup/__init__.py
CHANGED
|
@@ -35,7 +35,7 @@ Migration management
|
|
|
35
35
|
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
__version__ = "1.
|
|
38
|
+
__version__ = "1.19.0" # denote a release candidate for 0.1.0 with 0.1rc1
|
|
39
39
|
|
|
40
40
|
import os
|
|
41
41
|
import warnings
|
|
@@ -48,9 +48,9 @@ warnings.filterwarnings(
|
|
|
48
48
|
)
|
|
49
49
|
warnings.filterwarnings("ignore", category=DeprecationWarning, module="postgrest")
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
from . import core, errors,
|
|
51
|
+
# do not import io by default to reduce import time
|
|
52
|
+
# it's not immediately needed in the default user workflows
|
|
53
|
+
from . import core, errors, types
|
|
54
54
|
from ._check_setup import _check_instance_setup
|
|
55
55
|
from ._connect_instance import connect
|
|
56
56
|
from ._delete import delete
|
|
@@ -63,20 +63,6 @@ from ._register_instance import register
|
|
|
63
63
|
from ._setup_user import login, logout
|
|
64
64
|
from .core._settings import settings
|
|
65
65
|
|
|
66
|
-
# check that the version of s3fs is higher than the lower bound
|
|
67
|
-
# needed because spatialdata installs old versions of s3fs
|
|
68
|
-
try:
|
|
69
|
-
from s3fs import __version__ as s3fs_version
|
|
70
|
-
|
|
71
|
-
if packaging_version.parse(s3fs_version) < packaging_version.parse("2023.12.2"):
|
|
72
|
-
raise RuntimeError(
|
|
73
|
-
f"The version of s3fs you have ({s3fs_version}) is impompatible "
|
|
74
|
-
"with lamindb, please upgrade it: pip install s3fs>=2023.12.2"
|
|
75
|
-
)
|
|
76
|
-
except ImportError:
|
|
77
|
-
# might be not installed
|
|
78
|
-
pass
|
|
79
|
-
|
|
80
66
|
|
|
81
67
|
def _is_CI_environment() -> bool:
|
|
82
68
|
ci_env_vars = [
|
|
@@ -112,5 +98,4 @@ _call_registered_entry_points("lamindb_setup.on_import")
|
|
|
112
98
|
|
|
113
99
|
settings.__doc__ = """Global :class:`~lamindb.setup.core.SetupSettings`."""
|
|
114
100
|
|
|
115
|
-
|
|
116
101
|
close = disconnect # backward compatibility
|
|
@@ -13,8 +13,6 @@ from ._check_setup import _check_instance_setup
|
|
|
13
13
|
from ._disconnect import disconnect
|
|
14
14
|
from ._init_instance import load_from_isettings
|
|
15
15
|
from ._silence_loggers import silence_loggers
|
|
16
|
-
from .core._hub_core import connect_instance_hub
|
|
17
|
-
from .core._hub_utils import LaminDsnModel
|
|
18
16
|
from .core._settings import settings
|
|
19
17
|
from .core._settings_instance import InstanceSettings
|
|
20
18
|
from .core._settings_load import load_instance_settings
|
|
@@ -66,6 +64,9 @@ def update_db_using_local(
|
|
|
66
64
|
# read directly from the environment
|
|
67
65
|
db_updated = db_env
|
|
68
66
|
else:
|
|
67
|
+
# dynamic import to avoid importing the heavy LaminDsnModel at root
|
|
68
|
+
from .core._hub_utils import LaminDsnModel
|
|
69
|
+
|
|
69
70
|
db_hub = hub_instance_result["db"]
|
|
70
71
|
db_dsn_hub = LaminDsnModel(db=db_hub)
|
|
71
72
|
# read from a cached settings file in case the hub result is inexistent
|
|
@@ -113,6 +114,8 @@ def _connect_instance(
|
|
|
113
114
|
# the following will return a string if the instance does not exist on the hub
|
|
114
115
|
# do not call hub if the user is anonymous
|
|
115
116
|
if owner != "anonymous":
|
|
117
|
+
from .core._hub_core import connect_instance_hub
|
|
118
|
+
|
|
116
119
|
hub_result = connect_instance_hub(
|
|
117
120
|
owner=owner,
|
|
118
121
|
name=name,
|
|
@@ -233,7 +236,8 @@ def reset_django_module_variables():
|
|
|
233
236
|
|
|
234
237
|
|
|
235
238
|
def _connect_cli(
|
|
236
|
-
instance: str,
|
|
239
|
+
instance: str,
|
|
240
|
+
use_root_db_user: bool = False,
|
|
237
241
|
) -> None:
|
|
238
242
|
from lamindb_setup import settings as settings_
|
|
239
243
|
|
|
@@ -242,7 +246,6 @@ def _connect_cli(
|
|
|
242
246
|
owner,
|
|
243
247
|
name,
|
|
244
248
|
use_root_db_user=use_root_db_user,
|
|
245
|
-
use_proxy_db=use_proxy_db,
|
|
246
249
|
raise_systemexit=True,
|
|
247
250
|
)
|
|
248
251
|
isettings._persist(write_to_disk=True)
|
lamindb_setup/_delete.py
CHANGED
|
@@ -8,8 +8,6 @@ from lamin_utils import logger
|
|
|
8
8
|
|
|
9
9
|
from ._connect_instance import _connect_instance, get_owner_name_from_identifier
|
|
10
10
|
from .core._aws_options import HOSTED_BUCKETS
|
|
11
|
-
from .core._hub_core import delete_instance as delete_instance_on_hub
|
|
12
|
-
from .core._hub_core import get_storage_records_for_instance
|
|
13
11
|
from .core._settings import settings
|
|
14
12
|
from .core._settings_load import load_instance_settings
|
|
15
13
|
from .core._settings_storage import StorageSettings
|
|
@@ -120,6 +118,9 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
|
|
|
120
118
|
)
|
|
121
119
|
# now everything that's on the hub
|
|
122
120
|
if settings.user.handle != "anonymous":
|
|
121
|
+
# dynamic import to avoid importing hub logic at root
|
|
122
|
+
from .core._hub_core import get_storage_records_for_instance
|
|
123
|
+
|
|
123
124
|
storage_records = get_storage_records_for_instance(isettings._id)
|
|
124
125
|
for storage_record in storage_records:
|
|
125
126
|
if storage_record["root"] == isettings.storage.root_as_str:
|
|
@@ -139,7 +140,10 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
|
|
|
139
140
|
if settings.user.handle != "anonymous" and isettings.is_on_hub:
|
|
140
141
|
# start with deleting things on the hub
|
|
141
142
|
# this will error if the user doesn't have permission
|
|
142
|
-
|
|
143
|
+
# dynamic import to avoid importing hub logic at root
|
|
144
|
+
from .core._hub_core import delete_instance
|
|
145
|
+
|
|
146
|
+
delete_instance(isettings._id, require_empty=False)
|
|
143
147
|
delete_by_isettings(isettings)
|
|
144
148
|
# if lamin.db file was delete, then we might count -1
|
|
145
149
|
if n_files <= 0 and isettings.storage.type == "local":
|
lamindb_setup/_init_instance.py
CHANGED
|
@@ -6,7 +6,6 @@ import uuid
|
|
|
6
6
|
from typing import TYPE_CHECKING, Literal
|
|
7
7
|
from uuid import UUID
|
|
8
8
|
|
|
9
|
-
import click
|
|
10
9
|
from lamin_utils import logger
|
|
11
10
|
|
|
12
11
|
from ._disconnect import disconnect
|
|
@@ -17,7 +16,7 @@ from .core._settings import settings
|
|
|
17
16
|
from .core._settings_instance import check_is_instance_remote
|
|
18
17
|
from .core._settings_storage import StorageSettings, init_storage
|
|
19
18
|
from .core.upath import UPath
|
|
20
|
-
from .errors import CannotSwitchDefaultInstance
|
|
19
|
+
from .errors import CannotSwitchDefaultInstance, InstanceNotCreated
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
23
22
|
from lamindb.models import Storage
|
|
@@ -27,11 +26,6 @@ if TYPE_CHECKING:
|
|
|
27
26
|
from .types import UPathStr
|
|
28
27
|
|
|
29
28
|
|
|
30
|
-
class InstanceNotCreated(click.ClickException):
|
|
31
|
-
def show(self, file=None):
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
|
-
|
|
35
29
|
def get_schema_module_name(module_name, raise_import_error: bool = True) -> str | None:
|
|
36
30
|
import importlib.util
|
|
37
31
|
|
lamindb_setup/_migrate.py
CHANGED
|
@@ -2,9 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
import httpx
|
|
6
5
|
from django.db import connection
|
|
7
|
-
from django.db.migrations.loader import MigrationLoader
|
|
8
6
|
from lamin_utils import logger
|
|
9
7
|
from packaging import version
|
|
10
8
|
|
|
@@ -111,6 +109,9 @@ class migrate:
|
|
|
111
109
|
isettings = settings.instance
|
|
112
110
|
|
|
113
111
|
if isettings.is_on_hub and LAMIN_MIGRATE_ON_LAMBDA:
|
|
112
|
+
# dynamic import to avoid importing the heavy httpx at root
|
|
113
|
+
import httpx
|
|
114
|
+
|
|
114
115
|
response = httpx.post(
|
|
115
116
|
f"{isettings.api_url}/instances/{isettings._id}/migrate",
|
|
116
117
|
headers={"Authorization": f"Bearer {settings.user.access_token}"},
|
|
@@ -300,6 +301,9 @@ class migrate:
|
|
|
300
301
|
|
|
301
302
|
return latest_migrations
|
|
302
303
|
else:
|
|
304
|
+
# import dynamically to avoid importing the heavy django.db.migrations at the root
|
|
305
|
+
from django.db.migrations.loader import MigrationLoader
|
|
306
|
+
|
|
303
307
|
# Load all migrations using Django's migration loader
|
|
304
308
|
loader = MigrationLoader(connection)
|
|
305
309
|
squashed_replacements = set()
|
|
@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
from lamin_utils import logger
|
|
6
6
|
|
|
7
7
|
from ._init_instance import register_storage_in_instance
|
|
8
|
-
from .core._hub_core import delete_storage_record
|
|
9
8
|
from .core._settings import settings
|
|
10
9
|
from .core._settings_storage import StorageSettings, init_storage
|
|
11
10
|
|
|
@@ -65,6 +64,8 @@ def set_managed_storage(root: UPathStr, host: str | None = None, **fs_kwargs):
|
|
|
65
64
|
register_storage_in_instance(ssettings)
|
|
66
65
|
except Exception as e:
|
|
67
66
|
if hub_record_status == "hub-record-created" and ssettings._uuid is not None:
|
|
67
|
+
from .core._hub_core import delete_storage_record
|
|
68
|
+
|
|
68
69
|
delete_storage_record(ssettings)
|
|
69
70
|
raise e
|
|
70
71
|
|
|
@@ -58,7 +58,17 @@ class AWSOptionsManager:
|
|
|
58
58
|
self._parameters_cache = {} # this is not refreshed
|
|
59
59
|
|
|
60
60
|
from aiobotocore.session import AioSession
|
|
61
|
+
from packaging import version as packaging_version
|
|
62
|
+
|
|
63
|
+
# takes 100ms to import, so keep it here to avoid delaying the import of the main module
|
|
61
64
|
from s3fs import S3FileSystem
|
|
65
|
+
from s3fs import __version__ as s3fs_version
|
|
66
|
+
|
|
67
|
+
if packaging_version.parse(s3fs_version) < packaging_version.parse("2023.12.2"):
|
|
68
|
+
raise RuntimeError(
|
|
69
|
+
f"The version of s3fs you have ({s3fs_version}) is impompatible "
|
|
70
|
+
"with lamindb, please upgrade it: pip install s3fs>=2023.12.2"
|
|
71
|
+
)
|
|
62
72
|
|
|
63
73
|
anon_env = os.getenv("LAMIN_S3_ANON") == "true"
|
|
64
74
|
# this is cached so will be resued with the connection initialized
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import httpx
|
|
4
3
|
from lamin_utils import logger
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
def get_location(ip="ipinfo.io"):
|
|
7
|
+
# dynamic import to avoid importing the heavy httpx at root
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
8
10
|
response = httpx.get(f"http://{ip}/json").json()
|
|
9
11
|
loc = response["loc"].split(",")
|
|
10
12
|
return {"latitude": float(loc[0]), "longitude": float(loc[1])}
|
|
@@ -10,26 +10,20 @@ from urllib.request import urlretrieve
|
|
|
10
10
|
import httpx
|
|
11
11
|
from httpx_retries import Retry, RetryTransport
|
|
12
12
|
from lamin_utils import logger
|
|
13
|
-
from pydantic_settings import BaseSettings
|
|
14
13
|
from supabase import Client, ClientOptions, create_client
|
|
15
14
|
|
|
16
15
|
from ._settings_save import save_user_settings
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class Connector(BaseSettings):
|
|
20
|
-
url: str
|
|
21
|
-
key: str
|
|
16
|
+
from ._settings_store import Connector
|
|
22
17
|
|
|
23
18
|
|
|
24
19
|
def load_fallback_connector() -> Connector:
|
|
25
20
|
url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
|
|
26
21
|
connector_file, _ = urlretrieve(url)
|
|
27
|
-
|
|
28
|
-
return connector
|
|
22
|
+
return Connector.from_env_file(connector_file, "")
|
|
29
23
|
|
|
30
24
|
|
|
31
25
|
PROD_URL = "https://hub.lamin.ai"
|
|
32
|
-
PROD_ANON_KEY = "
|
|
26
|
+
PROD_ANON_KEY = "sb_publishable_YVa4h8hQ-yBhXpfa2cP39w_PhoLW6Nu"
|
|
33
27
|
|
|
34
28
|
|
|
35
29
|
class Environment:
|
|
@@ -48,13 +42,13 @@ class Environment:
|
|
|
48
42
|
key = connector.key
|
|
49
43
|
elif lamin_env == "staging":
|
|
50
44
|
url = "https://amvrvdwndlqdzgedrqdv.supabase.co"
|
|
51
|
-
key = "
|
|
45
|
+
key = "sb_publishable_amVjtilv_Yj4VmGLmxtq6A_sYlLoQx5"
|
|
52
46
|
elif lamin_env == "staging-test":
|
|
53
47
|
url = "https://iugyyajllqftbpidapak.supabase.co"
|
|
54
|
-
key = "
|
|
48
|
+
key = "sb_publishable_XmXroXqTLQw-eeT5kysCww_k8vJv-4L"
|
|
55
49
|
elif lamin_env == "prod-test":
|
|
56
50
|
url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
|
|
57
|
-
key = "
|
|
51
|
+
key = "sb_publishable_G-pyO5aW6VFErTzJyVvM5w_NAv1_Mf7"
|
|
58
52
|
else:
|
|
59
53
|
url = os.environ["SUPABASE_API_URL"]
|
|
60
54
|
key = os.environ["SUPABASE_ANON_KEY"]
|
lamindb_setup/core/_hub_core.py
CHANGED
|
@@ -627,8 +627,6 @@ def access_aws(storage_root: str, access_token: str | None = None) -> dict[str,
|
|
|
627
627
|
|
|
628
628
|
|
|
629
629
|
def _access_aws(*, storage_root: str, client: Client) -> dict[str, dict]:
|
|
630
|
-
import lamindb_setup
|
|
631
|
-
|
|
632
630
|
storage_root_info: dict[str, dict] = {"credentials": {}, "accessibility": {}}
|
|
633
631
|
response = client.functions.invoke(
|
|
634
632
|
"get-cloud-access-v1",
|
|
@@ -5,14 +5,9 @@ import shutil
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import TYPE_CHECKING, Literal
|
|
7
7
|
|
|
8
|
-
from django.db import connection
|
|
9
|
-
from django.db.utils import ProgrammingError
|
|
10
8
|
from lamin_utils import logger
|
|
11
9
|
|
|
12
10
|
from ._deprecated import deprecated
|
|
13
|
-
from ._hub_client import call_with_fallback
|
|
14
|
-
from ._hub_crud import select_account_handle_name_by_lnid
|
|
15
|
-
from ._hub_utils import LaminDsn, LaminDsnModel
|
|
16
11
|
from ._settings_save import save_instance_settings
|
|
17
12
|
from ._settings_storage import (
|
|
18
13
|
LEGACY_STORAGE_UID_FILE_KEY,
|
|
@@ -85,6 +80,7 @@ class InstanceSettings:
|
|
|
85
80
|
_locker_user: UserSettings | None = None, # user to lock for if cloud sqlite,
|
|
86
81
|
_is_clone: bool = False,
|
|
87
82
|
):
|
|
83
|
+
# dynamic import to avoid importing pydantic at root
|
|
88
84
|
from ._hub_utils import validate_db_arg
|
|
89
85
|
|
|
90
86
|
self._id_: UUID = id
|
|
@@ -135,6 +131,9 @@ class InstanceSettings:
|
|
|
135
131
|
)
|
|
136
132
|
elif attr == "db":
|
|
137
133
|
if self.dialect != "sqlite":
|
|
134
|
+
# dynamic import to avoid importing pydantic at root
|
|
135
|
+
from ._hub_utils import LaminDsn, LaminDsnModel
|
|
136
|
+
|
|
138
137
|
model = LaminDsnModel(db=value)
|
|
139
138
|
db_print = LaminDsn.build(
|
|
140
139
|
scheme=model.db.scheme,
|
|
@@ -166,6 +165,7 @@ class InstanceSettings:
|
|
|
166
165
|
def _search_local_root(
|
|
167
166
|
self, local_root: str | None = None, mute_warning: bool = False
|
|
168
167
|
) -> StorageSettings | None:
|
|
168
|
+
from django.db.utils import ProgrammingError
|
|
169
169
|
from lamindb.models import Storage
|
|
170
170
|
|
|
171
171
|
if local_root is not None:
|
|
@@ -375,6 +375,7 @@ class InstanceSettings:
|
|
|
375
375
|
if self._db_permissions != "jwt":
|
|
376
376
|
return None
|
|
377
377
|
|
|
378
|
+
from django.db import connection
|
|
378
379
|
from lamindb.models import Space
|
|
379
380
|
|
|
380
381
|
spaces: dict = {"admin": [], "write": [], "read": []}
|
|
@@ -452,6 +453,9 @@ class InstanceSettings:
|
|
|
452
453
|
sqlite_file.synchronize_to(cache_file, print_progress=True) # type: ignore
|
|
453
454
|
|
|
454
455
|
def _check_sqlite_lock(self):
|
|
456
|
+
from ._hub_client import call_with_fallback
|
|
457
|
+
from ._hub_crud import select_account_handle_name_by_lnid
|
|
458
|
+
|
|
455
459
|
if not self._cloud_sqlite_locker.has_lock:
|
|
456
460
|
locked_by = self._cloud_sqlite_locker._locked_by
|
|
457
461
|
lock_msg = "Cannot load the instance, it is locked by "
|
|
@@ -560,7 +564,7 @@ class InstanceSettings:
|
|
|
560
564
|
Will return `False` in case the user token can't find the instance.
|
|
561
565
|
"""
|
|
562
566
|
if self._is_on_hub is None:
|
|
563
|
-
from ._hub_client import call_with_fallback_auth
|
|
567
|
+
from ._hub_client import call_with_fallback, call_with_fallback_auth
|
|
564
568
|
from ._hub_crud import select_instance_by_id
|
|
565
569
|
from ._settings import settings
|
|
566
570
|
|
|
@@ -8,7 +8,6 @@ from uuid import UUID, uuid4
|
|
|
8
8
|
|
|
9
9
|
from dotenv import dotenv_values
|
|
10
10
|
from lamin_utils import logger
|
|
11
|
-
from pydantic import ValidationError
|
|
12
11
|
|
|
13
12
|
from lamindb_setup.errors import CurrentInstanceNotConfigured, SettingsEnvFileOutdated
|
|
14
13
|
|
|
@@ -49,7 +48,7 @@ def load_cache_path_from_settings(storage_settings: Path | None = None) -> Path
|
|
|
49
48
|
|
|
50
49
|
def find_module_candidates():
|
|
51
50
|
"""Find all local packages that depend on lamindb."""
|
|
52
|
-
candidates = ["bionty", "
|
|
51
|
+
candidates = ["bionty", "pertdb"]
|
|
53
52
|
return [c for c in candidates if find_spec(c) is not None]
|
|
54
53
|
|
|
55
54
|
|
|
@@ -72,8 +71,10 @@ def load_instance_settings(instance_settings_file: Path | None = None):
|
|
|
72
71
|
# this errors only if the file was explicitly provided
|
|
73
72
|
raise CurrentInstanceNotConfigured
|
|
74
73
|
try:
|
|
75
|
-
settings_store = InstanceSettingsStore(
|
|
76
|
-
|
|
74
|
+
settings_store = InstanceSettingsStore.from_env_file(
|
|
75
|
+
isettings_file, "lamindb_instance_"
|
|
76
|
+
)
|
|
77
|
+
except (ValueError, KeyError, TypeError) as error:
|
|
77
78
|
raise SettingsEnvFileOutdated(
|
|
78
79
|
f"\n\n{error}\n\nYour instance settings file with\n\n{isettings_file.read_text()}\nis invalid"
|
|
79
80
|
f" (likely outdated), see validation error. Please delete {isettings_file} &"
|
|
@@ -108,8 +109,10 @@ def load_or_create_user_settings(api_key: str | None = None) -> UserSettings:
|
|
|
108
109
|
|
|
109
110
|
def load_user_settings(user_settings_file: Path):
|
|
110
111
|
try:
|
|
111
|
-
settings_store = UserSettingsStore(
|
|
112
|
-
|
|
112
|
+
settings_store = UserSettingsStore.from_env_file(
|
|
113
|
+
user_settings_file, "lamin_user_"
|
|
114
|
+
)
|
|
115
|
+
except (ValueError, KeyError, TypeError) as error:
|
|
113
116
|
msg = (
|
|
114
117
|
"Your user settings file is invalid, please delete"
|
|
115
118
|
f" {user_settings_file} and log in again."
|
|
@@ -121,7 +124,7 @@ def load_user_settings(user_settings_file: Path):
|
|
|
121
124
|
|
|
122
125
|
|
|
123
126
|
def _null_to_value(field, value=None):
|
|
124
|
-
return
|
|
127
|
+
return value if field in (None, "null") else field
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
def setup_instance_from_store(store: InstanceSettingsStore) -> InstanceSettings:
|
|
@@ -155,5 +158,5 @@ def setup_user_from_store(store: UserSettingsStore) -> UserSettings:
|
|
|
155
158
|
settings.uid = store.uid
|
|
156
159
|
settings.handle = _null_to_value(store.handle, value="anonymous")
|
|
157
160
|
settings.name = _null_to_value(store.name)
|
|
158
|
-
settings._uuid = UUID(store.uuid) if store.uuid
|
|
161
|
+
settings._uuid = UUID(store.uuid) if store.uuid not in (None, "null") else None
|
|
159
162
|
return settings
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Optional, get_type_hints
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, get_args, get_type_hints
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
|
|
7
7
|
from ._settings_store import (
|
|
@@ -33,6 +33,21 @@ def save_user_settings(settings: UserSettings):
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def _coerce_type_for_write(type_: Any) -> Any:
|
|
37
|
+
"""Resolve union types to the non-None part for coercion when value is not None."""
|
|
38
|
+
if type_ in (str, bool):
|
|
39
|
+
return type_
|
|
40
|
+
if type_ == Optional[str]: # noqa: UP045
|
|
41
|
+
return str
|
|
42
|
+
if type_ == Optional[bool]: # noqa: UP045
|
|
43
|
+
return bool
|
|
44
|
+
args = get_args(type_) or ()
|
|
45
|
+
if type(None) in args:
|
|
46
|
+
non_none = next((a for a in args if a is not type(None)), type_)
|
|
47
|
+
return non_none if non_none in (str, bool) else type_
|
|
48
|
+
return type_
|
|
49
|
+
|
|
50
|
+
|
|
36
51
|
def save_settings(
|
|
37
52
|
settings: Any,
|
|
38
53
|
settings_file: Path,
|
|
@@ -41,10 +56,7 @@ def save_settings(
|
|
|
41
56
|
):
|
|
42
57
|
with open(settings_file, "w") as f:
|
|
43
58
|
for store_key, type_ in type_hints.items():
|
|
44
|
-
|
|
45
|
-
type_ = str
|
|
46
|
-
if type_ == Optional[bool]: # noqa: UP045
|
|
47
|
-
type_ = bool
|
|
59
|
+
type_ = _coerce_type_for_write(type_)
|
|
48
60
|
if "__" not in store_key:
|
|
49
61
|
if store_key == "model_config":
|
|
50
62
|
continue
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import os
|
|
4
|
+
from dataclasses import MISSING, dataclass, fields
|
|
2
5
|
from pathlib import Path
|
|
3
|
-
from typing import
|
|
6
|
+
from typing import Any, get_args, get_type_hints
|
|
4
7
|
|
|
8
|
+
from dotenv import dotenv_values
|
|
5
9
|
from lamin_utils import logger
|
|
6
10
|
from platformdirs import site_config_dir
|
|
7
|
-
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
8
11
|
|
|
9
12
|
if "LAMIN_SETTINGS_DIR" in os.environ:
|
|
10
|
-
# Needed
|
|
13
|
+
# Needed for AWS Lambda, as only tmp/ has write access
|
|
11
14
|
settings_dir = Path(f"{os.environ['LAMIN_SETTINGS_DIR']}/.lamin")
|
|
12
15
|
else:
|
|
13
|
-
# user_config_dir is weird on MacOS!
|
|
14
|
-
# hence, let's take home/.lamin
|
|
15
16
|
settings_dir = Path.home() / ".lamin"
|
|
16
17
|
|
|
17
|
-
|
|
18
18
|
try:
|
|
19
19
|
settings_dir.mkdir(parents=True, exist_ok=True)
|
|
20
20
|
except Exception as e:
|
|
21
21
|
logger.warning(f"Failed to create lamin settings directory at {settings_dir}: {e}")
|
|
22
22
|
|
|
23
|
-
|
|
24
23
|
system_settings_dir = Path(site_config_dir(appname="lamindb", appauthor="laminlabs"))
|
|
25
24
|
|
|
26
25
|
|
|
@@ -53,7 +52,6 @@ def user_settings_file_handle(handle: str):
|
|
|
53
52
|
return settings_dir / f"{get_settings_file_name_prefix()}user--{handle}.env"
|
|
54
53
|
|
|
55
54
|
|
|
56
|
-
# here user means the user directory on os, not a lamindb user
|
|
57
55
|
def platform_user_storage_settings_file():
|
|
58
56
|
return settings_dir / "storage.env"
|
|
59
57
|
|
|
@@ -62,31 +60,103 @@ def system_settings_file():
|
|
|
62
60
|
return system_settings_dir / "system.env"
|
|
63
61
|
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
def _load_env_to_kwargs(
|
|
64
|
+
cls: type,
|
|
65
|
+
path: Path | str,
|
|
66
|
+
prefix: str,
|
|
67
|
+
) -> dict[str, Any]:
|
|
68
|
+
path = Path(path) if isinstance(path, str) else path
|
|
69
|
+
raw = dotenv_values(path)
|
|
70
|
+
type_hints = get_type_hints(cls)
|
|
71
|
+
flds = {f.name: f for f in fields(cls)}
|
|
72
|
+
optional = {
|
|
73
|
+
n
|
|
74
|
+
for n, f in flds.items()
|
|
75
|
+
if f.default is not MISSING or f.default_factory is not MISSING
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
kwargs: dict[str, Any] = {}
|
|
79
|
+
for store_key in type_hints:
|
|
80
|
+
if store_key.startswith("__"):
|
|
81
|
+
continue
|
|
82
|
+
env_key = f"{prefix}{store_key}"
|
|
83
|
+
has_key = env_key in raw
|
|
84
|
+
raw_val = raw.get(env_key) if has_key else None
|
|
85
|
+
is_opt = store_key in optional
|
|
86
|
+
|
|
87
|
+
if not has_key:
|
|
88
|
+
if not is_opt:
|
|
89
|
+
raise ValueError(f"Missing required key {env_key!r} in env file {path}")
|
|
90
|
+
kwargs[store_key] = None
|
|
91
|
+
continue
|
|
92
|
+
if raw_val is None or raw_val == "" or raw_val == "null":
|
|
93
|
+
kwargs[store_key] = None
|
|
94
|
+
continue
|
|
95
|
+
type_ = type_hints[store_key]
|
|
96
|
+
args = get_args(type_) or ()
|
|
97
|
+
if type_ is bool:
|
|
98
|
+
kwargs[store_key] = raw_val.lower() in ("true", "1", "yes")
|
|
99
|
+
elif type(None) in args:
|
|
100
|
+
non_none = next((a for a in args if a is not type(None)), type_)
|
|
101
|
+
if non_none is bool:
|
|
102
|
+
kwargs[store_key] = raw_val.lower() in ("true", "1", "yes")
|
|
103
|
+
else:
|
|
104
|
+
kwargs[store_key] = raw_val
|
|
105
|
+
else:
|
|
106
|
+
kwargs[store_key] = raw_val
|
|
107
|
+
return kwargs
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@dataclass
|
|
111
|
+
class InstanceSettingsStore:
|
|
112
|
+
# Required (no default) — must come first
|
|
67
113
|
owner: str
|
|
68
114
|
name: str
|
|
69
115
|
storage_root: str
|
|
70
116
|
storage_region: str | None
|
|
71
117
|
db: str | None
|
|
72
118
|
schema_str: str | None
|
|
73
|
-
schema_id: str | None = None
|
|
74
|
-
fine_grained_access: bool = False
|
|
75
|
-
db_permissions: str | None = None
|
|
76
119
|
id: str
|
|
77
120
|
git_repo: str | None
|
|
78
121
|
keep_artifacts_local: bool | None
|
|
122
|
+
# Optional
|
|
123
|
+
api_url: str | None = None
|
|
124
|
+
schema_id: str | None = None
|
|
125
|
+
fine_grained_access: bool = False
|
|
126
|
+
db_permissions: str | None = None
|
|
79
127
|
is_clone: bool = False
|
|
80
|
-
|
|
128
|
+
|
|
129
|
+
@classmethod
|
|
130
|
+
def from_env_file(cls, path: Path | str, prefix: str) -> InstanceSettingsStore:
|
|
131
|
+
kwargs = _load_env_to_kwargs(cls, path, prefix)
|
|
132
|
+
return cls(**kwargs)
|
|
81
133
|
|
|
82
134
|
|
|
83
|
-
|
|
135
|
+
@dataclass
|
|
136
|
+
class UserSettingsStore:
|
|
137
|
+
# Required (no default)
|
|
84
138
|
email: str
|
|
85
139
|
password: str
|
|
86
140
|
access_token: str
|
|
87
|
-
api_key: str | None = None
|
|
88
141
|
uid: str
|
|
89
142
|
uuid: str
|
|
90
143
|
handle: str
|
|
91
144
|
name: str
|
|
92
|
-
|
|
145
|
+
# Optional
|
|
146
|
+
api_key: str | None = None
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def from_env_file(cls, path: Path | str, prefix: str) -> UserSettingsStore:
|
|
150
|
+
kwargs = _load_env_to_kwargs(cls, path, prefix)
|
|
151
|
+
return cls(**kwargs)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass
|
|
155
|
+
class Connector:
|
|
156
|
+
url: str
|
|
157
|
+
key: str
|
|
158
|
+
|
|
159
|
+
@classmethod
|
|
160
|
+
def from_env_file(cls, path: Path | str, prefix: str) -> Connector:
|
|
161
|
+
kwargs = _load_env_to_kwargs(cls, path, prefix)
|
|
162
|
+
return cls(**kwargs)
|
lamindb_setup/core/django.py
CHANGED
|
@@ -276,6 +276,27 @@ def setup_django(
|
|
|
276
276
|
],
|
|
277
277
|
STATIC_URL="static/",
|
|
278
278
|
)
|
|
279
|
+
if logger._verbosity == 5: # debug-level verbosity
|
|
280
|
+
kwargs.update(
|
|
281
|
+
{
|
|
282
|
+
"DEBUG": True,
|
|
283
|
+
"LOGGING": {
|
|
284
|
+
"version": 1,
|
|
285
|
+
"handlers": {
|
|
286
|
+
"console": {
|
|
287
|
+
"level": "DEBUG",
|
|
288
|
+
"class": "logging.StreamHandler",
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"loggers": {
|
|
292
|
+
"django.db.backends": {
|
|
293
|
+
"level": "DEBUG",
|
|
294
|
+
"handlers": ["console"],
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
)
|
|
279
300
|
settings.configure(**kwargs)
|
|
280
301
|
# this isn't needed the first time django.setup() is called, but for unknown reason it's needed the second time
|
|
281
302
|
# the first time, it already defaults to true
|
lamindb_setup/errors.py
CHANGED
|
@@ -8,13 +8,12 @@
|
|
|
8
8
|
.. autoexception:: SettingsEnvFileOutdated
|
|
9
9
|
.. autoexception:: CannotSwitchDefaultInstance
|
|
10
10
|
.. autoexception:: InstanceNotFoundError
|
|
11
|
+
.. autoexception:: InstanceNotCreated
|
|
11
12
|
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
15
|
from __future__ import annotations
|
|
15
16
|
|
|
16
|
-
import click
|
|
17
|
-
|
|
18
17
|
|
|
19
18
|
class DefaultMessageException(Exception):
|
|
20
19
|
default_message: str | None = None
|
|
@@ -47,15 +46,18 @@ class StorageAlreadyManaged(Exception):
|
|
|
47
46
|
pass
|
|
48
47
|
|
|
49
48
|
|
|
50
|
-
class StorageNotEmpty(
|
|
51
|
-
|
|
52
|
-
pass
|
|
49
|
+
class StorageNotEmpty(Exception):
|
|
50
|
+
pass
|
|
53
51
|
|
|
54
52
|
|
|
55
53
|
class InstanceNotFoundError(Exception):
|
|
56
54
|
pass
|
|
57
55
|
|
|
58
56
|
|
|
57
|
+
class InstanceNotCreated(Exception):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
59
61
|
# raise if a cloud SQLite instance is already locked
|
|
60
62
|
# ignored by unlock_cloud_sqlite_upon_exception
|
|
61
63
|
class InstanceLockedException(Exception):
|
lamindb_setup/io.py
CHANGED
|
@@ -8,10 +8,7 @@ from importlib import import_module
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
|
-
import numpy as np
|
|
12
|
-
import pandas as pd
|
|
13
11
|
from django.db import models, transaction
|
|
14
|
-
from rich.progress import Progress
|
|
15
12
|
|
|
16
13
|
if TYPE_CHECKING:
|
|
17
14
|
from collections.abc import Iterable
|
|
@@ -59,6 +56,7 @@ def _export_full_table(
|
|
|
59
56
|
Returns:
|
|
60
57
|
String identifier for single-file exports, or list of (table_name, chunk_path) tuples for chunked exports that need merging.
|
|
61
58
|
"""
|
|
59
|
+
import pandas as pd
|
|
62
60
|
from django.db import connection
|
|
63
61
|
|
|
64
62
|
import lamindb_setup as ln_setup
|
|
@@ -156,12 +154,15 @@ def export_db(
|
|
|
156
154
|
Ensure that you connect to postgres instances using `use_root_db_user=True`.
|
|
157
155
|
|
|
158
156
|
Args:
|
|
159
|
-
module_names: Module names to export (e.g., ["lamindb", "bionty", "
|
|
157
|
+
module_names: Module names to export (e.g., ["lamindb", "bionty", "pertdb"]).
|
|
160
158
|
Defaults to "lamindb" if not provided.
|
|
161
159
|
output_dir: Directory path for exported parquet files.
|
|
162
160
|
max_workers: Number of parallel processes.
|
|
163
161
|
chunk_size: Number of rows per chunk for large tables.
|
|
164
162
|
"""
|
|
163
|
+
import pandas as pd
|
|
164
|
+
from rich.progress import Progress
|
|
165
|
+
|
|
165
166
|
import lamindb_setup as ln_setup
|
|
166
167
|
|
|
167
168
|
if output_dir is None:
|
|
@@ -212,6 +213,9 @@ def export_db(
|
|
|
212
213
|
|
|
213
214
|
def _serialize_value(val):
|
|
214
215
|
"""Convert value to JSON string if it's a dict, list, or numpy array, otherwise return as-is."""
|
|
216
|
+
# keep dynamic import to minimize import time
|
|
217
|
+
import numpy as np
|
|
218
|
+
|
|
215
219
|
if isinstance(val, (dict, list, np.ndarray)):
|
|
216
220
|
return json.dumps(
|
|
217
221
|
val, default=lambda o: o.tolist() if isinstance(o, np.ndarray) else None
|
|
@@ -232,6 +236,8 @@ def _import_registry(
|
|
|
232
236
|
For SQLite, uses multi-row INSERTs with dynamic chunking to stay under the 999
|
|
233
237
|
variable limit (2-5x faster than single-row INSERTs).
|
|
234
238
|
"""
|
|
239
|
+
import numpy as np
|
|
240
|
+
import pandas as pd
|
|
235
241
|
from django.db import connection
|
|
236
242
|
|
|
237
243
|
table_name = registry._meta.db_table
|
|
@@ -345,13 +351,14 @@ def import_db(
|
|
|
345
351
|
|
|
346
352
|
Args:
|
|
347
353
|
input_dir: Directory containing parquet files to import.
|
|
348
|
-
module_names: Module names to import (e.g., ["lamindb", "bionty", "
|
|
354
|
+
module_names: Module names to import (e.g., ["lamindb", "bionty", "pertdb"]).
|
|
349
355
|
if_exists: How to behave if table exists: 'fail', 'replace', or 'append'.
|
|
350
356
|
If set to 'replace', existing data is deleted and new data is imported. All PKs and indices are not guaranteed to be preserved which can lead to write errors.
|
|
351
357
|
If set to 'append', new data is added to existing data without clearing the table. All PKs and indices are preserved allowing write operations but database size will greatly increase.
|
|
352
358
|
If set to 'fail', raises an error if the table contains any data.
|
|
353
359
|
"""
|
|
354
360
|
from django.db import connection
|
|
361
|
+
from rich.progress import Progress
|
|
355
362
|
|
|
356
363
|
import lamindb_setup as ln_setup
|
|
357
364
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: lamindb_setup
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.19.0
|
|
4
4
|
Summary: Setup & configure LaminDB.
|
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
|
6
6
|
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: lamin_utils>=0.3.3
|
|
9
|
+
Requires-Dist: python-dotenv
|
|
9
10
|
Requires-Dist: django>=5.2,<5.3
|
|
10
11
|
Requires-Dist: dj_database_url>=1.3.0,<3.0.0
|
|
11
12
|
Requires-Dist: django-pgtrigger
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
lamindb_setup/__init__.py,sha256=
|
|
1
|
+
lamindb_setup/__init__.py,sha256=uog08tfBbwYslApetPEHt0FKE80mE6WEZNM-RU3ETec,2812
|
|
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=zPQho12dctJYjnZxpumq2r7XRvXwrNyWi5-UMRPSeuE,4297
|
|
5
|
-
lamindb_setup/_connect_instance.py,sha256=
|
|
6
|
-
lamindb_setup/_delete.py,sha256=
|
|
5
|
+
lamindb_setup/_connect_instance.py,sha256=mUR8Ue95esJQl6inEvxgaS81R6-Q--arYuznEa9VD78,17387
|
|
6
|
+
lamindb_setup/_delete.py,sha256=sYB1cRDA4fIekwrB6HBi1LtB5g8m7vkrEtInbujjGYo,6232
|
|
7
7
|
lamindb_setup/_disconnect.py,sha256=B0K0yTIIyhwc3MzDFL_-cKutm-_DHsiJSTrkp1MMyXA,1470
|
|
8
8
|
lamindb_setup/_django.py,sha256=uIQflpkp8l3axyPaKURlk3kacgpElVP5KOKmFxYSMGk,1454
|
|
9
9
|
lamindb_setup/_entry_points.py,sha256=sKwXPX9xjOotoAjvgkU5LBwjjHLWVkh0ZGdiSsrch9k,522
|
|
10
|
-
lamindb_setup/_init_instance.py,sha256=
|
|
11
|
-
lamindb_setup/_migrate.py,sha256=
|
|
10
|
+
lamindb_setup/_init_instance.py,sha256=3kRq5SJw7vvJi4DaCrLGm8fcGh7D3OJOoOcSkUk0Fbo,14790
|
|
11
|
+
lamindb_setup/_migrate.py,sha256=8_eS21sGIoJAdLD09LBCSn8kjhyymafkuDSjW67aBjE,12270
|
|
12
12
|
lamindb_setup/_register_instance.py,sha256=RdUZxZWHLdbvdNZWpF8e0UWROb_T0cStWbzc5yUw34I,1047
|
|
13
13
|
lamindb_setup/_schema.py,sha256=b3uzhhWpV5mQtDwhMINc2MabGCnGLESy51ito3yl6Wc,679
|
|
14
14
|
lamindb_setup/_schema_metadata.py,sha256=Whs-e4ZMnA1niZ2l5Eu8il-33IxI4Hr5ylGEgPxx8wk,15628
|
|
15
|
-
lamindb_setup/_set_managed_storage.py,sha256=
|
|
15
|
+
lamindb_setup/_set_managed_storage.py,sha256=vqxQ_993Db1ZyJ5j9SGU99Wpj5KUAIBveUyci9Z4aRk,3287
|
|
16
16
|
lamindb_setup/_setup_user.py,sha256=9CwKUru2jza1vXu4A5V-q-oXnbIXwR_YwjKbVnETK7Q,6931
|
|
17
17
|
lamindb_setup/_silence_loggers.py,sha256=oQnvnvieqxARQQMwQkR82EJVk1TaM-Bo9o0UCOsCcXY,1697
|
|
18
|
-
lamindb_setup/errors.py,sha256=
|
|
19
|
-
lamindb_setup/io.py,sha256=
|
|
18
|
+
lamindb_setup/errors.py,sha256=SDAnXvXYCsns54zTrHPfT2sKkEc1am_rCapdliqZiOQ,1646
|
|
19
|
+
lamindb_setup/io.py,sha256=WHdsfdL9yShBPsSu-Fzp5s2bJUzE8clU5h8nAQh1K8w,17330
|
|
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=oSTXxNCx6yfoqaHYTZM9qHuZKdMUIUF2DdXw4gBMBU4,592
|
|
23
|
-
lamindb_setup/core/_aws_options.py,sha256=
|
|
24
|
-
lamindb_setup/core/_aws_storage.py,sha256=
|
|
23
|
+
lamindb_setup/core/_aws_options.py,sha256=rV8CRRlDLoBk8YHNx5d665TeSJ6eBtCVjJz9dV_1b_w,10566
|
|
24
|
+
lamindb_setup/core/_aws_storage.py,sha256=sz1esr5R_xvLd9_U9UMzJR7Pp4M75OHem4Kmg_2fljQ,2072
|
|
25
25
|
lamindb_setup/core/_clone.py,sha256=IE7d9n4qc8dvUgYbFavIkdUZ_BhsEHfoQzmcPDFuF4A,1537
|
|
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
|
-
lamindb_setup/core/_hub_client.py,sha256=
|
|
29
|
-
lamindb_setup/core/_hub_core.py,sha256=
|
|
28
|
+
lamindb_setup/core/_hub_client.py,sha256=mhCuIWQ8fK0BZrMUXoXftbJv9BbvB9Een17_wuvZfcg,9697
|
|
29
|
+
lamindb_setup/core/_hub_core.py,sha256=mu_DuPvqEGeOgnl7d2KZblDkNOf6FN3c62HOcjiLzlA,29229
|
|
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
32
|
lamindb_setup/core/_private_django_api.py,sha256=e-9WiGkI7g683nOdTcScS_fPG-_neNvrcWuAI9NEeQs,2529
|
|
33
33
|
lamindb_setup/core/_settings.py,sha256=LTeh2jsM01GHW2ZTrcc6rXNz6qIUT0VPEzpE9I8tg3Q,15497
|
|
34
|
-
lamindb_setup/core/_settings_instance.py,sha256=
|
|
35
|
-
lamindb_setup/core/_settings_load.py,sha256=
|
|
36
|
-
lamindb_setup/core/_settings_save.py,sha256=
|
|
34
|
+
lamindb_setup/core/_settings_instance.py,sha256=PrjzAlbajCHPBR664379is4ci3Hq13mtTWwQgJoavdg,25111
|
|
35
|
+
lamindb_setup/core/_settings_load.py,sha256=W8zgrTZ1YWYn7AlRoy8jRWLAYa9hzS19QB4EKUyf-c0,5861
|
|
36
|
+
lamindb_setup/core/_settings_save.py,sha256=W1VvAWgeXNSf6p_fgCUU90JRAVbqDgL63A9yuZ45kII,3753
|
|
37
37
|
lamindb_setup/core/_settings_storage.py,sha256=e1FQ2uh13Cuw9Z5k6d71C825f6ISUnc1LtkDUO0QUIA,15590
|
|
38
|
-
lamindb_setup/core/_settings_store.py,sha256=
|
|
38
|
+
lamindb_setup/core/_settings_store.py,sha256=kFz-bgDRlpxosaIre3YIHJmOYmFNo4a2q8egFUD5hm0,4596
|
|
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=hy8SofeSKaOvsOiyrge1qgAp1fmcFiWQV8pIFhFIoeo,14420
|
|
43
43
|
lamindb_setup/core/exceptions.py,sha256=qjMzqy_uzPA7mCOdnoWnS_fdA6OWbdZGftz-YYplrY0,84
|
|
44
44
|
lamindb_setup/core/hashing.py,sha256=4EDiMkdn96ct3oVkB64_4ujj6_EY5Vt8WMOMT5qnewI,3695
|
|
45
45
|
lamindb_setup/core/lamin.db.gz,sha256=sFh_Qgg4Krui0lW4g2CrGfKpL59-UjOMgAJ7n0xP4XE,78228
|
|
46
46
|
lamindb_setup/core/types.py,sha256=T7NwspfRHgIIpYsXDcApks8jkOlGeGRW-YbVLB7jNIo,67
|
|
47
47
|
lamindb_setup/core/upath.py,sha256=zlPZcDRHDYT7OcoOiX_w9koAzfBr9q8hB66OPwhTpBo,36504
|
|
48
|
-
lamindb_setup-1.
|
|
49
|
-
lamindb_setup-1.
|
|
50
|
-
lamindb_setup-1.
|
|
51
|
-
lamindb_setup-1.
|
|
48
|
+
lamindb_setup-1.19.0.dist-info/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
|
|
49
|
+
lamindb_setup-1.19.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
50
|
+
lamindb_setup-1.19.0.dist-info/METADATA,sha256=EXnq7Rdvz2NKSKdf5hbvANX9NZHxoZZfYwQIoetiv_w,1807
|
|
51
|
+
lamindb_setup-1.19.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|