lamindb_setup 1.9.0__py3-none-any.whl → 1.9.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 +166 -166
- lamindb_setup/_connect_instance.py +328 -342
- lamindb_setup/_delete.py +141 -141
- lamindb_setup/_disconnect.py +32 -32
- lamindb_setup/_init_instance.py +440 -440
- lamindb_setup/_migrate.py +266 -266
- lamindb_setup/_register_instance.py +35 -35
- lamindb_setup/_schema_metadata.py +441 -441
- lamindb_setup/_set_managed_storage.py +70 -70
- lamindb_setup/_setup_user.py +133 -133
- lamindb_setup/core/__init__.py +21 -21
- lamindb_setup/core/_aws_options.py +223 -223
- lamindb_setup/core/_hub_client.py +248 -248
- lamindb_setup/core/_hub_core.py +665 -665
- lamindb_setup/core/_hub_crud.py +227 -227
- lamindb_setup/core/_private_django_api.py +83 -83
- lamindb_setup/core/_settings.py +377 -377
- lamindb_setup/core/_settings_instance.py +569 -569
- lamindb_setup/core/_settings_load.py +141 -141
- lamindb_setup/core/_settings_save.py +95 -95
- lamindb_setup/core/_settings_storage.py +429 -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 +305 -296
- 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 +70 -70
- lamindb_setup/types.py +20 -20
- {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/METADATA +1 -1
- lamindb_setup-1.9.1.dist-info/RECORD +50 -0
- lamindb_setup-1.9.0.dist-info/RECORD +0 -50
- {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/LICENSE +0 -0
- {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/WHEEL +0 -0
|
@@ -1,342 +1,328 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import importlib
|
|
4
|
-
import os
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
6
|
-
from uuid import UUID
|
|
7
|
-
|
|
8
|
-
from lamin_utils import logger
|
|
9
|
-
|
|
10
|
-
from ._check_setup import _check_instance_setup, _get_current_instance_settings
|
|
11
|
-
from ._disconnect import disconnect
|
|
12
|
-
from ._init_instance import (
|
|
13
|
-
MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE,
|
|
14
|
-
load_from_isettings,
|
|
15
|
-
)
|
|
16
|
-
from ._silence_loggers import silence_loggers
|
|
17
|
-
from .core._hub_core import connect_instance_hub
|
|
18
|
-
from .core._hub_utils import
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
from .core.
|
|
23
|
-
from .core.
|
|
24
|
-
from .core.
|
|
25
|
-
from .
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
from
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
from
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
db_dsn_hub.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
else:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
""
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if "/" in identifier:
|
|
330
|
-
if identifier.startswith("https://lamin.ai/"):
|
|
331
|
-
identifier = identifier.replace("https://lamin.ai/", "")
|
|
332
|
-
split = identifier.split("/")
|
|
333
|
-
if len(split) > 2:
|
|
334
|
-
raise ValueError(
|
|
335
|
-
"The instance identifier needs to be 'owner/name', the instance name"
|
|
336
|
-
" (owner is current user) or the URL: https://lamin.ai/owner/name."
|
|
337
|
-
)
|
|
338
|
-
owner, name = split
|
|
339
|
-
else:
|
|
340
|
-
owner = settings.user.handle
|
|
341
|
-
name = identifier
|
|
342
|
-
return owner, name
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import os
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from lamin_utils import logger
|
|
9
|
+
|
|
10
|
+
from ._check_setup import _check_instance_setup, _get_current_instance_settings
|
|
11
|
+
from ._disconnect import disconnect
|
|
12
|
+
from ._init_instance import (
|
|
13
|
+
MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE,
|
|
14
|
+
load_from_isettings,
|
|
15
|
+
)
|
|
16
|
+
from ._silence_loggers import silence_loggers
|
|
17
|
+
from .core._hub_core import connect_instance_hub
|
|
18
|
+
from .core._hub_utils import LaminDsnModel
|
|
19
|
+
from .core._settings import settings
|
|
20
|
+
from .core._settings_instance import InstanceSettings
|
|
21
|
+
from .core._settings_load import load_instance_settings
|
|
22
|
+
from .core._settings_storage import StorageSettings
|
|
23
|
+
from .core._settings_store import instance_settings_file, settings_dir
|
|
24
|
+
from .core.cloud_sqlite_locker import unlock_cloud_sqlite_upon_exception
|
|
25
|
+
from .errors import CannotSwitchDefaultInstance
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
from .core._settings_user import UserSettings
|
|
31
|
+
from .types import UPathStr
|
|
32
|
+
|
|
33
|
+
# this is for testing purposes only
|
|
34
|
+
# set to True only to test failed load
|
|
35
|
+
_TEST_FAILED_LOAD = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
INSTANCE_NOT_FOUND_MESSAGE = (
|
|
39
|
+
"'{owner}/{name}' not found:"
|
|
40
|
+
" '{hub_result}'\nCheck your permissions:"
|
|
41
|
+
" https://lamin.ai/{owner}/{name}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InstanceNotFoundError(SystemExit):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def check_db_dsn_equal_up_to_credentials(db_dsn_hub, db_dsn_local):
|
|
50
|
+
return (
|
|
51
|
+
db_dsn_hub.scheme == db_dsn_local.scheme
|
|
52
|
+
and db_dsn_hub.host == db_dsn_local.host
|
|
53
|
+
and db_dsn_hub.database == db_dsn_local.database
|
|
54
|
+
and db_dsn_hub.port == db_dsn_local.port
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def update_db_using_local(
|
|
59
|
+
hub_instance_result: dict[str, str],
|
|
60
|
+
settings_file: Path,
|
|
61
|
+
db: str | None = None,
|
|
62
|
+
raise_permission_error=True,
|
|
63
|
+
) -> str | None:
|
|
64
|
+
db_updated = None
|
|
65
|
+
# check if postgres
|
|
66
|
+
if hub_instance_result["db_scheme"] == "postgresql":
|
|
67
|
+
if db is not None:
|
|
68
|
+
# use only the provided db if it is set
|
|
69
|
+
db_updated = db
|
|
70
|
+
elif (db_env := os.getenv("LAMINDB_INSTANCE_DB")) is not None:
|
|
71
|
+
logger.important("loading db URL from env variable LAMINDB_INSTANCE_DB")
|
|
72
|
+
# read directly from the environment
|
|
73
|
+
db_updated = db_env
|
|
74
|
+
else:
|
|
75
|
+
db_hub = hub_instance_result["db"]
|
|
76
|
+
db_dsn_hub = LaminDsnModel(db=db_hub)
|
|
77
|
+
# read from a cached settings file in case the hub result is inexistent
|
|
78
|
+
if db_dsn_hub.db.user in {None, "none"} and settings_file.exists():
|
|
79
|
+
isettings = load_instance_settings(settings_file)
|
|
80
|
+
db_updated = isettings.db
|
|
81
|
+
else:
|
|
82
|
+
# just take the default hub result and ensure there is actually a user
|
|
83
|
+
if (
|
|
84
|
+
db_dsn_hub.db.user in {None, "none"}
|
|
85
|
+
and db_dsn_hub.db.password in {None, "none"}
|
|
86
|
+
and raise_permission_error
|
|
87
|
+
):
|
|
88
|
+
raise PermissionError(
|
|
89
|
+
"No database access, please ask your admin to provide you with"
|
|
90
|
+
" a DB URL and pass it via --db <db_url>"
|
|
91
|
+
)
|
|
92
|
+
db_updated = db_hub
|
|
93
|
+
return db_updated
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _connect_instance(
|
|
97
|
+
owner: str,
|
|
98
|
+
name: str,
|
|
99
|
+
*,
|
|
100
|
+
db: str | None = None,
|
|
101
|
+
raise_permission_error: bool = True,
|
|
102
|
+
access_token: str | None = None,
|
|
103
|
+
) -> InstanceSettings:
|
|
104
|
+
settings_file = instance_settings_file(name, owner)
|
|
105
|
+
make_hub_request = True
|
|
106
|
+
if settings_file.exists():
|
|
107
|
+
isettings = load_instance_settings(settings_file)
|
|
108
|
+
# skip hub request for a purely local instance
|
|
109
|
+
if isettings.is_remote:
|
|
110
|
+
make_hub_request = True
|
|
111
|
+
else:
|
|
112
|
+
make_hub_request = False
|
|
113
|
+
if db is not None and isettings.dialect == "postgresql":
|
|
114
|
+
isettings._db = db
|
|
115
|
+
if make_hub_request:
|
|
116
|
+
# the following will return a string if the instance does not exist
|
|
117
|
+
# on the hub
|
|
118
|
+
# do not call hub if the user is anonymous
|
|
119
|
+
if owner != "anonymous":
|
|
120
|
+
hub_result = connect_instance_hub(
|
|
121
|
+
owner=owner, name=name, access_token=access_token
|
|
122
|
+
)
|
|
123
|
+
else:
|
|
124
|
+
hub_result = "anonymous-user"
|
|
125
|
+
# if hub_result is not a string, it means it made a request
|
|
126
|
+
# that successfully returned metadata
|
|
127
|
+
if not isinstance(hub_result, str):
|
|
128
|
+
instance_result, storage_result = hub_result
|
|
129
|
+
db_updated = update_db_using_local(
|
|
130
|
+
instance_result,
|
|
131
|
+
settings_file,
|
|
132
|
+
db=db,
|
|
133
|
+
raise_permission_error=raise_permission_error,
|
|
134
|
+
)
|
|
135
|
+
ssettings = StorageSettings(
|
|
136
|
+
root=storage_result["root"],
|
|
137
|
+
region=storage_result["region"],
|
|
138
|
+
uid=storage_result["lnid"],
|
|
139
|
+
uuid=UUID(storage_result["id"]),
|
|
140
|
+
instance_id=UUID(instance_result["id"]),
|
|
141
|
+
)
|
|
142
|
+
isettings = InstanceSettings(
|
|
143
|
+
id=UUID(instance_result["id"]),
|
|
144
|
+
owner=owner,
|
|
145
|
+
name=instance_result["name"],
|
|
146
|
+
storage=ssettings,
|
|
147
|
+
db=db_updated,
|
|
148
|
+
modules=instance_result["schema_str"],
|
|
149
|
+
git_repo=instance_result["git_repo"],
|
|
150
|
+
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
151
|
+
is_on_hub=True,
|
|
152
|
+
api_url=instance_result["api_url"],
|
|
153
|
+
schema_id=None
|
|
154
|
+
if (schema_id := instance_result["schema_id"]) is None
|
|
155
|
+
else UUID(schema_id),
|
|
156
|
+
fine_grained_access=instance_result.get("fine_grained_access", False),
|
|
157
|
+
db_permissions=instance_result.get("db_permissions", None),
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
if hub_result != "anonymous-user":
|
|
161
|
+
message = INSTANCE_NOT_FOUND_MESSAGE.format(
|
|
162
|
+
owner=owner, name=name, hub_result=hub_result
|
|
163
|
+
)
|
|
164
|
+
else:
|
|
165
|
+
message = "It is not possible to load an anonymous-owned instance from the hub"
|
|
166
|
+
if settings_file.exists():
|
|
167
|
+
isettings = load_instance_settings(settings_file)
|
|
168
|
+
if isettings.is_remote:
|
|
169
|
+
raise InstanceNotFoundError(message)
|
|
170
|
+
else:
|
|
171
|
+
raise InstanceNotFoundError(message)
|
|
172
|
+
return isettings
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _connect_cli(instance: str) -> None:
|
|
176
|
+
from lamindb_setup import settings as settings_
|
|
177
|
+
|
|
178
|
+
settings_.auto_connect = True
|
|
179
|
+
owner, name = get_owner_name_from_identifier(instance)
|
|
180
|
+
isettings = _connect_instance(owner, name)
|
|
181
|
+
isettings._persist(write_to_disk=True)
|
|
182
|
+
if not isettings.is_on_hub or isettings._is_cloud_sqlite:
|
|
183
|
+
# there are two reasons to call the full-blown connect
|
|
184
|
+
# (1) if the instance is not on the hub, we need to register
|
|
185
|
+
# potential users through register_user()
|
|
186
|
+
# (2) if the instance is cloud sqlite, we need to lock it
|
|
187
|
+
connect(_write_settings=False, _reload_lamindb=False)
|
|
188
|
+
else:
|
|
189
|
+
logger.important(f"connected lamindb: {isettings.slug}")
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@unlock_cloud_sqlite_upon_exception(ignore_prev_locker=True)
|
|
194
|
+
def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
195
|
+
"""Connect to an instance.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
instance: Pass a slug (`account/name`) or URL (`https://lamin.ai/account/name`).
|
|
199
|
+
If `None`, looks for an environment variable `LAMIN_CURRENT_INSTANCE` to get the instance identifier.
|
|
200
|
+
If it doesn't find this variable, it connects to the instance that was connected with `lamin connect` through the CLI.
|
|
201
|
+
"""
|
|
202
|
+
# validate kwargs
|
|
203
|
+
valid_kwargs = {
|
|
204
|
+
"_db",
|
|
205
|
+
"_write_settings",
|
|
206
|
+
"_raise_not_found_error",
|
|
207
|
+
"_reload_lamindb",
|
|
208
|
+
"_test",
|
|
209
|
+
"_user",
|
|
210
|
+
}
|
|
211
|
+
for kwarg in kwargs:
|
|
212
|
+
if kwarg not in valid_kwargs:
|
|
213
|
+
raise TypeError(f"connect() got unexpected keyword argument '{kwarg}'")
|
|
214
|
+
isettings: InstanceSettings = None # type: ignore
|
|
215
|
+
# _db is still needed because it is called in init
|
|
216
|
+
_db: str | None = kwargs.get("_db", None)
|
|
217
|
+
_write_settings: bool = kwargs.get("_write_settings", False)
|
|
218
|
+
_raise_not_found_error: bool = kwargs.get("_raise_not_found_error", True)
|
|
219
|
+
_reload_lamindb: bool = kwargs.get("_reload_lamindb", True)
|
|
220
|
+
_test: bool = kwargs.get("_test", False)
|
|
221
|
+
|
|
222
|
+
access_token: str | None = None
|
|
223
|
+
_user: UserSettings | None = kwargs.get("_user", None)
|
|
224
|
+
if _user is not None:
|
|
225
|
+
access_token = _user.access_token
|
|
226
|
+
if instance is None:
|
|
227
|
+
instance = os.environ.get("LAMIN_CURRENT_INSTANCE")
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
if instance is None:
|
|
231
|
+
isettings_or_none = _get_current_instance_settings()
|
|
232
|
+
if isettings_or_none is None:
|
|
233
|
+
raise ValueError(
|
|
234
|
+
"No instance was connected through the CLI, pass a value to `instance` or connect via the CLI."
|
|
235
|
+
)
|
|
236
|
+
isettings = isettings_or_none
|
|
237
|
+
if _db is not None and isettings.dialect == "postgresql":
|
|
238
|
+
isettings._db = _db
|
|
239
|
+
else:
|
|
240
|
+
owner, name = get_owner_name_from_identifier(instance)
|
|
241
|
+
if _check_instance_setup() and not _test:
|
|
242
|
+
if (
|
|
243
|
+
settings._instance_exists
|
|
244
|
+
and f"{owner}/{name}" == settings.instance.slug
|
|
245
|
+
):
|
|
246
|
+
logger.important(f"connected lamindb: {settings.instance.slug}")
|
|
247
|
+
return None
|
|
248
|
+
else:
|
|
249
|
+
raise CannotSwitchDefaultInstance(
|
|
250
|
+
MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE
|
|
251
|
+
)
|
|
252
|
+
elif (
|
|
253
|
+
_write_settings
|
|
254
|
+
and settings._instance_exists
|
|
255
|
+
and f"{owner}/{name}" != settings.instance.slug
|
|
256
|
+
):
|
|
257
|
+
disconnect(mute=True)
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
isettings = _connect_instance(
|
|
261
|
+
owner, name, db=_db, access_token=access_token
|
|
262
|
+
)
|
|
263
|
+
except InstanceNotFoundError as e:
|
|
264
|
+
if _raise_not_found_error:
|
|
265
|
+
raise e
|
|
266
|
+
else:
|
|
267
|
+
return "instance-not-found"
|
|
268
|
+
if isinstance(isettings, str):
|
|
269
|
+
return isettings
|
|
270
|
+
# at this point we have checked already that isettings is not a string
|
|
271
|
+
# _user is passed to lock cloud sqlite for this user in isettings._load_db()
|
|
272
|
+
# has no effect if _user is None or if not cloud sqlite instance
|
|
273
|
+
isettings._locker_user = _user
|
|
274
|
+
isettings._persist(write_to_disk=_write_settings)
|
|
275
|
+
if _test:
|
|
276
|
+
return None
|
|
277
|
+
silence_loggers()
|
|
278
|
+
check, msg = isettings._load_db()
|
|
279
|
+
if not check:
|
|
280
|
+
local_db = (
|
|
281
|
+
isettings._is_cloud_sqlite and isettings._sqlite_file_local.exists()
|
|
282
|
+
)
|
|
283
|
+
if local_db:
|
|
284
|
+
logger.warning(
|
|
285
|
+
"SQLite file does not exist in the cloud, but exists locally:"
|
|
286
|
+
f" {isettings._sqlite_file_local}\nTo push the file to the cloud,"
|
|
287
|
+
" call: lamin disconnect"
|
|
288
|
+
)
|
|
289
|
+
elif _raise_not_found_error:
|
|
290
|
+
raise SystemExit(msg)
|
|
291
|
+
else:
|
|
292
|
+
logger.warning(
|
|
293
|
+
f"instance exists with id {isettings._id.hex}, but database is not"
|
|
294
|
+
" loadable: re-initializing"
|
|
295
|
+
)
|
|
296
|
+
return "instance-corrupted-or-deleted"
|
|
297
|
+
# this is for testing purposes only
|
|
298
|
+
if _TEST_FAILED_LOAD:
|
|
299
|
+
raise RuntimeError("Technical testing error.")
|
|
300
|
+
|
|
301
|
+
load_from_isettings(isettings, user=_user, write_settings=_write_settings)
|
|
302
|
+
if _reload_lamindb:
|
|
303
|
+
importlib.reload(importlib.import_module("lamindb"))
|
|
304
|
+
logger.important(f"connected lamindb: {isettings.slug}")
|
|
305
|
+
except Exception as e:
|
|
306
|
+
if isettings is not None:
|
|
307
|
+
if _write_settings:
|
|
308
|
+
isettings._get_settings_file().unlink(missing_ok=True) # type: ignore
|
|
309
|
+
settings._instance_settings = None
|
|
310
|
+
raise e
|
|
311
|
+
return None
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def get_owner_name_from_identifier(identifier: str):
|
|
315
|
+
if "/" in identifier:
|
|
316
|
+
if identifier.startswith("https://lamin.ai/"):
|
|
317
|
+
identifier = identifier.replace("https://lamin.ai/", "")
|
|
318
|
+
split = identifier.split("/")
|
|
319
|
+
if len(split) > 2:
|
|
320
|
+
raise ValueError(
|
|
321
|
+
"The instance identifier needs to be 'owner/name', the instance name"
|
|
322
|
+
" (owner is current user) or the URL: https://lamin.ai/owner/name."
|
|
323
|
+
)
|
|
324
|
+
owner, name = split
|
|
325
|
+
else:
|
|
326
|
+
owner = settings.user.handle
|
|
327
|
+
name = identifier
|
|
328
|
+
return owner, name
|