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