lamindb_setup 1.18.2__py3-none-any.whl → 1.19.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 +4 -19
- lamindb_setup/_cache.py +87 -87
- lamindb_setup/_check.py +7 -7
- lamindb_setup/_check_setup.py +131 -131
- lamindb_setup/_connect_instance.py +443 -438
- lamindb_setup/_delete.py +155 -151
- lamindb_setup/_disconnect.py +38 -38
- lamindb_setup/_django.py +39 -39
- lamindb_setup/_entry_points.py +19 -19
- lamindb_setup/_init_instance.py +423 -429
- lamindb_setup/_migrate.py +331 -327
- lamindb_setup/_register_instance.py +32 -32
- lamindb_setup/_schema.py +27 -27
- lamindb_setup/_schema_metadata.py +451 -451
- lamindb_setup/_set_managed_storage.py +81 -80
- lamindb_setup/_setup_user.py +198 -198
- lamindb_setup/_silence_loggers.py +46 -46
- lamindb_setup/core/__init__.py +25 -34
- lamindb_setup/core/_aws_options.py +276 -266
- lamindb_setup/core/_aws_storage.py +57 -55
- lamindb_setup/core/_clone.py +50 -50
- lamindb_setup/core/_deprecated.py +62 -62
- lamindb_setup/core/_docs.py +14 -14
- lamindb_setup/core/_hub_client.py +288 -294
- lamindb_setup/core/_hub_core.py +0 -2
- lamindb_setup/core/_hub_crud.py +247 -247
- lamindb_setup/core/_hub_utils.py +100 -100
- lamindb_setup/core/_private_django_api.py +80 -80
- lamindb_setup/core/_settings.py +440 -434
- lamindb_setup/core/_settings_instance.py +32 -7
- lamindb_setup/core/_settings_load.py +162 -159
- lamindb_setup/core/_settings_save.py +108 -96
- lamindb_setup/core/_settings_storage.py +433 -433
- lamindb_setup/core/_settings_store.py +162 -92
- 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 +414 -413
- 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 +1031 -1028
- lamindb_setup/errors.py +72 -70
- lamindb_setup/io.py +423 -416
- lamindb_setup/types.py +17 -17
- {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info}/METADATA +4 -2
- lamindb_setup-1.19.1.dist-info/RECORD +51 -0
- {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info}/WHEEL +1 -1
- {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info/licenses}/LICENSE +201 -201
- lamindb_setup-1.18.2.dist-info/RECORD +0 -51
lamindb_setup/_delete.py
CHANGED
|
@@ -1,151 +1,155 @@
|
|
|
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.
|
|
12
|
-
from .core.
|
|
13
|
-
from .core.
|
|
14
|
-
from .core.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
from
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
isettings.
|
|
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
|
-
|
|
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._settings import settings
|
|
12
|
+
from .core._settings_load import load_instance_settings
|
|
13
|
+
from .core._settings_storage import StorageSettings
|
|
14
|
+
from .core.upath import LocalPathClasses, check_storage_is_empty
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from .core._settings_instance import InstanceSettings
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def delete_cache(isettings: InstanceSettings):
|
|
23
|
+
if isettings.storage is None:
|
|
24
|
+
return
|
|
25
|
+
# avoid init of root
|
|
26
|
+
root = isettings.storage._root_init
|
|
27
|
+
if not isinstance(root, LocalPathClasses):
|
|
28
|
+
cache_dir = settings.cache_dir / root.path
|
|
29
|
+
if cache_dir.exists():
|
|
30
|
+
shutil.rmtree(cache_dir)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def delete_exclusion_dir(isettings: InstanceSettings) -> None:
|
|
34
|
+
exclusion_dir = isettings.storage.root / f".lamindb/_exclusion/{isettings._id.hex}"
|
|
35
|
+
if exclusion_dir.exists():
|
|
36
|
+
exclusion_dir.rmdir()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def delete_by_isettings(isettings: InstanceSettings) -> None:
|
|
40
|
+
assert isettings.slug != "none/none"
|
|
41
|
+
|
|
42
|
+
settings_file = isettings._get_settings_file()
|
|
43
|
+
if settings_file.exists():
|
|
44
|
+
settings_file.unlink()
|
|
45
|
+
delete_cache(isettings)
|
|
46
|
+
if isettings.dialect == "sqlite" and isettings.storage is not None:
|
|
47
|
+
try:
|
|
48
|
+
if isettings._sqlite_file.exists():
|
|
49
|
+
isettings._sqlite_file.unlink()
|
|
50
|
+
except PermissionError:
|
|
51
|
+
logger.warning(
|
|
52
|
+
"Did not have permission to delete SQLite file:"
|
|
53
|
+
f" {isettings._sqlite_file}"
|
|
54
|
+
)
|
|
55
|
+
# unset the global instance settings
|
|
56
|
+
isettings_on_disk = load_instance_settings()
|
|
57
|
+
if isettings_on_disk.slug == isettings.slug:
|
|
58
|
+
settings._instance_settings_path.unlink() # current instance settings file
|
|
59
|
+
# settings.instance can differ from instance in current_settings_file()
|
|
60
|
+
# due to connect() in the same process
|
|
61
|
+
if settings.instance.slug == isettings.slug:
|
|
62
|
+
settings._instance_settings = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def delete(slug: str, force: bool = False, require_empty: bool = True) -> int | None:
|
|
66
|
+
"""Delete a LaminDB instance.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
slug: The instance slug `account_handle/instance_name` or URL.
|
|
70
|
+
If the instance is owned by you, it suffices to pass the instance name.
|
|
71
|
+
force: Whether to skip the confirmation prompt.
|
|
72
|
+
require_empty: Whether to check if the instance is empty before deleting.
|
|
73
|
+
|
|
74
|
+
See Also:
|
|
75
|
+
Delete an instance via the CLI, see `here <https://docs.lamin.ai/cli#delete>`__.
|
|
76
|
+
"""
|
|
77
|
+
owner, name = get_owner_name_from_identifier(slug)
|
|
78
|
+
isettings = _connect_instance(owner, name, raise_permission_error=False)
|
|
79
|
+
if isettings.dialect != "sqlite":
|
|
80
|
+
logger.warning(
|
|
81
|
+
f"delete() does not yet affect your Postgres database at {isettings.db}"
|
|
82
|
+
)
|
|
83
|
+
if isettings.is_on_hub and settings.user.handle == "anonymous":
|
|
84
|
+
logger.warning(
|
|
85
|
+
"won't delete the hub component of this instance because you're not logged in"
|
|
86
|
+
)
|
|
87
|
+
if not force:
|
|
88
|
+
valid_responses = ["y", "yes"]
|
|
89
|
+
user_input = (
|
|
90
|
+
input(f"Are you sure you want to delete instance {isettings.slug}? (y/n) ")
|
|
91
|
+
.strip()
|
|
92
|
+
.lower()
|
|
93
|
+
)
|
|
94
|
+
if user_input not in valid_responses:
|
|
95
|
+
return -1
|
|
96
|
+
|
|
97
|
+
# the actual deletion process begins here
|
|
98
|
+
if isettings.dialect == "sqlite" and isettings.is_remote:
|
|
99
|
+
# delete the exlusion dir first because it's hard to count its objects
|
|
100
|
+
delete_exclusion_dir(isettings)
|
|
101
|
+
if isettings.storage.type_is_cloud and isettings.storage.root_as_str.startswith(
|
|
102
|
+
HOSTED_BUCKETS
|
|
103
|
+
):
|
|
104
|
+
if not require_empty:
|
|
105
|
+
logger.warning(
|
|
106
|
+
"hosted storage always has to be empty, ignoring `require_empty`"
|
|
107
|
+
)
|
|
108
|
+
require_empty = True
|
|
109
|
+
# first the default storage
|
|
110
|
+
n_files = check_storage_is_empty(
|
|
111
|
+
isettings.storage.root,
|
|
112
|
+
raise_error=require_empty,
|
|
113
|
+
account_for_sqlite_file=isettings.dialect == "sqlite",
|
|
114
|
+
)
|
|
115
|
+
if isettings.storage._mark_storage_root.exists():
|
|
116
|
+
isettings.storage._mark_storage_root.unlink(
|
|
117
|
+
missing_ok=True # this is totally weird, but needed on Py3.11
|
|
118
|
+
)
|
|
119
|
+
# now everything that's on the hub
|
|
120
|
+
if settings.user.handle != "anonymous":
|
|
121
|
+
# dynamic import to avoid importing hub logic at root
|
|
122
|
+
from .core._hub_core import get_storage_records_for_instance
|
|
123
|
+
|
|
124
|
+
storage_records = get_storage_records_for_instance(isettings._id)
|
|
125
|
+
for storage_record in storage_records:
|
|
126
|
+
if storage_record["root"] == isettings.storage.root_as_str:
|
|
127
|
+
continue
|
|
128
|
+
ssettings = StorageSettings(storage_record["root"]) # type: ignore
|
|
129
|
+
check_storage_is_empty(
|
|
130
|
+
ssettings.root, # type: ignore
|
|
131
|
+
raise_error=require_empty,
|
|
132
|
+
)
|
|
133
|
+
if ssettings._mark_storage_root.exists():
|
|
134
|
+
ssettings._mark_storage_root.unlink(
|
|
135
|
+
missing_ok=True # this is totally weird, but needed on Py3.11
|
|
136
|
+
)
|
|
137
|
+
logger.info(f"deleting instance {isettings.slug}")
|
|
138
|
+
# below we can skip check_storage_is_empty() because we already called
|
|
139
|
+
# it above
|
|
140
|
+
if settings.user.handle != "anonymous" and isettings.is_on_hub:
|
|
141
|
+
# start with deleting things on the hub
|
|
142
|
+
# this will error if the user doesn't have permission
|
|
143
|
+
# dynamic import to avoid importing hub logic at root
|
|
144
|
+
from .core._hub_core import delete_instance
|
|
145
|
+
|
|
146
|
+
delete_instance(isettings._id, require_empty=False)
|
|
147
|
+
delete_by_isettings(isettings)
|
|
148
|
+
# if lamin.db file was delete, then we might count -1
|
|
149
|
+
if n_files <= 0 and isettings.storage.type == "local":
|
|
150
|
+
# dir is only empty after sqlite file was delete via delete_by_isettings
|
|
151
|
+
if (isettings.storage.root / ".lamindb").exists():
|
|
152
|
+
(isettings.storage.root / ".lamindb").rmdir()
|
|
153
|
+
if isettings.storage.root.exists():
|
|
154
|
+
isettings.storage.root.rmdir()
|
|
155
|
+
return None
|
lamindb_setup/_disconnect.py
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from lamin_utils import logger
|
|
4
|
-
|
|
5
|
-
from .core._settings import settings
|
|
6
|
-
from .core._settings_load import load_instance_settings
|
|
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
|
-
# settings._instance_exists can be true due to connect even without having a file
|
|
19
|
-
if settings._instance_exists:
|
|
20
|
-
instance = settings.instance
|
|
21
|
-
try:
|
|
22
|
-
instance._update_cloud_sqlite_file()
|
|
23
|
-
except Exception as e:
|
|
24
|
-
if isinstance(e, FileNotFoundError):
|
|
25
|
-
logger.warning("did not find local cache file")
|
|
26
|
-
elif isinstance(e, PermissionError):
|
|
27
|
-
logger.warning("did not upload cache file - not enough permissions")
|
|
28
|
-
else:
|
|
29
|
-
raise e
|
|
30
|
-
clear_locker()
|
|
31
|
-
# instance in current instance file can differ from instance in settings
|
|
32
|
-
if load_instance_settings().slug == instance.slug:
|
|
33
|
-
settings._instance_settings_path.unlink(missing_ok=True)
|
|
34
|
-
settings._instance_settings = None
|
|
35
|
-
if not mute:
|
|
36
|
-
logger.success(f"disconnected instance: {instance.slug}")
|
|
37
|
-
elif not mute:
|
|
38
|
-
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_load import load_instance_settings
|
|
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
|
+
# settings._instance_exists can be true due to connect even without having a file
|
|
19
|
+
if settings._instance_exists:
|
|
20
|
+
instance = settings.instance
|
|
21
|
+
try:
|
|
22
|
+
instance._update_cloud_sqlite_file()
|
|
23
|
+
except Exception as e:
|
|
24
|
+
if isinstance(e, FileNotFoundError):
|
|
25
|
+
logger.warning("did not find local cache file")
|
|
26
|
+
elif isinstance(e, PermissionError):
|
|
27
|
+
logger.warning("did not upload cache file - not enough permissions")
|
|
28
|
+
else:
|
|
29
|
+
raise e
|
|
30
|
+
clear_locker()
|
|
31
|
+
# instance in current instance file can differ from instance in settings
|
|
32
|
+
if load_instance_settings().slug == instance.slug:
|
|
33
|
+
settings._instance_settings_path.unlink(missing_ok=True)
|
|
34
|
+
settings._instance_settings = None
|
|
35
|
+
if not mute:
|
|
36
|
+
logger.success(f"disconnected instance: {instance.slug}")
|
|
37
|
+
elif not mute:
|
|
38
|
+
logger.info("no instance loaded")
|
lamindb_setup/_django.py
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from .core._settings import settings
|
|
4
|
-
from .core.django import setup_django
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def django(command: str, package_name: str | None = None, **kwargs):
|
|
8
|
-
r"""Call Django commands.
|
|
9
|
-
|
|
10
|
-
Examples:
|
|
11
|
-
|
|
12
|
-
Reset auto-incrementing primary integer ids after a database import:
|
|
13
|
-
|
|
14
|
-
>>> import lamindb as ln
|
|
15
|
-
>>> ln.setup.django("sqlsequencereset", "lamindb")
|
|
16
|
-
BEGIN;
|
|
17
|
-
SELECT setval(pg_get_serial_sequence('"lamindb_user"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_user"; # noqa
|
|
18
|
-
SELECT setval(pg_get_serial_sequence('"lamindb_storage"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_storage"; # noqa
|
|
19
|
-
COMMIT;
|
|
20
|
-
|
|
21
|
-
You can then run the SQL output that you'll see like so:
|
|
22
|
-
|
|
23
|
-
>>> sql = \"\"\"BEGIN;
|
|
24
|
-
SELECT setval(pg_get_serial_sequence('"lamindb_user"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_user"; # noqa
|
|
25
|
-
SELECT setval(pg_get_serial_sequence('"lamindb_storage"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_storage"; # noqa
|
|
26
|
-
COMMIT;\"\"\"
|
|
27
|
-
>>> from django.db import connection
|
|
28
|
-
>>> with connection.cursor() as cursor:
|
|
29
|
-
cursor.execute(sql)
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
from django.core.management import call_command
|
|
33
|
-
|
|
34
|
-
setup_django(settings.instance)
|
|
35
|
-
if package_name is not None:
|
|
36
|
-
args = [package_name]
|
|
37
|
-
else:
|
|
38
|
-
args = []
|
|
39
|
-
call_command(command, *args, **kwargs)
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .core._settings import settings
|
|
4
|
+
from .core.django import setup_django
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def django(command: str, package_name: str | None = None, **kwargs):
|
|
8
|
+
r"""Call Django commands.
|
|
9
|
+
|
|
10
|
+
Examples:
|
|
11
|
+
|
|
12
|
+
Reset auto-incrementing primary integer ids after a database import:
|
|
13
|
+
|
|
14
|
+
>>> import lamindb as ln
|
|
15
|
+
>>> ln.setup.django("sqlsequencereset", "lamindb")
|
|
16
|
+
BEGIN;
|
|
17
|
+
SELECT setval(pg_get_serial_sequence('"lamindb_user"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_user"; # noqa
|
|
18
|
+
SELECT setval(pg_get_serial_sequence('"lamindb_storage"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_storage"; # noqa
|
|
19
|
+
COMMIT;
|
|
20
|
+
|
|
21
|
+
You can then run the SQL output that you'll see like so:
|
|
22
|
+
|
|
23
|
+
>>> sql = \"\"\"BEGIN;
|
|
24
|
+
SELECT setval(pg_get_serial_sequence('"lamindb_user"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_user"; # noqa
|
|
25
|
+
SELECT setval(pg_get_serial_sequence('"lamindb_storage"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "lamindb_storage"; # noqa
|
|
26
|
+
COMMIT;\"\"\"
|
|
27
|
+
>>> from django.db import connection
|
|
28
|
+
>>> with connection.cursor() as cursor:
|
|
29
|
+
cursor.execute(sql)
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
from django.core.management import call_command
|
|
33
|
+
|
|
34
|
+
setup_django(settings.instance)
|
|
35
|
+
if package_name is not None:
|
|
36
|
+
args = [package_name]
|
|
37
|
+
else:
|
|
38
|
+
args = []
|
|
39
|
+
call_command(command, *args, **kwargs)
|
lamindb_setup/_entry_points.py
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import warnings
|
|
3
|
-
from importlib.metadata import entry_points
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def call_registered_entry_points(group, **kwargs):
|
|
7
|
-
"""load and call entry points registered under group."""
|
|
8
|
-
eps = entry_points(group=group)
|
|
9
|
-
|
|
10
|
-
for ep in eps:
|
|
11
|
-
func = ep.load()
|
|
12
|
-
try:
|
|
13
|
-
func(**kwargs)
|
|
14
|
-
except BaseException as e:
|
|
15
|
-
warnings.warn(
|
|
16
|
-
f"Error loading entry point of group {group!r}: {ep} -> {e}",
|
|
17
|
-
RuntimeWarning,
|
|
18
|
-
stacklevel=2,
|
|
19
|
-
)
|
|
1
|
+
import sys
|
|
2
|
+
import warnings
|
|
3
|
+
from importlib.metadata import entry_points
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def call_registered_entry_points(group, **kwargs):
|
|
7
|
+
"""load and call entry points registered under group."""
|
|
8
|
+
eps = entry_points(group=group)
|
|
9
|
+
|
|
10
|
+
for ep in eps:
|
|
11
|
+
func = ep.load()
|
|
12
|
+
try:
|
|
13
|
+
func(**kwargs)
|
|
14
|
+
except BaseException as e:
|
|
15
|
+
warnings.warn(
|
|
16
|
+
f"Error loading entry point of group {group!r}: {ep} -> {e}",
|
|
17
|
+
RuntimeWarning,
|
|
18
|
+
stacklevel=2,
|
|
19
|
+
)
|