lamindb_setup 0.77.1__py2.py3-none-any.whl → 0.77.3__py2.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 (48) hide show
  1. lamindb_setup/__init__.py +1 -1
  2. lamindb_setup/_cache.py +34 -34
  3. lamindb_setup/_check.py +7 -7
  4. lamindb_setup/_check_setup.py +79 -79
  5. lamindb_setup/_close.py +35 -35
  6. lamindb_setup/_connect_instance.py +444 -440
  7. lamindb_setup/_delete.py +139 -137
  8. lamindb_setup/_django.py +41 -41
  9. lamindb_setup/_entry_points.py +22 -22
  10. lamindb_setup/_exportdb.py +68 -68
  11. lamindb_setup/_importdb.py +50 -50
  12. lamindb_setup/_init_instance.py +374 -374
  13. lamindb_setup/_migrate.py +239 -239
  14. lamindb_setup/_register_instance.py +36 -36
  15. lamindb_setup/_schema.py +27 -27
  16. lamindb_setup/_schema_metadata.py +411 -411
  17. lamindb_setup/_set_managed_storage.py +55 -55
  18. lamindb_setup/_setup_user.py +137 -134
  19. lamindb_setup/_silence_loggers.py +44 -44
  20. lamindb_setup/core/__init__.py +21 -21
  21. lamindb_setup/core/_aws_credentials.py +151 -151
  22. lamindb_setup/core/_aws_storage.py +48 -48
  23. lamindb_setup/core/_deprecated.py +55 -55
  24. lamindb_setup/core/_docs.py +14 -14
  25. lamindb_setup/core/_hub_client.py +1 -1
  26. lamindb_setup/core/_hub_core.py +590 -524
  27. lamindb_setup/core/_hub_crud.py +211 -211
  28. lamindb_setup/core/_hub_utils.py +109 -109
  29. lamindb_setup/core/_private_django_api.py +88 -88
  30. lamindb_setup/core/_settings.py +138 -138
  31. lamindb_setup/core/_settings_instance.py +467 -461
  32. lamindb_setup/core/_settings_load.py +105 -105
  33. lamindb_setup/core/_settings_save.py +81 -81
  34. lamindb_setup/core/_settings_storage.py +405 -393
  35. lamindb_setup/core/_settings_store.py +75 -73
  36. lamindb_setup/core/_settings_user.py +53 -53
  37. lamindb_setup/core/_setup_bionty_sources.py +101 -101
  38. lamindb_setup/core/cloud_sqlite_locker.py +232 -232
  39. lamindb_setup/core/django.py +114 -113
  40. lamindb_setup/core/exceptions.py +12 -12
  41. lamindb_setup/core/hashing.py +114 -114
  42. lamindb_setup/core/types.py +19 -19
  43. lamindb_setup/core/upath.py +779 -779
  44. {lamindb_setup-0.77.1.dist-info → lamindb_setup-0.77.3.dist-info}/METADATA +1 -1
  45. lamindb_setup-0.77.3.dist-info/RECORD +47 -0
  46. {lamindb_setup-0.77.1.dist-info → lamindb_setup-0.77.3.dist-info}/WHEEL +1 -1
  47. lamindb_setup-0.77.1.dist-info/RECORD +0 -47
  48. {lamindb_setup-0.77.1.dist-info → lamindb_setup-0.77.3.dist-info}/LICENSE +0 -0
lamindb_setup/_migrate.py CHANGED
@@ -1,239 +1,239 @@
1
- from __future__ import annotations
2
-
3
- from django.db import connection
4
- from django.db.migrations.loader import MigrationLoader
5
- from lamin_utils import logger
6
- from packaging import version
7
-
8
- from ._check_setup import _check_instance_setup
9
- from .core._settings import settings
10
- from .core.django import setup_django
11
-
12
-
13
- # for the django-based synching code, see laminhub_rest
14
- def check_whether_migrations_in_sync(db_version_str: str):
15
- from importlib import metadata
16
-
17
- try:
18
- installed_version_str = metadata.version("lamindb")
19
- except metadata.PackageNotFoundError:
20
- return None
21
- if db_version_str is None:
22
- logger.warning("no lamindb version stored to compare with installed version")
23
- return None
24
- installed_version = version.parse(installed_version_str)
25
- db_version = version.parse(db_version_str)
26
- if (
27
- installed_version.major < db_version.major
28
- or installed_version.minor < db_version.minor
29
- ):
30
- db_version_lower = f"{db_version.major}.{db_version.minor}"
31
- db_version_upper = f"{db_version.major}.{db_version.minor + 1}"
32
- logger.warning(
33
- f"your database ({db_version_str}) is ahead of your installed lamindb"
34
- f" package ({installed_version_str})"
35
- )
36
- logger.important(
37
- "please update lamindb: pip install"
38
- f' "lamindb>={db_version_lower},<{db_version_upper}"'
39
- )
40
- elif (
41
- installed_version.major > db_version.major
42
- or installed_version.minor > db_version.minor
43
- ):
44
- logger.warning(
45
- f"your database ({db_version_str}) is behind your installed lamindb package"
46
- f" ({installed_version_str})"
47
- )
48
- logger.important("please migrate your database: lamin migrate deploy")
49
-
50
-
51
- # for tests, see lamin-cli
52
- class migrate:
53
- """Manage migrations.
54
-
55
- Examples:
56
-
57
- >>> import lamindb as ln
58
- >>> ln.setup.migrate.create()
59
- >>> ln.setup.migrate.deploy()
60
- >>> ln.setup.migrate.check()
61
-
62
- """
63
-
64
- @classmethod
65
- def create(cls) -> None:
66
- """Create a migration."""
67
- if _check_instance_setup():
68
- raise RuntimeError("Restart Python session to create migration or use CLI!")
69
- setup_django(settings.instance, create_migrations=True)
70
-
71
- @classmethod
72
- def deploy(cls) -> None:
73
- """Deploy a migration."""
74
- from ._schema_metadata import update_schema_in_hub
75
-
76
- if _check_instance_setup():
77
- raise RuntimeError("Restart Python session to migrate or use CLI!")
78
- from lamindb_setup.core._hub_client import call_with_fallback_auth
79
- from lamindb_setup.core._hub_crud import (
80
- select_collaborator,
81
- update_instance,
82
- )
83
-
84
- if settings.instance.is_on_hub:
85
- # double check that user is an admin, otherwise will fail below
86
- # due to insufficient SQL permissions with cryptic error
87
- collaborator = call_with_fallback_auth(
88
- select_collaborator,
89
- instance_id=settings.instance._id,
90
- account_id=settings.user._uuid,
91
- )
92
- if collaborator is None or collaborator["role"] != "admin":
93
- raise SystemExit(
94
- "❌ Only admins can deploy migrations, please ensure that you're an"
95
- f" admin: https://lamin.ai/{settings.instance.slug}/settings"
96
- )
97
- # we need lamindb to be installed, otherwise we can't populate the version
98
- # information in the hub
99
- import lamindb
100
-
101
- # this sets up django and deploys the migrations
102
- setup_django(settings.instance, deploy_migrations=True)
103
- # this populates the hub
104
- if settings.instance.is_on_hub:
105
- logger.important(f"updating lamindb version in hub: {lamindb.__version__}")
106
- # TODO: integrate update of instance table within update_schema_in_hub & below
107
- if settings.instance.dialect != "sqlite":
108
- update_schema_in_hub()
109
- call_with_fallback_auth(
110
- update_instance,
111
- instance_id=settings.instance._id.hex,
112
- instance_fields={"lamindb_version": lamindb.__version__},
113
- )
114
-
115
- @classmethod
116
- def check(cls) -> bool:
117
- """Check whether Registry definitions are in sync with migrations."""
118
- from django.core.management import call_command
119
-
120
- setup_django(settings.instance)
121
- try:
122
- call_command("makemigrations", check_changes=True)
123
- except SystemExit:
124
- logger.error(
125
- "migrations are not in sync with ORMs, please create a migration: lamin"
126
- " migrate create"
127
- )
128
- return False
129
- return True
130
-
131
- @classmethod
132
- def squash(
133
- cls, package_name, migration_nr, start_migration_nr: str | None = None
134
- ) -> None:
135
- """Squash migrations."""
136
- from django.core.management import call_command
137
-
138
- setup_django(settings.instance)
139
- if start_migration_nr is not None:
140
- call_command(
141
- "squashmigrations", package_name, start_migration_nr, migration_nr
142
- )
143
- else:
144
- call_command("squashmigrations", package_name, migration_nr)
145
-
146
- @classmethod
147
- def show(cls) -> None:
148
- """Show migrations."""
149
- from django.core.management import call_command
150
-
151
- setup_django(settings.instance)
152
- call_command("showmigrations")
153
-
154
- @classmethod
155
- def defined_migrations(cls, latest: bool = False):
156
- from io import StringIO
157
-
158
- from django.core.management import call_command
159
-
160
- def parse_migration_output(output):
161
- """Parse the output of the showmigrations command to get migration names."""
162
- lines = output.splitlines()
163
-
164
- # Initialize an empty dict to store migration names of each module
165
- migration_names = {}
166
-
167
- # Process each line
168
- for line in lines:
169
- if " " not in line:
170
- # CLI displays the module name in bold
171
- name = line.strip().replace("\x1b[1m", "")
172
- migration_names[name] = []
173
- continue
174
- # Strip whitespace and split the line into status and migration name
175
- migration_name = line.strip().split("] ")[-1].split(" ")[0]
176
- # The second part is the migration name
177
- migration_names[name].append(migration_name)
178
-
179
- return migration_names
180
-
181
- out = StringIO()
182
- call_command("showmigrations", stdout=out)
183
- out.seek(0)
184
- output = out.getvalue()
185
- if latest:
186
- return {k: v[-1] for k, v in parse_migration_output(output).items()}
187
- else:
188
- return parse_migration_output(output)
189
-
190
- @classmethod
191
- def deployed_migrations(cls, latest: bool = False):
192
- """Get the list of deployed migrations from Migration table in DB."""
193
- if latest:
194
- latest_migrations = {}
195
- with connection.cursor() as cursor:
196
- # query to get the latest migration for each app that is not squashed
197
- cursor.execute(
198
- """
199
- SELECT app, name
200
- FROM django_migrations
201
- WHERE id IN (
202
- SELECT MAX(id)
203
- FROM django_migrations
204
- WHERE name NOT LIKE '%%_squashed_%%'
205
- GROUP BY app
206
- )
207
- """
208
- )
209
- # fetch all the results
210
- for app, name in cursor.fetchall():
211
- latest_migrations[app] = name
212
-
213
- return latest_migrations
214
- else:
215
- # Load all migrations using Django's migration loader
216
- loader = MigrationLoader(connection)
217
- squashed_replacements = set()
218
- for _key, migration in loader.disk_migrations.items():
219
- if hasattr(migration, "replaces"):
220
- squashed_replacements.update(migration.replaces)
221
-
222
- deployed_migrations: dict = {}
223
- with connection.cursor() as cursor:
224
- cursor.execute(
225
- """
226
- SELECT app, name, deployed
227
- FROM django_migrations
228
- ORDER BY app, deployed DESC
229
- """
230
- )
231
- for app, name, _deployed in cursor.fetchall():
232
- # skip migrations that are part of a squashed migration
233
- if (app, name) in squashed_replacements:
234
- continue
235
-
236
- if app not in deployed_migrations:
237
- deployed_migrations[app] = []
238
- deployed_migrations[app].append(name)
239
- return deployed_migrations
1
+ from __future__ import annotations
2
+
3
+ from django.db import connection
4
+ from django.db.migrations.loader import MigrationLoader
5
+ from lamin_utils import logger
6
+ from packaging import version
7
+
8
+ from ._check_setup import _check_instance_setup
9
+ from .core._settings import settings
10
+ from .core.django import setup_django
11
+
12
+
13
+ # for the django-based synching code, see laminhub_rest
14
+ def check_whether_migrations_in_sync(db_version_str: str):
15
+ from importlib import metadata
16
+
17
+ try:
18
+ installed_version_str = metadata.version("lamindb")
19
+ except metadata.PackageNotFoundError:
20
+ return None
21
+ if db_version_str is None:
22
+ logger.warning("no lamindb version stored to compare with installed version")
23
+ return None
24
+ installed_version = version.parse(installed_version_str)
25
+ db_version = version.parse(db_version_str)
26
+ if (
27
+ installed_version.major < db_version.major
28
+ or installed_version.minor < db_version.minor
29
+ ):
30
+ db_version_lower = f"{db_version.major}.{db_version.minor}"
31
+ db_version_upper = f"{db_version.major}.{db_version.minor + 1}"
32
+ logger.warning(
33
+ f"your database ({db_version_str}) is ahead of your installed lamindb"
34
+ f" package ({installed_version_str})"
35
+ )
36
+ logger.important(
37
+ "please update lamindb: pip install"
38
+ f' "lamindb>={db_version_lower},<{db_version_upper}"'
39
+ )
40
+ elif (
41
+ installed_version.major > db_version.major
42
+ or installed_version.minor > db_version.minor
43
+ ):
44
+ logger.warning(
45
+ f"your database ({db_version_str}) is behind your installed lamindb package"
46
+ f" ({installed_version_str})"
47
+ )
48
+ logger.important("please migrate your database: lamin migrate deploy")
49
+
50
+
51
+ # for tests, see lamin-cli
52
+ class migrate:
53
+ """Manage migrations.
54
+
55
+ Examples:
56
+
57
+ >>> import lamindb as ln
58
+ >>> ln.setup.migrate.create()
59
+ >>> ln.setup.migrate.deploy()
60
+ >>> ln.setup.migrate.check()
61
+
62
+ """
63
+
64
+ @classmethod
65
+ def create(cls) -> None:
66
+ """Create a migration."""
67
+ if _check_instance_setup():
68
+ raise RuntimeError("Restart Python session to create migration or use CLI!")
69
+ setup_django(settings.instance, create_migrations=True)
70
+
71
+ @classmethod
72
+ def deploy(cls) -> None:
73
+ """Deploy a migration."""
74
+ from ._schema_metadata import update_schema_in_hub
75
+
76
+ if _check_instance_setup():
77
+ raise RuntimeError("Restart Python session to migrate or use CLI!")
78
+ from lamindb_setup.core._hub_client import call_with_fallback_auth
79
+ from lamindb_setup.core._hub_crud import (
80
+ select_collaborator,
81
+ update_instance,
82
+ )
83
+
84
+ if settings.instance.is_on_hub:
85
+ # double check that user is an admin, otherwise will fail below
86
+ # due to insufficient SQL permissions with cryptic error
87
+ collaborator = call_with_fallback_auth(
88
+ select_collaborator,
89
+ instance_id=settings.instance._id,
90
+ account_id=settings.user._uuid,
91
+ )
92
+ if collaborator is None or collaborator["role"] != "admin":
93
+ raise SystemExit(
94
+ "❌ Only admins can deploy migrations, please ensure that you're an"
95
+ f" admin: https://lamin.ai/{settings.instance.slug}/settings"
96
+ )
97
+ # we need lamindb to be installed, otherwise we can't populate the version
98
+ # information in the hub
99
+ import lamindb
100
+
101
+ # this sets up django and deploys the migrations
102
+ setup_django(settings.instance, deploy_migrations=True)
103
+ # this populates the hub
104
+ if settings.instance.is_on_hub:
105
+ logger.important(f"updating lamindb version in hub: {lamindb.__version__}")
106
+ # TODO: integrate update of instance table within update_schema_in_hub & below
107
+ if settings.instance.dialect != "sqlite":
108
+ update_schema_in_hub()
109
+ call_with_fallback_auth(
110
+ update_instance,
111
+ instance_id=settings.instance._id.hex,
112
+ instance_fields={"lamindb_version": lamindb.__version__},
113
+ )
114
+
115
+ @classmethod
116
+ def check(cls) -> bool:
117
+ """Check whether Registry definitions are in sync with migrations."""
118
+ from django.core.management import call_command
119
+
120
+ setup_django(settings.instance)
121
+ try:
122
+ call_command("makemigrations", check_changes=True)
123
+ except SystemExit:
124
+ logger.error(
125
+ "migrations are not in sync with ORMs, please create a migration: lamin"
126
+ " migrate create"
127
+ )
128
+ return False
129
+ return True
130
+
131
+ @classmethod
132
+ def squash(
133
+ cls, package_name, migration_nr, start_migration_nr: str | None = None
134
+ ) -> None:
135
+ """Squash migrations."""
136
+ from django.core.management import call_command
137
+
138
+ setup_django(settings.instance)
139
+ if start_migration_nr is not None:
140
+ call_command(
141
+ "squashmigrations", package_name, start_migration_nr, migration_nr
142
+ )
143
+ else:
144
+ call_command("squashmigrations", package_name, migration_nr)
145
+
146
+ @classmethod
147
+ def show(cls) -> None:
148
+ """Show migrations."""
149
+ from django.core.management import call_command
150
+
151
+ setup_django(settings.instance)
152
+ call_command("showmigrations")
153
+
154
+ @classmethod
155
+ def defined_migrations(cls, latest: bool = False):
156
+ from io import StringIO
157
+
158
+ from django.core.management import call_command
159
+
160
+ def parse_migration_output(output):
161
+ """Parse the output of the showmigrations command to get migration names."""
162
+ lines = output.splitlines()
163
+
164
+ # Initialize an empty dict to store migration names of each module
165
+ migration_names = {}
166
+
167
+ # Process each line
168
+ for line in lines:
169
+ if " " not in line:
170
+ # CLI displays the module name in bold
171
+ name = line.strip().replace("\x1b[1m", "")
172
+ migration_names[name] = []
173
+ continue
174
+ # Strip whitespace and split the line into status and migration name
175
+ migration_name = line.strip().split("] ")[-1].split(" ")[0]
176
+ # The second part is the migration name
177
+ migration_names[name].append(migration_name)
178
+
179
+ return migration_names
180
+
181
+ out = StringIO()
182
+ call_command("showmigrations", stdout=out)
183
+ out.seek(0)
184
+ output = out.getvalue()
185
+ if latest:
186
+ return {k: v[-1] for k, v in parse_migration_output(output).items()}
187
+ else:
188
+ return parse_migration_output(output)
189
+
190
+ @classmethod
191
+ def deployed_migrations(cls, latest: bool = False):
192
+ """Get the list of deployed migrations from Migration table in DB."""
193
+ if latest:
194
+ latest_migrations = {}
195
+ with connection.cursor() as cursor:
196
+ # query to get the latest migration for each app that is not squashed
197
+ cursor.execute(
198
+ """
199
+ SELECT app, name
200
+ FROM django_migrations
201
+ WHERE id IN (
202
+ SELECT MAX(id)
203
+ FROM django_migrations
204
+ WHERE name NOT LIKE '%%_squashed_%%'
205
+ GROUP BY app
206
+ )
207
+ """
208
+ )
209
+ # fetch all the results
210
+ for app, name in cursor.fetchall():
211
+ latest_migrations[app] = name
212
+
213
+ return latest_migrations
214
+ else:
215
+ # Load all migrations using Django's migration loader
216
+ loader = MigrationLoader(connection)
217
+ squashed_replacements = set()
218
+ for _key, migration in loader.disk_migrations.items():
219
+ if hasattr(migration, "replaces"):
220
+ squashed_replacements.update(migration.replaces)
221
+
222
+ deployed_migrations: dict = {}
223
+ with connection.cursor() as cursor:
224
+ cursor.execute(
225
+ """
226
+ SELECT app, name, deployed
227
+ FROM django_migrations
228
+ ORDER BY app, deployed DESC
229
+ """
230
+ )
231
+ for app, name, _deployed in cursor.fetchall():
232
+ # skip migrations that are part of a squashed migration
233
+ if (app, name) in squashed_replacements:
234
+ continue
235
+
236
+ if app not in deployed_migrations:
237
+ deployed_migrations[app] = []
238
+ deployed_migrations[app].append(name)
239
+ return deployed_migrations
@@ -1,36 +1,36 @@
1
- from __future__ import annotations
2
-
3
- from lamin_utils import logger
4
-
5
- from .core._settings import settings
6
- from .core._settings_storage import base62
7
- from .core.django import setup_django
8
-
9
-
10
- def register(_test: bool = False):
11
- """Register an instance on the hub."""
12
- from ._check_setup import _check_instance_setup
13
- from .core._hub_core import init_instance as init_instance_hub
14
- from .core._hub_core import init_storage as init_storage_hub
15
-
16
- logger.warning("""lamin register will be removed soon""")
17
-
18
- isettings = settings.instance
19
- if not _check_instance_setup() and not _test:
20
- setup_django(isettings)
21
-
22
- ssettings = settings.instance.storage
23
- if ssettings._uid is None and _test:
24
- # because django isn't up, we can't get it from the database
25
- ssettings._uid = base62(8)
26
- # cannot yet populate the instance id here
27
- ssettings._instance_id = None
28
- # flag auto_populate_instance can be removed once FK migration is over
29
- init_storage_hub(ssettings, auto_populate_instance=False)
30
- init_instance_hub(isettings)
31
- isettings._is_on_hub = True
32
- isettings._persist()
33
- if isettings.dialect != "sqlite" and not _test:
34
- from ._schema_metadata import update_schema_in_hub
35
-
36
- update_schema_in_hub()
1
+ from __future__ import annotations
2
+
3
+ from lamin_utils import logger
4
+
5
+ from .core._settings import settings
6
+ from .core._settings_storage import base62
7
+ from .core.django import setup_django
8
+
9
+
10
+ def register(_test: bool = False):
11
+ """Register an instance on the hub."""
12
+ from ._check_setup import _check_instance_setup
13
+ from .core._hub_core import init_instance as init_instance_hub
14
+ from .core._hub_core import init_storage as init_storage_hub
15
+
16
+ logger.warning("""lamin register will be removed soon""")
17
+
18
+ isettings = settings.instance
19
+ if not _check_instance_setup() and not _test:
20
+ setup_django(isettings)
21
+
22
+ ssettings = settings.instance.storage
23
+ if ssettings._uid is None and _test:
24
+ # because django isn't up, we can't get it from the database
25
+ ssettings._uid = base62(8)
26
+ # cannot yet populate the instance id here
27
+ ssettings._instance_id = None
28
+ # flag auto_populate_instance can be removed once FK migration is over
29
+ init_storage_hub(ssettings, auto_populate_instance=False)
30
+ init_instance_hub(isettings)
31
+ isettings._is_on_hub = True
32
+ isettings._persist()
33
+ if isettings.dialect != "sqlite" and not _test:
34
+ from ._schema_metadata import update_schema_in_hub
35
+
36
+ update_schema_in_hub()
lamindb_setup/_schema.py CHANGED
@@ -1,27 +1,27 @@
1
- from __future__ import annotations
2
-
3
- from django.urls import path
4
- from lamin_utils import logger
5
-
6
- try:
7
- from schema_graph.views import Schema
8
- except ImportError:
9
- logger.error("to view the schema: pip install django-schema-graph")
10
-
11
-
12
- urlpatterns = [
13
- path("schema/", Schema.as_view()),
14
- ]
15
-
16
-
17
- def view():
18
- from django.core.management import call_command
19
-
20
- from ._check_setup import _check_instance_setup
21
- from .core._settings import settings
22
- from .core.django import setup_django
23
-
24
- if _check_instance_setup():
25
- raise RuntimeError("Restart Python session or use CLI!")
26
- setup_django(settings.instance, view_schema=True)
27
- call_command("runserver")
1
+ from __future__ import annotations
2
+
3
+ from django.urls import path
4
+ from lamin_utils import logger
5
+
6
+ try:
7
+ from schema_graph.views import Schema
8
+ except ImportError:
9
+ logger.error("to view the schema: pip install django-schema-graph")
10
+
11
+
12
+ urlpatterns = [
13
+ path("schema/", Schema.as_view()),
14
+ ]
15
+
16
+
17
+ def view():
18
+ from django.core.management import call_command
19
+
20
+ from ._check_setup import _check_instance_setup
21
+ from .core._settings import settings
22
+ from .core.django import setup_django
23
+
24
+ if _check_instance_setup():
25
+ raise RuntimeError("Restart Python session or use CLI!")
26
+ setup_django(settings.instance, view_schema=True)
27
+ call_command("runserver")