lamindb_setup 0.71.2__tar.gz → 0.71.4__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.71.2 → lamindb_setup-0.71.4}/.github/workflows/build.yml +2 -2
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/PKG-INFO +1 -1
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/changelog.md +7 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/03-add-managed-storage.ipynb +26 -7
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/__init__.py +1 -1
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_connect_instance.py +78 -61
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_delete.py +6 -46
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_init_instance.py +18 -17
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_set_managed_storage.py +4 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_hub_core.py +5 -3
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_instance.py +3 -12
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_storage.py +10 -1
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_user.py +2 -6
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/django.py +4 -1
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/hashing.py +23 -20
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_connect_instance.py +8 -11
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-local/conftest.py +1 -1
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-local/test_all.py +3 -3
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-prod/conftest.py +2 -2
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/.github/workflows/latest-changes.jinja2 +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/.github/workflows/latest-changes.yml +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/.gitignore +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/.pre-commit-config.yaml +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/LICENSE +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/README.md +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/test-multi-session.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/test_notebooks.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-cache-management.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-empty-init.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-import-schema.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-insufficient-user-info.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-prod/test_notebooks2.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/index.md +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/notebooks.md +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/reference.md +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_cache.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_check.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_check_setup.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_close.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_django.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_exportdb.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_importdb.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_migrate.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_register_instance.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_schema.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_setup_user.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/_silence_loggers.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/__init__.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_aws_storage.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_deprecated.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_docs.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_hub_client.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_hub_crud.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_hub_utils.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_load.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_save.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_settings_store.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/exceptions.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/types.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/lamindb_setup/core/upath.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/noxfile.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/pyproject.toml +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_delete_instance.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_init_instance.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_login.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_migrate.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-cloud/test_set_storage.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-prod/test_auto_connect.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-prod/test_django.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/hub-prod/test_upath.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/storage/test_hashing.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/storage/test_storage_access.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/storage/test_storage_basis.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/storage/test_storage_stats.py +0 -0
- {lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/tests/storage/test_to_url.py +0 -0
|
@@ -61,7 +61,7 @@ jobs:
|
|
|
61
61
|
repository: laminlabs/laminapp-ui
|
|
62
62
|
token: ${{ secrets.GH_TOKEN_DEPLOY_LAMINAPP }}
|
|
63
63
|
path: laminhub
|
|
64
|
-
ref:
|
|
64
|
+
ref: main
|
|
65
65
|
- uses: actions/cache@v3
|
|
66
66
|
with:
|
|
67
67
|
path: ~/.cache/pre-commit
|
|
@@ -130,7 +130,7 @@ jobs:
|
|
|
130
130
|
repository: laminlabs/laminapp-ui
|
|
131
131
|
token: ${{ secrets.GH_TOKEN_DEPLOY_LAMINAPP }}
|
|
132
132
|
path: laminhub
|
|
133
|
-
ref:
|
|
133
|
+
ref: main
|
|
134
134
|
- name: Set env file for local test of edge functions
|
|
135
135
|
run: |
|
|
136
136
|
touch .env.local
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
<!-- prettier-ignore -->
|
|
4
4
|
Name | PR | Developer | Date | Version
|
|
5
5
|
--- | --- | --- | --- | ---
|
|
6
|
+
⚡️ Speed-up file hash | [761](https://github.com/laminlabs/lamindb-setup/pull/761) | [Koncopd](https://github.com/Koncopd) | 2024-05-11 | 0.71.4
|
|
7
|
+
♻️ Account for public storage locations | [758](https://github.com/laminlabs/lamindb-setup/pull/758) | [falexwolf](https://github.com/falexwolf) | 2024-05-10 |
|
|
8
|
+
♻️ Make init_instance_hub idempotent | [757](https://github.com/laminlabs/lamindb-setup/pull/757) | [falexwolf](https://github.com/falexwolf) | 2024-05-09 |
|
|
9
|
+
♻️ Refactor delete & connect | [756](https://github.com/laminlabs/lamindb-setup/pull/756) | [falexwolf](https://github.com/falexwolf) | 2024-05-09 |
|
|
10
|
+
🔥 Remove laminapp-admin logic | [755](https://github.com/laminlabs/lamindb-setup/pull/755) | [falexwolf](https://github.com/falexwolf) | 2024-05-08 |
|
|
11
|
+
♻️ Better treatment of current_user_id | [754](https://github.com/laminlabs/lamindb-setup/pull/754) | [falexwolf](https://github.com/falexwolf) | 2024-05-06 | 0.71.2
|
|
12
|
+
💚 Fix tests | [753](https://github.com/laminlabs/lamindb-setup/pull/753) | [fredericenard](https://github.com/fredericenard) | 2024-05-06 |
|
|
6
13
|
♻️ Actually use local db | [751](https://github.com/laminlabs/lamindb-setup/pull/751) | [falexwolf](https://github.com/falexwolf) | 2024-05-06 | 0.71.2
|
|
7
14
|
✏️ Restore view_tree py3.9 compatibility | [750](https://github.com/laminlabs/lamindb-setup/pull/750) | [sunnyosun](https://github.com/sunnyosun) | 2024-05-06 |
|
|
8
15
|
💚 Pin laminapp-ui | [749](https://github.com/laminlabs/lamindb-setup/pull/749) | [falexwolf](https://github.com/falexwolf) | 2024-05-06 |
|
|
@@ -255,7 +255,8 @@
|
|
|
255
255
|
"# root.fs contains the underlying fsspec filesystem\n",
|
|
256
256
|
"assert (\n",
|
|
257
257
|
" ln_setup.settings.storage.root.fs.cache_regions # set by lamindb to True for s3 by default\n",
|
|
258
|
-
")"
|
|
258
|
+
")\n",
|
|
259
|
+
"assert ln_setup.settings.storage._instance_id is not None"
|
|
259
260
|
]
|
|
260
261
|
},
|
|
261
262
|
{
|
|
@@ -287,6 +288,26 @@
|
|
|
287
288
|
"assert not ln_setup.settings.storage.root.fs.cache_regions"
|
|
288
289
|
]
|
|
289
290
|
},
|
|
291
|
+
{
|
|
292
|
+
"cell_type": "markdown",
|
|
293
|
+
"id": "015b8f36",
|
|
294
|
+
"metadata": {},
|
|
295
|
+
"source": [
|
|
296
|
+
"Cloud storage with mere read access:"
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"cell_type": "code",
|
|
301
|
+
"execution_count": null,
|
|
302
|
+
"id": "4ef50cab",
|
|
303
|
+
"metadata": {},
|
|
304
|
+
"outputs": [],
|
|
305
|
+
"source": [
|
|
306
|
+
"with pytest.raises(ValueError) as error:\n",
|
|
307
|
+
" set_managed_storage(\"gs://rxrx1-europe-west4/images/test/HEPG2-08\")\n",
|
|
308
|
+
"assert error.exconly().startswith(\"ValueError: Cannot manage storage without write access\")"
|
|
309
|
+
]
|
|
310
|
+
},
|
|
290
311
|
{
|
|
291
312
|
"cell_type": "markdown",
|
|
292
313
|
"id": "83a2ee6b",
|
|
@@ -302,16 +323,14 @@
|
|
|
302
323
|
"metadata": {},
|
|
303
324
|
"outputs": [],
|
|
304
325
|
"source": [
|
|
305
|
-
"from laminhub_rest.core.collaborator
|
|
326
|
+
"from laminhub_rest.core.instance.collaborator import InstanceCollaboratorHandler\n",
|
|
306
327
|
"from lamindb_setup.core._hub_client import connect_hub_with_auth\n",
|
|
307
328
|
"\n",
|
|
308
329
|
"admin_hub = connect_hub_with_auth()\n",
|
|
309
|
-
"
|
|
330
|
+
"InstanceCollaboratorHandler(admin_hub).add_by_slug(\n",
|
|
331
|
+
" \"testuser1/test-add-managed-storage\",\n",
|
|
310
332
|
" \"testuser2\",\n",
|
|
311
|
-
" \"
|
|
312
|
-
" \"test-add-managed-storage\",\n",
|
|
313
|
-
" \"write\",\n",
|
|
314
|
-
" admin_hub,\n",
|
|
333
|
+
" \"write\"\n",
|
|
315
334
|
")\n",
|
|
316
335
|
"admin_hub.auth.close()"
|
|
317
336
|
]
|
|
@@ -55,7 +55,10 @@ def check_db_dsn_equal_up_to_credentials(db_dsn_hub, db_dsn_local):
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
def update_db_using_local(
|
|
58
|
-
hub_instance_result: dict[str, str],
|
|
58
|
+
hub_instance_result: dict[str, str],
|
|
59
|
+
settings_file: Path,
|
|
60
|
+
db: str | None = None,
|
|
61
|
+
raise_permission_error=True,
|
|
59
62
|
) -> str | None:
|
|
60
63
|
db_updated = None
|
|
61
64
|
# check if postgres
|
|
@@ -77,7 +80,11 @@ def update_db_using_local(
|
|
|
77
80
|
db_dsn_local = LaminDsnModel(db=isettings.db)
|
|
78
81
|
else:
|
|
79
82
|
# just take the default hub result and ensure there is actually a user
|
|
80
|
-
if
|
|
83
|
+
if (
|
|
84
|
+
db_dsn_hub.db.user == "none"
|
|
85
|
+
and db_dsn_hub.db.password == "none"
|
|
86
|
+
and raise_permission_error
|
|
87
|
+
):
|
|
81
88
|
raise PermissionError(
|
|
82
89
|
"No database access, please ask your admin to provide you with"
|
|
83
90
|
" a DB URL and pass it via --db <db_url>"
|
|
@@ -101,6 +108,65 @@ def update_db_using_local(
|
|
|
101
108
|
return db_updated
|
|
102
109
|
|
|
103
110
|
|
|
111
|
+
def _connect_instance(
|
|
112
|
+
owner: str,
|
|
113
|
+
name: str,
|
|
114
|
+
*,
|
|
115
|
+
db: str | None = None,
|
|
116
|
+
raise_permission_error: bool = True,
|
|
117
|
+
) -> InstanceSettings:
|
|
118
|
+
settings_file = instance_settings_file(name, owner)
|
|
119
|
+
make_hub_request = True
|
|
120
|
+
if settings_file.exists():
|
|
121
|
+
isettings = load_instance_settings(settings_file)
|
|
122
|
+
# skip hub request for a purely local instance
|
|
123
|
+
make_hub_request = isettings.is_remote
|
|
124
|
+
if make_hub_request:
|
|
125
|
+
# the following will return a string if the instance does not exist
|
|
126
|
+
# on the hub
|
|
127
|
+
hub_result = load_instance_from_hub(owner=owner, name=name)
|
|
128
|
+
# if hub_result is not a string, it means it made a request
|
|
129
|
+
# that successfully returned metadata
|
|
130
|
+
if not isinstance(hub_result, str):
|
|
131
|
+
instance_result, storage_result = hub_result
|
|
132
|
+
db_updated = update_db_using_local(
|
|
133
|
+
instance_result,
|
|
134
|
+
settings_file,
|
|
135
|
+
db=db,
|
|
136
|
+
raise_permission_error=raise_permission_error,
|
|
137
|
+
)
|
|
138
|
+
ssettings = StorageSettings(
|
|
139
|
+
root=storage_result["root"],
|
|
140
|
+
region=storage_result["region"],
|
|
141
|
+
uid=storage_result["lnid"],
|
|
142
|
+
uuid=UUID(storage_result["id"]),
|
|
143
|
+
instance_id=UUID(instance_result["id"]),
|
|
144
|
+
)
|
|
145
|
+
isettings = InstanceSettings(
|
|
146
|
+
id=UUID(instance_result["id"]),
|
|
147
|
+
owner=owner,
|
|
148
|
+
name=name,
|
|
149
|
+
storage=ssettings,
|
|
150
|
+
db=db_updated,
|
|
151
|
+
schema=instance_result["schema_str"],
|
|
152
|
+
git_repo=instance_result["git_repo"],
|
|
153
|
+
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
154
|
+
is_on_hub=True,
|
|
155
|
+
)
|
|
156
|
+
check_whether_migrations_in_sync(instance_result["lamindb_version"])
|
|
157
|
+
else:
|
|
158
|
+
message = INSTANCE_NOT_FOUND_MESSAGE.format(
|
|
159
|
+
owner=owner, name=name, hub_result=hub_result
|
|
160
|
+
)
|
|
161
|
+
if settings_file.exists():
|
|
162
|
+
isettings = load_instance_settings(settings_file)
|
|
163
|
+
if isettings.is_remote:
|
|
164
|
+
raise InstanceNotFoundError(message)
|
|
165
|
+
else:
|
|
166
|
+
raise InstanceNotFoundError(message)
|
|
167
|
+
return isettings
|
|
168
|
+
|
|
169
|
+
|
|
104
170
|
@unlock_cloud_sqlite_upon_exception(ignore_prev_locker=True)
|
|
105
171
|
def connect(
|
|
106
172
|
slug: str,
|
|
@@ -134,71 +200,22 @@ def connect(
|
|
|
134
200
|
elif settings._instance_exists and f"{owner}/{name}" != settings.instance.slug:
|
|
135
201
|
close_instance(mute=True)
|
|
136
202
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
# mimic instance_result from hub
|
|
143
|
-
instance_result = {"id": isettings._id.hex}
|
|
144
|
-
# skip hub request for a purely local instance
|
|
145
|
-
make_hub_request = isettings.is_remote
|
|
146
|
-
|
|
147
|
-
if make_hub_request:
|
|
148
|
-
# the following will return a string if the instance does not exist
|
|
149
|
-
# on the hub
|
|
150
|
-
hub_result = load_instance_from_hub(owner=owner, name=name)
|
|
151
|
-
# if hub_result is not a string, it means it made a request
|
|
152
|
-
# that successfully returned metadata
|
|
153
|
-
if not isinstance(hub_result, str):
|
|
154
|
-
instance_result, storage_result = hub_result
|
|
155
|
-
db_updated = update_db_using_local(
|
|
156
|
-
instance_result, settings_file, db=db
|
|
157
|
-
)
|
|
158
|
-
ssettings = StorageSettings(
|
|
159
|
-
root=storage_result["root"],
|
|
160
|
-
region=storage_result["region"],
|
|
161
|
-
uid=storage_result["lnid"],
|
|
162
|
-
uuid=UUID(storage_result["id"]),
|
|
163
|
-
instance_id=UUID(instance_result["id"]),
|
|
164
|
-
)
|
|
165
|
-
isettings = InstanceSettings(
|
|
166
|
-
id=UUID(instance_result["id"]),
|
|
167
|
-
owner=owner,
|
|
168
|
-
name=name,
|
|
169
|
-
storage=ssettings,
|
|
170
|
-
db=db_updated,
|
|
171
|
-
schema=instance_result["schema_str"],
|
|
172
|
-
git_repo=instance_result["git_repo"],
|
|
173
|
-
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
174
|
-
is_on_hub=True,
|
|
175
|
-
)
|
|
176
|
-
check_whether_migrations_in_sync(instance_result["lamindb_version"])
|
|
203
|
+
try:
|
|
204
|
+
isettings = _connect_instance(owner, name, db=db)
|
|
205
|
+
except InstanceNotFoundError as e:
|
|
206
|
+
if _raise_not_found_error:
|
|
207
|
+
raise e
|
|
177
208
|
else:
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if settings_file.exists():
|
|
182
|
-
isettings = load_instance_settings(settings_file)
|
|
183
|
-
if isettings.is_remote:
|
|
184
|
-
if _raise_not_found_error:
|
|
185
|
-
raise InstanceNotFoundError(message)
|
|
186
|
-
return "instance-not-found"
|
|
187
|
-
|
|
188
|
-
else:
|
|
189
|
-
if _raise_not_found_error:
|
|
190
|
-
raise InstanceNotFoundError(message)
|
|
191
|
-
return "instance-not-found"
|
|
192
|
-
|
|
209
|
+
return "instance-not-found"
|
|
210
|
+
if isinstance(isettings, str):
|
|
211
|
+
return isettings
|
|
193
212
|
if storage is not None:
|
|
194
213
|
update_isettings_with_storage(isettings, storage)
|
|
195
214
|
isettings._persist()
|
|
196
215
|
if _test:
|
|
197
216
|
return None
|
|
198
217
|
silence_loggers()
|
|
199
|
-
check, msg = isettings._load_db(
|
|
200
|
-
do_not_lock_for_laminapp_admin=True
|
|
201
|
-
) # this also updates local SQLite
|
|
218
|
+
check, msg = isettings._load_db()
|
|
202
219
|
if not check:
|
|
203
220
|
local_db = (
|
|
204
221
|
isettings._is_cloud_sqlite and isettings._sqlite_file_local.exists()
|
|
@@ -216,7 +233,7 @@ def connect(
|
|
|
216
233
|
f"instance exists with id {isettings._id.hex}, but database is not"
|
|
217
234
|
" loadable: re-initializing"
|
|
218
235
|
)
|
|
219
|
-
return "instance-corrupted-or-deleted"
|
|
236
|
+
return "instance-corrupted-or-deleted"
|
|
220
237
|
# this is for testing purposes only
|
|
221
238
|
if _TEST_FAILED_LOAD:
|
|
222
239
|
raise RuntimeError("Technical testing error.")
|
|
@@ -1,29 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import shutil
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
|
|
7
7
|
from lamin_utils import logger
|
|
8
8
|
|
|
9
|
-
from ._connect_instance import
|
|
10
|
-
INSTANCE_NOT_FOUND_MESSAGE,
|
|
11
|
-
InstanceNotFoundError,
|
|
12
|
-
get_owner_name_from_identifier,
|
|
13
|
-
)
|
|
14
|
-
from .core._hub_core import connect_instance as load_instance_from_hub
|
|
9
|
+
from ._connect_instance import _connect_instance, get_owner_name_from_identifier
|
|
15
10
|
from .core._hub_core import delete_instance as delete_instance_on_hub
|
|
16
11
|
from .core._hub_core import get_storage_records_for_instance
|
|
17
12
|
from .core._settings import settings
|
|
18
|
-
from .core._settings_instance import InstanceSettings
|
|
19
|
-
from .core._settings_load import load_instance_settings
|
|
20
13
|
from .core._settings_storage import StorageSettings
|
|
21
|
-
from .core._settings_store import instance_settings_file
|
|
22
14
|
from .core.upath import HOSTED_BUCKETS, check_storage_is_empty
|
|
23
15
|
|
|
24
16
|
if TYPE_CHECKING:
|
|
25
17
|
from pathlib import Path
|
|
26
18
|
|
|
19
|
+
from .core._settings_instance import InstanceSettings
|
|
20
|
+
|
|
27
21
|
|
|
28
22
|
def delete_cache(cache_dir: Path):
|
|
29
23
|
if cache_dir is not None and cache_dir.exists():
|
|
@@ -67,42 +61,8 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
|
|
|
67
61
|
force: Whether to skip the confirmation prompt.
|
|
68
62
|
require_empty: Whether to check if the instance is empty before deleting.
|
|
69
63
|
"""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
isettings = settings.instance
|
|
73
|
-
else:
|
|
74
|
-
settings_file = instance_settings_file(instance_name, instance_owner)
|
|
75
|
-
if not settings_file.exists():
|
|
76
|
-
hub_result = load_instance_from_hub(
|
|
77
|
-
owner=instance_owner, name=instance_name
|
|
78
|
-
)
|
|
79
|
-
if isinstance(hub_result, str):
|
|
80
|
-
message = INSTANCE_NOT_FOUND_MESSAGE.format(
|
|
81
|
-
owner=instance_owner,
|
|
82
|
-
name=instance_name,
|
|
83
|
-
hub_result=hub_result,
|
|
84
|
-
)
|
|
85
|
-
raise InstanceNotFoundError(message)
|
|
86
|
-
instance_result, storage_result = hub_result
|
|
87
|
-
ssettings = StorageSettings(
|
|
88
|
-
root=storage_result["root"],
|
|
89
|
-
region=storage_result["region"],
|
|
90
|
-
uid=storage_result["lnid"],
|
|
91
|
-
uuid=UUID(storage_result["id"]),
|
|
92
|
-
)
|
|
93
|
-
isettings = InstanceSettings(
|
|
94
|
-
id=UUID(instance_result["id"]),
|
|
95
|
-
owner=instance_owner,
|
|
96
|
-
name=instance_name,
|
|
97
|
-
storage=ssettings,
|
|
98
|
-
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
99
|
-
db=instance_result["db"] if "db" in instance_result else None,
|
|
100
|
-
schema=instance_result["schema_str"],
|
|
101
|
-
git_repo=instance_result["git_repo"],
|
|
102
|
-
is_on_hub=True,
|
|
103
|
-
)
|
|
104
|
-
else:
|
|
105
|
-
isettings = load_instance_settings(settings_file)
|
|
64
|
+
owner, name = get_owner_name_from_identifier(slug)
|
|
65
|
+
isettings = _connect_instance(owner, name, raise_permission_error=False)
|
|
106
66
|
if isettings.dialect != "sqlite":
|
|
107
67
|
logger.warning(
|
|
108
68
|
f"delete() does not yet affect your Postgres database at {isettings.db}"
|
|
@@ -44,15 +44,17 @@ def register_storage_in_instance(ssettings: StorageSettings):
|
|
|
44
44
|
|
|
45
45
|
from .core.hashing import hash_and_encode_as_b62
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
if ssettings._instance_id is not None:
|
|
48
|
+
instance_uid = hash_and_encode_as_b62(ssettings._instance_id.hex)[:12]
|
|
49
|
+
else:
|
|
50
|
+
instance_uid = None
|
|
49
51
|
# how do we ensure that this function is only called passing
|
|
50
52
|
# the managing instance?
|
|
51
53
|
defaults = {
|
|
52
54
|
"root": ssettings.root_as_str,
|
|
53
55
|
"type": ssettings.type,
|
|
54
56
|
"region": ssettings.region,
|
|
55
|
-
"instance_uid":
|
|
57
|
+
"instance_uid": instance_uid,
|
|
56
58
|
"created_by_id": current_user_id(),
|
|
57
59
|
}
|
|
58
60
|
if ssettings._uid is not None:
|
|
@@ -67,20 +69,19 @@ def register_storage_in_instance(ssettings: StorageSettings):
|
|
|
67
69
|
def register_user(usettings):
|
|
68
70
|
from lnschema_core.models import User
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
try
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
pass
|
|
72
|
+
try:
|
|
73
|
+
# need to have try except because of integer primary key migration
|
|
74
|
+
user, created = User.objects.update_or_create(
|
|
75
|
+
uid=usettings.uid,
|
|
76
|
+
defaults={
|
|
77
|
+
"handle": usettings.handle,
|
|
78
|
+
"name": usettings.name,
|
|
79
|
+
},
|
|
80
|
+
)
|
|
81
|
+
# for users with only read access, except via ProgrammingError
|
|
82
|
+
# ProgrammingError: permission denied for table lnschema_core_user
|
|
83
|
+
except (OperationalError, FieldError, ProgrammingError):
|
|
84
|
+
pass
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
def register_user_and_storage_in_instance(isettings: InstanceSettings, usettings):
|
|
@@ -31,6 +31,10 @@ def set_managed_storage(root: UPathStr, **fs_kwargs):
|
|
|
31
31
|
ssettings = init_storage(
|
|
32
32
|
root=root, instance_id=settings.instance._id, register_hub=True
|
|
33
33
|
)
|
|
34
|
+
if ssettings._instance_id is None:
|
|
35
|
+
raise ValueError(
|
|
36
|
+
f"Cannot manage storage without write access: {ssettings.root}"
|
|
37
|
+
)
|
|
34
38
|
settings.instance._storage = ssettings
|
|
35
39
|
settings.instance._persist() # this also updates the settings object
|
|
36
40
|
register_storage_in_instance(ssettings)
|
|
@@ -284,9 +284,11 @@ def _init_instance(isettings: InstanceSettings, client: Client) -> None:
|
|
|
284
284
|
# as then init_instance is no longer idempotent
|
|
285
285
|
try:
|
|
286
286
|
client.table("instance").insert(fields, returning="minimal").execute()
|
|
287
|
-
except APIError
|
|
288
|
-
logger.warning(
|
|
289
|
-
|
|
287
|
+
except APIError:
|
|
288
|
+
logger.warning(
|
|
289
|
+
f"instance already existed at: https://lamin.ai/{isettings.owner}/{isettings.name}"
|
|
290
|
+
)
|
|
291
|
+
return None
|
|
290
292
|
client.table("storage").update(
|
|
291
293
|
{"instance_id": isettings._id.hex, "is_default": True}
|
|
292
294
|
).eq("id", isettings.storage._uuid.hex).execute() # type: ignore
|
|
@@ -42,7 +42,7 @@ class InstanceSettings:
|
|
|
42
42
|
db: str | None = None, # DB URI
|
|
43
43
|
schema: str | None = None, # comma-separated string of schema names
|
|
44
44
|
git_repo: str | None = None, # a git repo URL
|
|
45
|
-
is_on_hub: bool =
|
|
45
|
+
is_on_hub: bool | None = None, # initialized from hub
|
|
46
46
|
):
|
|
47
47
|
from ._hub_utils import validate_db_arg
|
|
48
48
|
|
|
@@ -406,9 +406,7 @@ class InstanceSettings:
|
|
|
406
406
|
|
|
407
407
|
setup_django(self, init=True)
|
|
408
408
|
|
|
409
|
-
def _load_db(
|
|
410
|
-
self, do_not_lock_for_laminapp_admin: bool = False
|
|
411
|
-
) -> tuple[bool, str]:
|
|
409
|
+
def _load_db(self) -> tuple[bool, str]:
|
|
412
410
|
# Is the database available and initialized as LaminDB?
|
|
413
411
|
# returns a tuple of status code and message
|
|
414
412
|
if self.dialect == "sqlite" and not self._sqlite_file.exists():
|
|
@@ -423,15 +421,8 @@ class InstanceSettings:
|
|
|
423
421
|
|
|
424
422
|
from .django import setup_django
|
|
425
423
|
|
|
426
|
-
# lock in all cases except if do_not_lock_for_laminapp_admin is True and
|
|
427
|
-
# user is `laminapp-admin`
|
|
428
|
-
# value doesn't matter if not a cloud sqlite instance
|
|
429
|
-
lock_cloud_sqlite = self._is_cloud_sqlite and (
|
|
430
|
-
not do_not_lock_for_laminapp_admin
|
|
431
|
-
or settings.user.handle != "laminapp-admin"
|
|
432
|
-
)
|
|
433
424
|
# we need the local sqlite to setup django
|
|
434
|
-
self._update_local_sqlite_file(lock_cloud_sqlite=
|
|
425
|
+
self._update_local_sqlite_file(lock_cloud_sqlite=self._is_cloud_sqlite)
|
|
435
426
|
# setting up django also performs a check for migrations & prints them
|
|
436
427
|
# as warnings
|
|
437
428
|
# this should fail, e.g., if the db is not reachable
|
|
@@ -113,11 +113,20 @@ def init_storage(
|
|
|
113
113
|
)
|
|
114
114
|
# the below might update the uid with one that's already taken on the hub
|
|
115
115
|
if ssettings.type_is_cloud or register_hub:
|
|
116
|
+
from ._hub_core import delete_storage_record
|
|
116
117
|
from ._hub_core import init_storage as init_storage_hub
|
|
117
118
|
|
|
118
119
|
init_storage_hub(ssettings)
|
|
119
120
|
# below comes last only if everything else was successful
|
|
120
|
-
|
|
121
|
+
try:
|
|
122
|
+
mark_storage_root(ssettings.root, ssettings.uid) # type: ignore
|
|
123
|
+
except Exception:
|
|
124
|
+
logger.important(
|
|
125
|
+
f"due to lack of write access, LaminDB won't manage storage location: {ssettings.root}"
|
|
126
|
+
)
|
|
127
|
+
if ssettings._uuid is not None:
|
|
128
|
+
delete_storage_record(ssettings._uuid) # type: ignore
|
|
129
|
+
ssettings._instance_id = None
|
|
121
130
|
return ssettings
|
|
122
131
|
|
|
123
132
|
|
|
@@ -46,10 +46,6 @@ class UserSettings:
|
|
|
46
46
|
@property
|
|
47
47
|
def id(self):
|
|
48
48
|
"""Integer id valid in current intance."""
|
|
49
|
-
|
|
50
|
-
# doesn't error - it needs to be this way to have
|
|
51
|
-
# a user id available in migrations
|
|
52
|
-
# from lnschema_core.users import current_user_id
|
|
53
|
-
from lnschema_core.models import User
|
|
49
|
+
from lnschema_core.users import current_user_id
|
|
54
50
|
|
|
55
|
-
return
|
|
51
|
+
return current_user_id()
|
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
import builtins
|
|
5
5
|
import os
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
import shutil
|
|
8
7
|
import time
|
|
9
8
|
from lamin_utils import logger
|
|
10
9
|
from ._settings_store import current_instance_settings_file
|
|
@@ -12,6 +11,7 @@ from ._settings_instance import InstanceSettings
|
|
|
12
11
|
|
|
13
12
|
IS_RUN_FROM_IPYTHON = getattr(builtins, "__IPYTHON__", False)
|
|
14
13
|
IS_SETUP = False
|
|
14
|
+
IS_MIGRATING = False
|
|
15
15
|
CONN_MAX_AGE = 299
|
|
16
16
|
|
|
17
17
|
|
|
@@ -101,7 +101,10 @@ def setup_django(
|
|
|
101
101
|
call_command("migrate", verbosity=2)
|
|
102
102
|
isettings._update_cloud_sqlite_file(unlock_cloud_sqlite=False)
|
|
103
103
|
elif init:
|
|
104
|
+
global IS_MIGRATING
|
|
105
|
+
IS_MIGRATING = True
|
|
104
106
|
call_command("migrate", verbosity=0)
|
|
107
|
+
IS_MIGRATING = False
|
|
105
108
|
|
|
106
109
|
global IS_SETUP
|
|
107
110
|
IS_SETUP = True
|
|
@@ -40,11 +40,11 @@ def hash_set(s: set[str]) -> str:
|
|
|
40
40
|
return to_b64_str(hashlib.md5(bstr).digest())[:20]
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
def hash_md5s_from_dir(
|
|
43
|
+
def hash_md5s_from_dir(hashes: list[str]) -> tuple[str, str]:
|
|
44
44
|
# need to sort below because we don't want the order of parsing the dir to
|
|
45
45
|
# affect the hash
|
|
46
46
|
digests = b"".join(
|
|
47
|
-
hashlib.md5(
|
|
47
|
+
hashlib.md5(hash.encode("utf-8")).digest() for hash in sorted(hashes)
|
|
48
48
|
)
|
|
49
49
|
digest = hashlib.md5(digests).digest()
|
|
50
50
|
return to_b64_str(digest)[:22], "md5-d"
|
|
@@ -59,24 +59,27 @@ def hash_code(file_path: UPathStr):
|
|
|
59
59
|
return hashlib.sha1(blob)
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
def hash_file(
|
|
63
|
-
|
|
62
|
+
def hash_file(
|
|
63
|
+
file_path: Path,
|
|
64
|
+
file_size: int | None = None,
|
|
65
|
+
chunk_size: int | None = 50 * 1024 * 1024,
|
|
66
|
+
) -> tuple[str, str]:
|
|
64
67
|
with open(file_path, "rb") as fp:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if
|
|
70
|
-
|
|
68
|
+
if file_size is None:
|
|
69
|
+
fp.seek(0, 2)
|
|
70
|
+
file_size = fp.tell()
|
|
71
|
+
fp.seek(0, 0)
|
|
72
|
+
if chunk_size is None:
|
|
73
|
+
chunk_size = file_size
|
|
74
|
+
first_chunk = fp.read(chunk_size)
|
|
75
|
+
if file_size <= chunk_size:
|
|
76
|
+
digest = hashlib.md5(first_chunk).digest()
|
|
77
|
+
hash_type = "md5"
|
|
78
|
+
else:
|
|
71
79
|
fp.seek(-chunk_size, 2)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
hash_type = "md5"
|
|
78
|
-
else:
|
|
79
|
-
digests = b"".join(hashlib.sha1(chunk).digest() for chunk in chunks)
|
|
80
|
-
digest = hashlib.sha1(digests).digest()
|
|
81
|
-
hash_type = "sha1-fl" # sha1 first last chunk
|
|
80
|
+
last_chunk = fp.read(chunk_size)
|
|
81
|
+
digest = hashlib.sha1(
|
|
82
|
+
hashlib.sha1(first_chunk).digest() + hashlib.sha1(last_chunk).digest()
|
|
83
|
+
).digest()
|
|
84
|
+
hash_type = "sha1-fl"
|
|
82
85
|
return to_b64_str(digest)[:22], hash_type
|
|
@@ -7,8 +7,7 @@ import pytest
|
|
|
7
7
|
from lamindb_setup._connect_instance import InstanceNotFoundError
|
|
8
8
|
from lamindb_setup.core._hub_client import connect_hub_with_auth
|
|
9
9
|
from lamindb_setup.core._hub_crud import update_instance
|
|
10
|
-
from laminhub_rest.core.collaborator
|
|
11
|
-
from laminhub_rest.core.collaborator._delete_collaborator import delete_collaborator
|
|
10
|
+
from laminhub_rest.core.instance.collaborator import InstanceCollaboratorHandler
|
|
12
11
|
from postgrest.exceptions import APIError
|
|
13
12
|
|
|
14
13
|
# @pytest.fixture
|
|
@@ -24,15 +23,16 @@ def test_connect_after_revoked_access():
|
|
|
24
23
|
if os.getenv("LAMIN_ENV") == "prod":
|
|
25
24
|
ln_setup.login("testuser1@lamin.ai")
|
|
26
25
|
admin_hub = connect_hub_with_auth()
|
|
26
|
+
collaborator_handler = InstanceCollaboratorHandler(admin_hub)
|
|
27
27
|
try:
|
|
28
28
|
# if a previous test run failed, this will
|
|
29
29
|
# error with a violation of a unique constraint
|
|
30
|
-
|
|
30
|
+
collaborator_handler.add_by_slug(
|
|
31
|
+
"laminlabs/static-test-instance-private-sqlite",
|
|
31
32
|
"testuser2",
|
|
32
|
-
"laminlabs",
|
|
33
|
-
"static-test-instance-private-sqlite",
|
|
34
33
|
"write",
|
|
35
|
-
|
|
34
|
+
"default",
|
|
35
|
+
skip_insert_user_table=True,
|
|
36
36
|
)
|
|
37
37
|
except APIError:
|
|
38
38
|
pass
|
|
@@ -44,11 +44,8 @@ def test_connect_after_revoked_access():
|
|
|
44
44
|
ln_setup.settings.instance.storage.root_as_str
|
|
45
45
|
== "s3://lamindb-setup-private-bucket"
|
|
46
46
|
)
|
|
47
|
-
|
|
48
|
-
"laminlabs",
|
|
49
|
-
"static-test-instance-private-sqlite",
|
|
50
|
-
ln_setup.settings.user._uuid,
|
|
51
|
-
admin_hub,
|
|
47
|
+
collaborator_handler.delete_by_slug(
|
|
48
|
+
"laminlabs/static-test-instance-private-sqlite", "testuser2"
|
|
52
49
|
)
|
|
53
50
|
# make the instance private
|
|
54
51
|
with pytest.raises(InstanceNotFoundError):
|
|
@@ -34,7 +34,7 @@ from lamindb_setup.core._settings_save import save_user_settings
|
|
|
34
34
|
from lamindb_setup.core._settings_storage import base62
|
|
35
35
|
from lamindb_setup.core._settings_storage import init_storage as init_storage_base
|
|
36
36
|
from lamindb_setup.core._settings_user import UserSettings
|
|
37
|
-
from laminhub_rest.core.collaborator
|
|
37
|
+
from laminhub_rest.core.instance.collaborator import InstanceCollaboratorHandler
|
|
38
38
|
from postgrest.exceptions import APIError
|
|
39
39
|
|
|
40
40
|
|
|
@@ -196,11 +196,11 @@ def test_db_user(
|
|
|
196
196
|
)
|
|
197
197
|
assert db_collaborator is None
|
|
198
198
|
# now add testreader1 as a collaborator
|
|
199
|
-
|
|
199
|
+
InstanceCollaboratorHandler(admin_client).add(
|
|
200
200
|
account_id=reader_settings._uuid,
|
|
201
201
|
instance_id=instance_id,
|
|
202
202
|
role="read",
|
|
203
|
-
|
|
203
|
+
skip_insert_user_table=True,
|
|
204
204
|
)
|
|
205
205
|
# check that this was successful and can be read by the reader
|
|
206
206
|
db_collaborator = select_collaborator(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
3
2
|
from uuid import UUID
|
|
4
3
|
|
|
5
4
|
import lamindb_setup
|
|
@@ -10,6 +9,7 @@ from lamin_utils import logger
|
|
|
10
9
|
def pytest_sessionstart(session: pytest.Session):
|
|
11
10
|
lamindb_instance_id = UUID("e1a2d3ab762e4592af5a1e53f288284e")
|
|
12
11
|
os.environ["LAMINDB_INSTANCE_ID_INIT"] = lamindb_instance_id.hex
|
|
12
|
+
assert lamindb_setup.settings.user.handle == "testuser2"
|
|
13
13
|
lamindb_setup.init(
|
|
14
14
|
storage="./default_storage",
|
|
15
15
|
schema="bionty",
|
|
@@ -21,4 +21,4 @@ def pytest_sessionstart(session: pytest.Session):
|
|
|
21
21
|
|
|
22
22
|
def pytest_sessionfinish(session: pytest.Session):
|
|
23
23
|
logger.set_verbosity(1)
|
|
24
|
-
lamindb_setup.delete("lamindb-setup-unit-tests", force=True)
|
|
24
|
+
lamindb_setup.delete("testuser2/lamindb-setup-unit-tests", force=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/docs/hub-cloud/02-connect-local-instance.ipynb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/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
|
|
File without changes
|
{lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/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
|
{lamindb_setup-0.71.2 → lamindb_setup-0.71.4}/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
|