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.
Files changed (39) hide show
  1. lamindb_setup/__init__.py +107 -107
  2. lamindb_setup/_cache.py +87 -87
  3. lamindb_setup/_check_setup.py +166 -166
  4. lamindb_setup/_connect_instance.py +328 -342
  5. lamindb_setup/_delete.py +141 -141
  6. lamindb_setup/_disconnect.py +32 -32
  7. lamindb_setup/_init_instance.py +440 -440
  8. lamindb_setup/_migrate.py +266 -266
  9. lamindb_setup/_register_instance.py +35 -35
  10. lamindb_setup/_schema_metadata.py +441 -441
  11. lamindb_setup/_set_managed_storage.py +70 -70
  12. lamindb_setup/_setup_user.py +133 -133
  13. lamindb_setup/core/__init__.py +21 -21
  14. lamindb_setup/core/_aws_options.py +223 -223
  15. lamindb_setup/core/_hub_client.py +248 -248
  16. lamindb_setup/core/_hub_core.py +665 -665
  17. lamindb_setup/core/_hub_crud.py +227 -227
  18. lamindb_setup/core/_private_django_api.py +83 -83
  19. lamindb_setup/core/_settings.py +377 -377
  20. lamindb_setup/core/_settings_instance.py +569 -569
  21. lamindb_setup/core/_settings_load.py +141 -141
  22. lamindb_setup/core/_settings_save.py +95 -95
  23. lamindb_setup/core/_settings_storage.py +429 -429
  24. lamindb_setup/core/_settings_store.py +91 -91
  25. lamindb_setup/core/_settings_user.py +55 -55
  26. lamindb_setup/core/_setup_bionty_sources.py +44 -44
  27. lamindb_setup/core/cloud_sqlite_locker.py +240 -240
  28. lamindb_setup/core/django.py +305 -296
  29. lamindb_setup/core/exceptions.py +1 -1
  30. lamindb_setup/core/hashing.py +134 -134
  31. lamindb_setup/core/types.py +1 -1
  32. lamindb_setup/core/upath.py +1013 -1013
  33. lamindb_setup/errors.py +70 -70
  34. lamindb_setup/types.py +20 -20
  35. {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/METADATA +1 -1
  36. lamindb_setup-1.9.1.dist-info/RECORD +50 -0
  37. lamindb_setup-1.9.0.dist-info/RECORD +0 -50
  38. {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/LICENSE +0 -0
  39. {lamindb_setup-1.9.0.dist-info → lamindb_setup-1.9.1.dist-info}/WHEEL +0 -0
lamindb_setup/_delete.py CHANGED
@@ -1,141 +1,141 @@
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
+ 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,32 +1,32 @@
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
+ """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")