lamindb_setup 1.9.1__py3-none-any.whl → 1.10.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_setup/__init__.py +107 -107
- lamindb_setup/_cache.py +87 -87
- lamindb_setup/_check_setup.py +192 -166
- lamindb_setup/_connect_instance.py +430 -328
- lamindb_setup/_delete.py +144 -141
- lamindb_setup/_disconnect.py +35 -32
- lamindb_setup/_init_instance.py +430 -440
- lamindb_setup/_migrate.py +278 -266
- lamindb_setup/_register_instance.py +32 -35
- lamindb_setup/_schema_metadata.py +441 -441
- lamindb_setup/_set_managed_storage.py +69 -70
- lamindb_setup/_setup_user.py +172 -133
- lamindb_setup/core/__init__.py +21 -21
- lamindb_setup/core/_aws_options.py +223 -223
- lamindb_setup/core/_aws_storage.py +9 -1
- lamindb_setup/core/_deprecated.py +1 -1
- lamindb_setup/core/_hub_client.py +248 -248
- lamindb_setup/core/_hub_core.py +751 -665
- lamindb_setup/core/_hub_crud.py +247 -227
- lamindb_setup/core/_private_django_api.py +83 -83
- lamindb_setup/core/_settings.py +374 -377
- lamindb_setup/core/_settings_instance.py +609 -569
- lamindb_setup/core/_settings_load.py +141 -141
- lamindb_setup/core/_settings_save.py +95 -95
- lamindb_setup/core/_settings_storage.py +427 -429
- lamindb_setup/core/_settings_store.py +91 -91
- lamindb_setup/core/_settings_user.py +55 -55
- lamindb_setup/core/_setup_bionty_sources.py +44 -44
- lamindb_setup/core/cloud_sqlite_locker.py +240 -240
- lamindb_setup/core/django.py +311 -305
- lamindb_setup/core/exceptions.py +1 -1
- lamindb_setup/core/hashing.py +134 -134
- lamindb_setup/core/types.py +1 -1
- lamindb_setup/core/upath.py +1013 -1013
- lamindb_setup/errors.py +80 -70
- lamindb_setup/types.py +20 -20
- {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/METADATA +4 -4
- lamindb_setup-1.10.1.dist-info/RECORD +50 -0
- lamindb_setup-1.9.1.dist-info/RECORD +0 -50
- {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/LICENSE +0 -0
- {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/WHEEL +0 -0
lamindb_setup/_check_setup.py
CHANGED
|
@@ -1,166 +1,192 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import functools
|
|
4
|
-
import importlib as il
|
|
5
|
-
import inspect
|
|
6
|
-
import os
|
|
7
|
-
from
|
|
8
|
-
|
|
9
|
-
from
|
|
10
|
-
|
|
11
|
-
from
|
|
12
|
-
|
|
13
|
-
from .
|
|
14
|
-
from .core
|
|
15
|
-
from .
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
from .
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
raise
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import importlib as il
|
|
5
|
+
import inspect
|
|
6
|
+
import os
|
|
7
|
+
from importlib.metadata import distributions
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
from uuid import UUID
|
|
10
|
+
|
|
11
|
+
from lamin_utils import logger
|
|
12
|
+
|
|
13
|
+
from ._silence_loggers import silence_loggers
|
|
14
|
+
from .core import django as django_lamin
|
|
15
|
+
from .core._settings import settings
|
|
16
|
+
from .core._settings_store import current_instance_settings_file
|
|
17
|
+
from .errors import (
|
|
18
|
+
MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE,
|
|
19
|
+
InstanceNotSetupError,
|
|
20
|
+
ModuleWasntConfigured,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from collections.abc import Callable
|
|
25
|
+
|
|
26
|
+
from .core._settings_instance import InstanceSettings
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
CURRENT_ISETTINGS: InstanceSettings | None = None
|
|
30
|
+
MODULE_CANDIDATES: set[str] | None = None
|
|
31
|
+
IS_LOADING: bool = False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# decorator to disable auto-connect when importing a module such as lamindb
|
|
35
|
+
def disable_auto_connect(func: Callable):
|
|
36
|
+
@functools.wraps(func)
|
|
37
|
+
def wrapper(*args, **kwargs):
|
|
38
|
+
global IS_LOADING
|
|
39
|
+
IS_LOADING = True
|
|
40
|
+
try:
|
|
41
|
+
return func(*args, **kwargs)
|
|
42
|
+
finally:
|
|
43
|
+
IS_LOADING = False
|
|
44
|
+
|
|
45
|
+
return wrapper
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def find_module_candidates():
|
|
49
|
+
"""Find all local packages that depend on lamindb."""
|
|
50
|
+
global MODULE_CANDIDATES
|
|
51
|
+
if MODULE_CANDIDATES is not None:
|
|
52
|
+
return MODULE_CANDIDATES
|
|
53
|
+
all_dists = list(distributions())
|
|
54
|
+
lamindb_deps = {
|
|
55
|
+
dist.metadata["Name"].lower()
|
|
56
|
+
for dist in all_dists
|
|
57
|
+
if dist.requires and any("lamindb" in req.lower() for req in dist.requires)
|
|
58
|
+
}
|
|
59
|
+
lamindb_deps.remove("lamindb")
|
|
60
|
+
MODULE_CANDIDATES = lamindb_deps
|
|
61
|
+
return lamindb_deps
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _get_current_instance_settings(from_module: str | None = None) -> InstanceSettings:
|
|
65
|
+
from .core._settings_instance import InstanceSettings
|
|
66
|
+
|
|
67
|
+
global CURRENT_ISETTINGS
|
|
68
|
+
|
|
69
|
+
if CURRENT_ISETTINGS is not None:
|
|
70
|
+
return CURRENT_ISETTINGS
|
|
71
|
+
if current_instance_settings_file().exists():
|
|
72
|
+
from .core._settings_load import load_instance_settings
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
isettings = load_instance_settings()
|
|
76
|
+
except Exception as e:
|
|
77
|
+
# user will get more detailed traceback once they run the CLI
|
|
78
|
+
logger.error(
|
|
79
|
+
"Current instance cannot be reached, disconnect from it: `lamin disconnect`\n"
|
|
80
|
+
"Alternatively, init or load a connectable instance on the"
|
|
81
|
+
" command line: `lamin connect <instance>` or `lamin init <...>`"
|
|
82
|
+
)
|
|
83
|
+
raise e
|
|
84
|
+
else:
|
|
85
|
+
module_candidates = find_module_candidates()
|
|
86
|
+
isettings = InstanceSettings(
|
|
87
|
+
id=UUID("00000000-0000-0000-0000-000000000000"),
|
|
88
|
+
owner="none",
|
|
89
|
+
name="none",
|
|
90
|
+
storage=None,
|
|
91
|
+
modules=",".join(module_candidates),
|
|
92
|
+
)
|
|
93
|
+
CURRENT_ISETTINGS = isettings
|
|
94
|
+
return isettings
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _normalize_module_name(module_name: str) -> str:
|
|
98
|
+
return module_name.replace("lnschema_", "").replace("_", "-")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# checks that the provided modules is in the modules of the provided instance
|
|
102
|
+
# or in the apps setup by django
|
|
103
|
+
def _check_module_in_instance_modules(
|
|
104
|
+
module: str, isettings: InstanceSettings | None = None
|
|
105
|
+
) -> None:
|
|
106
|
+
if isettings is not None:
|
|
107
|
+
modules_raw = isettings.modules
|
|
108
|
+
modules = set(modules_raw).union(
|
|
109
|
+
_normalize_module_name(module) for module in modules_raw
|
|
110
|
+
)
|
|
111
|
+
if _normalize_module_name(module) not in modules and module not in modules:
|
|
112
|
+
raise ModuleWasntConfigured(
|
|
113
|
+
MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module)
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
from django.apps import apps
|
|
119
|
+
|
|
120
|
+
for app in apps.get_app_configs():
|
|
121
|
+
# app.name is always unnormalized module (python package) name
|
|
122
|
+
if module == app.name or module == _normalize_module_name(app.name):
|
|
123
|
+
return
|
|
124
|
+
raise ModuleWasntConfigured(MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# infer the name of the module that calls this function
|
|
128
|
+
def _infer_callers_module_name() -> str | None:
|
|
129
|
+
stack = inspect.stack()
|
|
130
|
+
if len(stack) < 3:
|
|
131
|
+
return None
|
|
132
|
+
module = inspect.getmodule(stack[2][0])
|
|
133
|
+
return module.__name__.partition(".")[0] if module is not None else None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# we make this a private function because in all the places it's used,
|
|
137
|
+
# users should not see it
|
|
138
|
+
def _check_instance_setup(from_module: str | None = None) -> bool:
|
|
139
|
+
if django_lamin.IS_SETUP:
|
|
140
|
+
# reload logic here because module might not yet have been imported
|
|
141
|
+
# upon first setup
|
|
142
|
+
if from_module is not None:
|
|
143
|
+
if from_module != "lamindb":
|
|
144
|
+
_check_module_in_instance_modules(from_module)
|
|
145
|
+
il.reload(il.import_module(from_module))
|
|
146
|
+
else:
|
|
147
|
+
infer_module = _infer_callers_module_name()
|
|
148
|
+
if infer_module is not None and infer_module not in {
|
|
149
|
+
"lamindb",
|
|
150
|
+
"lamindb_setup",
|
|
151
|
+
"lamin_cli",
|
|
152
|
+
}:
|
|
153
|
+
_check_module_in_instance_modules(infer_module)
|
|
154
|
+
return True
|
|
155
|
+
silence_loggers()
|
|
156
|
+
if os.environ.get("LAMINDB_MULTI_INSTANCE") == "true":
|
|
157
|
+
logger.warning(
|
|
158
|
+
"running LaminDB in multi-instance mode; you'll experience "
|
|
159
|
+
"errors in regular lamindb usage"
|
|
160
|
+
)
|
|
161
|
+
return True
|
|
162
|
+
isettings = _get_current_instance_settings()
|
|
163
|
+
if isettings is not None:
|
|
164
|
+
if from_module is not None and not django_lamin.IS_SETUP and not IS_LOADING:
|
|
165
|
+
if from_module != "lamindb":
|
|
166
|
+
_check_module_in_instance_modules(from_module, isettings)
|
|
167
|
+
|
|
168
|
+
import lamindb
|
|
169
|
+
|
|
170
|
+
il.reload(il.import_module(from_module))
|
|
171
|
+
else:
|
|
172
|
+
django_lamin.setup_django(isettings)
|
|
173
|
+
if isettings.slug != "none/none":
|
|
174
|
+
logger.important(f"connected lamindb: {isettings.slug}")
|
|
175
|
+
# update of local storage location through search_local_root()
|
|
176
|
+
settings._instance_settings = isettings
|
|
177
|
+
else:
|
|
178
|
+
logger.warning("not connected, call: ln.connect('account/name')")
|
|
179
|
+
return django_lamin.IS_SETUP
|
|
180
|
+
else:
|
|
181
|
+
if from_module is not None:
|
|
182
|
+
# the below enables users to auto-connect to an instance
|
|
183
|
+
# simply by setting an environment variable, bypassing the
|
|
184
|
+
# need of calling connect() manually
|
|
185
|
+
if os.environ.get("LAMIN_CURRENT_INSTANCE") is not None:
|
|
186
|
+
from ._connect_instance import connect
|
|
187
|
+
|
|
188
|
+
connect(_write_settings=False, _reload_lamindb=False)
|
|
189
|
+
return django_lamin.IS_SETUP
|
|
190
|
+
else:
|
|
191
|
+
logger.warning(InstanceNotSetupError.default_message)
|
|
192
|
+
return False
|