lamindb_setup 0.76.4__tar.gz → 0.76.6__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.
Files changed (94) hide show
  1. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/PKG-INFO +1 -1
  2. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/03-add-managed-storage.ipynb +1 -1
  3. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/notebooks.md +2 -2
  4. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/__init__.py +1 -1
  5. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_init_instance.py +1 -1
  6. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_set_managed_storage.py +16 -2
  7. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_hub_core.py +6 -6
  8. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_instance.py +1 -1
  9. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_storage.py +22 -5
  10. lamindb_setup-0.76.6/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +26 -0
  11. lamindb_setup-0.76.6/tests/hub-cloud/test_fail_managed_storage.py +12 -0
  12. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-local/test_all.py +2 -2
  13. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/.github/workflows/build.yml +0 -0
  14. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/.github/workflows/doc-changes.yml +0 -0
  15. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/.gitignore +0 -0
  16. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/.pre-commit-config.yaml +0 -0
  17. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/LICENSE +0 -0
  18. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/README.md +0 -0
  19. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/changelog.md +0 -0
  20. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
  21. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
  22. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
  23. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
  24. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
  25. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
  26. /lamindb_setup-0.76.4/docs/hub-cloud/test-multi-session.ipynb → /lamindb_setup-0.76.6/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
  27. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-cloud/test_notebooks.py +0 -0
  28. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-cache-management.ipynb +0 -0
  29. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
  30. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
  31. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-empty-init.ipynb +0 -0
  32. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-import-schema.ipynb +0 -0
  33. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-insufficient-user-info.ipynb +0 -0
  34. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
  35. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
  36. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/hub-prod/test_notebooks2.py +0 -0
  37. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/index.md +0 -0
  38. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/docs/reference.md +0 -0
  39. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_cache.py +0 -0
  40. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_check.py +0 -0
  41. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_check_setup.py +0 -0
  42. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_close.py +0 -0
  43. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_connect_instance.py +0 -0
  44. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_delete.py +0 -0
  45. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_django.py +0 -0
  46. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_exportdb.py +0 -0
  47. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_importdb.py +0 -0
  48. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_migrate.py +0 -0
  49. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_register_instance.py +0 -0
  50. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_schema.py +0 -0
  51. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_schema_metadata.py +0 -0
  52. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_setup_user.py +0 -0
  53. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/_silence_loggers.py +0 -0
  54. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/__init__.py +0 -0
  55. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_aws_credentials.py +0 -0
  56. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_aws_storage.py +0 -0
  57. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_deprecated.py +0 -0
  58. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_docs.py +0 -0
  59. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_hub_client.py +0 -0
  60. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_hub_crud.py +0 -0
  61. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_hub_utils.py +0 -0
  62. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_private_django_api.py +0 -0
  63. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings.py +0 -0
  64. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_load.py +0 -0
  65. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_save.py +0 -0
  66. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_store.py +0 -0
  67. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_settings_user.py +0 -0
  68. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
  69. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
  70. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/django.py +0 -0
  71. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/exceptions.py +0 -0
  72. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/hashing.py +0 -0
  73. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/types.py +0 -0
  74. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/lamindb_setup/core/upath.py +0 -0
  75. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/noxfile.py +0 -0
  76. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/pyproject.toml +0 -0
  77. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_connect_instance.py +0 -0
  78. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_delete_instance.py +0 -0
  79. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_init_instance.py +0 -0
  80. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_login.py +0 -0
  81. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_migrate.py +0 -0
  82. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-cloud/test_set_storage.py +0 -0
  83. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-local/conftest.py +0 -0
  84. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-local/test_update_schema_in_hub.py +0 -0
  85. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-prod/conftest.py +0 -0
  86. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-prod/test_django.py +0 -0
  87. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-prod/test_global_settings.py +0 -0
  88. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
  89. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/hub-prod/test_upath.py +0 -0
  90. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/storage/test_hashing.py +0 -0
  91. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/storage/test_storage_access.py +0 -0
  92. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/storage/test_storage_basis.py +0 -0
  93. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/storage/test_storage_stats.py +0 -0
  94. {lamindb_setup-0.76.4 → lamindb_setup-0.76.6}/tests/storage/test_to_url.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamindb_setup
3
- Version: 0.76.4
3
+ Version: 0.76.6
4
4
  Summary: Setup & configure LaminDB.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Description-Content-Type: text/markdown
@@ -433,7 +433,7 @@
433
433
  "name": "python",
434
434
  "nbconvert_exporter": "python",
435
435
  "pygments_lexer": "ipython3",
436
- "version": "3.10.13"
436
+ "version": "3.9.17"
437
437
  },
438
438
  "vscode": {
439
439
  "interpreter": {
@@ -5,12 +5,12 @@
5
5
 
6
6
  hub-cloud/init-local-instance
7
7
  hub-cloud/connect-local-instance
8
- hub-cloud/set-storage
8
+ hub-cloud/add-managed-storage
9
9
  hub-cloud/test-bionty
10
10
  hub-cloud/init-hosted-instance
11
11
  hub-cloud/connect-hosted-instance
12
- hub-cloud/test-multi-session
13
12
  hub-cloud/keep-artifacts-local
13
+ hub-cloud/test-multi-session
14
14
 
15
15
  hub-prod/test-cache-management
16
16
  hub-prod/test-empty-init
@@ -34,7 +34,7 @@ Modules & settings:
34
34
 
35
35
  """
36
36
 
37
- __version__ = "0.76.4" # denote a release candidate for 0.1.0 with 0.1rc1
37
+ __version__ = "0.76.6" # denote a release candidate for 0.1.0 with 0.1rc1
38
38
 
39
39
  import sys
40
40
  from os import name as _os_name
@@ -250,7 +250,7 @@ def init(
250
250
  # see a way of making this more elegant; should become possible if we
251
251
  # remove the instance.storage_id FK on the hub
252
252
  prevent_register_hub = is_local_db_url(db) if db is not None else False
253
- ssettings = init_storage(
253
+ ssettings, _ = init_storage(
254
254
  storage,
255
255
  instance_id=instance_id,
256
256
  init_instance=True,
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
  from lamin_utils import logger
6
6
 
7
7
  from ._init_instance import register_storage_in_instance
8
+ from .core._hub_core import delete_storage_record
8
9
  from .core._settings import settings
9
10
  from .core._settings_storage import init_storage
10
11
 
@@ -28,14 +29,27 @@ def set_managed_storage(root: UPathStr, **fs_kwargs):
28
29
  raise ValueError(
29
30
  "Can't add additional managed storage locations for instances that aren't managed through the hub."
30
31
  )
31
- ssettings = init_storage(
32
+ # here the storage is registered in the hub
33
+ # hub_record_status="hub-record-created" if a new record is created
34
+ # "hub-record-retireved" if the storage is in the hub already
35
+ ssettings, hub_record_status = init_storage(
32
36
  root=root, instance_id=settings.instance._id, register_hub=True
33
37
  )
34
38
  if ssettings._instance_id is None:
35
39
  raise ValueError(
36
40
  f"Cannot manage storage without write access: {ssettings.root}"
37
41
  )
42
+
43
+ # here the storage is saved in the instance
44
+ # if any error happens the record in the hub is deleted
45
+ # if it was created earlier and not retrieved
46
+ try:
47
+ register_storage_in_instance(ssettings)
48
+ except Exception as e:
49
+ if hub_record_status == "hub-record-created" and ssettings._uuid is not None:
50
+ delete_storage_record(ssettings._uuid) # type: ignore
51
+ raise e
52
+
38
53
  settings.instance._storage = ssettings
39
54
  settings.instance._persist() # this also updates the settings object
40
- register_storage_in_instance(ssettings)
41
55
  settings.storage._set_fs_kwargs(**fs_kwargs)
@@ -4,7 +4,7 @@ import json
4
4
  import os
5
5
  import uuid
6
6
  from importlib import metadata
7
- from typing import TYPE_CHECKING
7
+ from typing import TYPE_CHECKING, Literal
8
8
  from uuid import UUID
9
9
 
10
10
  from lamin_utils import logger
@@ -119,7 +119,7 @@ def _select_storage(
119
119
  def init_storage(
120
120
  ssettings: StorageSettings,
121
121
  auto_populate_instance: bool = True,
122
- ) -> None:
122
+ ) -> Literal["hub-record-retireved", "hub-record-created"]:
123
123
  if settings.user.handle != "anonymous":
124
124
  return call_with_fallback_auth(
125
125
  _init_storage,
@@ -131,21 +131,21 @@ def init_storage(
131
131
  _select_storage, ssettings=ssettings, update_uid=True
132
132
  )
133
133
  if storage_exists:
134
- return None
134
+ return "hub-record-retireved"
135
135
  else:
136
136
  raise ValueError("Log in to create a storage location on the hub.")
137
137
 
138
138
 
139
139
  def _init_storage(
140
140
  ssettings: StorageSettings, auto_populate_instance: bool, client: Client
141
- ) -> None:
141
+ ) -> Literal["hub-record-retireved", "hub-record-created"]:
142
142
  from lamindb_setup import settings
143
143
 
144
144
  # storage roots are always stored without the trailing slash in the SQL
145
145
  # database
146
146
  root = ssettings.root_as_str
147
147
  if _select_storage(ssettings, update_uid=True, client=client):
148
- return None
148
+ return "hub-record-retireved"
149
149
  if ssettings.type_is_cloud:
150
150
  id = uuid.uuid5(uuid.NAMESPACE_URL, root)
151
151
  else:
@@ -181,7 +181,7 @@ def _init_storage(
181
181
  # on root & description
182
182
  client.table("storage").upsert(fields).execute()
183
183
  ssettings._uuid_ = id
184
- return None
184
+ return "hub-record-created"
185
185
 
186
186
 
187
187
  def delete_instance(identifier: UUID | str, require_empty: bool = True) -> str | None:
@@ -230,7 +230,7 @@ class InstanceSettings:
230
230
  return None
231
231
  local_root = UPath(local_root)
232
232
  assert isinstance(local_root, LocalPathClasses)
233
- self._storage_local = init_storage(local_root, self._id, register_hub=True) # type: ignore
233
+ self._storage_local, _ = init_storage(local_root, self._id, register_hub=True) # type: ignore
234
234
  register_storage_in_instance(self._storage_local) # type: ignore
235
235
  logger.important(f"defaulting to local storage: {self._storage_local.root}")
236
236
 
@@ -83,10 +83,17 @@ def init_storage(
83
83
  register_hub: bool | None = None,
84
84
  prevent_register_hub: bool = False,
85
85
  init_instance: bool = False,
86
- ) -> StorageSettings:
86
+ ) -> tuple[
87
+ StorageSettings,
88
+ Literal["hub-record-not-created", "hub-record-retireved", "hub-record-created"],
89
+ ]:
87
90
  if root is None:
88
91
  raise ValueError("`storage` argument can't be `None`")
89
92
  root_str = str(root) # ensure we have a string
93
+ if ".lamindb" in root_str:
94
+ raise ValueError(
95
+ 'Please pass a folder name that does not end or contain ".lamindb"'
96
+ )
90
97
  uid = base62(12)
91
98
  region = None
92
99
  lamin_env = os.getenv("LAMIN_ENV")
@@ -117,13 +124,19 @@ def init_storage(
117
124
  region=region,
118
125
  instance_id=instance_id,
119
126
  )
127
+ # this stores the result of init_storage_hub
128
+ hub_record_status: Literal[
129
+ "hub-record-not-created", "hub-record-retireved", "hub-record-created"
130
+ ] = "hub-record-not-created"
120
131
  # the below might update the uid with one that's already taken on the hub
121
132
  if not prevent_register_hub:
122
133
  if ssettings.type_is_cloud or register_hub:
123
134
  from ._hub_core import delete_storage_record
124
135
  from ._hub_core import init_storage as init_storage_hub
125
136
 
126
- init_storage_hub(ssettings, auto_populate_instance=not init_instance)
137
+ hub_record_status = init_storage_hub(
138
+ ssettings, auto_populate_instance=not init_instance
139
+ )
127
140
  # below comes last only if everything else was successful
128
141
  try:
129
142
  # (federated) credentials for AWS access are provisioned under-the-hood
@@ -133,10 +146,14 @@ def init_storage(
133
146
  logger.important(
134
147
  f"due to lack of write access, LaminDB won't manage storage location: {ssettings.root}"
135
148
  )
136
- if ssettings._uuid is not None:
149
+ # we have to check hub_record_status here because
150
+ # _select_storage inside init_storage_hub also populates ssettings._uuid
151
+ # and we don't want to delete an existing storage record here
152
+ # only newly created
153
+ if hub_record_status == "hub-record-created" and ssettings._uuid is not None:
137
154
  delete_storage_record(ssettings._uuid) # type: ignore
138
155
  ssettings._instance_id = None
139
- return ssettings
156
+ return ssettings, hub_record_status
140
157
 
141
158
 
142
159
  def _process_cache_path(cache_path: str | Path | UPath | None):
@@ -171,7 +188,7 @@ class StorageSettings:
171
188
  (self._root_init / ".lamindb").mkdir(parents=True, exist_ok=True)
172
189
  self._root_init = self._root_init.resolve()
173
190
  except Exception:
174
- logger.warning("unable to create .lamindb folder")
191
+ logger.warning(f"unable to create .lamindb folder in {self._root_init}")
175
192
  pass
176
193
  self._root = None
177
194
  self._instance_id = instance_id
@@ -0,0 +1,26 @@
1
+ from pathlib import Path
2
+
3
+ import lamindb_setup as ln_setup
4
+ import pytest
5
+ from django.db.utils import ProgrammingError
6
+ from lamindb_setup._set_managed_storage import set_managed_storage
7
+ from lamindb_setup.core._hub_client import connect_hub_with_auth
8
+
9
+ # a user should have read-only access to laminlabs/lamin-site-assets
10
+ ln_setup.login("testuser1")
11
+ ln_setup.connect("laminlabs/lamin-site-assets")
12
+
13
+ test_root = Path("./test_script_ci_storage").resolve().as_posix()
14
+
15
+ with pytest.raises(ProgrammingError) as error:
16
+ set_managed_storage(test_root)
17
+ assert error.exconly().endswith(
18
+ "ProgrammingError: permission denied for table lnschema_core_storage"
19
+ )
20
+
21
+ hub_client = connect_hub_with_auth()
22
+
23
+ records = hub_client.table("storage").select("*").eq("root", test_root).execute().data
24
+ assert len(records) == 0
25
+
26
+ hub_client.auth.sign_out()
@@ -0,0 +1,12 @@
1
+ import os
2
+ import subprocess
3
+
4
+
5
+ def test_fail_managed_storage():
6
+ if os.environ["LAMIN_ENV"] == "prod":
7
+ result = subprocess.run(
8
+ "python ./tests/hub-cloud/scripts/script-to-fail-managed-storage.py",
9
+ shell=True,
10
+ capture_output=True,
11
+ )
12
+ assert result.returncode == 0
@@ -121,7 +121,7 @@ def create_myinstance(create_testadmin1_session): # -> Dict
121
121
  # cannot yet pass instance_id here as it does not yet exist
122
122
  storage=init_storage_base(
123
123
  "s3://lamindb-ci/myinstance",
124
- ),
124
+ )[0],
125
125
  db=db_str,
126
126
  )
127
127
  init_instance(isettings)
@@ -329,6 +329,6 @@ def test_init_storage_with_non_existing_bucket(create_testadmin1_session):
329
329
  init_storage(
330
330
  ssettings=init_storage_base(
331
331
  "s3://non_existing_storage_root", instance_id=uuid4()
332
- )
332
+ )[0]
333
333
  )
334
334
  assert error.exconly().endswith("Not Found")
File without changes
File without changes