lamindb_setup 1.9.0__tar.gz → 1.10.0__tar.gz
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-1.9.0 → lamindb_setup-1.10.0}/PKG-INFO +3 -3
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/08-test-multi-session.ipynb +19 -39
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-insufficient-user-info.ipynb +1 -11
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/__init__.py +1 -1
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_cache.py +3 -3
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_check_setup.py +40 -14
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_connect_instance.py +117 -44
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_delete.py +3 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_disconnect.py +4 -1
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_init_instance.py +36 -46
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_migrate.py +19 -7
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_register_instance.py +2 -5
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_set_managed_storage.py +0 -1
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_setup_user.py +52 -13
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_aws_storage.py +9 -1
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_hub_core.py +87 -24
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings.py +12 -5
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_instance.py +23 -15
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_load.py +2 -2
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_storage.py +4 -6
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/django.py +21 -2
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/upath.py +4 -4
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/errors.py +10 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/pyproject.toml +2 -2
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_connect_instance.py +2 -6
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_init_instance.py +4 -3
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_login.py +5 -2
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-local/scripts/script-connect-fine-grained-access.py +1 -1
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-local/test_all.py +19 -12
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/.github/workflows/build.yml +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/.github/workflows/doc-changes.yml +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/.gitignore +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/.pre-commit-config.yaml +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/LICENSE +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/README.md +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/changelog.md +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-cloud/test_notebooks.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-cache-management.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-empty-init.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-import-schema.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-init-load-local-anonymously.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test_notebooks2.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/index.md +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/notebooks.md +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/reference.md +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_check.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_django.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_entry_points.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_exportdb.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_importdb.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_schema.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_schema_metadata.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/_silence_loggers.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/__init__.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_aws_options.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_deprecated.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_docs.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_hub_client.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_hub_crud.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_hub_utils.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_private_django_api.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_save.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_store.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_settings_user.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/exceptions.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/hashing.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/core/types.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/py.typed +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/lamindb_setup/types.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/noxfile.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/scripts/script-init-pass-user-no-writes.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_delete_instance.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_edge_request.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_init_pass_user_no_writes.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_migrate.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-cloud/test_set_storage.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-local/conftest.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-local/test_update_schema_in_hub.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/conftest.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/test_aws_options_manager.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/test_django.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/test_global_settings.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/hub-prod/test_upath.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_entry_point.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_hashing.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_storage_access.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_storage_basis.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_storage_settings.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_storage_stats.py +0 -0
- {lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/tests/storage/test_to_url.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: lamindb_setup
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.10.0
|
|
4
4
|
Summary: Setup & configure LaminDB.
|
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -21,7 +21,7 @@ Requires-Dist: psutil
|
|
|
21
21
|
Requires-Dist: packaging
|
|
22
22
|
Requires-Dist: urllib3<2 ; extra == "aws"
|
|
23
23
|
Requires-Dist: aiobotocore[boto3]>=2.5.4,<3.0.0 ; extra == "aws"
|
|
24
|
-
Requires-Dist: s3fs>=2023.12.2,<=2025.
|
|
24
|
+
Requires-Dist: s3fs>=2023.12.2,<=2025.7.0,!=2024.10.0 ; extra == "aws"
|
|
25
25
|
Requires-Dist: line_profiler ; extra == "dev"
|
|
26
26
|
Requires-Dist: psycopg2-binary ; extra == "dev"
|
|
27
27
|
Requires-Dist: python-dotenv ; extra == "dev"
|
|
@@ -32,7 +32,7 @@ Requires-Dist: pytest-xdist ; extra == "dev"
|
|
|
32
32
|
Requires-Dist: nbproject-test>=0.4.3 ; extra == "dev"
|
|
33
33
|
Requires-Dist: pandas ; extra == "dev"
|
|
34
34
|
Requires-Dist: django-schema-graph ; extra == "erdiagram"
|
|
35
|
-
Requires-Dist: gcsfs>=2023.12.2,<=2025.
|
|
35
|
+
Requires-Dist: gcsfs>=2023.12.2,<=2025.7.0 ; extra == "gcp"
|
|
36
36
|
Project-URL: Home, https://github.com/laminlabs/lamindb-setup
|
|
37
37
|
Provides-Extra: aws
|
|
38
38
|
Provides-Extra: dev
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
"# Test multi instance and multi user session"
|
|
8
8
|
]
|
|
9
9
|
},
|
|
10
|
+
{
|
|
11
|
+
"cell_type": "markdown",
|
|
12
|
+
"metadata": {},
|
|
13
|
+
"source": [
|
|
14
|
+
"This notebook is complemented by the `faq/setup.ipynb` notebook in lamindb."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
10
17
|
{
|
|
11
18
|
"cell_type": "code",
|
|
12
19
|
"execution_count": null,
|
|
@@ -54,6 +61,15 @@
|
|
|
54
61
|
"ln_setup.init(storage=\"./testsetup\")"
|
|
55
62
|
]
|
|
56
63
|
},
|
|
64
|
+
{
|
|
65
|
+
"cell_type": "code",
|
|
66
|
+
"execution_count": null,
|
|
67
|
+
"metadata": {},
|
|
68
|
+
"outputs": [],
|
|
69
|
+
"source": [
|
|
70
|
+
"assert ln_setup.settings.instance.slug == \"testuser1/testsetup\""
|
|
71
|
+
]
|
|
72
|
+
},
|
|
57
73
|
{
|
|
58
74
|
"cell_type": "code",
|
|
59
75
|
"execution_count": null,
|
|
@@ -111,43 +127,7 @@
|
|
|
111
127
|
"cell_type": "markdown",
|
|
112
128
|
"metadata": {},
|
|
113
129
|
"source": [
|
|
114
|
-
"
|
|
115
|
-
]
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"cell_type": "code",
|
|
119
|
-
"execution_count": null,
|
|
120
|
-
"metadata": {},
|
|
121
|
-
"outputs": [],
|
|
122
|
-
"source": [
|
|
123
|
-
"from lamindb_setup._init_instance import CannotSwitchDefaultInstance\n",
|
|
124
|
-
"\n",
|
|
125
|
-
"with pytest.raises(CannotSwitchDefaultInstance):\n",
|
|
126
|
-
" ln_setup.init(storage=\"./testsetup2\")\n",
|
|
127
|
-
"with pytest.raises(CannotSwitchDefaultInstance):\n",
|
|
128
|
-
" ln_setup.connect(\"testsetup\")\n",
|
|
129
|
-
"with pytest.raises(RuntimeError):\n",
|
|
130
|
-
" ln_setup.migrate.create()\n",
|
|
131
|
-
"with pytest.raises(RuntimeError):\n",
|
|
132
|
-
" ln_setup.migrate.deploy()\n",
|
|
133
|
-
"\n",
|
|
134
|
-
"assert ln_setup.settings.instance.slug == \"testuser1/testsetup\""
|
|
135
|
-
]
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
"cell_type": "markdown",
|
|
139
|
-
"metadata": {},
|
|
140
|
-
"source": [
|
|
141
|
-
"Reset `django` and connect to another instance:"
|
|
142
|
-
]
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
"cell_type": "code",
|
|
146
|
-
"execution_count": null,
|
|
147
|
-
"metadata": {},
|
|
148
|
-
"outputs": [],
|
|
149
|
-
"source": [
|
|
150
|
-
"ln_setup.core.django.reset_django()"
|
|
130
|
+
"Connect to another instance in the same process:"
|
|
151
131
|
]
|
|
152
132
|
},
|
|
153
133
|
{
|
|
@@ -182,7 +162,7 @@
|
|
|
182
162
|
],
|
|
183
163
|
"metadata": {
|
|
184
164
|
"kernelspec": {
|
|
185
|
-
"display_name": "
|
|
165
|
+
"display_name": "py312",
|
|
186
166
|
"language": "python",
|
|
187
167
|
"name": "python3"
|
|
188
168
|
},
|
|
@@ -196,7 +176,7 @@
|
|
|
196
176
|
"name": "python",
|
|
197
177
|
"nbconvert_exporter": "python",
|
|
198
178
|
"pygments_lexer": "ipython3",
|
|
199
|
-
"version": "3.
|
|
179
|
+
"version": "3.12.8"
|
|
200
180
|
}
|
|
201
181
|
},
|
|
202
182
|
"nbformat": 4,
|
{lamindb_setup-1.9.0 → lamindb_setup-1.10.0}/docs/hub-prod/test-insufficient-user-info.ipynb
RENAMED
|
@@ -38,16 +38,6 @@
|
|
|
38
38
|
"## Log in with in-sufficient information"
|
|
39
39
|
]
|
|
40
40
|
},
|
|
41
|
-
{
|
|
42
|
-
"cell_type": "code",
|
|
43
|
-
"execution_count": null,
|
|
44
|
-
"metadata": {},
|
|
45
|
-
"outputs": [],
|
|
46
|
-
"source": [
|
|
47
|
-
"with pytest.raises(ValueError):\n",
|
|
48
|
-
" ln_setup.login()"
|
|
49
|
-
]
|
|
50
|
-
},
|
|
51
41
|
{
|
|
52
42
|
"cell_type": "markdown",
|
|
53
43
|
"metadata": {},
|
|
@@ -179,7 +169,7 @@
|
|
|
179
169
|
"name": "python",
|
|
180
170
|
"nbconvert_exporter": "python",
|
|
181
171
|
"pygments_lexer": "ipython3",
|
|
182
|
-
"version": "3.
|
|
172
|
+
"version": "3.10.16"
|
|
183
173
|
},
|
|
184
174
|
"nbproject": {
|
|
185
175
|
"id": "vLOmzd6d4Jow",
|
|
@@ -8,6 +8,7 @@ from lamin_utils import logger
|
|
|
8
8
|
|
|
9
9
|
from .core._settings_save import save_platform_user_storage_settings
|
|
10
10
|
from .core._settings_store import system_settings_file
|
|
11
|
+
from .errors import CurrentInstanceNotConfigured
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def clear_cache_dir():
|
|
@@ -19,9 +20,8 @@ def clear_cache_dir():
|
|
|
19
20
|
"disconnecting the current instance to update the cloud sqlite database."
|
|
20
21
|
)
|
|
21
22
|
disconnect()
|
|
22
|
-
except
|
|
23
|
-
|
|
24
|
-
raise e
|
|
23
|
+
except CurrentInstanceNotConfigured:
|
|
24
|
+
pass
|
|
25
25
|
|
|
26
26
|
cache_dir = settings.cache_dir
|
|
27
27
|
if cache_dir.exists():
|
|
@@ -4,7 +4,9 @@ import functools
|
|
|
4
4
|
import importlib as il
|
|
5
5
|
import inspect
|
|
6
6
|
import os
|
|
7
|
+
from importlib.metadata import distributions
|
|
7
8
|
from typing import TYPE_CHECKING
|
|
9
|
+
from uuid import UUID
|
|
8
10
|
|
|
9
11
|
from lamin_utils import logger
|
|
10
12
|
|
|
@@ -25,6 +27,7 @@ if TYPE_CHECKING:
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
CURRENT_ISETTINGS: InstanceSettings | None = None
|
|
30
|
+
MODULE_CANDIDATES: set[str] | None = None
|
|
28
31
|
IS_LOADING: bool = False
|
|
29
32
|
|
|
30
33
|
|
|
@@ -42,7 +45,25 @@ def disable_auto_connect(func: Callable):
|
|
|
42
45
|
return wrapper
|
|
43
46
|
|
|
44
47
|
|
|
45
|
-
def
|
|
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
|
+
|
|
46
67
|
global CURRENT_ISETTINGS
|
|
47
68
|
|
|
48
69
|
if CURRENT_ISETTINGS is not None:
|
|
@@ -60,9 +81,17 @@ def _get_current_instance_settings() -> InstanceSettings | None:
|
|
|
60
81
|
" command line: `lamin connect <instance>` or `lamin init <...>`"
|
|
61
82
|
)
|
|
62
83
|
raise e
|
|
63
|
-
return isettings
|
|
64
84
|
else:
|
|
65
|
-
|
|
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
|
|
66
95
|
|
|
67
96
|
|
|
68
97
|
def _normalize_module_name(module_name: str) -> str:
|
|
@@ -132,12 +161,7 @@ def _check_instance_setup(from_module: str | None = None) -> bool:
|
|
|
132
161
|
return True
|
|
133
162
|
isettings = _get_current_instance_settings()
|
|
134
163
|
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
|
-
):
|
|
164
|
+
if from_module is not None and not django_lamin.IS_SETUP and not IS_LOADING:
|
|
141
165
|
if from_module != "lamindb":
|
|
142
166
|
_check_module_in_instance_modules(from_module, isettings)
|
|
143
167
|
|
|
@@ -146,13 +170,15 @@ def _check_instance_setup(from_module: str | None = None) -> bool:
|
|
|
146
170
|
il.reload(il.import_module(from_module))
|
|
147
171
|
else:
|
|
148
172
|
django_lamin.setup_django(isettings)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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')")
|
|
153
179
|
return django_lamin.IS_SETUP
|
|
154
180
|
else:
|
|
155
|
-
if from_module is not None
|
|
181
|
+
if from_module is not None:
|
|
156
182
|
# the below enables users to auto-connect to an instance
|
|
157
183
|
# simply by setting an environment variable, bypassing the
|
|
158
184
|
# need of calling connect() manually
|
|
@@ -2,23 +2,22 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
4
|
import os
|
|
5
|
+
import sys
|
|
5
6
|
from typing import TYPE_CHECKING, Any
|
|
6
7
|
from uuid import UUID
|
|
7
8
|
|
|
8
9
|
from lamin_utils import logger
|
|
9
10
|
|
|
10
|
-
from ._check_setup import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
load_from_isettings,
|
|
11
|
+
from ._check_setup import (
|
|
12
|
+
_check_instance_setup,
|
|
13
|
+
_get_current_instance_settings,
|
|
14
|
+
find_module_candidates,
|
|
15
15
|
)
|
|
16
|
+
from ._disconnect import disconnect
|
|
17
|
+
from ._init_instance import load_from_isettings
|
|
16
18
|
from ._silence_loggers import silence_loggers
|
|
17
19
|
from .core._hub_core import connect_instance_hub
|
|
18
|
-
from .core._hub_utils import
|
|
19
|
-
LaminDsn,
|
|
20
|
-
LaminDsnModel,
|
|
21
|
-
)
|
|
20
|
+
from .core._hub_utils import LaminDsnModel
|
|
22
21
|
from .core._settings import settings
|
|
23
22
|
from .core._settings_instance import InstanceSettings
|
|
24
23
|
from .core._settings_load import load_instance_settings
|
|
@@ -69,21 +68,18 @@ def update_db_using_local(
|
|
|
69
68
|
if hub_instance_result["db_scheme"] == "postgresql":
|
|
70
69
|
if db is not None:
|
|
71
70
|
# use only the provided db if it is set
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
db_dsn_hub = LaminDsnModel(db=hub_instance_result["db"])
|
|
71
|
+
db_updated = db
|
|
72
|
+
elif (db_env := os.getenv("LAMINDB_INSTANCE_DB")) is not None:
|
|
73
|
+
logger.important("loading db URL from env variable LAMINDB_INSTANCE_DB")
|
|
76
74
|
# read directly from the environment
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
# read
|
|
82
|
-
|
|
83
|
-
db_dsn_hub.db.user in {None, "none"} or "read" in db_dsn_hub.db.user # type:ignore
|
|
84
|
-
):
|
|
75
|
+
db_updated = db_env
|
|
76
|
+
else:
|
|
77
|
+
db_hub = hub_instance_result["db"]
|
|
78
|
+
db_dsn_hub = LaminDsnModel(db=db_hub)
|
|
79
|
+
# read from a cached settings file in case the hub result is inexistent
|
|
80
|
+
if db_dsn_hub.db.user in {None, "none"} and settings_file.exists():
|
|
85
81
|
isettings = load_instance_settings(settings_file)
|
|
86
|
-
|
|
82
|
+
db_updated = isettings.db
|
|
87
83
|
else:
|
|
88
84
|
# just take the default hub result and ensure there is actually a user
|
|
89
85
|
if (
|
|
@@ -95,22 +91,7 @@ def update_db_using_local(
|
|
|
95
91
|
"No database access, please ask your admin to provide you with"
|
|
96
92
|
" a DB URL and pass it via --db <db_url>"
|
|
97
93
|
)
|
|
98
|
-
|
|
99
|
-
if not check_db_dsn_equal_up_to_credentials(db_dsn_hub.db, db_dsn_local.db):
|
|
100
|
-
raise ValueError(
|
|
101
|
-
"The local differs from the hub database information:\n"
|
|
102
|
-
"did your database get updated by an admin?\n"
|
|
103
|
-
"Consider deleting your cached database environment:\nrm"
|
|
104
|
-
f" {settings_file.as_posix()}"
|
|
105
|
-
)
|
|
106
|
-
db_updated = LaminDsn.build(
|
|
107
|
-
scheme=db_dsn_hub.db.scheme,
|
|
108
|
-
user=db_dsn_local.db.user,
|
|
109
|
-
password=db_dsn_local.db.password,
|
|
110
|
-
host=db_dsn_hub.db.host, # type: ignore
|
|
111
|
-
port=db_dsn_hub.db.port,
|
|
112
|
-
database=db_dsn_hub.db.database,
|
|
113
|
-
)
|
|
94
|
+
db_updated = db_hub
|
|
114
95
|
return db_updated
|
|
115
96
|
|
|
116
97
|
|
|
@@ -127,7 +108,12 @@ def _connect_instance(
|
|
|
127
108
|
if settings_file.exists():
|
|
128
109
|
isettings = load_instance_settings(settings_file)
|
|
129
110
|
# skip hub request for a purely local instance
|
|
130
|
-
|
|
111
|
+
if isettings.is_remote:
|
|
112
|
+
make_hub_request = True
|
|
113
|
+
else:
|
|
114
|
+
make_hub_request = False
|
|
115
|
+
if db is not None and isettings.dialect == "postgresql":
|
|
116
|
+
isettings._db = db
|
|
131
117
|
if make_hub_request:
|
|
132
118
|
# the following will return a string if the instance does not exist
|
|
133
119
|
# on the hub
|
|
@@ -188,6 +174,62 @@ def _connect_instance(
|
|
|
188
174
|
return isettings
|
|
189
175
|
|
|
190
176
|
|
|
177
|
+
def reset_django_module_variables():
|
|
178
|
+
# This function updates all module-level references to Django classes
|
|
179
|
+
# But it will fail to update function level references
|
|
180
|
+
# So, if a user has
|
|
181
|
+
# def my_function():
|
|
182
|
+
# import lamindb as ln
|
|
183
|
+
# ...
|
|
184
|
+
#
|
|
185
|
+
# Then it will **not** work and the `ln` variable will become stale and hold a reference
|
|
186
|
+
# to the old classes
|
|
187
|
+
# There doesn't seem to be an easy way to fix this problem
|
|
188
|
+
|
|
189
|
+
import types
|
|
190
|
+
|
|
191
|
+
from django.apps import apps
|
|
192
|
+
|
|
193
|
+
app_names = {app.name for app in apps.get_app_configs()}
|
|
194
|
+
|
|
195
|
+
for name, module in sys.modules.items():
|
|
196
|
+
if (
|
|
197
|
+
module is not None
|
|
198
|
+
and (not name.startswith("__") or name == "__main__")
|
|
199
|
+
and name not in sys.builtin_module_names
|
|
200
|
+
and not (
|
|
201
|
+
hasattr(module, "__file__")
|
|
202
|
+
and module.__file__
|
|
203
|
+
and any(
|
|
204
|
+
path in module.__file__ for path in ["/lib/python", "\\lib\\python"]
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
):
|
|
208
|
+
try:
|
|
209
|
+
for k, v in vars(module).items():
|
|
210
|
+
if (
|
|
211
|
+
isinstance(v, types.ModuleType)
|
|
212
|
+
and not k.startswith("_")
|
|
213
|
+
and getattr(v, "__name__", None) in app_names
|
|
214
|
+
):
|
|
215
|
+
if v.__name__ in sys.modules:
|
|
216
|
+
vars(module)[k] = sys.modules[v.__name__]
|
|
217
|
+
# Also reset classes from Django apps - but check if the class module starts with any app name
|
|
218
|
+
elif hasattr(v, "__module__") and getattr(v, "__module__", None):
|
|
219
|
+
class_module = v.__module__
|
|
220
|
+
# Check if the class module starts with any of our app names
|
|
221
|
+
if any(
|
|
222
|
+
class_module.startswith(app_name) for app_name in app_names
|
|
223
|
+
):
|
|
224
|
+
if class_module in sys.modules:
|
|
225
|
+
fresh_module = sys.modules[class_module]
|
|
226
|
+
attr_name = getattr(v, "__name__", k)
|
|
227
|
+
if hasattr(fresh_module, attr_name):
|
|
228
|
+
vars(module)[k] = getattr(fresh_module, attr_name)
|
|
229
|
+
except (AttributeError, TypeError):
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
|
|
191
233
|
def _connect_cli(instance: str) -> None:
|
|
192
234
|
from lamindb_setup import settings as settings_
|
|
193
235
|
|
|
@@ -214,6 +256,9 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
214
256
|
instance: Pass a slug (`account/name`) or URL (`https://lamin.ai/account/name`).
|
|
215
257
|
If `None`, looks for an environment variable `LAMIN_CURRENT_INSTANCE` to get the instance identifier.
|
|
216
258
|
If it doesn't find this variable, it connects to the instance that was connected with `lamin connect` through the CLI.
|
|
259
|
+
|
|
260
|
+
See Also:
|
|
261
|
+
Configure an instance for auto-connect via the CLI, see `here <https://docs.lamin.ai/cli#connect>`__.
|
|
217
262
|
"""
|
|
218
263
|
# validate kwargs
|
|
219
264
|
valid_kwargs = {
|
|
@@ -250,19 +295,45 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
250
295
|
"No instance was connected through the CLI, pass a value to `instance` or connect via the CLI."
|
|
251
296
|
)
|
|
252
297
|
isettings = isettings_or_none
|
|
298
|
+
if _db is not None and isettings.dialect == "postgresql":
|
|
299
|
+
isettings._db = _db
|
|
253
300
|
else:
|
|
301
|
+
from django.db import connection
|
|
302
|
+
|
|
254
303
|
owner, name = get_owner_name_from_identifier(instance)
|
|
255
304
|
if _check_instance_setup() and not _test:
|
|
256
305
|
if (
|
|
257
306
|
settings._instance_exists
|
|
258
307
|
and f"{owner}/{name}" == settings.instance.slug
|
|
308
|
+
# below is to ensure that if another process interferes
|
|
309
|
+
# we don't use the in-memory mock database
|
|
310
|
+
# could be made more specific by checking whether the django
|
|
311
|
+
# configured database is the same as the one in settings
|
|
312
|
+
and connection.settings_dict["NAME"] != ":memory:"
|
|
259
313
|
):
|
|
260
|
-
logger.important(
|
|
314
|
+
logger.important(
|
|
315
|
+
f"doing nothing, already connected lamindb: {settings.instance.slug}"
|
|
316
|
+
)
|
|
261
317
|
return None
|
|
262
318
|
else:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
319
|
+
from lamindb_setup.core.django import reset_django
|
|
320
|
+
|
|
321
|
+
if (
|
|
322
|
+
settings._instance_exists
|
|
323
|
+
and settings.instance.slug != "none/none"
|
|
324
|
+
):
|
|
325
|
+
import lamindb as ln
|
|
326
|
+
|
|
327
|
+
if ln.context.transform is not None:
|
|
328
|
+
raise CannotSwitchDefaultInstance(
|
|
329
|
+
"Cannot switch default instance while `ln.track()` is live: call `ln.finish()`"
|
|
330
|
+
)
|
|
331
|
+
else:
|
|
332
|
+
logger.important_hint(
|
|
333
|
+
"switching the default lamindb instance might produce unexpected side effects with function-scoped imports: "
|
|
334
|
+
"please import lamindb at the module level instead of inside functions"
|
|
335
|
+
)
|
|
336
|
+
reset_django()
|
|
266
337
|
elif (
|
|
267
338
|
_write_settings
|
|
268
339
|
and settings._instance_exists
|
|
@@ -315,7 +386,9 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
315
386
|
load_from_isettings(isettings, user=_user, write_settings=_write_settings)
|
|
316
387
|
if _reload_lamindb:
|
|
317
388
|
importlib.reload(importlib.import_module("lamindb"))
|
|
318
|
-
|
|
389
|
+
reset_django_module_variables()
|
|
390
|
+
if isettings.slug != "none/none":
|
|
391
|
+
logger.important(f"connected lamindb: {isettings.slug}")
|
|
319
392
|
except Exception as e:
|
|
320
393
|
if isettings is not None:
|
|
321
394
|
if _write_settings:
|
|
@@ -65,6 +65,9 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
|
|
|
65
65
|
If the instance is owned by you, it suffices to pass the instance name.
|
|
66
66
|
force: Whether to skip the confirmation prompt.
|
|
67
67
|
require_empty: Whether to check if the instance is empty before deleting.
|
|
68
|
+
|
|
69
|
+
See Also:
|
|
70
|
+
Delete an instance via the CLI, see `here <https://docs.lamin.ai/cli#delete>`__.
|
|
68
71
|
"""
|
|
69
72
|
owner, name = get_owner_name_from_identifier(slug)
|
|
70
73
|
isettings = _connect_instance(owner, name, raise_permission_error=False)
|
|
@@ -8,9 +8,12 @@ from .core.cloud_sqlite_locker import clear_locker
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def disconnect(mute: bool = False) -> None:
|
|
11
|
-
"""
|
|
11
|
+
"""Clear default instance configuration.
|
|
12
12
|
|
|
13
13
|
Returns `None` if succeeds, otherwise an exception is raised.
|
|
14
|
+
|
|
15
|
+
See Also:
|
|
16
|
+
Clear default instance configuration via the CLI, see `here <https://docs.lamin.ai/cli#disconnect>`__.
|
|
14
17
|
"""
|
|
15
18
|
if current_instance_settings_file().exists():
|
|
16
19
|
instance = settings.instance.slug
|