lamindb_setup 1.15.2__tar.gz → 1.17.0__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-1.15.2 → lamindb_setup-1.17.0}/.github/workflows/build.yml +58 -5
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/.gitignore +1 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/PKG-INFO +5 -5
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/__init__.py +6 -3
- lamindb_setup-1.17.0/lamindb_setup/_check_setup.py +131 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_connect_instance.py +9 -23
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_delete.py +10 -5
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_disconnect.py +12 -9
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_init_instance.py +0 -1
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_migrate.py +0 -14
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_schema_metadata.py +9 -11
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_setup_user.py +28 -7
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_silence_loggers.py +2 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_aws_options.py +17 -7
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_clone.py +1 -1
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_client.py +1 -2
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_core.py +9 -6
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_private_django_api.py +0 -1
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings.py +14 -10
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_instance.py +28 -6
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_load.py +25 -7
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_storage.py +3 -1
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/django.py +48 -18
- lamindb_setup-1.17.0/lamindb_setup/core/lamin.db.gz +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/upath.py +34 -13
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/errors.py +0 -12
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/io.py +69 -33
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/noxfile.py +18 -3
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/pyproject.toml +3 -3
- lamindb_setup-1.17.0/tests/connectivity/conftest.py +33 -0
- lamindb_setup-1.17.0/tests/connectivity/test_proxies_certificates.py +58 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_clone_instance.py +3 -3
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_connect_instance.py +15 -6
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_edge_request.py +1 -1
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_init_instance.py +1 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_login.py +3 -8
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-local/conftest.py +8 -2
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-local/test_all.py +2 -2
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-local/test_update_schema_in_hub.py +10 -6
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_switch_and_fallback_env.py +2 -2
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_db_import_export.py +160 -2
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_storage_access.py +4 -8
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_storage_basis.py +1 -0
- lamindb_setup-1.15.2/docs/hub-prod/test-insufficient-user-info.ipynb +0 -192
- lamindb_setup-1.15.2/lamindb_setup/_check_setup.py +0 -192
- lamindb_setup-1.15.2/tests/storage/test_httpx_client.py +0 -21
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/.github/workflows/doc-changes.yml +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/.pre-commit-config.yaml +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/LICENSE +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/README.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/changelog.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/09-test-migrate.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-cloud/test_notebooks.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-cache-management.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-empty-init.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-import-schema.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-init-load-local-anonymously.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/hub-prod/test_notebooks2.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/index.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/notebooks.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/docs/reference.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_cache.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_check.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_django.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_entry_points.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_register_instance.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_schema.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/_set_managed_storage.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/__init__.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_aws_storage.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_deprecated.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_docs.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_crud.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_utils.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_save.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_store.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_user.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/exceptions.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/hashing.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/core/types.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/py.typed +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/lamindb_setup/types.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/scripts/script-init-pass-user-no-writes.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_delete_instance.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_init_pass_user_no_writes.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-cloud/test_set_storage.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-local/README.md +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-local/scripts/script-connect-fine-grained-access.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/conftest.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_aws_options_manager.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_django.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_global_settings.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_migrate.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/hub-prod/test_upath.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/conftest.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_entry_point.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_hashing.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_storage_settings.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_storage_stats.py +0 -0
- {lamindb_setup-1.15.2 → lamindb_setup-1.17.0}/tests/storage/test_to_url.py +0 -0
|
@@ -12,7 +12,7 @@ jobs:
|
|
|
12
12
|
# tests only on production hub
|
|
13
13
|
hub-prod:
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
|
-
timeout-minutes:
|
|
15
|
+
timeout-minutes: 13
|
|
16
16
|
steps:
|
|
17
17
|
- uses: actions/checkout@v4
|
|
18
18
|
- uses: actions/setup-python@v6
|
|
@@ -44,7 +44,7 @@ jobs:
|
|
|
44
44
|
python-version: "3.11"
|
|
45
45
|
- lamin_env: "staging"
|
|
46
46
|
python-version: "3.10"
|
|
47
|
-
timeout-minutes:
|
|
47
|
+
timeout-minutes: 13
|
|
48
48
|
steps:
|
|
49
49
|
- uses: aws-actions/configure-aws-credentials@v4
|
|
50
50
|
with:
|
|
@@ -94,7 +94,7 @@ jobs:
|
|
|
94
94
|
# test user access to storage
|
|
95
95
|
storage:
|
|
96
96
|
runs-on: ubuntu-latest
|
|
97
|
-
timeout-minutes:
|
|
97
|
+
timeout-minutes: 13
|
|
98
98
|
steps:
|
|
99
99
|
- uses: actions/checkout@v4
|
|
100
100
|
- uses: actions/setup-python@v6
|
|
@@ -107,7 +107,6 @@ jobs:
|
|
|
107
107
|
- run: nox -s lint
|
|
108
108
|
- run: nox -s storage
|
|
109
109
|
env:
|
|
110
|
-
TEST_INSTANCE_PRIVATE_POSTGRES: ${{ secrets.TEST_INSTANCE_PRIVATE_POSTGRES }}
|
|
111
110
|
TMP_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
112
111
|
TMP_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
113
112
|
- uses: actions/upload-artifact@v4
|
|
@@ -119,7 +118,7 @@ jobs:
|
|
|
119
118
|
# test low-level hub functionality
|
|
120
119
|
hub-local:
|
|
121
120
|
runs-on: ubuntu-latest
|
|
122
|
-
timeout-minutes:
|
|
121
|
+
timeout-minutes: 13
|
|
123
122
|
steps:
|
|
124
123
|
- uses: aws-actions/configure-aws-credentials@v4
|
|
125
124
|
with:
|
|
@@ -163,6 +162,60 @@ jobs:
|
|
|
163
162
|
path: .coverage
|
|
164
163
|
include-hidden-files: true
|
|
165
164
|
|
|
165
|
+
# test custom proxies and certificates
|
|
166
|
+
connectivity:
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
timeout-minutes: 13
|
|
169
|
+
steps:
|
|
170
|
+
- uses: aws-actions/configure-aws-credentials@v4
|
|
171
|
+
with:
|
|
172
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
173
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
174
|
+
aws-region: eu-central-1
|
|
175
|
+
- uses: actions/checkout@v4
|
|
176
|
+
- uses: actions/setup-python@v6
|
|
177
|
+
with:
|
|
178
|
+
python-version: "3.11"
|
|
179
|
+
cache: "pip"
|
|
180
|
+
cache-dependency-path: ".github/workflows/build.yml"
|
|
181
|
+
- run: pip install "laminci@git+https://x-access-token:${{ secrets.LAMIN_BUILD_DOCS }}@github.com/laminlabs/laminci"
|
|
182
|
+
- run: nox -s "install(group='connectivity')"
|
|
183
|
+
- name: cache mitmproxy
|
|
184
|
+
id: cache-mitmproxy
|
|
185
|
+
uses: actions/cache@v4
|
|
186
|
+
with:
|
|
187
|
+
path: ~/mitmproxy.tar
|
|
188
|
+
key: cache-mitmproxy-0
|
|
189
|
+
- name: cache mitmproxy miss
|
|
190
|
+
if: ${{ steps.cache-mitmproxy.outputs.cache-hit != 'true' }}
|
|
191
|
+
run: docker pull mitmproxy/mitmproxy:latest && docker image save mitmproxy/mitmproxy:latest --output ~/mitmproxy.tar
|
|
192
|
+
- name: cache mitmproxy use
|
|
193
|
+
if: ${{ steps.cache-mitmproxy.outputs.cache-hit == 'true' }}
|
|
194
|
+
run: docker image load --input ~/mitmproxy.tar
|
|
195
|
+
- name: start mitmproxy
|
|
196
|
+
run: |
|
|
197
|
+
# Start mitmdump (headless mitmproxy) as a forward proxy on 8080
|
|
198
|
+
docker run -d \
|
|
199
|
+
--name mitmproxy \
|
|
200
|
+
-p 8080:8080 \
|
|
201
|
+
mitmproxy/mitmproxy:latest \
|
|
202
|
+
mitmdump --mode regular --listen-port 8080
|
|
203
|
+
# Give it a few seconds to start and generate the CA
|
|
204
|
+
sleep 10
|
|
205
|
+
echo "mitmproxy state:"
|
|
206
|
+
docker ps -a
|
|
207
|
+
echo "Container ~/.mitmproxy contents:"
|
|
208
|
+
docker exec mitmproxy ls -l /home/mitmproxy/.mitmproxy || true
|
|
209
|
+
echo "Container logs (if it still exited):"
|
|
210
|
+
docker logs mitmproxy || true
|
|
211
|
+
- name: export mitmproxy certificate
|
|
212
|
+
run: |
|
|
213
|
+
# Copy CA cert from inside the container to the workspace
|
|
214
|
+
docker cp mitmproxy:/home/mitmproxy/.mitmproxy/mitmproxy-ca-cert.pem ./mitmproxy-ca.pem
|
|
215
|
+
ls -l ./mitmproxy-ca.pem
|
|
216
|
+
- name: run tests
|
|
217
|
+
run: nox -s connectivity
|
|
218
|
+
|
|
166
219
|
coverage:
|
|
167
220
|
needs: [hub-prod, hub-cloud, storage, hub-local]
|
|
168
221
|
runs-on: ubuntu-latest
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: lamindb_setup
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.17.0
|
|
4
4
|
Summary: Setup & configure LaminDB.
|
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
|
6
6
|
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Requires-Dist: lamin_utils>=0.3.3
|
|
9
10
|
Requires-Dist: django>=5.2,<5.3
|
|
10
11
|
Requires-Dist: dj_database_url>=1.3.0,<3.0.0
|
|
12
|
+
Requires-Dist: django-pgtrigger
|
|
11
13
|
Requires-Dist: pydantic-settings
|
|
12
14
|
Requires-Dist: platformdirs<5.0.0
|
|
13
15
|
Requires-Dist: httpx_retries<1.0.0
|
|
14
16
|
Requires-Dist: requests
|
|
15
17
|
Requires-Dist: universal_pathlib==0.2.6
|
|
16
18
|
Requires-Dist: botocore<2.0.0
|
|
17
|
-
Requires-Dist: supabase>=2.
|
|
18
|
-
Requires-Dist: gotrue<=2.12.0
|
|
19
|
-
Requires-Dist: storage3!=0.11.2; python_version < '3.11'
|
|
19
|
+
Requires-Dist: supabase>=2.20.0,<=2.24.0
|
|
20
20
|
Requires-Dist: pyjwt<3.0.0
|
|
21
21
|
Requires-Dist: psutil
|
|
22
22
|
Requires-Dist: packaging
|
|
@@ -35,14 +35,17 @@ Migration management
|
|
|
35
35
|
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
__version__ = "1.
|
|
38
|
+
__version__ = "1.17.0" # denote a release candidate for 0.1.0 with 0.1rc1
|
|
39
39
|
|
|
40
40
|
import os
|
|
41
41
|
import warnings
|
|
42
42
|
|
|
43
|
-
# ignore for now,
|
|
43
|
+
# ignore for now, this is for timeout parameter,
|
|
44
|
+
# it is more convenient to specify it directly for now
|
|
44
45
|
warnings.filterwarnings("ignore", category=DeprecationWarning, module="supabase")
|
|
45
|
-
warnings.filterwarnings(
|
|
46
|
+
warnings.filterwarnings(
|
|
47
|
+
"ignore", category=DeprecationWarning, module="supabase_functions"
|
|
48
|
+
)
|
|
46
49
|
warnings.filterwarnings("ignore", category=DeprecationWarning, module="postgrest")
|
|
47
50
|
|
|
48
51
|
from packaging import version as packaging_version
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import importlib as il
|
|
5
|
+
import inspect
|
|
6
|
+
import os
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
|
|
10
|
+
from lamin_utils import logger
|
|
11
|
+
|
|
12
|
+
from ._silence_loggers import silence_loggers
|
|
13
|
+
from .core import django as django_lamin
|
|
14
|
+
from .core._settings import settings
|
|
15
|
+
from .core._settings_store import current_instance_settings_file
|
|
16
|
+
from .errors import (
|
|
17
|
+
MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE,
|
|
18
|
+
ModuleWasntConfigured,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from collections.abc import Callable
|
|
23
|
+
|
|
24
|
+
from .core._settings_instance import InstanceSettings
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
IS_LOADING: bool = False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# decorator to disable auto-connect when importing a module such as lamindb
|
|
31
|
+
def disable_auto_connect(func: Callable):
|
|
32
|
+
@functools.wraps(func)
|
|
33
|
+
def wrapper(*args, **kwargs):
|
|
34
|
+
global IS_LOADING
|
|
35
|
+
IS_LOADING = True
|
|
36
|
+
try:
|
|
37
|
+
return func(*args, **kwargs)
|
|
38
|
+
finally:
|
|
39
|
+
IS_LOADING = False
|
|
40
|
+
|
|
41
|
+
return wrapper
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _normalize_module_name(module_name: str) -> str:
|
|
45
|
+
return module_name.replace("lnschema_", "").replace("_", "-")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# checks that the provided modules is in the modules of the provided instance
|
|
49
|
+
# or in the apps setup by django
|
|
50
|
+
def _check_module_in_instance_modules(
|
|
51
|
+
module: str, isettings: InstanceSettings | None = None
|
|
52
|
+
) -> None:
|
|
53
|
+
if isettings is not None:
|
|
54
|
+
modules_raw = isettings.modules
|
|
55
|
+
modules = set(modules_raw).union(
|
|
56
|
+
_normalize_module_name(module) for module in modules_raw
|
|
57
|
+
)
|
|
58
|
+
if _normalize_module_name(module) not in modules and module not in modules:
|
|
59
|
+
raise ModuleWasntConfigured(
|
|
60
|
+
MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module)
|
|
61
|
+
)
|
|
62
|
+
else:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
from django.apps import apps
|
|
66
|
+
|
|
67
|
+
for app in apps.get_app_configs():
|
|
68
|
+
# app.name is always unnormalized module (python package) name
|
|
69
|
+
if module == app.name or module == _normalize_module_name(app.name):
|
|
70
|
+
return
|
|
71
|
+
raise ModuleWasntConfigured(MODULE_WASNT_CONFIGURED_MESSAGE_TEMPLATE.format(module))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# infer the name of the module that calls this function
|
|
75
|
+
def _infer_callers_module_name() -> str | None:
|
|
76
|
+
stack = inspect.stack()
|
|
77
|
+
if len(stack) < 3:
|
|
78
|
+
return None
|
|
79
|
+
module = inspect.getmodule(stack[2][0])
|
|
80
|
+
return module.__name__.partition(".")[0] if module is not None else None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# we make this a private function because in all the places it's used,
|
|
84
|
+
# users should not see it
|
|
85
|
+
def _check_instance_setup(from_module: str | None = None) -> bool:
|
|
86
|
+
if django_lamin.IS_SETUP:
|
|
87
|
+
if from_module is not None:
|
|
88
|
+
if from_module != "lamindb":
|
|
89
|
+
_check_module_in_instance_modules(from_module)
|
|
90
|
+
else:
|
|
91
|
+
infer_module = _infer_callers_module_name()
|
|
92
|
+
if infer_module is not None and infer_module not in {
|
|
93
|
+
"lamindb",
|
|
94
|
+
"lamindb_setup",
|
|
95
|
+
"lamin_cli",
|
|
96
|
+
}:
|
|
97
|
+
_check_module_in_instance_modules(infer_module)
|
|
98
|
+
return True
|
|
99
|
+
silence_loggers()
|
|
100
|
+
if os.environ.get("LAMINDB_MULTI_INSTANCE") == "true":
|
|
101
|
+
logger.warning(
|
|
102
|
+
"running LaminDB in multi-instance mode; you'll experience "
|
|
103
|
+
"errors in regular lamindb usage"
|
|
104
|
+
)
|
|
105
|
+
return True
|
|
106
|
+
|
|
107
|
+
if IS_LOADING or from_module is None:
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
not settings._instance_exists
|
|
112
|
+
and os.environ.get("LAMIN_CURRENT_INSTANCE") is not None
|
|
113
|
+
):
|
|
114
|
+
from ._connect_instance import connect
|
|
115
|
+
|
|
116
|
+
connect(_write_settings=False, _reload_lamindb=False)
|
|
117
|
+
return django_lamin.IS_SETUP
|
|
118
|
+
else:
|
|
119
|
+
isettings = settings.instance
|
|
120
|
+
if from_module != "lamindb":
|
|
121
|
+
_check_module_in_instance_modules(from_module, isettings)
|
|
122
|
+
|
|
123
|
+
import lamindb # connect to the instance
|
|
124
|
+
else:
|
|
125
|
+
# disable_auto_connect to avoid triggering _check_instance_setup in modules
|
|
126
|
+
disable_auto_connect(django_lamin.setup_django)(isettings)
|
|
127
|
+
if isettings.slug != "none/none":
|
|
128
|
+
logger.important(f"connected lamindb: {isettings.slug}")
|
|
129
|
+
# update of local storage location through search_local_root()
|
|
130
|
+
settings._instance_settings = isettings
|
|
131
|
+
return django_lamin.IS_SETUP
|
|
@@ -9,10 +9,7 @@ from uuid import UUID
|
|
|
9
9
|
|
|
10
10
|
from lamin_utils import logger
|
|
11
11
|
|
|
12
|
-
from ._check_setup import
|
|
13
|
-
_check_instance_setup,
|
|
14
|
-
_get_current_instance_settings,
|
|
15
|
-
)
|
|
12
|
+
from ._check_setup import _check_instance_setup
|
|
16
13
|
from ._disconnect import disconnect
|
|
17
14
|
from ._init_instance import load_from_isettings
|
|
18
15
|
from ._silence_loggers import silence_loggers
|
|
@@ -266,13 +263,8 @@ def validate_connection_state(
|
|
|
266
263
|
from django.db import connection
|
|
267
264
|
|
|
268
265
|
if (
|
|
269
|
-
settings._instance_exists
|
|
266
|
+
settings._instance_exists # exists only for real instances, not for none/none
|
|
270
267
|
and f"{owner}/{name}" == settings.instance.slug
|
|
271
|
-
# below is to ensure that if another process interferes
|
|
272
|
-
# we don't use the in-memory mock database
|
|
273
|
-
# could be made more specific by checking whether the django
|
|
274
|
-
# configured database is the same as the one in settings
|
|
275
|
-
and connection.settings_dict["NAME"] != ":memory:"
|
|
276
268
|
and not use_root_db_user # always re-connect for root db user
|
|
277
269
|
):
|
|
278
270
|
logger.important(
|
|
@@ -280,7 +272,7 @@ def validate_connection_state(
|
|
|
280
272
|
)
|
|
281
273
|
return None
|
|
282
274
|
else:
|
|
283
|
-
if settings._instance_exists
|
|
275
|
+
if settings._instance_exists:
|
|
284
276
|
import lamindb as ln
|
|
285
277
|
|
|
286
278
|
if ln.context.transform is not None:
|
|
@@ -292,7 +284,9 @@ def validate_connection_state(
|
|
|
292
284
|
|
|
293
285
|
@unlock_cloud_sqlite_upon_exception(ignore_prev_locker=True)
|
|
294
286
|
def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
295
|
-
"""Connect
|
|
287
|
+
"""Connect the global default instance.
|
|
288
|
+
|
|
289
|
+
If you want to create a read-only database client, use :class:`~lamindb.DB` instead.
|
|
296
290
|
|
|
297
291
|
Args:
|
|
298
292
|
instance: Pass a slug (`account/name`) or URL (`https://lamin.ai/account/name`).
|
|
@@ -340,12 +334,9 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
340
334
|
if settings._instance_exists:
|
|
341
335
|
isettings = settings.instance
|
|
342
336
|
else:
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
"No instance was connected through the CLI, pass a value to `instance` or connect via the CLI."
|
|
347
|
-
)
|
|
348
|
-
isettings = isettings_or_none
|
|
337
|
+
raise ValueError(
|
|
338
|
+
"No instance was connected through the CLI, pass a value to `instance` or connect via the CLI."
|
|
339
|
+
)
|
|
349
340
|
if use_root_db_user:
|
|
350
341
|
reset_django()
|
|
351
342
|
owner, name = isettings.owner, isettings.name
|
|
@@ -414,7 +405,6 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
414
405
|
|
|
415
406
|
load_from_isettings(isettings, user=_user, write_settings=_write_settings)
|
|
416
407
|
if _reload_lamindb:
|
|
417
|
-
importlib.reload(importlib.import_module("lamindb"))
|
|
418
408
|
reset_django_module_variables()
|
|
419
409
|
if isettings.slug != "none/none":
|
|
420
410
|
logger.important(f"connected lamindb: {isettings.slug}")
|
|
@@ -424,10 +414,6 @@ def connect(instance: str | None = None, **kwargs: Any) -> str | tuple | None:
|
|
|
424
414
|
isettings._get_settings_file().unlink(missing_ok=True) # type: ignore
|
|
425
415
|
settings._instance_settings = None
|
|
426
416
|
raise e
|
|
427
|
-
if settings.dev_dir is None:
|
|
428
|
-
logger.important_hint(
|
|
429
|
-
"to map a local dev directory, set: ln.setup.settings.dev_dir = '.'"
|
|
430
|
-
)
|
|
431
417
|
return None
|
|
432
418
|
|
|
433
419
|
|
|
@@ -11,6 +11,7 @@ from .core._aws_options import HOSTED_BUCKETS
|
|
|
11
11
|
from .core._hub_core import delete_instance as delete_instance_on_hub
|
|
12
12
|
from .core._hub_core import get_storage_records_for_instance
|
|
13
13
|
from .core._settings import settings
|
|
14
|
+
from .core._settings_load import load_instance_settings
|
|
14
15
|
from .core._settings_storage import StorageSettings
|
|
15
16
|
from .core.upath import LocalPathClasses, check_storage_is_empty
|
|
16
17
|
|
|
@@ -38,6 +39,8 @@ def delete_exclusion_dir(isettings: InstanceSettings) -> None:
|
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
def delete_by_isettings(isettings: InstanceSettings) -> None:
|
|
42
|
+
assert isettings.slug != "none/none"
|
|
43
|
+
|
|
41
44
|
settings_file = isettings._get_settings_file()
|
|
42
45
|
if settings_file.exists():
|
|
43
46
|
settings_file.unlink()
|
|
@@ -51,12 +54,14 @@ def delete_by_isettings(isettings: InstanceSettings) -> None:
|
|
|
51
54
|
"Did not have permission to delete SQLite file:"
|
|
52
55
|
f" {isettings._sqlite_file}"
|
|
53
56
|
)
|
|
54
|
-
pass
|
|
55
57
|
# unset the global instance settings
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
settings.
|
|
58
|
+
isettings_on_disk = load_instance_settings()
|
|
59
|
+
if isettings_on_disk.slug == isettings.slug:
|
|
60
|
+
settings._instance_settings_path.unlink() # current instance settings file
|
|
61
|
+
# settings.instance can differ from instance in current_settings_file()
|
|
62
|
+
# due to connect() in the same process
|
|
63
|
+
if settings.instance.slug == isettings.slug:
|
|
64
|
+
settings._instance_settings = None
|
|
60
65
|
|
|
61
66
|
|
|
62
67
|
def delete(slug: str, force: bool = False, require_empty: bool = True) -> int | None:
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from lamin_utils import logger
|
|
4
4
|
|
|
5
5
|
from .core._settings import settings
|
|
6
|
-
from .core.
|
|
6
|
+
from .core._settings_load import load_instance_settings
|
|
7
7
|
from .core.cloud_sqlite_locker import clear_locker
|
|
8
8
|
|
|
9
9
|
|
|
@@ -15,10 +15,11 @@ def disconnect(mute: bool = False) -> None:
|
|
|
15
15
|
See Also:
|
|
16
16
|
Clear default instance configuration via the CLI, see `here <https://docs.lamin.ai/cli#disconnect>`__.
|
|
17
17
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
# settings._instance_exists can be true due to connect even without having a file
|
|
19
|
+
if settings._instance_exists:
|
|
20
|
+
instance = settings.instance
|
|
20
21
|
try:
|
|
21
|
-
|
|
22
|
+
instance._update_cloud_sqlite_file()
|
|
22
23
|
except Exception as e:
|
|
23
24
|
if isinstance(e, FileNotFoundError):
|
|
24
25
|
logger.warning("did not find local cache file")
|
|
@@ -26,10 +27,12 @@ def disconnect(mute: bool = False) -> None:
|
|
|
26
27
|
logger.warning("did not upload cache file - not enough permissions")
|
|
27
28
|
else:
|
|
28
29
|
raise e
|
|
29
|
-
current_instance_settings_file().unlink()
|
|
30
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
|
|
31
35
|
if not mute:
|
|
32
|
-
logger.success(f"disconnected instance: {instance}")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
logger.info("no instance loaded")
|
|
36
|
+
logger.success(f"disconnected instance: {instance.slug}")
|
|
37
|
+
elif not mute:
|
|
38
|
+
logger.info("no instance loaded")
|
|
@@ -340,7 +340,6 @@ def init(
|
|
|
340
340
|
from ._schema_metadata import update_schema_in_hub
|
|
341
341
|
|
|
342
342
|
update_schema_in_hub(access_token=access_token)
|
|
343
|
-
importlib.reload(importlib.import_module("lamindb"))
|
|
344
343
|
reset_django_module_variables()
|
|
345
344
|
logger.important(f"initialized lamindb: {isettings.slug}")
|
|
346
345
|
except Exception as e:
|
|
@@ -125,24 +125,10 @@ class migrate:
|
|
|
125
125
|
from lamindb_setup._schema_metadata import update_schema_in_hub
|
|
126
126
|
from lamindb_setup.core._hub_client import call_with_fallback_auth
|
|
127
127
|
from lamindb_setup.core._hub_crud import (
|
|
128
|
-
select_collaborator,
|
|
129
128
|
update_instance,
|
|
130
129
|
)
|
|
131
130
|
|
|
132
131
|
if settings.instance.is_on_hub:
|
|
133
|
-
# double check that user is an admin, otherwise will fail below
|
|
134
|
-
# due to insufficient SQL permissions with cryptic error
|
|
135
|
-
collaborator = call_with_fallback_auth(
|
|
136
|
-
select_collaborator,
|
|
137
|
-
instance_id=settings.instance._id,
|
|
138
|
-
account_id=settings.user._uuid,
|
|
139
|
-
fine_grained_access=settings.instance._fine_grained_access,
|
|
140
|
-
)
|
|
141
|
-
if collaborator is None or collaborator["role"] != "admin":
|
|
142
|
-
raise SystemExit(
|
|
143
|
-
"❌ Only admins can deploy migrations, please ensure that you're an"
|
|
144
|
-
f" admin: https://lamin.ai/{settings.instance.slug}/settings"
|
|
145
|
-
)
|
|
146
132
|
# ensure we connect with the root user
|
|
147
133
|
if "root" not in settings.instance.db:
|
|
148
134
|
connect(use_root_db_user=True)
|
|
@@ -172,7 +172,8 @@ class _ModelHandler:
|
|
|
172
172
|
self.table_name = model._meta.db_table
|
|
173
173
|
self.included_modules = included_modules
|
|
174
174
|
self.fields = self._get_fields_metadata(self.model)
|
|
175
|
-
self.
|
|
175
|
+
self.is_auto_created = bool(model._meta.auto_created)
|
|
176
|
+
self.is_link_table = issubclass(model, IsLink) or self.is_auto_created
|
|
176
177
|
self.name_field = model._name_field if hasattr(model, "_name_field") else None
|
|
177
178
|
self.ontology_id_field = (
|
|
178
179
|
model._ontology_id_field if hasattr(model, "_ontology_id_field") else None
|
|
@@ -183,6 +184,7 @@ class _ModelHandler:
|
|
|
183
184
|
"fields": self.fields.copy(),
|
|
184
185
|
"class_name": self.class_name,
|
|
185
186
|
"table_name": self.table_name,
|
|
187
|
+
"is_auto_created": self.is_auto_created,
|
|
186
188
|
"is_link_table": self.is_link_table,
|
|
187
189
|
"name_field": self.name_field,
|
|
188
190
|
"ontology_id_field": self.ontology_id_field,
|
|
@@ -249,13 +251,13 @@ class _ModelHandler:
|
|
|
249
251
|
return related_fields
|
|
250
252
|
|
|
251
253
|
def _get_field_metadata(self, model, field: Field):
|
|
252
|
-
from lamindb.models import IsLink
|
|
254
|
+
from lamindb.models import IsLink, Registry
|
|
253
255
|
|
|
254
256
|
internal_type = field.get_internal_type()
|
|
255
257
|
model_name = field.model._meta.model_name
|
|
256
258
|
relation_type = self._get_relation_type(model, field)
|
|
257
259
|
|
|
258
|
-
schema_name = field.model
|
|
260
|
+
schema_name = Registry.__get_module_name__(field.model)
|
|
259
261
|
|
|
260
262
|
if field.related_model is None:
|
|
261
263
|
related_model_name = None
|
|
@@ -265,7 +267,7 @@ class _ModelHandler:
|
|
|
265
267
|
max_length = field.max_length
|
|
266
268
|
else:
|
|
267
269
|
related_model_name = field.related_model._meta.model_name
|
|
268
|
-
related_schema_name = field.related_model
|
|
270
|
+
related_schema_name = Registry.__get_module_name__(field.related_model)
|
|
269
271
|
related_field_name = field.remote_field.name
|
|
270
272
|
is_editable = False
|
|
271
273
|
max_length = None
|
|
@@ -418,14 +420,10 @@ class _SchemaHandler:
|
|
|
418
420
|
all_models = {module_name: {} for module_name in self.included_modules}
|
|
419
421
|
|
|
420
422
|
# Iterate through all registered Django models
|
|
421
|
-
for model in apps.get_models():
|
|
423
|
+
for model in apps.get_models(include_auto_created=True):
|
|
422
424
|
# Check if model meets the criteria
|
|
423
|
-
if
|
|
424
|
-
|
|
425
|
-
and model is not SQLRecord
|
|
426
|
-
and not model._meta.abstract
|
|
427
|
-
):
|
|
428
|
-
module_name = model.__get_module_name__()
|
|
425
|
+
if model is not SQLRecord and not model._meta.abstract:
|
|
426
|
+
module_name = Registry.__get_module_name__(model)
|
|
429
427
|
# Only include if module is in our included list
|
|
430
428
|
if module_name in self.included_modules:
|
|
431
429
|
model_name = model._meta.model_name
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
from time import sleep
|
|
4
5
|
from typing import TYPE_CHECKING
|
|
5
6
|
|
|
6
7
|
from lamin_utils import logger
|
|
@@ -43,6 +44,14 @@ def load_user(email: str | None = None, handle: str | None = None) -> UserSettin
|
|
|
43
44
|
return user_settings
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
def current_user_uid() -> str:
|
|
48
|
+
current_user_settings = current_user_settings_file()
|
|
49
|
+
if current_user_settings.exists():
|
|
50
|
+
return load_user_settings(current_user_settings).uid
|
|
51
|
+
|
|
52
|
+
return "00000000" # anonymous
|
|
53
|
+
|
|
54
|
+
|
|
46
55
|
def login(
|
|
47
56
|
user: str | None = None, *, api_key: str | None = None, **kwargs
|
|
48
57
|
) -> UserSettings:
|
|
@@ -51,15 +60,14 @@ def login(
|
|
|
51
60
|
|
|
52
61
|
`login()` prompts for your API key unless you set it via the `LAMIN_API_KEY` environment variable or pass it as an argument.
|
|
53
62
|
|
|
54
|
-
You can create your API key in your account settings on LaminHub
|
|
63
|
+
You can create your API key in your account settings on LaminHub at `lamin.ai/settings <https://lamin.ai/settings>`__.
|
|
64
|
+
|
|
65
|
+
Note that the preferred method is to use the CLI command `lamin login`: `docs.lamin.ai/cli#login <https://docs.lamin.ai/cli#login>`__.
|
|
55
66
|
|
|
56
67
|
Args:
|
|
57
68
|
user: User handle.
|
|
58
69
|
api_key: API key.
|
|
59
70
|
|
|
60
|
-
See Also:
|
|
61
|
-
Login via the CLI command `lamin login`, see `here <https://docs.lamin.ai/cli#login>`__.
|
|
62
|
-
|
|
63
71
|
Examples:
|
|
64
72
|
|
|
65
73
|
Logging in the first time::
|
|
@@ -72,12 +80,15 @@ def login(
|
|
|
72
80
|
|
|
73
81
|
ln.setup.login("myhandle") # pass your user handle
|
|
74
82
|
"""
|
|
83
|
+
from getpass import getpass
|
|
84
|
+
|
|
75
85
|
if user is None:
|
|
76
86
|
if api_key is None:
|
|
77
87
|
if "LAMIN_API_KEY" in os.environ:
|
|
78
88
|
api_key = os.environ["LAMIN_API_KEY"]
|
|
79
89
|
else:
|
|
80
|
-
|
|
90
|
+
print("Copy your API key. To create one: https://lamin.ai/settings")
|
|
91
|
+
api_key = getpass("Paste it: ")
|
|
81
92
|
elif api_key is not None:
|
|
82
93
|
raise ValueError("Please provide either 'user' or 'api_key', not both.")
|
|
83
94
|
|
|
@@ -90,6 +101,9 @@ def login(
|
|
|
90
101
|
"the legacy API key is deprecated and will likely be removed in a future version"
|
|
91
102
|
)
|
|
92
103
|
|
|
104
|
+
# do this here because load_user overwrites current_user_settings_file
|
|
105
|
+
previous_user_uid = current_user_uid()
|
|
106
|
+
|
|
93
107
|
if api_key is None:
|
|
94
108
|
if "@" in user: # type: ignore
|
|
95
109
|
email, handle = user, None
|
|
@@ -144,8 +158,15 @@ def login(
|
|
|
144
158
|
user_settings.api_key = api_key
|
|
145
159
|
save_user_settings(user_settings)
|
|
146
160
|
|
|
147
|
-
if settings._instance_exists
|
|
148
|
-
|
|
161
|
+
if settings._instance_exists:
|
|
162
|
+
if (
|
|
163
|
+
isettings := settings.instance
|
|
164
|
+
).is_on_hub and previous_user_uid != user_settings.uid:
|
|
165
|
+
logger.important_hint(
|
|
166
|
+
f"consider re-connecting to update permissions: lamin connect {isettings.slug}"
|
|
167
|
+
)
|
|
168
|
+
if _check_instance_setup():
|
|
169
|
+
register_user(user_settings)
|
|
149
170
|
|
|
150
171
|
settings._user_settings = None
|
|
151
172
|
# aws s3 credentials are scoped to the user
|
|
@@ -25,6 +25,8 @@ def silence_loggers():
|
|
|
25
25
|
set_stream_logger(name="botocore.auth", level=logging.WARNING)
|
|
26
26
|
set_stream_logger(name="botocore.endpoint", level=logging.WARNING)
|
|
27
27
|
set_stream_logger(name="httpx", level=logging.WARNING)
|
|
28
|
+
set_stream_logger(name="httpcore", level=logging.WARNING)
|
|
29
|
+
set_stream_logger(name="hpack", level=logging.WARNING)
|
|
28
30
|
try:
|
|
29
31
|
import aiobotocore
|
|
30
32
|
|