lamindb_setup 1.16.0__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.16.0 → lamindb_setup-1.17.0}/.github/workflows/build.yml +54 -1
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/.gitignore +1 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/PKG-INFO +4 -5
- {lamindb_setup-1.16.0 → 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.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_connect_instance.py +9 -23
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_delete.py +10 -5
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_disconnect.py +12 -9
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_init_instance.py +0 -1
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_migrate.py +0 -14
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_setup_user.py +8 -5
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_silence_loggers.py +2 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_aws_options.py +17 -7
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_client.py +1 -2
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_core.py +9 -6
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings.py +14 -10
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_instance.py +28 -6
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_load.py +25 -7
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/django.py +46 -18
- lamindb_setup-1.17.0/lamindb_setup/core/lamin.db.gz +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/upath.py +15 -6
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/errors.py +0 -12
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/io.py +16 -5
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/noxfile.py +18 -3
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/pyproject.toml +1 -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.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_clone_instance.py +1 -1
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_connect_instance.py +15 -6
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_edge_request.py +1 -1
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_init_instance.py +1 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_login.py +3 -8
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-local/conftest.py +8 -2
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-local/test_all.py +2 -2
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_switch_and_fallback_env.py +2 -2
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_db_import_export.py +2 -2
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_storage_access.py +4 -8
- lamindb_setup-1.16.0/docs/hub-prod/test-insufficient-user-info.ipynb +0 -192
- lamindb_setup-1.16.0/lamindb_setup/_check_setup.py +0 -192
- lamindb_setup-1.16.0/tests/storage/test_httpx_client.py +0 -21
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/.github/workflows/doc-changes.yml +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/.pre-commit-config.yaml +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/LICENSE +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/README.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/changelog.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/09-test-migrate.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-cloud/test_notebooks.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-cache-management.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-empty-init.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-import-schema.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-init-load-local-anonymously.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/hub-prod/test_notebooks2.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/index.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/notebooks.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/docs/reference.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_cache.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_check.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_django.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_entry_points.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_register_instance.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_schema.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_schema_metadata.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/_set_managed_storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/__init__.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_aws_storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_clone.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_deprecated.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_docs.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_crud.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_hub_utils.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_private_django_api.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_save.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_store.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_settings_user.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/exceptions.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/hashing.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/core/types.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/py.typed +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/lamindb_setup/types.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/scripts/script-init-pass-user-no-writes.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_delete_instance.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_init_pass_user_no_writes.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-cloud/test_set_storage.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-local/README.md +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-local/scripts/script-connect-fine-grained-access.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-local/test_update_schema_in_hub.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/conftest.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_aws_options_manager.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_django.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_global_settings.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_migrate.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/hub-prod/test_upath.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/conftest.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_entry_point.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_hashing.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_storage_basis.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_storage_settings.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_storage_stats.py +0 -0
- {lamindb_setup-1.16.0 → lamindb_setup-1.17.0}/tests/storage/test_to_url.py +0 -0
|
@@ -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
|
|
@@ -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,10 +1,11 @@
|
|
|
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
|
|
@@ -15,9 +16,7 @@ Requires-Dist: httpx_retries<1.0.0
|
|
|
15
16
|
Requires-Dist: requests
|
|
16
17
|
Requires-Dist: universal_pathlib==0.2.6
|
|
17
18
|
Requires-Dist: botocore<2.0.0
|
|
18
|
-
Requires-Dist: supabase>=2.
|
|
19
|
-
Requires-Dist: gotrue<=2.12.0
|
|
20
|
-
Requires-Dist: storage3!=0.11.2; python_version < '3.11'
|
|
19
|
+
Requires-Dist: supabase>=2.20.0,<=2.24.0
|
|
21
20
|
Requires-Dist: pyjwt<3.0.0
|
|
22
21
|
Requires-Dist: psutil
|
|
23
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)
|
|
@@ -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
|
|
@@ -59,15 +60,14 @@ def login(
|
|
|
59
60
|
|
|
60
61
|
`login()` prompts for your API key unless you set it via the `LAMIN_API_KEY` environment variable or pass it as an argument.
|
|
61
62
|
|
|
62
|
-
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>`__.
|
|
63
66
|
|
|
64
67
|
Args:
|
|
65
68
|
user: User handle.
|
|
66
69
|
api_key: API key.
|
|
67
70
|
|
|
68
|
-
See Also:
|
|
69
|
-
Login via the CLI command `lamin login`, see `here <https://docs.lamin.ai/cli#login>`__.
|
|
70
|
-
|
|
71
71
|
Examples:
|
|
72
72
|
|
|
73
73
|
Logging in the first time::
|
|
@@ -80,12 +80,15 @@ def login(
|
|
|
80
80
|
|
|
81
81
|
ln.setup.login("myhandle") # pass your user handle
|
|
82
82
|
"""
|
|
83
|
+
from getpass import getpass
|
|
84
|
+
|
|
83
85
|
if user is None:
|
|
84
86
|
if api_key is None:
|
|
85
87
|
if "LAMIN_API_KEY" in os.environ:
|
|
86
88
|
api_key = os.environ["LAMIN_API_KEY"]
|
|
87
89
|
else:
|
|
88
|
-
|
|
90
|
+
print("Copy your API key. To create one: https://lamin.ai/settings")
|
|
91
|
+
api_key = getpass("Paste it: ")
|
|
89
92
|
elif api_key is not None:
|
|
90
93
|
raise ValueError("Please provide either 'user' or 'api_key', not both.")
|
|
91
94
|
|
|
@@ -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
|
|
|
@@ -60,6 +60,7 @@ class AWSOptionsManager:
|
|
|
60
60
|
from aiobotocore.session import AioSession
|
|
61
61
|
from s3fs import S3FileSystem
|
|
62
62
|
|
|
63
|
+
anon_env = os.getenv("LAMIN_S3_ANON") == "true"
|
|
63
64
|
# this is cached so will be resued with the connection initialized
|
|
64
65
|
# these options are set for paths in _path_inject_options
|
|
65
66
|
# here we set the same options to cache the filesystem
|
|
@@ -68,19 +69,28 @@ class AWSOptionsManager:
|
|
|
68
69
|
use_listings_cache=True,
|
|
69
70
|
version_aware=False,
|
|
70
71
|
config_kwargs={"max_pool_connections": 64},
|
|
72
|
+
anon=anon_env,
|
|
71
73
|
)
|
|
72
74
|
|
|
73
75
|
self._suppress_aiobotocore_traceback_logging()
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.anon: bool = fs.session._credentials is None
|
|
78
|
-
except Exception as e:
|
|
77
|
+
if anon_env:
|
|
78
|
+
self.anon: bool = True
|
|
79
79
|
logger.warning(
|
|
80
|
-
|
|
81
|
-
"
|
|
80
|
+
"`anon` mode will be used for all non-managed buckets "
|
|
81
|
+
"because the environment variable LAMIN_S3_ANON was set to 'true'"
|
|
82
82
|
)
|
|
83
|
-
|
|
83
|
+
else:
|
|
84
|
+
try:
|
|
85
|
+
fs.connect()
|
|
86
|
+
self.anon = fs.session._credentials is None
|
|
87
|
+
except Exception as e:
|
|
88
|
+
logger.warning(
|
|
89
|
+
f"There is a problem with your default AWS Credentials: {e}\n"
|
|
90
|
+
"`anon` mode will be used for all non-managed buckets"
|
|
91
|
+
)
|
|
92
|
+
self.anon = True
|
|
93
|
+
|
|
84
94
|
self.anon_public: bool | None = None
|
|
85
95
|
if not self.anon:
|
|
86
96
|
try:
|
|
@@ -11,8 +11,7 @@ import httpx
|
|
|
11
11
|
from httpx_retries import Retry, RetryTransport
|
|
12
12
|
from lamin_utils import logger
|
|
13
13
|
from pydantic_settings import BaseSettings
|
|
14
|
-
from supabase import Client, create_client
|
|
15
|
-
from supabase.lib.client_options import ClientOptions
|
|
14
|
+
from supabase import Client, ClientOptions, create_client
|
|
16
15
|
|
|
17
16
|
from ._settings_save import save_user_settings
|
|
18
17
|
|
|
@@ -383,7 +383,8 @@ def _init_instance_hub(
|
|
|
383
383
|
) -> None:
|
|
384
384
|
from ._settings import settings
|
|
385
385
|
|
|
386
|
-
|
|
386
|
+
created_by_id = settings.user._uuid.hex if account_id is None else account_id.hex # type: ignore
|
|
387
|
+
owner_account_id = os.getenv("LAMINDB_ACCOUNT_ID_INIT", created_by_id)
|
|
387
388
|
|
|
388
389
|
try:
|
|
389
390
|
lamindb_version = metadata.version("lamindb")
|
|
@@ -391,13 +392,13 @@ def _init_instance_hub(
|
|
|
391
392
|
lamindb_version = None
|
|
392
393
|
fields = {
|
|
393
394
|
"id": isettings._id.hex,
|
|
394
|
-
"account_id":
|
|
395
|
+
"account_id": owner_account_id,
|
|
395
396
|
"name": isettings.name,
|
|
396
397
|
"lnid": isettings.uid,
|
|
397
398
|
"schema_str": isettings._schema_str,
|
|
398
399
|
"lamindb_version": lamindb_version,
|
|
399
400
|
"public": False,
|
|
400
|
-
"created_by_id":
|
|
401
|
+
"created_by_id": created_by_id,
|
|
401
402
|
}
|
|
402
403
|
if isettings.dialect != "sqlite":
|
|
403
404
|
db_dsn = LaminDsnModel(db=isettings.db)
|
|
@@ -407,7 +408,7 @@ def _init_instance_hub(
|
|
|
407
408
|
"db_port": db_dsn.db.port,
|
|
408
409
|
"db_database": db_dsn.db.database,
|
|
409
410
|
}
|
|
410
|
-
fields.update(db_fields)
|
|
411
|
+
fields.update(db_fields) # type: ignore
|
|
411
412
|
slug = isettings.slug
|
|
412
413
|
# I'd like the following to be an upsert, but this seems to violate RLS
|
|
413
414
|
# Similarly, if we don't specify `returning="minimal"`, we'll violate RLS
|
|
@@ -415,7 +416,9 @@ def _init_instance_hub(
|
|
|
415
416
|
# as then init_instance is no longer idempotent
|
|
416
417
|
try:
|
|
417
418
|
client.table("instance").insert(fields, returning="minimal").execute()
|
|
418
|
-
except APIError:
|
|
419
|
+
except APIError as e:
|
|
420
|
+
if "new row violates row-level security policy" in str(e):
|
|
421
|
+
raise e
|
|
419
422
|
logger.warning(f"instance already existed at: https://lamin.ai/{slug}")
|
|
420
423
|
return None
|
|
421
424
|
if isettings.dialect != "sqlite" and isettings.is_remote:
|
|
@@ -713,7 +716,7 @@ def get_lamin_site_base_url():
|
|
|
713
716
|
|
|
714
717
|
|
|
715
718
|
def sign_up_local_hub(email) -> str | tuple[str, str, str]:
|
|
716
|
-
# raises
|
|
719
|
+
# raises AuthApiError: User already registered
|
|
717
720
|
password = base62(40) # generate new password
|
|
718
721
|
sign_up_kwargs = {"email": email, "password": password}
|
|
719
722
|
client = connect_hub()
|
|
@@ -46,6 +46,12 @@ def _process_cache_path(cache_path: UPathStr | None) -> UPath | None:
|
|
|
46
46
|
return cache_dir
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
# returned by settings.branch for none/none instance
|
|
50
|
+
class MainBranchMock:
|
|
51
|
+
id = 1
|
|
52
|
+
name = "main"
|
|
53
|
+
|
|
54
|
+
|
|
49
55
|
class SetupSettings:
|
|
50
56
|
"""Setup settings."""
|
|
51
57
|
|
|
@@ -140,6 +146,10 @@ class SetupSettings:
|
|
|
140
146
|
# and we never need a DB request
|
|
141
147
|
def branch(self) -> Branch:
|
|
142
148
|
"""Default branch."""
|
|
149
|
+
# this is needed for .filter() with non-default connections
|
|
150
|
+
if not self._instance_exists:
|
|
151
|
+
return MainBranchMock()
|
|
152
|
+
|
|
143
153
|
if self._branch is None:
|
|
144
154
|
from lamindb import Branch
|
|
145
155
|
|
|
@@ -222,10 +232,9 @@ class SetupSettings:
|
|
|
222
232
|
If `True`, the current instance is connected, meaning that the db and other settings
|
|
223
233
|
are properly configured for use.
|
|
224
234
|
"""
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return False
|
|
235
|
+
from . import django
|
|
236
|
+
|
|
237
|
+
return self._instance_exists and django.IS_SETUP
|
|
229
238
|
|
|
230
239
|
@property
|
|
231
240
|
def private_django_api(self) -> bool:
|
|
@@ -284,12 +293,7 @@ class SetupSettings:
|
|
|
284
293
|
|
|
285
294
|
@property
|
|
286
295
|
def _instance_exists(self):
|
|
287
|
-
|
|
288
|
-
self.instance # noqa
|
|
289
|
-
return True
|
|
290
|
-
# this is implicit logic that catches if no instance is loaded
|
|
291
|
-
except CurrentInstanceNotConfigured:
|
|
292
|
-
return False
|
|
296
|
+
return self.instance.slug != "none/none"
|
|
293
297
|
|
|
294
298
|
@property
|
|
295
299
|
def cache_dir(self) -> UPath:
|