lamindb_setup 1.6.1__py3-none-any.whl → 1.7.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 CHANGED
@@ -30,18 +30,20 @@ Modules & settings:
30
30
  settings
31
31
  core
32
32
  django
33
+ errors
34
+ types
33
35
 
34
36
  """
35
37
 
36
- __version__ = "1.6.1" # denote a release candidate for 0.1.0 with 0.1rc1
38
+ __version__ = "1.7.1" # denote a release candidate for 0.1.0 with 0.1rc1
37
39
 
38
40
  import os
39
41
 
40
42
  from packaging import version as packaging_version
41
43
 
42
- from . import core
44
+ from . import core, errors, types
43
45
  from ._check_setup import _check_instance_setup
44
- from ._connect_instance import connect, load
46
+ from ._connect_instance import connect
45
47
  from ._delete import delete
46
48
  from ._disconnect import disconnect
47
49
  from ._django import django
lamindb_setup/_cache.py CHANGED
@@ -1,10 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import shutil
4
+ from pathlib import Path
4
5
 
6
+ from dotenv import dotenv_values
5
7
  from lamin_utils import logger
6
8
 
7
- from .core._settings_save import save_system_storage_settings
9
+ from .core._settings_save import save_platform_user_storage_settings
10
+ from .core._settings_store import system_settings_file
8
11
 
9
12
 
10
13
  def clear_cache_dir():
@@ -13,7 +16,7 @@ def clear_cache_dir():
13
16
  try:
14
17
  if settings.instance._is_cloud_sqlite:
15
18
  logger.warning(
16
- "Disconnecting the current instance to update the cloud sqlite database."
19
+ "disconnecting the current instance to update the cloud sqlite database."
17
20
  )
18
21
  disconnect()
19
22
  except SystemExit as e:
@@ -21,9 +24,12 @@ def clear_cache_dir():
21
24
  raise e
22
25
 
23
26
  cache_dir = settings.cache_dir
24
- shutil.rmtree(cache_dir)
25
- cache_dir.mkdir()
26
- logger.success("The cache directory was cleared.")
27
+ if cache_dir.exists():
28
+ shutil.rmtree(cache_dir)
29
+ cache_dir.mkdir()
30
+ logger.success("the cache directory was cleared")
31
+ else:
32
+ logger.warning("the cache directory doesn't exist")
27
33
 
28
34
 
29
35
  def get_cache_dir():
@@ -41,12 +47,41 @@ def set_cache_dir(cache_dir: str):
41
47
 
42
48
  old_cache_dir = settings.cache_dir
43
49
  new_cache_dir = _process_cache_path(cache_dir)
50
+
51
+ system_cache_dir = None
52
+ if (system_settings := system_settings_file()).exists():
53
+ system_cache_dir = dotenv_values(system_settings).get(
54
+ "lamindb_cache_path", None
55
+ )
56
+ system_cache_dir = (
57
+ Path(system_cache_dir) if system_cache_dir is not None else None
58
+ )
59
+
60
+ need_reset = False
44
61
  if new_cache_dir is None:
45
- new_cache_dir = DEFAULT_CACHE_DIR
62
+ need_reset = True
63
+ new_cache_dir = (
64
+ DEFAULT_CACHE_DIR if system_cache_dir is None else system_cache_dir
65
+ )
66
+
46
67
  if new_cache_dir != old_cache_dir:
47
- shutil.copytree(old_cache_dir, new_cache_dir, dirs_exist_ok=True)
48
- shutil.rmtree(old_cache_dir)
49
- logger.info("The current cache directory was moved to the specified location")
50
- new_cache_dir = new_cache_dir.resolve()
51
- save_system_storage_settings(new_cache_dir)
68
+ if old_cache_dir.exists():
69
+ shutil.copytree(old_cache_dir, new_cache_dir, dirs_exist_ok=True)
70
+ logger.info(
71
+ f"the current cache directory was copied to {new_cache_dir.as_posix()} "
72
+ )
73
+ if old_cache_dir != system_cache_dir:
74
+ shutil.rmtree(old_cache_dir)
75
+ logger.info(
76
+ f"cleared the old cache directory {old_cache_dir.as_posix()}"
77
+ )
78
+ else:
79
+ logger.info(
80
+ f"didn't clear the system cache directory {system_cache_dir.as_posix()}, "
81
+ "please clear it manually if you need"
82
+ )
83
+ else:
84
+ new_cache_dir.mkdir(parents=True, exist_ok=True)
85
+ new_cache_dir = new_cache_dir.resolve()
86
+ save_platform_user_storage_settings(None if need_reset else new_cache_dir)
52
87
  settings._cache_dir = new_cache_dir
@@ -12,7 +12,11 @@ from ._silence_loggers import silence_loggers
12
12
  from .core import django as django_lamin
13
13
  from .core._settings import settings
14
14
  from .core._settings_store import current_instance_settings_file
15
- from .core.exceptions import DefaultMessageException
15
+ from .errors import (
16
+ MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE,
17
+ InstanceNotSetupError,
18
+ ModuleWasntConfigured,
19
+ )
16
20
 
17
21
  if TYPE_CHECKING:
18
22
  from collections.abc import Callable
@@ -20,24 +24,10 @@ if TYPE_CHECKING:
20
24
  from .core._settings_instance import InstanceSettings
21
25
 
22
26
 
23
- class InstanceNotSetupError(DefaultMessageException):
24
- default_message = """\
25
- To use lamindb, you need to connect to an instance.
26
-
27
- Connect to an instance: `ln.connect()`. Init an instance: `ln.setup.init()`.
28
-
29
- If you used the CLI to set up lamindb in a notebook, restart the Python session.
30
- """
31
-
32
-
33
27
  CURRENT_ISETTINGS: InstanceSettings | None = None
34
28
  IS_LOADING: bool = False
35
29
 
36
30
 
37
- class ModuleWasntConfigured(SystemExit):
38
- pass
39
-
40
-
41
31
  # decorator to disable auto-connect when importing a module such as lamindb
42
32
  def disable_auto_connect(func: Callable):
43
33
  @functools.wraps(func)
@@ -84,18 +74,15 @@ def _normalize_module_name(module_name: str) -> str:
84
74
  def _check_module_in_instance_modules(
85
75
  module: str, isettings: InstanceSettings | None = None
86
76
  ) -> None:
87
- not_in_instance_msg = (
88
- f"'{module}' is missing from this instance. "
89
- "Please go to your instance settings page and add it under 'schema modules'."
90
- )
91
-
92
77
  if isettings is not None:
93
78
  modules_raw = isettings.modules
94
79
  modules = set(modules_raw).union(
95
80
  _normalize_module_name(module) for module in modules_raw
96
81
  )
97
82
  if _normalize_module_name(module) not in modules and module not in modules:
98
- raise ModuleWasntConfigured(not_in_instance_msg)
83
+ raise ModuleWasntConfigured(
84
+ MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module)
85
+ )
99
86
  else:
100
87
  return
101
88
 
@@ -105,7 +92,7 @@ def _check_module_in_instance_modules(
105
92
  # app.name is always unnormalized module (python package) name
106
93
  if module == app.name or module == _normalize_module_name(app.name):
107
94
  return
108
- raise ModuleWasntConfigured(not_in_instance_msg)
95
+ raise ModuleWasntConfigured(MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module))
109
96
 
110
97
 
111
98
  # infer the name of the module that calls this function
@@ -11,7 +11,6 @@ from ._check_setup import _check_instance_setup, _get_current_instance_settings
11
11
  from ._disconnect import disconnect
12
12
  from ._init_instance import (
13
13
  MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE,
14
- CannotSwitchDefaultInstance,
15
14
  load_from_isettings,
16
15
  )
17
16
  from ._silence_loggers import silence_loggers
@@ -26,12 +25,13 @@ from .core._settings_load import load_instance_settings
26
25
  from .core._settings_storage import StorageSettings
27
26
  from .core._settings_store import instance_settings_file, settings_dir
28
27
  from .core.cloud_sqlite_locker import unlock_cloud_sqlite_upon_exception
28
+ from .errors import CannotSwitchDefaultInstance
29
29
 
30
30
  if TYPE_CHECKING:
31
31
  from pathlib import Path
32
32
 
33
33
  from .core._settings_user import UserSettings
34
- from .core.types import UPathStr
34
+ from .types import UPathStr
35
35
 
36
36
  # this is for testing purposes only
37
37
  # set to True only to test failed load
@@ -158,7 +158,7 @@ def _connect_instance(
158
158
  isettings = InstanceSettings(
159
159
  id=UUID(instance_result["id"]),
160
160
  owner=owner,
161
- name=name,
161
+ name=instance_result["name"],
162
162
  storage=ssettings,
163
163
  db=db_updated,
164
164
  modules=instance_result["schema_str"],
@@ -211,7 +211,7 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
211
211
  isettings: InstanceSettings = None # type: ignore
212
212
  # _db is still needed because it is called in init
213
213
  _db: str | None = kwargs.get("_db", None)
214
- _write_settings: bool = kwargs.get("_write_settings", True)
214
+ _write_settings: bool = kwargs.get("_write_settings", False)
215
215
  _raise_not_found_error: bool = kwargs.get("_raise_not_found_error", True)
216
216
  _reload_lamindb: bool = kwargs.get("_reload_lamindb", True)
217
217
  _test: bool = kwargs.get("_test", False)
@@ -270,15 +270,6 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
270
270
  if _test:
271
271
  return None
272
272
  silence_loggers()
273
- # migrate away from lnschema-core
274
- no_lnschema_core_file = (
275
- settings_dir / f"no_lnschema_core-{isettings.slug.replace('/', '--')}"
276
- )
277
- if not no_lnschema_core_file.exists():
278
- # sqlite file for cloud sqlite instances is already updated here
279
- migrate_lnschema_core(
280
- isettings, no_lnschema_core_file, write_file=_write_settings
281
- )
282
273
  check, msg = isettings._load_db()
283
274
  if not check:
284
275
  local_db = (
@@ -305,8 +296,7 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
305
296
  load_from_isettings(isettings, user=_user, write_settings=_write_settings)
306
297
  if _reload_lamindb:
307
298
  importlib.reload(importlib.import_module("lamindb"))
308
- else:
309
- logger.important(f"connected lamindb: {isettings.slug}")
299
+ logger.important(f"connected lamindb: {isettings.slug}")
310
300
  except Exception as e:
311
301
  if isettings is not None:
312
302
  if _write_settings:
@@ -316,141 +306,6 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
316
306
  return None
317
307
 
318
308
 
319
- def load(slug: str) -> str | tuple | None:
320
- """Connect to instance and set ``auto-connect`` to true.
321
-
322
- This is exactly the same as ``ln.connect()`` except for that
323
- ``ln.connect()`` doesn't change the state of ``auto-connect``.
324
- """
325
- print("Warning: This is deprecated and will be removed.")
326
- result = connect(slug)
327
- settings.auto_connect = True
328
- return result
329
-
330
-
331
- def migrate_lnschema_core(
332
- isettings: InstanceSettings, no_lnschema_core_file: Path, write_file: bool = True
333
- ):
334
- """Migrate lnschema_core tables to lamindb tables."""
335
- from urllib.parse import urlparse
336
-
337
- # we need to do this because the sqlite file should be already synced
338
- # has no effect if not cloud sqlite
339
- # errors if the sqlite file is not in the cloud and doesn't exist locally
340
- # isettings.db syncs but doesn't error in this case due to error_no_origin=False
341
- isettings._update_local_sqlite_file()
342
-
343
- parsed_uri = urlparse(isettings.db)
344
- db_type = parsed_uri.scheme
345
-
346
- if db_type == "sqlite":
347
- import sqlite3
348
-
349
- # maybe also use LAMINDB_DJANGO_DATABASE_URL here?
350
- conn = sqlite3.connect(parsed_uri.path)
351
- elif db_type in ["postgresql", "postgres"]:
352
- import psycopg2
353
-
354
- # do not ignore LAMINDB_DJANGO_DATABASE_URL if it is set
355
- conn = psycopg2.connect(
356
- os.environ.get("LAMINDB_DJANGO_DATABASE_URL", isettings.db)
357
- )
358
- else:
359
- raise ValueError("Unsupported database type. Use 'sqlite' or 'postgresql' URI.")
360
-
361
- cur = conn.cursor()
362
-
363
- try:
364
- if db_type == "sqlite":
365
- cur.execute(
366
- "SELECT name FROM sqlite_master WHERE type='table' AND name='lamindb_user'"
367
- )
368
- migrated = cur.fetchone() is not None
369
-
370
- # tables that need to be renamed
371
- cur.execute(
372
- "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'lnschema_core_%'"
373
- )
374
- tables_to_rename = [
375
- row[0][len("lnschema_core_") :] for row in cur.fetchall()
376
- ]
377
- else: # postgres
378
- cur.execute(
379
- "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'lamindb_user')"
380
- )
381
- migrated = cur.fetchone()[0]
382
-
383
- # tables that need to be renamed
384
- cur.execute(
385
- "SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'lnschema_core_%'"
386
- )
387
- tables_to_rename = [
388
- row[0][len("lnschema_core_") :] for row in cur.fetchall()
389
- ]
390
-
391
- if migrated:
392
- if write_file:
393
- no_lnschema_core_file.touch(exist_ok=True)
394
- else:
395
- try:
396
- response = input(
397
- f"Do you want to migrate to lamindb 1.0 (integrate lnschema_core into lamindb)? (y/n) -- Will rename {tables_to_rename}"
398
- )
399
- if response != "y":
400
- print("Aborted.")
401
- quit()
402
- if isettings.is_on_hub:
403
- from lamindb_setup.core._hub_client import call_with_fallback_auth
404
- from lamindb_setup.core._hub_crud import (
405
- select_collaborator,
406
- )
407
-
408
- # double check that user is an admin, otherwise will fail below
409
- # due to insufficient SQL permissions with cryptic error
410
- collaborator = call_with_fallback_auth(
411
- select_collaborator,
412
- instance_id=settings.instance._id,
413
- account_id=settings.user._uuid,
414
- )
415
- if collaborator is None or collaborator["role"] != "admin":
416
- raise SystemExit(
417
- "❌ Only admins can deploy migrations, please ensure that you're an"
418
- f" admin: https://lamin.ai/{settings.instance.slug}/settings"
419
- )
420
- for table in tables_to_rename:
421
- if db_type == "sqlite":
422
- cur.execute(
423
- f"ALTER TABLE lnschema_core_{table} RENAME TO lamindb_{table}"
424
- )
425
- else: # postgres
426
- cur.execute(
427
- f"ALTER TABLE lnschema_core_{table} RENAME TO lamindb_{table};"
428
- )
429
-
430
- cur.execute(
431
- "UPDATE django_migrations SET app = 'lamindb' WHERE app = 'lnschema_core'"
432
- )
433
- print(
434
- "Renaming tables finished.\nNow, *please* call: lamin migrate deploy"
435
- )
436
- if write_file:
437
- no_lnschema_core_file.touch(exist_ok=True)
438
- except Exception:
439
- # read-only users can't rename tables
440
- pass
441
-
442
- conn.commit()
443
-
444
- except Exception as e:
445
- print(f"An error occurred: {e}")
446
- conn.rollback()
447
-
448
- finally:
449
- # close the cursor and connection
450
- cur.close()
451
- conn.close()
452
-
453
-
454
309
  def get_owner_name_from_identifier(identifier: str):
455
310
  if "/" in identifier:
456
311
  if identifier.startswith("https://lamin.ai/"):
@@ -8,7 +8,7 @@ from uuid import UUID
8
8
 
9
9
  import click
10
10
  from django.core.exceptions import FieldError
11
- from django.db.utils import OperationalError, ProgrammingError
11
+ from django.db.utils import IntegrityError, OperationalError, ProgrammingError
12
12
  from lamin_utils import logger
13
13
 
14
14
  from ._disconnect import disconnect
@@ -19,12 +19,13 @@ from .core._settings import settings
19
19
  from .core._settings_instance import is_local_db_url
20
20
  from .core._settings_storage import StorageSettings, init_storage
21
21
  from .core.upath import UPath
22
+ from .errors import CannotSwitchDefaultInstance
22
23
 
23
24
  if TYPE_CHECKING:
24
25
  from pydantic import PostgresDsn
25
26
 
26
27
  from .core._settings_user import UserSettings
27
- from .core.types import UPathStr
28
+ from .types import UPathStr
28
29
 
29
30
 
30
31
  class InstanceNotCreated(click.ClickException):
@@ -49,37 +50,31 @@ def get_schema_module_name(module_name, raise_import_error: bool = True) -> str
49
50
 
50
51
 
51
52
  def register_storage_in_instance(ssettings: StorageSettings):
52
- from lamindb.base.users import current_user_id
53
53
  from lamindb.models import Storage
54
54
 
55
- from .core.hashing import hash_and_encode_as_b62
56
-
57
- if ssettings._instance_id is not None:
58
- instance_uid = hash_and_encode_as_b62(ssettings._instance_id.hex)[:12]
59
- else:
60
- instance_uid = None
61
55
  # how do we ensure that this function is only called passing
62
56
  # the managing instance?
63
- defaults = {
57
+ kwargs = {
64
58
  "root": ssettings.root_as_str,
65
59
  "type": ssettings.type,
66
60
  "region": ssettings.region,
67
- "instance_uid": instance_uid,
68
- "created_by_id": current_user_id(),
61
+ "instance_uid": ssettings.instance_uid,
69
62
  "run": None,
63
+ "_skip_preparation": True,
70
64
  }
71
65
  if ssettings._uid is not None:
72
- defaults["uid"] = ssettings._uid
73
- storage, _ = Storage.objects.update_or_create(
74
- root=ssettings.root_as_str,
75
- defaults=defaults,
76
- )
66
+ kwargs["uid"] = ssettings._uid
67
+ # this checks if the storage already exists under the hood
68
+ storage = Storage(**kwargs).save()
77
69
  return storage
78
70
 
79
71
 
80
- def register_user(usettings):
72
+ def register_user(usettings: UserSettings, update_user: bool = True):
81
73
  from lamindb.models import User
82
74
 
75
+ if not update_user and User.objects.filter(uid=usettings.uid).exists():
76
+ return
77
+
83
78
  try:
84
79
  # need to have try except because of integer primary key migration
85
80
  user, created = User.objects.update_or_create(
@@ -90,37 +85,38 @@ def register_user(usettings):
90
85
  },
91
86
  )
92
87
  # for users with only read access, except via ProgrammingError
93
- # ProgrammingError: permission denied for table lnschema_core_user
94
- except (OperationalError, FieldError, ProgrammingError):
88
+ # ProgrammingError: permission denied for table lamindb_user
89
+ # IntegrityError: when trying to update a user on a fine-grained access instance
90
+ except (OperationalError, FieldError, ProgrammingError, IntegrityError):
95
91
  pass
96
92
 
97
93
 
98
- def register_initial_records(isettings: InstanceSettings, usettings):
94
+ def register_initial_records(isettings: InstanceSettings, usettings: UserSettings):
99
95
  """Register space, user & storage in DB."""
100
96
  from django.db.utils import OperationalError
101
97
  from lamindb.models import Branch, Space
102
98
 
103
99
  try:
104
100
  Space.objects.get_or_create(
105
- uid="A",
106
- name="All",
101
+ uid="a",
102
+ name="all",
107
103
  description="Every team & user with access to the instance has access.",
108
104
  )
109
105
  Branch.objects.get_or_create(
110
106
  id=-1,
111
- uid="T",
112
- name="Trash",
107
+ uid="t",
108
+ name="trash",
113
109
  description="The trash.",
114
110
  )
115
111
  Branch.objects.get_or_create(
116
112
  id=0,
117
- uid="A",
118
- name="Archive",
113
+ uid="a",
114
+ name="archive",
119
115
  description="The archive.",
120
116
  )
121
117
  Branch.objects.get_or_create(
122
- uid="M",
123
- name="Main",
118
+ uid="m",
119
+ name="main",
124
120
  description="The main & default branch of the instance.",
125
121
  )
126
122
  register_user(usettings)
@@ -178,7 +174,7 @@ def validate_init_args(
178
174
  _user: UserSettings | None = None,
179
175
  ) -> tuple[
180
176
  str,
181
- UUID | None,
177
+ UUID,
182
178
  Literal[
183
179
  "connected",
184
180
  "instance-corrupted-or-deleted",
@@ -204,23 +200,21 @@ def validate_init_args(
204
200
  _write_settings=_write_settings,
205
201
  _user=_user,
206
202
  )
203
+ instance_id: UUID
207
204
  instance_state: Literal[
208
205
  "connected",
209
206
  "instance-corrupted-or-deleted",
210
207
  "account-not-exists",
211
208
  "instance-not-found",
212
- ] = "connected"
213
- instance_id = None
214
- if response is not None:
209
+ ]
210
+ if response is None:
211
+ instance_state, instance_id = "connected", settings.instance._id
212
+ else:
215
213
  instance_id, instance_state = process_connect_response(response, instance_slug)
216
214
  modules = process_modules_arg(modules)
217
215
  return name_str, instance_id, instance_state, instance_slug
218
216
 
219
217
 
220
- class CannotSwitchDefaultInstance(SystemExit):
221
- pass
222
-
223
-
224
218
  MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE = """
225
219
  You cannot write to different instances in the same Python session.
226
220
 
@@ -296,13 +290,11 @@ def init(
296
290
  if _write_settings:
297
291
  settings.auto_connect = True # we can also debate this switch here
298
292
  return None
299
- # the conditions here match `isettings.is_remote`, but I currently don't
300
- # see a way of making this more elegant; should become possible if we
301
- # remove the instance.storage_id FK on the hub
302
293
  prevent_register_hub = is_local_db_url(db) if db is not None else False
303
294
  ssettings, _ = init_storage(
304
295
  storage,
305
296
  instance_id=instance_id,
297
+ instance_slug=f"{user_handle}/{name_str}",
306
298
  init_instance=True,
307
299
  prevent_register_hub=prevent_register_hub,
308
300
  created_by=user__uuid,
@@ -370,7 +362,7 @@ def init(
370
362
  and (user_handle != "anonymous" or access_token is not None)
371
363
  and ssettings.is_on_hub
372
364
  ):
373
- delete_storage_record(ssettings._uuid, access_token=access_token) # type: ignore
365
+ delete_storage_record(ssettings, access_token=access_token) # type: ignore
374
366
  if isettings is not None:
375
367
  if (
376
368
  user_handle != "anonymous" or access_token is not None
@@ -404,7 +396,9 @@ def load_from_isettings(
404
396
  # this is our best proxy for that the user might not
405
397
  # yet be registered
406
398
  if not isettings._get_settings_file().exists():
407
- register_user(user)
399
+ # do not try to update the user on fine grained access instances
400
+ # this is blocked anyways, only select and insert are allowed
401
+ register_user(user, update_user=not isettings._fine_grained_access)
408
402
  isettings._persist(write_to_disk=write_settings)
409
403
 
410
404
 
@@ -12,7 +12,7 @@ def register(_test: bool = False):
12
12
  from ._check_setup import _check_instance_setup
13
13
  from .core._hub_core import init_instance_hub, init_storage_hub
14
14
 
15
- logger.warning("""lamin register will be removed soon""")
15
+ logger.warning("note that register() is only for testing purposes")
16
16
 
17
17
  isettings = settings.instance
18
18
  if not _check_instance_setup() and not _test:
@@ -16,6 +16,7 @@ from django.db.models import (
16
16
  OneToOneField,
17
17
  OneToOneRel,
18
18
  )
19
+ from lamin_utils import logger
19
20
  from pydantic import BaseModel
20
21
 
21
22
  from lamindb_setup import settings
@@ -25,6 +26,9 @@ from lamindb_setup.core._hub_client import call_with_fallback_auth
25
26
  # surpress pydantic warning about `model_` namespace
26
27
  try:
27
28
  BaseModel.model_config["protected_namespaces"] = ()
29
+ logger.debug(
30
+ "pydantic.BaseModel.model_config['protected_namespaces'] has been set to ()"
31
+ )
28
32
  except Exception:
29
33
  pass
30
34
 
@@ -10,7 +10,7 @@ from .core._settings import settings
10
10
  from .core._settings_storage import init_storage
11
11
 
12
12
  if TYPE_CHECKING:
13
- from lamindb_setup.core.types import UPathStr
13
+ from lamindb_setup.types import UPathStr
14
14
 
15
15
 
16
16
  def set_managed_storage(root: UPathStr, **fs_kwargs):
@@ -33,7 +33,10 @@ def set_managed_storage(root: UPathStr, **fs_kwargs):
33
33
  # hub_record_status="hub-record-created" if a new record is created
34
34
  # "hub-record-retrieved" if the storage is in the hub already
35
35
  ssettings, hub_record_status = init_storage(
36
- root=root, instance_id=settings.instance._id, register_hub=True
36
+ root=root,
37
+ instance_id=settings.instance._id,
38
+ instance_slug=settings.instance.slug,
39
+ register_hub=True,
37
40
  )
38
41
  if ssettings._instance_id is None:
39
42
  raise ValueError(
@@ -47,9 +50,8 @@ def set_managed_storage(root: UPathStr, **fs_kwargs):
47
50
  register_storage_in_instance(ssettings)
48
51
  except Exception as e:
49
52
  if hub_record_status == "hub-record-created" and ssettings._uuid is not None:
50
- delete_storage_record(ssettings._uuid) # type: ignore
53
+ delete_storage_record(ssettings)
51
54
  raise e
52
55
 
53
56
  settings.instance._storage = ssettings
54
- settings.instance._persist() # this also updates the settings object
55
57
  settings.storage._set_fs_kwargs(**fs_kwargs)
@@ -12,7 +12,7 @@ Settings:
12
12
 
13
13
  """
14
14
 
15
- from . import django, types, upath
15
+ from . import django, upath
16
16
  from ._deprecated import deprecated
17
17
  from ._docs import doc_args
18
18
  from ._settings import SetupSettings
@@ -31,7 +31,7 @@ AWS_CREDENTIALS_EXPIRATION: int = 11 * 60 * 60 # refresh credentials after 11 h
31
31
 
32
32
  # set anon=True for these buckets if credentials fail for a public bucket
33
33
  # to be expanded
34
- PUBLIC_BUCKETS: tuple[str] = ("cellxgene-data-public",)
34
+ PUBLIC_BUCKETS: tuple[str, ...] = ("cellxgene-data-public", "bionty-assets")
35
35
 
36
36
 
37
37
  # s3-comaptible endpoints managed by lamin
@@ -79,8 +79,8 @@ class AWSOptionsManager:
79
79
  # use lamindata public bucket for this test
80
80
  fs.call_s3("head_bucket", Bucket="lamindata")
81
81
  self.anon_public = False
82
- except Exception as e:
83
- self.anon_public = isinstance(e, PermissionError)
82
+ except Exception:
83
+ self.anon_public = True
84
84
 
85
85
  def _find_root(self, path_str: str) -> str | None:
86
86
  roots = self._credentials_cache.keys()