lamindb_setup 1.9.1__py3-none-any.whl → 1.10.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. lamindb_setup/__init__.py +107 -107
  2. lamindb_setup/_cache.py +87 -87
  3. lamindb_setup/_check_setup.py +192 -166
  4. lamindb_setup/_connect_instance.py +430 -328
  5. lamindb_setup/_delete.py +144 -141
  6. lamindb_setup/_disconnect.py +35 -32
  7. lamindb_setup/_init_instance.py +430 -440
  8. lamindb_setup/_migrate.py +278 -266
  9. lamindb_setup/_register_instance.py +32 -35
  10. lamindb_setup/_schema_metadata.py +441 -441
  11. lamindb_setup/_set_managed_storage.py +69 -70
  12. lamindb_setup/_setup_user.py +172 -133
  13. lamindb_setup/core/__init__.py +21 -21
  14. lamindb_setup/core/_aws_options.py +223 -223
  15. lamindb_setup/core/_aws_storage.py +9 -1
  16. lamindb_setup/core/_deprecated.py +1 -1
  17. lamindb_setup/core/_hub_client.py +248 -248
  18. lamindb_setup/core/_hub_core.py +751 -665
  19. lamindb_setup/core/_hub_crud.py +247 -227
  20. lamindb_setup/core/_private_django_api.py +83 -83
  21. lamindb_setup/core/_settings.py +374 -377
  22. lamindb_setup/core/_settings_instance.py +609 -569
  23. lamindb_setup/core/_settings_load.py +141 -141
  24. lamindb_setup/core/_settings_save.py +95 -95
  25. lamindb_setup/core/_settings_storage.py +427 -429
  26. lamindb_setup/core/_settings_store.py +91 -91
  27. lamindb_setup/core/_settings_user.py +55 -55
  28. lamindb_setup/core/_setup_bionty_sources.py +44 -44
  29. lamindb_setup/core/cloud_sqlite_locker.py +240 -240
  30. lamindb_setup/core/django.py +311 -305
  31. lamindb_setup/core/exceptions.py +1 -1
  32. lamindb_setup/core/hashing.py +134 -134
  33. lamindb_setup/core/types.py +1 -1
  34. lamindb_setup/core/upath.py +1013 -1013
  35. lamindb_setup/errors.py +80 -70
  36. lamindb_setup/types.py +20 -20
  37. {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/METADATA +4 -4
  38. lamindb_setup-1.10.1.dist-info/RECORD +50 -0
  39. lamindb_setup-1.9.1.dist-info/RECORD +0 -50
  40. {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/LICENSE +0 -0
  41. {lamindb_setup-1.9.1.dist-info → lamindb_setup-1.10.1.dist-info}/WHEEL +0 -0
lamindb_setup/_delete.py CHANGED
@@ -1,141 +1,144 @@
1
- from __future__ import annotations
2
-
3
- import shutil
4
- from typing import TYPE_CHECKING
5
- from uuid import UUID
6
-
7
- from lamin_utils import logger
8
-
9
- from ._connect_instance import _connect_instance, get_owner_name_from_identifier
10
- from .core._aws_options import HOSTED_BUCKETS
11
- from .core._hub_core import delete_instance as delete_instance_on_hub
12
- from .core._hub_core import get_storage_records_for_instance
13
- from .core._settings import settings
14
- from .core._settings_storage import StorageSettings
15
- from .core.upath import LocalPathClasses, check_storage_is_empty
16
-
17
- if TYPE_CHECKING:
18
- from pathlib import Path
19
-
20
- from .core._settings_instance import InstanceSettings
21
-
22
-
23
- def delete_cache(isettings: InstanceSettings):
24
- # avoid init of root
25
- root = isettings.storage._root_init
26
- if not isinstance(root, LocalPathClasses):
27
- cache_dir = settings.cache_dir / root.path
28
- if cache_dir.exists():
29
- shutil.rmtree(cache_dir)
30
-
31
-
32
- def delete_exclusion_dir(isettings: InstanceSettings) -> None:
33
- exclusion_dir = isettings.storage.root / f".lamindb/_exclusion/{isettings._id.hex}"
34
- if exclusion_dir.exists():
35
- exclusion_dir.rmdir()
36
-
37
-
38
- def delete_by_isettings(isettings: InstanceSettings) -> None:
39
- settings_file = isettings._get_settings_file()
40
- if settings_file.exists():
41
- settings_file.unlink()
42
- delete_cache(isettings)
43
- if isettings.dialect == "sqlite":
44
- try:
45
- if isettings._sqlite_file.exists():
46
- isettings._sqlite_file.unlink()
47
- except PermissionError:
48
- logger.warning(
49
- "Did not have permission to delete SQLite file:"
50
- f" {isettings._sqlite_file}"
51
- )
52
- pass
53
- # unset the global instance settings
54
- if settings._instance_exists and isettings.slug == settings.instance.slug:
55
- if settings._instance_settings_path.exists():
56
- settings._instance_settings_path.unlink()
57
- settings._instance_settings = None
58
-
59
-
60
- def delete(slug: str, force: bool = False, require_empty: bool = True) -> int | None:
61
- """Delete a LaminDB instance.
62
-
63
- Args:
64
- slug: The instance slug `account_handle/instance_name` or URL.
65
- If the instance is owned by you, it suffices to pass the instance name.
66
- force: Whether to skip the confirmation prompt.
67
- require_empty: Whether to check if the instance is empty before deleting.
68
- """
69
- owner, name = get_owner_name_from_identifier(slug)
70
- isettings = _connect_instance(owner, name, raise_permission_error=False)
71
- if isettings.dialect != "sqlite":
72
- logger.warning(
73
- f"delete() does not yet affect your Postgres database at {isettings.db}"
74
- )
75
- if isettings.is_on_hub and settings.user.handle == "anonymous":
76
- logger.warning(
77
- "won't delete the hub component of this instance because you're not logged in"
78
- )
79
- if not force:
80
- valid_responses = ["y", "yes"]
81
- user_input = (
82
- input(f"Are you sure you want to delete instance {isettings.slug}? (y/n) ")
83
- .strip()
84
- .lower()
85
- )
86
- if user_input not in valid_responses:
87
- return -1
88
-
89
- # the actual deletion process begins here
90
- if isettings.dialect == "sqlite" and isettings.is_remote:
91
- # delete the exlusion dir first because it's hard to count its objects
92
- delete_exclusion_dir(isettings)
93
- if isettings.storage.type_is_cloud and isettings.storage.root_as_str.startswith(
94
- HOSTED_BUCKETS
95
- ):
96
- if not require_empty:
97
- logger.warning(
98
- "hosted storage always has to be empty, ignoring `require_empty`"
99
- )
100
- require_empty = True
101
- # first the default storage
102
- n_files = check_storage_is_empty(
103
- isettings.storage.root,
104
- raise_error=require_empty,
105
- account_for_sqlite_file=isettings.dialect == "sqlite",
106
- )
107
- if isettings.storage._mark_storage_root.exists():
108
- isettings.storage._mark_storage_root.unlink(
109
- missing_ok=True # this is totally weird, but needed on Py3.11
110
- )
111
- # now everything that's on the hub
112
- if settings.user.handle != "anonymous":
113
- storage_records = get_storage_records_for_instance(isettings._id)
114
- for storage_record in storage_records:
115
- if storage_record["root"] == isettings.storage.root_as_str:
116
- continue
117
- ssettings = StorageSettings(storage_record["root"]) # type: ignore
118
- check_storage_is_empty(
119
- ssettings.root, # type: ignore
120
- raise_error=require_empty,
121
- )
122
- if ssettings._mark_storage_root.exists():
123
- ssettings._mark_storage_root.unlink(
124
- missing_ok=True # this is totally weird, but needed on Py3.11
125
- )
126
- logger.info(f"deleting instance {isettings.slug}")
127
- # below we can skip check_storage_is_empty() because we already called
128
- # it above
129
- if settings.user.handle != "anonymous" and isettings.is_on_hub:
130
- # start with deleting things on the hub
131
- # this will error if the user doesn't have permission
132
- delete_instance_on_hub(isettings._id, require_empty=False)
133
- delete_by_isettings(isettings)
134
- # if lamin.db file was delete, then we might count -1
135
- if n_files <= 0 and isettings.storage.type == "local":
136
- # dir is only empty after sqlite file was delete via delete_by_isettings
137
- if (isettings.storage.root / ".lamindb").exists():
138
- (isettings.storage.root / ".lamindb").rmdir()
139
- if isettings.storage.root.exists():
140
- isettings.storage.root.rmdir()
141
- return None
1
+ from __future__ import annotations
2
+
3
+ import shutil
4
+ from typing import TYPE_CHECKING
5
+ from uuid import UUID
6
+
7
+ from lamin_utils import logger
8
+
9
+ from ._connect_instance import _connect_instance, get_owner_name_from_identifier
10
+ from .core._aws_options import HOSTED_BUCKETS
11
+ from .core._hub_core import delete_instance as delete_instance_on_hub
12
+ from .core._hub_core import get_storage_records_for_instance
13
+ from .core._settings import settings
14
+ from .core._settings_storage import StorageSettings
15
+ from .core.upath import LocalPathClasses, check_storage_is_empty
16
+
17
+ if TYPE_CHECKING:
18
+ from pathlib import Path
19
+
20
+ from .core._settings_instance import InstanceSettings
21
+
22
+
23
+ def delete_cache(isettings: InstanceSettings):
24
+ # avoid init of root
25
+ root = isettings.storage._root_init
26
+ if not isinstance(root, LocalPathClasses):
27
+ cache_dir = settings.cache_dir / root.path
28
+ if cache_dir.exists():
29
+ shutil.rmtree(cache_dir)
30
+
31
+
32
+ def delete_exclusion_dir(isettings: InstanceSettings) -> None:
33
+ exclusion_dir = isettings.storage.root / f".lamindb/_exclusion/{isettings._id.hex}"
34
+ if exclusion_dir.exists():
35
+ exclusion_dir.rmdir()
36
+
37
+
38
+ def delete_by_isettings(isettings: InstanceSettings) -> None:
39
+ settings_file = isettings._get_settings_file()
40
+ if settings_file.exists():
41
+ settings_file.unlink()
42
+ delete_cache(isettings)
43
+ if isettings.dialect == "sqlite":
44
+ try:
45
+ if isettings._sqlite_file.exists():
46
+ isettings._sqlite_file.unlink()
47
+ except PermissionError:
48
+ logger.warning(
49
+ "Did not have permission to delete SQLite file:"
50
+ f" {isettings._sqlite_file}"
51
+ )
52
+ pass
53
+ # unset the global instance settings
54
+ if settings._instance_exists and isettings.slug == settings.instance.slug:
55
+ if settings._instance_settings_path.exists():
56
+ settings._instance_settings_path.unlink()
57
+ settings._instance_settings = None
58
+
59
+
60
+ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int | None:
61
+ """Delete a LaminDB instance.
62
+
63
+ Args:
64
+ slug: The instance slug `account_handle/instance_name` or URL.
65
+ If the instance is owned by you, it suffices to pass the instance name.
66
+ force: Whether to skip the confirmation prompt.
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>`__.
71
+ """
72
+ owner, name = get_owner_name_from_identifier(slug)
73
+ isettings = _connect_instance(owner, name, raise_permission_error=False)
74
+ if isettings.dialect != "sqlite":
75
+ logger.warning(
76
+ f"delete() does not yet affect your Postgres database at {isettings.db}"
77
+ )
78
+ if isettings.is_on_hub and settings.user.handle == "anonymous":
79
+ logger.warning(
80
+ "won't delete the hub component of this instance because you're not logged in"
81
+ )
82
+ if not force:
83
+ valid_responses = ["y", "yes"]
84
+ user_input = (
85
+ input(f"Are you sure you want to delete instance {isettings.slug}? (y/n) ")
86
+ .strip()
87
+ .lower()
88
+ )
89
+ if user_input not in valid_responses:
90
+ return -1
91
+
92
+ # the actual deletion process begins here
93
+ if isettings.dialect == "sqlite" and isettings.is_remote:
94
+ # delete the exlusion dir first because it's hard to count its objects
95
+ delete_exclusion_dir(isettings)
96
+ if isettings.storage.type_is_cloud and isettings.storage.root_as_str.startswith(
97
+ HOSTED_BUCKETS
98
+ ):
99
+ if not require_empty:
100
+ logger.warning(
101
+ "hosted storage always has to be empty, ignoring `require_empty`"
102
+ )
103
+ require_empty = True
104
+ # first the default storage
105
+ n_files = check_storage_is_empty(
106
+ isettings.storage.root,
107
+ raise_error=require_empty,
108
+ account_for_sqlite_file=isettings.dialect == "sqlite",
109
+ )
110
+ if isettings.storage._mark_storage_root.exists():
111
+ isettings.storage._mark_storage_root.unlink(
112
+ missing_ok=True # this is totally weird, but needed on Py3.11
113
+ )
114
+ # now everything that's on the hub
115
+ if settings.user.handle != "anonymous":
116
+ storage_records = get_storage_records_for_instance(isettings._id)
117
+ for storage_record in storage_records:
118
+ if storage_record["root"] == isettings.storage.root_as_str:
119
+ continue
120
+ ssettings = StorageSettings(storage_record["root"]) # type: ignore
121
+ check_storage_is_empty(
122
+ ssettings.root, # type: ignore
123
+ raise_error=require_empty,
124
+ )
125
+ if ssettings._mark_storage_root.exists():
126
+ ssettings._mark_storage_root.unlink(
127
+ missing_ok=True # this is totally weird, but needed on Py3.11
128
+ )
129
+ logger.info(f"deleting instance {isettings.slug}")
130
+ # below we can skip check_storage_is_empty() because we already called
131
+ # it above
132
+ if settings.user.handle != "anonymous" and isettings.is_on_hub:
133
+ # start with deleting things on the hub
134
+ # this will error if the user doesn't have permission
135
+ delete_instance_on_hub(isettings._id, require_empty=False)
136
+ delete_by_isettings(isettings)
137
+ # if lamin.db file was delete, then we might count -1
138
+ if n_files <= 0 and isettings.storage.type == "local":
139
+ # dir is only empty after sqlite file was delete via delete_by_isettings
140
+ if (isettings.storage.root / ".lamindb").exists():
141
+ (isettings.storage.root / ".lamindb").rmdir()
142
+ if isettings.storage.root.exists():
143
+ isettings.storage.root.rmdir()
144
+ return None
@@ -1,32 +1,35 @@
1
- from __future__ import annotations
2
-
3
- from lamin_utils import logger
4
-
5
- from .core._settings import settings
6
- from .core._settings_store import current_instance_settings_file
7
- from .core.cloud_sqlite_locker import clear_locker
8
-
9
-
10
- def disconnect(mute: bool = False) -> None:
11
- """Disconnect an instance.
12
-
13
- Returns `None` if succeeds, otherwise an exception is raised.
14
- """
15
- if current_instance_settings_file().exists():
16
- instance = settings.instance.slug
17
- try:
18
- settings.instance._update_cloud_sqlite_file()
19
- except Exception as e:
20
- if isinstance(e, FileNotFoundError):
21
- logger.warning("did not find local cache file")
22
- elif isinstance(e, PermissionError):
23
- logger.warning("did not upload cache file - not enough permissions")
24
- else:
25
- raise e
26
- current_instance_settings_file().unlink()
27
- clear_locker()
28
- if not mute:
29
- logger.success(f"disconnected instance: {instance}")
30
- else:
31
- if not mute:
32
- logger.info("no instance loaded")
1
+ from __future__ import annotations
2
+
3
+ from lamin_utils import logger
4
+
5
+ from .core._settings import settings
6
+ from .core._settings_store import current_instance_settings_file
7
+ from .core.cloud_sqlite_locker import clear_locker
8
+
9
+
10
+ def disconnect(mute: bool = False) -> None:
11
+ """Clear default instance configuration.
12
+
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>`__.
17
+ """
18
+ if current_instance_settings_file().exists():
19
+ instance = settings.instance.slug
20
+ try:
21
+ settings.instance._update_cloud_sqlite_file()
22
+ except Exception as e:
23
+ if isinstance(e, FileNotFoundError):
24
+ logger.warning("did not find local cache file")
25
+ elif isinstance(e, PermissionError):
26
+ logger.warning("did not upload cache file - not enough permissions")
27
+ else:
28
+ raise e
29
+ current_instance_settings_file().unlink()
30
+ clear_locker()
31
+ if not mute:
32
+ logger.success(f"disconnected instance: {instance}")
33
+ else:
34
+ if not mute:
35
+ logger.info("no instance loaded")