lamindb_setup 1.18.1__tar.gz → 1.19.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.
Files changed (117) hide show
  1. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/.github/workflows/build.yml +34 -8
  2. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/PKG-INFO +2 -1
  3. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/02-connect-local-instance.ipynb +2 -2
  4. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/03-add-managed-storage.ipynb +12 -1
  5. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-cache-management.ipynb +4 -4
  6. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-import-schema.ipynb +3 -3
  7. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/__init__.py +4 -19
  8. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_connect_instance.py +7 -4
  9. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_delete.py +7 -3
  10. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_init_instance.py +1 -7
  11. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_migrate.py +6 -2
  12. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_set_managed_storage.py +2 -1
  13. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_aws_options.py +10 -0
  14. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_aws_storage.py +3 -1
  15. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_hub_client.py +6 -12
  16. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_hub_core.py +0 -2
  17. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings_instance.py +10 -6
  18. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings_load.py +11 -8
  19. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings_save.py +17 -5
  20. lamindb_setup-1.19.0/lamindb_setup/core/_settings_store.py +162 -0
  21. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/django.py +21 -0
  22. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/errors.py +7 -5
  23. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/io.py +12 -5
  24. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/noxfile.py +13 -12
  25. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/pyproject.toml +1 -0
  26. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_db_import_export.py +9 -0
  27. lamindb_setup-1.19.0/tests/core/test_settings_store_load_save.py +149 -0
  28. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_storage_access.py +1 -1
  29. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_edge_request.py +1 -1
  30. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-local/conftest.py +5 -6
  31. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-local/test_update_schema_in_hub.py +5 -5
  32. lamindb_setup-1.19.0/tests/profiling/connect_cli.py +3 -0
  33. lamindb_setup-1.19.0/tests/profiling/import_lamindb_setup.py +1 -0
  34. lamindb_setup-1.19.0/tests/profiling/print_lamindb_setup_settings.py +3 -0
  35. lamindb_setup-1.18.1/lamindb_setup/core/_settings_store.py +0 -92
  36. lamindb_setup-1.18.1/tests/storage/conftest.py +0 -10
  37. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/.github/workflows/doc-changes.yml +0 -0
  38. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/.gitignore +0 -0
  39. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/.pre-commit-config.yaml +0 -0
  40. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/LICENSE +0 -0
  41. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/README.md +0 -0
  42. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/changelog.md +0 -0
  43. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
  44. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
  45. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
  46. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
  47. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
  48. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
  49. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/09-test-migrate.ipynb +0 -0
  50. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-cloud/test_notebooks.py +0 -0
  51. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
  52. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
  53. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-empty-init.ipynb +0 -0
  54. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-init-load-local-anonymously.ipynb +0 -0
  55. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
  56. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
  57. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/hub-prod/test_notebooks2.py +0 -0
  58. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/index.md +0 -0
  59. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/notebooks.md +0 -0
  60. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/docs/reference.md +0 -0
  61. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_cache.py +0 -0
  62. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_check.py +0 -0
  63. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_check_setup.py +0 -0
  64. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_disconnect.py +0 -0
  65. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_django.py +0 -0
  66. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_entry_points.py +0 -0
  67. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_register_instance.py +0 -0
  68. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_schema.py +0 -0
  69. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_schema_metadata.py +0 -0
  70. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_setup_user.py +0 -0
  71. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/_silence_loggers.py +0 -0
  72. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/__init__.py +0 -0
  73. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_clone.py +0 -0
  74. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_deprecated.py +0 -0
  75. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_docs.py +0 -0
  76. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_hub_crud.py +0 -0
  77. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_hub_utils.py +0 -0
  78. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_private_django_api.py +0 -0
  79. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings.py +0 -0
  80. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings_storage.py +0 -0
  81. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_settings_user.py +0 -0
  82. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
  83. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
  84. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/exceptions.py +0 -0
  85. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/hashing.py +0 -0
  86. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/lamin.db.gz +0 -0
  87. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/types.py +0 -0
  88. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/core/upath.py +0 -0
  89. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/py.typed +0 -0
  90. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/lamindb_setup/types.py +0 -0
  91. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/connectivity/conftest.py +0 -0
  92. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/connectivity/test_proxies_certificates.py +0 -0
  93. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_entry_point.py +0 -0
  94. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_hashing.py +0 -0
  95. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_storage_basis.py +0 -0
  96. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_storage_settings.py +0 -0
  97. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_storage_stats.py +0 -0
  98. {lamindb_setup-1.18.1/tests/storage → lamindb_setup-1.19.0/tests/core}/test_to_url.py +0 -0
  99. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/scripts/script-init-pass-user-no-writes.py +0 -0
  100. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
  101. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_connect_instance.py +0 -0
  102. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_delete_instance.py +0 -0
  103. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
  104. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_init_instance.py +0 -0
  105. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_init_pass_user_no_writes.py +0 -0
  106. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_login.py +0 -0
  107. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-cloud/test_set_storage.py +0 -0
  108. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-local/README.md +0 -0
  109. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-local/scripts/script-connect-fine-grained-access.py +0 -0
  110. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-local/test_all.py +0 -0
  111. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/conftest.py +0 -0
  112. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_aws_options_manager.py +0 -0
  113. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_django.py +0 -0
  114. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_global_settings.py +0 -0
  115. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_migrate.py +0 -0
  116. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
  117. {lamindb_setup-1.18.1 → lamindb_setup-1.19.0}/tests/hub-prod/test_upath.py +0 -0
@@ -91,8 +91,7 @@ jobs:
91
91
  path: .coverage
92
92
  include-hidden-files: true
93
93
 
94
- # test user access to storage
95
- storage:
94
+ core:
96
95
  runs-on: ubuntu-latest
97
96
  timeout-minutes: 13
98
97
  steps:
@@ -103,15 +102,15 @@ jobs:
103
102
  cache: "pip"
104
103
  cache-dependency-path: ".github/workflows/build.yml"
105
104
  - run: pip install "laminci@git+https://x-access-token:${{ secrets.LAMIN_BUILD_DOCS }}@github.com/laminlabs/laminci"
106
- - run: nox -s "install(group='storage')"
105
+ - run: nox -s "install(group='core')"
107
106
  - run: nox -s lint
108
- - run: nox -s storage
107
+ - run: nox -s core
109
108
  env:
110
109
  TMP_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
111
110
  TMP_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
112
111
  - uses: actions/upload-artifact@v4
113
112
  with:
114
- name: coverage--storage
113
+ name: coverage--core
115
114
  path: .coverage
116
115
  include-hidden-files: true
117
116
 
@@ -137,7 +136,7 @@ jobs:
137
136
  touch .env.local
138
137
  echo "AWS_ACCESS_KEY_ID_HOSTED_S3=${{ secrets.AWS_ACCESS_KEY_ID }}" >> .env.local
139
138
  echo "AWS_SECRET_ACCESS_KEY_HOSTED_S3=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> .env.local
140
- working-directory: laminhub/backend/central/supabase
139
+ working-directory: laminhub/backend/services/central/supabase
141
140
  - uses: actions/setup-python@v6
142
141
  with:
143
142
  python-version: "3.11" # we need to run everything for coverage on 3.11
@@ -152,7 +151,7 @@ jobs:
152
151
  key: cache-supabase
153
152
  - uses: supabase/setup-cli@v1
154
153
  with:
155
- version: "2.6.8"
154
+ version: "2.72.7"
156
155
  - run: nox -s hub_local
157
156
  env:
158
157
  LAMIN_ENV: "local"
@@ -216,8 +215,35 @@ jobs:
216
215
  - name: run tests
217
216
  run: nox -s connectivity
218
217
 
218
+ profile:
219
+ runs-on: ubuntu-latest
220
+ timeout-minutes: 10
221
+ env:
222
+ LAMIN_API_KEY: ${{ secrets.LAMIN_API_KEY_TESTUSER1 }}
223
+ steps:
224
+ - uses: actions/checkout@v4
225
+ with:
226
+ submodules: recursive
227
+ fetch-depth: 0
228
+ - uses: actions/setup-python@v6
229
+ with:
230
+ python-version: |
231
+ ${{ github.ref == 'refs/heads/release' && '3.11' ||
232
+ '3.13'
233
+ }}
234
+ - run: pip install git+https://github.com/laminlabs/laminci
235
+ - run: uv pip install --system git+https://github.com/laminlabs/lamin-cli
236
+ - run: uv pip install --system git+https://github.com/laminlabs/lamindb
237
+ - run: uv pip install --system git+https://github.com/laminlabs/laminprofiler
238
+ - run: uv pip install --system -e .
239
+ - run: lamin login
240
+ - run: lamin connect laminlabs/lamindata
241
+ - run: laminprofiler check tests/profiling/import_lamindb_setup.py --threshold 0.25
242
+ - run: laminprofiler check tests/profiling/print_lamindb_setup_settings.py --threshold 0.4
243
+ - run: laminprofiler check tests/profiling/connect_cli.py --threshold 2.0
244
+
219
245
  coverage:
220
- needs: [hub-prod, hub-cloud, storage, hub-local]
246
+ needs: [hub-prod, hub-cloud, core, hub-local]
221
247
  runs-on: ubuntu-latest
222
248
  steps:
223
249
  - uses: actions/checkout@v4
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lamindb_setup
3
- Version: 1.18.1
3
+ Version: 1.19.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
8
  Requires-Dist: lamin_utils>=0.3.3
9
+ Requires-Dist: python-dotenv
9
10
  Requires-Dist: django>=5.2,<5.3
10
11
  Requires-Dist: dj_database_url>=1.3.0,<3.0.0
11
12
  Requires-Dist: django-pgtrigger
@@ -94,10 +94,10 @@
94
94
  "metadata": {},
95
95
  "outputs": [],
96
96
  "source": [
97
- "# wetlab is not in the (schema) modules of mydata\n",
97
+ "# pertdb is not in the (schema) modules of mydata\n",
98
98
  "with pytest.raises(ModuleWasntConfigured):\n",
99
99
  " # _check_instance_setup is called inside\n",
100
- " import wetlab"
100
+ " import pertdb"
101
101
  ]
102
102
  },
103
103
  {
@@ -48,11 +48,22 @@
48
48
  {
49
49
  "cell_type": "code",
50
50
  "execution_count": null,
51
- "id": "33c2bb76-d61f-4866-87e2-780e61600022",
51
+ "id": "cc2ba3c0",
52
52
  "metadata": {},
53
53
  "outputs": [],
54
54
  "source": [
55
55
  "import os\n",
56
+ "\n",
57
+ "os.environ[\"LAMINHUB_ID\"] = \"00000000-0000-0000-0000-000000000000\""
58
+ ]
59
+ },
60
+ {
61
+ "cell_type": "code",
62
+ "execution_count": null,
63
+ "id": "33c2bb76-d61f-4866-87e2-780e61600022",
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
56
67
  "import laminci\n",
57
68
  "import pytest\n",
58
69
  "from pathlib import Path\n",
@@ -239,7 +239,7 @@
239
239
  "metadata": {},
240
240
  "outputs": [],
241
241
  "source": [
242
- "exit_status = os.system(\"lamin cache clear\")\n",
242
+ "exit_status = os.system(\"lamin settings cache-dir clear\")\n",
243
243
  "assert exit_status == 0"
244
244
  ]
245
245
  },
@@ -346,7 +346,7 @@
346
346
  "metadata": {},
347
347
  "outputs": [],
348
348
  "source": [
349
- "exit_status = os.system(\"lamin cache get\")\n",
349
+ "exit_status = os.system(\"lamin settings cache-dir get\")\n",
350
350
  "assert exit_status == 0"
351
351
  ]
352
352
  },
@@ -357,7 +357,7 @@
357
357
  "metadata": {},
358
358
  "outputs": [],
359
359
  "source": [
360
- "exit_status = os.system(\"lamin cache set 'null'\")\n",
360
+ "exit_status = os.system(\"lamin settings cache-dir set 'null'\")\n",
361
361
  "assert exit_status == 0"
362
362
  ]
363
363
  },
@@ -397,7 +397,7 @@
397
397
  "name": "python",
398
398
  "nbconvert_exporter": "python",
399
399
  "pygments_lexer": "ipython3",
400
- "version": "3.10.16"
400
+ "version": "3.11.14"
401
401
  }
402
402
  },
403
403
  "nbformat": 4,
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "outputs": [],
29
29
  "source": [
30
- "!lamin init --storage test-implicit-load --modules wetlab,bionty"
30
+ "!lamin init --storage test-implicit-load --modules pertdb,bionty"
31
31
  ]
32
32
  },
33
33
  {
@@ -49,7 +49,7 @@
49
49
  "metadata": {},
50
50
  "outputs": [],
51
51
  "source": [
52
- "import wetlab as wl"
52
+ "import pertdb"
53
53
  ]
54
54
  },
55
55
  {
@@ -69,7 +69,7 @@
69
69
  "metadata": {},
70
70
  "outputs": [],
71
71
  "source": [
72
- "wl.Compound"
72
+ "pertdb.Compound"
73
73
  ]
74
74
  },
75
75
  {
@@ -35,7 +35,7 @@ Migration management
35
35
 
36
36
  """
37
37
 
38
- __version__ = "1.18.1" # denote a release candidate for 0.1.0 with 0.1rc1
38
+ __version__ = "1.19.0" # denote a release candidate for 0.1.0 with 0.1rc1
39
39
 
40
40
  import os
41
41
  import warnings
@@ -48,9 +48,9 @@ warnings.filterwarnings(
48
48
  )
49
49
  warnings.filterwarnings("ignore", category=DeprecationWarning, module="postgrest")
50
50
 
51
- from packaging import version as packaging_version
52
-
53
- from . import core, errors, io, types
51
+ # do not import io by default to reduce import time
52
+ # it's not immediately needed in the default user workflows
53
+ from . import core, errors, types
54
54
  from ._check_setup import _check_instance_setup
55
55
  from ._connect_instance import connect
56
56
  from ._delete import delete
@@ -63,20 +63,6 @@ from ._register_instance import register
63
63
  from ._setup_user import login, logout
64
64
  from .core._settings import settings
65
65
 
66
- # check that the version of s3fs is higher than the lower bound
67
- # needed because spatialdata installs old versions of s3fs
68
- try:
69
- from s3fs import __version__ as s3fs_version
70
-
71
- if packaging_version.parse(s3fs_version) < packaging_version.parse("2023.12.2"):
72
- raise RuntimeError(
73
- f"The version of s3fs you have ({s3fs_version}) is impompatible "
74
- "with lamindb, please upgrade it: pip install s3fs>=2023.12.2"
75
- )
76
- except ImportError:
77
- # might be not installed
78
- pass
79
-
80
66
 
81
67
  def _is_CI_environment() -> bool:
82
68
  ci_env_vars = [
@@ -112,5 +98,4 @@ _call_registered_entry_points("lamindb_setup.on_import")
112
98
 
113
99
  settings.__doc__ = """Global :class:`~lamindb.setup.core.SetupSettings`."""
114
100
 
115
-
116
101
  close = disconnect # backward compatibility
@@ -13,8 +13,6 @@ from ._check_setup import _check_instance_setup
13
13
  from ._disconnect import disconnect
14
14
  from ._init_instance import load_from_isettings
15
15
  from ._silence_loggers import silence_loggers
16
- from .core._hub_core import connect_instance_hub
17
- from .core._hub_utils import LaminDsnModel
18
16
  from .core._settings import settings
19
17
  from .core._settings_instance import InstanceSettings
20
18
  from .core._settings_load import load_instance_settings
@@ -66,6 +64,9 @@ def update_db_using_local(
66
64
  # read directly from the environment
67
65
  db_updated = db_env
68
66
  else:
67
+ # dynamic import to avoid importing the heavy LaminDsnModel at root
68
+ from .core._hub_utils import LaminDsnModel
69
+
69
70
  db_hub = hub_instance_result["db"]
70
71
  db_dsn_hub = LaminDsnModel(db=db_hub)
71
72
  # read from a cached settings file in case the hub result is inexistent
@@ -113,6 +114,8 @@ def _connect_instance(
113
114
  # the following will return a string if the instance does not exist on the hub
114
115
  # do not call hub if the user is anonymous
115
116
  if owner != "anonymous":
117
+ from .core._hub_core import connect_instance_hub
118
+
116
119
  hub_result = connect_instance_hub(
117
120
  owner=owner,
118
121
  name=name,
@@ -233,7 +236,8 @@ def reset_django_module_variables():
233
236
 
234
237
 
235
238
  def _connect_cli(
236
- instance: str, use_root_db_user: bool = False, use_proxy_db: bool = False
239
+ instance: str,
240
+ use_root_db_user: bool = False,
237
241
  ) -> None:
238
242
  from lamindb_setup import settings as settings_
239
243
 
@@ -242,7 +246,6 @@ def _connect_cli(
242
246
  owner,
243
247
  name,
244
248
  use_root_db_user=use_root_db_user,
245
- use_proxy_db=use_proxy_db,
246
249
  raise_systemexit=True,
247
250
  )
248
251
  isettings._persist(write_to_disk=True)
@@ -8,8 +8,6 @@ from lamin_utils import logger
8
8
 
9
9
  from ._connect_instance import _connect_instance, get_owner_name_from_identifier
10
10
  from .core._aws_options import HOSTED_BUCKETS
11
- from .core._hub_core import delete_instance as delete_instance_on_hub
12
- from .core._hub_core import get_storage_records_for_instance
13
11
  from .core._settings import settings
14
12
  from .core._settings_load import load_instance_settings
15
13
  from .core._settings_storage import StorageSettings
@@ -120,6 +118,9 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
120
118
  )
121
119
  # now everything that's on the hub
122
120
  if settings.user.handle != "anonymous":
121
+ # dynamic import to avoid importing hub logic at root
122
+ from .core._hub_core import get_storage_records_for_instance
123
+
123
124
  storage_records = get_storage_records_for_instance(isettings._id)
124
125
  for storage_record in storage_records:
125
126
  if storage_record["root"] == isettings.storage.root_as_str:
@@ -139,7 +140,10 @@ def delete(slug: str, force: bool = False, require_empty: bool = True) -> int |
139
140
  if settings.user.handle != "anonymous" and isettings.is_on_hub:
140
141
  # start with deleting things on the hub
141
142
  # this will error if the user doesn't have permission
142
- delete_instance_on_hub(isettings._id, require_empty=False)
143
+ # dynamic import to avoid importing hub logic at root
144
+ from .core._hub_core import delete_instance
145
+
146
+ delete_instance(isettings._id, require_empty=False)
143
147
  delete_by_isettings(isettings)
144
148
  # if lamin.db file was delete, then we might count -1
145
149
  if n_files <= 0 and isettings.storage.type == "local":
@@ -6,7 +6,6 @@ import uuid
6
6
  from typing import TYPE_CHECKING, Literal
7
7
  from uuid import UUID
8
8
 
9
- import click
10
9
  from lamin_utils import logger
11
10
 
12
11
  from ._disconnect import disconnect
@@ -17,7 +16,7 @@ from .core._settings import settings
17
16
  from .core._settings_instance import check_is_instance_remote
18
17
  from .core._settings_storage import StorageSettings, init_storage
19
18
  from .core.upath import UPath
20
- from .errors import CannotSwitchDefaultInstance
19
+ from .errors import CannotSwitchDefaultInstance, InstanceNotCreated
21
20
 
22
21
  if TYPE_CHECKING:
23
22
  from lamindb.models import Storage
@@ -27,11 +26,6 @@ if TYPE_CHECKING:
27
26
  from .types import UPathStr
28
27
 
29
28
 
30
- class InstanceNotCreated(click.ClickException):
31
- def show(self, file=None):
32
- pass
33
-
34
-
35
29
  def get_schema_module_name(module_name, raise_import_error: bool = True) -> str | None:
36
30
  import importlib.util
37
31
 
@@ -2,9 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
 
5
- import httpx
6
5
  from django.db import connection
7
- from django.db.migrations.loader import MigrationLoader
8
6
  from lamin_utils import logger
9
7
  from packaging import version
10
8
 
@@ -111,6 +109,9 @@ class migrate:
111
109
  isettings = settings.instance
112
110
 
113
111
  if isettings.is_on_hub and LAMIN_MIGRATE_ON_LAMBDA:
112
+ # dynamic import to avoid importing the heavy httpx at root
113
+ import httpx
114
+
114
115
  response = httpx.post(
115
116
  f"{isettings.api_url}/instances/{isettings._id}/migrate",
116
117
  headers={"Authorization": f"Bearer {settings.user.access_token}"},
@@ -300,6 +301,9 @@ class migrate:
300
301
 
301
302
  return latest_migrations
302
303
  else:
304
+ # import dynamically to avoid importing the heavy django.db.migrations at the root
305
+ from django.db.migrations.loader import MigrationLoader
306
+
303
307
  # Load all migrations using Django's migration loader
304
308
  loader = MigrationLoader(connection)
305
309
  squashed_replacements = set()
@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING
5
5
  from lamin_utils import logger
6
6
 
7
7
  from ._init_instance import register_storage_in_instance
8
- from .core._hub_core import delete_storage_record
9
8
  from .core._settings import settings
10
9
  from .core._settings_storage import StorageSettings, init_storage
11
10
 
@@ -65,6 +64,8 @@ def set_managed_storage(root: UPathStr, host: str | None = None, **fs_kwargs):
65
64
  register_storage_in_instance(ssettings)
66
65
  except Exception as e:
67
66
  if hub_record_status == "hub-record-created" and ssettings._uuid is not None:
67
+ from .core._hub_core import delete_storage_record
68
+
68
69
  delete_storage_record(ssettings)
69
70
  raise e
70
71
 
@@ -58,7 +58,17 @@ class AWSOptionsManager:
58
58
  self._parameters_cache = {} # this is not refreshed
59
59
 
60
60
  from aiobotocore.session import AioSession
61
+ from packaging import version as packaging_version
62
+
63
+ # takes 100ms to import, so keep it here to avoid delaying the import of the main module
61
64
  from s3fs import S3FileSystem
65
+ from s3fs import __version__ as s3fs_version
66
+
67
+ if packaging_version.parse(s3fs_version) < packaging_version.parse("2023.12.2"):
68
+ raise RuntimeError(
69
+ f"The version of s3fs you have ({s3fs_version}) is impompatible "
70
+ "with lamindb, please upgrade it: pip install s3fs>=2023.12.2"
71
+ )
62
72
 
63
73
  anon_env = os.getenv("LAMIN_S3_ANON") == "true"
64
74
  # this is cached so will be resued with the connection initialized
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- import httpx
4
3
  from lamin_utils import logger
5
4
 
6
5
 
7
6
  def get_location(ip="ipinfo.io"):
7
+ # dynamic import to avoid importing the heavy httpx at root
8
+ import httpx
9
+
8
10
  response = httpx.get(f"http://{ip}/json").json()
9
11
  loc = response["loc"].split(",")
10
12
  return {"latitude": float(loc[0]), "longitude": float(loc[1])}
@@ -10,26 +10,20 @@ from urllib.request import urlretrieve
10
10
  import httpx
11
11
  from httpx_retries import Retry, RetryTransport
12
12
  from lamin_utils import logger
13
- from pydantic_settings import BaseSettings
14
13
  from supabase import Client, ClientOptions, create_client
15
14
 
16
15
  from ._settings_save import save_user_settings
17
-
18
-
19
- class Connector(BaseSettings):
20
- url: str
21
- key: str
16
+ from ._settings_store import Connector
22
17
 
23
18
 
24
19
  def load_fallback_connector() -> Connector:
25
20
  url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
26
21
  connector_file, _ = urlretrieve(url)
27
- connector = Connector(_env_file=connector_file)
28
- return connector
22
+ return Connector.from_env_file(connector_file, "")
29
23
 
30
24
 
31
25
  PROD_URL = "https://hub.lamin.ai"
32
- PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c"
26
+ PROD_ANON_KEY = "sb_publishable_YVa4h8hQ-yBhXpfa2cP39w_PhoLW6Nu"
33
27
 
34
28
 
35
29
  class Environment:
@@ -48,13 +42,13 @@ class Environment:
48
42
  key = connector.key
49
43
  elif lamin_env == "staging":
50
44
  url = "https://amvrvdwndlqdzgedrqdv.supabase.co"
51
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0"
45
+ key = "sb_publishable_amVjtilv_Yj4VmGLmxtq6A_sYlLoQx5"
52
46
  elif lamin_env == "staging-test":
53
47
  url = "https://iugyyajllqftbpidapak.supabase.co"
54
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90"
48
+ key = "sb_publishable_XmXroXqTLQw-eeT5kysCww_k8vJv-4L"
55
49
  elif lamin_env == "prod-test":
56
50
  url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
57
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4"
51
+ key = "sb_publishable_G-pyO5aW6VFErTzJyVvM5w_NAv1_Mf7"
58
52
  else:
59
53
  url = os.environ["SUPABASE_API_URL"]
60
54
  key = os.environ["SUPABASE_ANON_KEY"]
@@ -627,8 +627,6 @@ def access_aws(storage_root: str, access_token: str | None = None) -> dict[str,
627
627
 
628
628
 
629
629
  def _access_aws(*, storage_root: str, client: Client) -> dict[str, dict]:
630
- import lamindb_setup
631
-
632
630
  storage_root_info: dict[str, dict] = {"credentials": {}, "accessibility": {}}
633
631
  response = client.functions.invoke(
634
632
  "get-cloud-access-v1",
@@ -5,14 +5,9 @@ import shutil
5
5
  from pathlib import Path
6
6
  from typing import TYPE_CHECKING, Literal
7
7
 
8
- from django.db import connection
9
- from django.db.utils import ProgrammingError
10
8
  from lamin_utils import logger
11
9
 
12
10
  from ._deprecated import deprecated
13
- from ._hub_client import call_with_fallback
14
- from ._hub_crud import select_account_handle_name_by_lnid
15
- from ._hub_utils import LaminDsn, LaminDsnModel
16
11
  from ._settings_save import save_instance_settings
17
12
  from ._settings_storage import (
18
13
  LEGACY_STORAGE_UID_FILE_KEY,
@@ -85,6 +80,7 @@ class InstanceSettings:
85
80
  _locker_user: UserSettings | None = None, # user to lock for if cloud sqlite,
86
81
  _is_clone: bool = False,
87
82
  ):
83
+ # dynamic import to avoid importing pydantic at root
88
84
  from ._hub_utils import validate_db_arg
89
85
 
90
86
  self._id_: UUID = id
@@ -135,6 +131,9 @@ class InstanceSettings:
135
131
  )
136
132
  elif attr == "db":
137
133
  if self.dialect != "sqlite":
134
+ # dynamic import to avoid importing pydantic at root
135
+ from ._hub_utils import LaminDsn, LaminDsnModel
136
+
138
137
  model = LaminDsnModel(db=value)
139
138
  db_print = LaminDsn.build(
140
139
  scheme=model.db.scheme,
@@ -166,6 +165,7 @@ class InstanceSettings:
166
165
  def _search_local_root(
167
166
  self, local_root: str | None = None, mute_warning: bool = False
168
167
  ) -> StorageSettings | None:
168
+ from django.db.utils import ProgrammingError
169
169
  from lamindb.models import Storage
170
170
 
171
171
  if local_root is not None:
@@ -375,6 +375,7 @@ class InstanceSettings:
375
375
  if self._db_permissions != "jwt":
376
376
  return None
377
377
 
378
+ from django.db import connection
378
379
  from lamindb.models import Space
379
380
 
380
381
  spaces: dict = {"admin": [], "write": [], "read": []}
@@ -452,6 +453,9 @@ class InstanceSettings:
452
453
  sqlite_file.synchronize_to(cache_file, print_progress=True) # type: ignore
453
454
 
454
455
  def _check_sqlite_lock(self):
456
+ from ._hub_client import call_with_fallback
457
+ from ._hub_crud import select_account_handle_name_by_lnid
458
+
455
459
  if not self._cloud_sqlite_locker.has_lock:
456
460
  locked_by = self._cloud_sqlite_locker._locked_by
457
461
  lock_msg = "Cannot load the instance, it is locked by "
@@ -560,7 +564,7 @@ class InstanceSettings:
560
564
  Will return `False` in case the user token can't find the instance.
561
565
  """
562
566
  if self._is_on_hub is None:
563
- from ._hub_client import call_with_fallback_auth
567
+ from ._hub_client import call_with_fallback, call_with_fallback_auth
564
568
  from ._hub_crud import select_instance_by_id
565
569
  from ._settings import settings
566
570
 
@@ -8,7 +8,6 @@ from uuid import UUID, uuid4
8
8
 
9
9
  from dotenv import dotenv_values
10
10
  from lamin_utils import logger
11
- from pydantic import ValidationError
12
11
 
13
12
  from lamindb_setup.errors import CurrentInstanceNotConfigured, SettingsEnvFileOutdated
14
13
 
@@ -49,7 +48,7 @@ def load_cache_path_from_settings(storage_settings: Path | None = None) -> Path
49
48
 
50
49
  def find_module_candidates():
51
50
  """Find all local packages that depend on lamindb."""
52
- candidates = ["bionty", "wetlab"]
51
+ candidates = ["bionty", "pertdb"]
53
52
  return [c for c in candidates if find_spec(c) is not None]
54
53
 
55
54
 
@@ -72,8 +71,10 @@ def load_instance_settings(instance_settings_file: Path | None = None):
72
71
  # this errors only if the file was explicitly provided
73
72
  raise CurrentInstanceNotConfigured
74
73
  try:
75
- settings_store = InstanceSettingsStore(_env_file=isettings_file)
76
- except (ValidationError, TypeError) as error:
74
+ settings_store = InstanceSettingsStore.from_env_file(
75
+ isettings_file, "lamindb_instance_"
76
+ )
77
+ except (ValueError, KeyError, TypeError) as error:
77
78
  raise SettingsEnvFileOutdated(
78
79
  f"\n\n{error}\n\nYour instance settings file with\n\n{isettings_file.read_text()}\nis invalid"
79
80
  f" (likely outdated), see validation error. Please delete {isettings_file} &"
@@ -108,8 +109,10 @@ def load_or_create_user_settings(api_key: str | None = None) -> UserSettings:
108
109
 
109
110
  def load_user_settings(user_settings_file: Path):
110
111
  try:
111
- settings_store = UserSettingsStore(_env_file=user_settings_file)
112
- except (ValidationError, TypeError) as error:
112
+ settings_store = UserSettingsStore.from_env_file(
113
+ user_settings_file, "lamin_user_"
114
+ )
115
+ except (ValueError, KeyError, TypeError) as error:
113
116
  msg = (
114
117
  "Your user settings file is invalid, please delete"
115
118
  f" {user_settings_file} and log in again."
@@ -121,7 +124,7 @@ def load_user_settings(user_settings_file: Path):
121
124
 
122
125
 
123
126
  def _null_to_value(field, value=None):
124
- return field if field != "null" else value
127
+ return value if field in (None, "null") else field
125
128
 
126
129
 
127
130
  def setup_instance_from_store(store: InstanceSettingsStore) -> InstanceSettings:
@@ -155,5 +158,5 @@ def setup_user_from_store(store: UserSettingsStore) -> UserSettings:
155
158
  settings.uid = store.uid
156
159
  settings.handle = _null_to_value(store.handle, value="anonymous")
157
160
  settings.name = _null_to_value(store.name)
158
- settings._uuid = UUID(store.uuid) if store.uuid != "null" else None
161
+ settings._uuid = UUID(store.uuid) if store.uuid not in (None, "null") else None
159
162
  return settings
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
- from typing import TYPE_CHECKING, Any, Optional, get_type_hints
4
+ from typing import TYPE_CHECKING, Any, Optional, get_args, get_type_hints
5
5
  from uuid import UUID
6
6
 
7
7
  from ._settings_store import (
@@ -33,6 +33,21 @@ def save_user_settings(settings: UserSettings):
33
33
  )
34
34
 
35
35
 
36
+ def _coerce_type_for_write(type_: Any) -> Any:
37
+ """Resolve union types to the non-None part for coercion when value is not None."""
38
+ if type_ in (str, bool):
39
+ return type_
40
+ if type_ == Optional[str]: # noqa: UP045
41
+ return str
42
+ if type_ == Optional[bool]: # noqa: UP045
43
+ return bool
44
+ args = get_args(type_) or ()
45
+ if type(None) in args:
46
+ non_none = next((a for a in args if a is not type(None)), type_)
47
+ return non_none if non_none in (str, bool) else type_
48
+ return type_
49
+
50
+
36
51
  def save_settings(
37
52
  settings: Any,
38
53
  settings_file: Path,
@@ -41,10 +56,7 @@ def save_settings(
41
56
  ):
42
57
  with open(settings_file, "w") as f:
43
58
  for store_key, type_ in type_hints.items():
44
- if type_ == Optional[str]: # noqa: UP045
45
- type_ = str
46
- if type_ == Optional[bool]: # noqa: UP045
47
- type_ = bool
59
+ type_ = _coerce_type_for_write(type_)
48
60
  if "__" not in store_key:
49
61
  if store_key == "model_config":
50
62
  continue