lamindb_setup 0.81.4__tar.gz → 0.81.5__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.
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/PKG-INFO +2 -2
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-cloud-sync.ipynb +0 -82
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/__init__.py +1 -1
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_check_setup.py +44 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_migrate.py +5 -8
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_hub_core.py +1 -4
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_hub_crud.py +19 -24
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings.py +3 -8
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_storage.py +14 -15
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/upath.py +26 -36
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-local/test_all.py +0 -6
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/.github/workflows/build.yml +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/.github/workflows/doc-changes.yml +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/.gitignore +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/.pre-commit-config.yaml +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/LICENSE +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/README.md +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/changelog.md +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/test_notebooks.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-cache-management.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-empty-init.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-import-schema.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-init-load-local-anonymously.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-insufficient-user-info.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test_notebooks2.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/index.md +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/notebooks.md +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/reference.md +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_cache.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_check.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_close.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_connect_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_delete.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_django.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_entry_points.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_exportdb.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_importdb.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_init_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_register_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_schema.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_schema_metadata.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_set_managed_storage.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_setup_user.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/_silence_loggers.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/__init__.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_aws_credentials.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_aws_storage.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_deprecated.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_docs.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_hub_client.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_hub_utils.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_private_django_api.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_load.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_save.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_store.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_settings_user.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/django.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/exceptions.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/hashing.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/lamindb_setup/core/types.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/noxfile.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/pyproject.toml +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/scripts/script-init-pass-user-no-writes.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_connect_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_delete_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_edge_request.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_init_instance.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_init_pass_user_no_writes.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_login.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_migrate.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_set_storage.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-local/conftest.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-local/test_update_schema_in_hub.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/conftest.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_aws_credentials_manager.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_django.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_global_settings.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_upath.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_entry_point.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_hashing.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_storage_access.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_storage_basis.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_storage_stats.py +0 -0
- {lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/storage/test_to_url.py +0 -0
|
@@ -149,37 +149,6 @@
|
|
|
149
149
|
"assert settings.paths.cloud_to_local_no_update(dir_sync.as_posix(), cache_key=\"dir_cache/key\") == settings.cache_dir / \"dir_cache/key\""
|
|
150
150
|
]
|
|
151
151
|
},
|
|
152
|
-
{
|
|
153
|
-
"cell_type": "code",
|
|
154
|
-
"execution_count": null,
|
|
155
|
-
"id": "eda84820",
|
|
156
|
-
"metadata": {},
|
|
157
|
-
"outputs": [],
|
|
158
|
-
"source": [
|
|
159
|
-
"# for http urls\n",
|
|
160
|
-
"http_path = UPath(\"https://raw.githubusercontent.com/laminlabs/lamindb-setup/refs/heads/main/README.md\")\n",
|
|
161
|
-
"assert http_path.protocol == \"https\"\n",
|
|
162
|
-
"\n",
|
|
163
|
-
"http_stat = http_path.stat()\n",
|
|
164
|
-
"assert http_stat.st_size != 0\n",
|
|
165
|
-
"assert http_stat.st_mtime == 0\n",
|
|
166
|
-
"assert http_stat.as_info()[\"type\"] == \"file\""
|
|
167
|
-
]
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
"cell_type": "code",
|
|
171
|
-
"execution_count": null,
|
|
172
|
-
"id": "df6a9be4",
|
|
173
|
-
"metadata": {},
|
|
174
|
-
"outputs": [],
|
|
175
|
-
"source": [
|
|
176
|
-
"http_key = \"raw.githubusercontent.com/laminlabs/lamindb-setup/refs/heads/main/README.md\"\n",
|
|
177
|
-
"\n",
|
|
178
|
-
"assert settings.paths.cloud_to_local_no_update(http_path) == settings.cache_dir / http_key\n",
|
|
179
|
-
"assert settings.paths.cloud_to_local_no_update(str(http_path)) == settings.cache_dir / http_key\n",
|
|
180
|
-
"assert settings.paths.cloud_to_local_no_update(http_path, cache_key=\"check/README.md\") == settings.cache_dir / \"check/README.md\""
|
|
181
|
-
]
|
|
182
|
-
},
|
|
183
152
|
{
|
|
184
153
|
"cell_type": "markdown",
|
|
185
154
|
"id": "0b79f2f7",
|
|
@@ -222,57 +191,6 @@
|
|
|
222
191
|
"dir_sync_local.rmdir()"
|
|
223
192
|
]
|
|
224
193
|
},
|
|
225
|
-
{
|
|
226
|
-
"cell_type": "markdown",
|
|
227
|
-
"id": "d2246f90",
|
|
228
|
-
"metadata": {},
|
|
229
|
-
"source": [
|
|
230
|
-
"Test `cloud_to_local` for http"
|
|
231
|
-
]
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
"cell_type": "code",
|
|
235
|
-
"execution_count": null,
|
|
236
|
-
"id": "bc1b7736",
|
|
237
|
-
"metadata": {},
|
|
238
|
-
"outputs": [],
|
|
239
|
-
"source": [
|
|
240
|
-
"http_local = settings.paths.cloud_to_local(http_path)"
|
|
241
|
-
]
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"cell_type": "code",
|
|
245
|
-
"execution_count": null,
|
|
246
|
-
"id": "ca9f0ba8",
|
|
247
|
-
"metadata": {},
|
|
248
|
-
"outputs": [],
|
|
249
|
-
"source": [
|
|
250
|
-
"assert isinstance(http_local, LocalPathClasses)\n",
|
|
251
|
-
"assert http_local.stat().st_size == http_path.stat().st_size"
|
|
252
|
-
]
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
"cell_type": "code",
|
|
256
|
-
"execution_count": null,
|
|
257
|
-
"id": "6ae7cd2b",
|
|
258
|
-
"metadata": {},
|
|
259
|
-
"outputs": [],
|
|
260
|
-
"source": [
|
|
261
|
-
"http_local_mtime = http_local.stat().st_mtime\n",
|
|
262
|
-
"# no changes here because the file exists already\n",
|
|
263
|
-
"assert settings.paths.cloud_to_local(http_path).stat().st_mtime == http_local_mtime"
|
|
264
|
-
]
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"cell_type": "code",
|
|
268
|
-
"execution_count": null,
|
|
269
|
-
"id": "9da41c21",
|
|
270
|
-
"metadata": {},
|
|
271
|
-
"outputs": [],
|
|
272
|
-
"source": [
|
|
273
|
-
"http_local.unlink()"
|
|
274
|
-
]
|
|
275
|
-
},
|
|
276
194
|
{
|
|
277
195
|
"cell_type": "markdown",
|
|
278
196
|
"id": "574c3f95",
|
|
@@ -52,6 +52,49 @@ def _get_current_instance_settings() -> InstanceSettings | None:
|
|
|
52
52
|
return None
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
def check_connecting_to_v1_instance(isettings: InstanceSettings):
|
|
56
|
+
from urllib.parse import urlparse
|
|
57
|
+
|
|
58
|
+
# we need to do this because the sqlite file should be already synced
|
|
59
|
+
# has no effect if not cloud sqlite
|
|
60
|
+
# errors if the sqlite file is not in the cloud and doesn't exist locally
|
|
61
|
+
# isettings.db syncs but doesn't error in this case due to error_no_origin=False
|
|
62
|
+
isettings._update_local_sqlite_file()
|
|
63
|
+
|
|
64
|
+
parsed_uri = urlparse(isettings.db)
|
|
65
|
+
db_type = parsed_uri.scheme
|
|
66
|
+
|
|
67
|
+
if db_type == "sqlite":
|
|
68
|
+
import sqlite3
|
|
69
|
+
|
|
70
|
+
conn = sqlite3.connect(parsed_uri.path)
|
|
71
|
+
elif db_type in ["postgresql", "postgres"]:
|
|
72
|
+
import psycopg2
|
|
73
|
+
|
|
74
|
+
conn = psycopg2.connect(isettings.db)
|
|
75
|
+
else:
|
|
76
|
+
raise ValueError("Unsupported database type. Use 'sqlite' or 'postgresql' URI.")
|
|
77
|
+
|
|
78
|
+
cur = conn.cursor()
|
|
79
|
+
|
|
80
|
+
if db_type == "sqlite":
|
|
81
|
+
cur.execute(
|
|
82
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name='lamindb_user'"
|
|
83
|
+
)
|
|
84
|
+
isv1 = cur.fetchone() is not None
|
|
85
|
+
|
|
86
|
+
else: # postgres
|
|
87
|
+
cur.execute(
|
|
88
|
+
"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'lamindb_user')"
|
|
89
|
+
)
|
|
90
|
+
isv1 = cur.fetchone()[0]
|
|
91
|
+
|
|
92
|
+
if isv1:
|
|
93
|
+
raise SystemExit(
|
|
94
|
+
"This instance runs lamindb v1. Please run: pip install 'lamindb[bionty,wetlab,clinicore,ourprojects]'>1.0.0"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
55
98
|
# we make this a private function because in all the places it's used,
|
|
56
99
|
# users should not see it
|
|
57
100
|
def _check_instance_setup(
|
|
@@ -77,6 +120,7 @@ def _check_instance_setup(
|
|
|
77
120
|
if isettings is not None:
|
|
78
121
|
if reload_module and settings.auto_connect:
|
|
79
122
|
if not django.IS_SETUP:
|
|
123
|
+
check_connecting_to_v1_instance(isettings)
|
|
80
124
|
django.setup_django(isettings)
|
|
81
125
|
if from_module is not None:
|
|
82
126
|
# this only reloads `from_module`
|
|
@@ -28,14 +28,11 @@ def check_whether_migrations_in_sync(db_version_str: str):
|
|
|
28
28
|
or installed_version.minor < db_version.minor
|
|
29
29
|
):
|
|
30
30
|
db_version_lower = f"{db_version.major}.{db_version.minor}"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
f"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
logger.important(
|
|
37
|
-
"please update lamindb: pip install"
|
|
38
|
-
f' "lamindb>={db_version_lower},<{db_version_upper}"'
|
|
31
|
+
raise SystemExit(
|
|
32
|
+
f"The database ({db_version_str}) is ahead of your installed lamindb"
|
|
33
|
+
f" package ({installed_version_str})\n"
|
|
34
|
+
"Please update lamindb: pip install"
|
|
35
|
+
f" 'lamindb[bionty,wetlab,clinicore,ourprojects]'>={db_version_lower}"
|
|
39
36
|
)
|
|
40
37
|
elif (
|
|
41
38
|
installed_version.major > db_version.major
|
|
@@ -239,10 +239,6 @@ def _delete_instance(
|
|
|
239
239
|
)
|
|
240
240
|
root_string = storage_record["root"]
|
|
241
241
|
# gate storage and instance deletion on empty storage location for
|
|
242
|
-
# normally auth.get_session() doesn't have access_token
|
|
243
|
-
# so this block is useless i think (Sergei)
|
|
244
|
-
# the token is received from user settings inside create_path
|
|
245
|
-
# might be needed in the hub though
|
|
246
242
|
if client.auth.get_session() is not None:
|
|
247
243
|
access_token = client.auth.get_session().access_token
|
|
248
244
|
else:
|
|
@@ -255,6 +251,7 @@ def _delete_instance(
|
|
|
255
251
|
check_storage_is_empty(
|
|
256
252
|
root_path, account_for_sqlite_file=account_for_sqlite_file
|
|
257
253
|
)
|
|
254
|
+
_update_instance_record(instance_with_storage["id"], {"storage_id": None}, client)
|
|
258
255
|
# first delete the storage records because we will turn instance_id on
|
|
259
256
|
# storage into a FK soon
|
|
260
257
|
for storage_record in storage_records:
|
|
@@ -12,23 +12,25 @@ def select_instance_by_owner_name(
|
|
|
12
12
|
name: str,
|
|
13
13
|
client: Client,
|
|
14
14
|
) -> dict | None:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
try:
|
|
16
|
+
data = (
|
|
17
|
+
client.table("instance")
|
|
18
|
+
.select(
|
|
19
|
+
"*, account!inner!instance_account_id_28936e8f_fk_account_id(*),"
|
|
20
|
+
" storage!inner!storage_instance_id_359fca71_fk_instance_id(*)"
|
|
21
|
+
)
|
|
22
|
+
.eq("name", name)
|
|
23
|
+
.eq("account.handle", owner)
|
|
24
|
+
.eq("storage.is_default", True)
|
|
25
|
+
.execute()
|
|
26
|
+
.data
|
|
21
27
|
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
.eq("storage.is_default", True)
|
|
25
|
-
.execute()
|
|
26
|
-
.data
|
|
27
|
-
)
|
|
28
|
+
except Exception:
|
|
29
|
+
return None
|
|
28
30
|
if len(data) == 0:
|
|
29
31
|
return None
|
|
30
32
|
result = data[0]
|
|
31
|
-
# this is a list
|
|
33
|
+
# this is now a list
|
|
32
34
|
# assume only one default storage
|
|
33
35
|
result["storage"] = result["storage"][0]
|
|
34
36
|
return result
|
|
@@ -87,22 +89,15 @@ def select_instance_by_id_with_storage(
|
|
|
87
89
|
instance_id: str,
|
|
88
90
|
client: Client,
|
|
89
91
|
):
|
|
90
|
-
|
|
91
|
-
data = (
|
|
92
|
+
response = (
|
|
92
93
|
client.table("instance")
|
|
93
|
-
.select("*, storage!
|
|
94
|
+
.select("*, storage!instance_storage_id_87963cc8_fk_storage_id(*)")
|
|
94
95
|
.eq("id", instance_id)
|
|
95
|
-
.eq("storage.is_default", True)
|
|
96
96
|
.execute()
|
|
97
|
-
.data
|
|
98
97
|
)
|
|
99
|
-
if len(data) == 0:
|
|
98
|
+
if len(response.data) == 0:
|
|
100
99
|
return None
|
|
101
|
-
|
|
102
|
-
# this is a list
|
|
103
|
-
# assume only one default storage
|
|
104
|
-
result["storage"] = result["storage"][0]
|
|
105
|
-
return result
|
|
100
|
+
return response.data[0]
|
|
106
101
|
|
|
107
102
|
|
|
108
103
|
def update_instance(instance_id: str, instance_fields: dict, client: Client):
|
|
@@ -200,14 +200,9 @@ class SetupPaths:
|
|
|
200
200
|
# cache_key is ignored if filepath is a local path
|
|
201
201
|
if not isinstance(filepath, LocalPathClasses):
|
|
202
202
|
# settings is defined further in this file
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if protocol in {"http", "https"}:
|
|
207
|
-
local_key = local_key.removeprefix(protocol + "://")
|
|
208
|
-
else:
|
|
209
|
-
local_key = cache_key
|
|
210
|
-
local_filepath = settings.cache_dir / local_key
|
|
203
|
+
local_filepath = settings.cache_dir / (
|
|
204
|
+
filepath.path if cache_key is None else cache_key # type: ignore
|
|
205
|
+
)
|
|
211
206
|
else:
|
|
212
207
|
local_filepath = filepath
|
|
213
208
|
return local_filepath
|
|
@@ -7,7 +7,6 @@ import string
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import TYPE_CHECKING, Any, Literal
|
|
9
9
|
|
|
10
|
-
import fsspec
|
|
11
10
|
from lamin_utils import logger
|
|
12
11
|
|
|
13
12
|
from ._aws_credentials import HOSTED_REGIONS, get_aws_credentials_manager
|
|
@@ -25,10 +24,6 @@ if TYPE_CHECKING:
|
|
|
25
24
|
|
|
26
25
|
IS_INITIALIZED_KEY = ".lamindb/_is_initialized"
|
|
27
26
|
|
|
28
|
-
# a list of supported fsspec protocols
|
|
29
|
-
# rename file to local before showing to a user
|
|
30
|
-
VALID_PROTOCOLS = ("file", "gs", "s3", "hf", "http", "https")
|
|
31
|
-
|
|
32
27
|
|
|
33
28
|
def base62(n_char: int) -> str:
|
|
34
29
|
"""Like nanoid without hyphen and underscore."""
|
|
@@ -119,11 +114,16 @@ def init_storage(
|
|
|
119
114
|
root_str = f"s3://lamin-{region}/{uid}"
|
|
120
115
|
else:
|
|
121
116
|
root_str = f"s3://lamin-hosted-test/{uid}"
|
|
122
|
-
elif (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
elif root_str.startswith(("gs://", "s3://", "hf://")):
|
|
118
|
+
pass
|
|
119
|
+
else: # local path
|
|
120
|
+
try:
|
|
121
|
+
_ = Path(root_str)
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logger.error(
|
|
124
|
+
"`storage` is not a valid local, GCP storage, AWS S3 path or Hugging Face path"
|
|
125
|
+
)
|
|
126
|
+
raise e
|
|
127
127
|
ssettings = StorageSettings(
|
|
128
128
|
uid=uid,
|
|
129
129
|
root=root_str,
|
|
@@ -227,7 +227,7 @@ class StorageSettings:
|
|
|
227
227
|
|
|
228
228
|
@property
|
|
229
229
|
def record(self) -> Any:
|
|
230
|
-
"""Storage record in
|
|
230
|
+
"""Storage record in current instance."""
|
|
231
231
|
if self._record is None:
|
|
232
232
|
# dynamic import because of import order
|
|
233
233
|
from lnschema_core.models import Storage
|
|
@@ -299,15 +299,14 @@ class StorageSettings:
|
|
|
299
299
|
return self._region
|
|
300
300
|
|
|
301
301
|
@property
|
|
302
|
-
def type(self) -> Literal["local", "s3", "gs"
|
|
302
|
+
def type(self) -> Literal["local", "s3", "gs"]:
|
|
303
303
|
"""AWS S3 vs. Google Cloud vs. local.
|
|
304
304
|
|
|
305
|
-
Returns the protocol as a string: "local", "s3", "gs"
|
|
305
|
+
Returns the protocol as a string: "local", "s3", "gs".
|
|
306
306
|
"""
|
|
307
307
|
import fsspec
|
|
308
308
|
|
|
309
309
|
convert = {"file": "local"}
|
|
310
|
-
# init_storage checks that the root protocol belongs to VALID_PROTOCOLS
|
|
311
310
|
protocol = fsspec.utils.get_protocol(self.root_as_str)
|
|
312
311
|
return convert.get(protocol, protocol) # type: ignore
|
|
313
312
|
|
|
@@ -346,5 +345,5 @@ class StorageSettings:
|
|
|
346
345
|
return self.root / filekey
|
|
347
346
|
|
|
348
347
|
def local_filepath(self, filekey: UPathStr) -> UPath:
|
|
349
|
-
"""Local (cache) filepath from filekey
|
|
348
|
+
"""Local (cache) filepath from filekey: `local(filepath(...))`."""
|
|
350
349
|
return self.cloud_to_local(self.key_to_filepath(filekey))
|
|
@@ -190,13 +190,7 @@ class ProgressCallback(fsspec.callbacks.Callback):
|
|
|
190
190
|
pass
|
|
191
191
|
|
|
192
192
|
def update_relative_value(self, inc=1):
|
|
193
|
-
|
|
194
|
-
self.value += inc
|
|
195
|
-
# this is specific to http filesystem
|
|
196
|
-
# for some reason the last update is 0 always
|
|
197
|
-
# here 100% is forced manually in this case
|
|
198
|
-
elif self.value >= 0.999:
|
|
199
|
-
self.value = self.size
|
|
193
|
+
self.value += inc
|
|
200
194
|
self.call()
|
|
201
195
|
|
|
202
196
|
def branch(self, path_1, path_2, kwargs):
|
|
@@ -356,19 +350,27 @@ def synchronize(
|
|
|
356
350
|
exists = True
|
|
357
351
|
cloud_mts = timestamp
|
|
358
352
|
else:
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
353
|
+
# hf requires special treatment
|
|
354
|
+
if protocol == "hf":
|
|
355
|
+
try:
|
|
356
|
+
stat_hf = self.stat().as_info()
|
|
357
|
+
is_dir = stat_hf["type"] == "directory"
|
|
358
|
+
exists = True
|
|
359
|
+
if not is_dir:
|
|
360
|
+
cloud_mts = stat_hf["last_commit"].date.timestamp()
|
|
361
|
+
except FileNotFoundError:
|
|
362
|
+
exists = False
|
|
363
|
+
else:
|
|
364
|
+
# perform only one network request to check existence, type and timestamp
|
|
365
|
+
try:
|
|
366
|
+
cloud_mts = self.modified.timestamp()
|
|
367
|
+
is_dir = False
|
|
368
|
+
exists = True
|
|
369
|
+
except FileNotFoundError:
|
|
370
|
+
exists = False
|
|
371
|
+
except IsADirectoryError:
|
|
372
|
+
is_dir = True
|
|
373
|
+
exists = True
|
|
372
374
|
|
|
373
375
|
if not exists:
|
|
374
376
|
warn_or_error = f"The original path {self} does not exist anymore."
|
|
@@ -384,7 +386,6 @@ def synchronize(
|
|
|
384
386
|
return None
|
|
385
387
|
|
|
386
388
|
# synchronization logic for directories
|
|
387
|
-
# to synchronize directories, it should be possible to get modification times
|
|
388
389
|
if is_dir:
|
|
389
390
|
files = self.fs.find(str(self), detail=True)
|
|
390
391
|
if protocol == "s3":
|
|
@@ -450,16 +451,8 @@ def synchronize(
|
|
|
450
451
|
callback, print_progress, objectpath.name, "synchronizing"
|
|
451
452
|
)
|
|
452
453
|
if objectpath.exists():
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
need_synchronize = cloud_mts > local_mts_obj
|
|
456
|
-
else:
|
|
457
|
-
# this is true for http for example
|
|
458
|
-
# where size is present but st_mtime is not
|
|
459
|
-
# we assume that any change without the change in size is unlikely
|
|
460
|
-
cloud_size = cloud_stat.st_size
|
|
461
|
-
local_size_obj = objectpath.stat().st_size
|
|
462
|
-
need_synchronize = cloud_size != local_size_obj
|
|
454
|
+
local_mts_obj = objectpath.stat().st_mtime # type: ignore
|
|
455
|
+
need_synchronize = cloud_mts > local_mts_obj
|
|
463
456
|
else:
|
|
464
457
|
objectpath.parent.mkdir(parents=True, exist_ok=True)
|
|
465
458
|
need_synchronize = True
|
|
@@ -471,8 +464,7 @@ def synchronize(
|
|
|
471
464
|
self.download_to(
|
|
472
465
|
objectpath, recursive=False, print_progress=False, callback=callback
|
|
473
466
|
)
|
|
474
|
-
|
|
475
|
-
os.utime(objectpath, times=(cloud_mts, cloud_mts))
|
|
467
|
+
os.utime(objectpath, times=(cloud_mts, cloud_mts))
|
|
476
468
|
else:
|
|
477
469
|
# nothing happens if parent_update is not defined
|
|
478
470
|
# because of Callback.no_op
|
|
@@ -747,9 +739,7 @@ def get_stat_file_cloud(stat: dict) -> tuple[int, str | None, str | None]:
|
|
|
747
739
|
hash = b16_to_b64(stat["blob_id"])
|
|
748
740
|
hash_type = "sha1"
|
|
749
741
|
# s3
|
|
750
|
-
|
|
751
|
-
# because http also has ETag
|
|
752
|
-
elif "ETag" in stat and "StorageClass" in stat:
|
|
742
|
+
elif "ETag" in stat:
|
|
753
743
|
etag = stat["ETag"]
|
|
754
744
|
# small files
|
|
755
745
|
if "-" not in etag:
|
|
@@ -360,9 +360,3 @@ def test_init_storage_with_non_existing_bucket(create_testadmin1_session):
|
|
|
360
360
|
)[0]
|
|
361
361
|
)
|
|
362
362
|
assert error.exconly().endswith("Not Found")
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
def test_init_storage_incorrect_protocol():
|
|
366
|
-
with pytest.raises(ValueError) as error:
|
|
367
|
-
init_storage_base("incorrect-protocol://some-path/some-path-level")
|
|
368
|
-
assert "Protocol incorrect-protocol is not supported" in error.exconly()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/02-connect-local-instance.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-cloud/06-connect-hosted-instance.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-init-load-local-anonymously.ipynb
RENAMED
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/docs/hub-prod/test-insufficient-user-info.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-cloud/test_init_pass_user_no_writes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_aws_credentials_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.81.4 → lamindb_setup-0.81.5}/tests/hub-prod/test_switch_and_fallback_env.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|