lamindb_setup 0.76.8__tar.gz → 0.77.1__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 (98) hide show
  1. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/.github/workflows/build.yml +7 -7
  2. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/PKG-INFO +1 -1
  3. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/07-keep-artifacts-local.ipynb +16 -12
  4. lamindb_setup-0.77.1/docs/hub-prod/test-init-load-local-anonymously.ipynb +140 -0
  5. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-insufficient-user-info.ipynb +8 -15
  6. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-sqlite-lock.ipynb +7 -7
  7. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/notebooks.md +1 -0
  8. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/__init__.py +10 -7
  9. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_connect_instance.py +11 -4
  10. lamindb_setup-0.77.1/lamindb_setup/_entry_points.py +22 -0
  11. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_setup_user.py +55 -39
  12. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_hub_client.py +11 -2
  13. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_hub_core.py +56 -5
  14. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_load.py +13 -8
  15. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_store.py +1 -0
  16. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_user.py +3 -1
  17. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/noxfile.py +1 -1
  18. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_connect_instance.py +9 -0
  19. lamindb_setup-0.77.1/tests/hub-cloud/test_login.py +67 -0
  20. lamindb_setup-0.77.1/tests/storage/test_entry_point.py +76 -0
  21. lamindb_setup-0.76.8/tests/hub-cloud/test_login.py +0 -19
  22. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/.github/workflows/doc-changes.yml +0 -0
  23. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/.gitignore +0 -0
  24. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/.pre-commit-config.yaml +0 -0
  25. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/LICENSE +0 -0
  26. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/README.md +0 -0
  27. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/changelog.md +0 -0
  28. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
  29. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
  30. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
  31. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/04-test-bionty.ipynb +0 -0
  32. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
  33. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
  34. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/08-test-multi-session.ipynb +0 -0
  35. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-cloud/test_notebooks.py +0 -0
  36. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-cache-management.ipynb +0 -0
  37. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
  38. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
  39. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-empty-init.ipynb +0 -0
  40. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-import-schema.ipynb +0 -0
  41. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
  42. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/hub-prod/test_notebooks2.py +0 -0
  43. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/index.md +0 -0
  44. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/docs/reference.md +0 -0
  45. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_cache.py +0 -0
  46. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_check.py +0 -0
  47. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_check_setup.py +0 -0
  48. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_close.py +0 -0
  49. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_delete.py +0 -0
  50. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_django.py +0 -0
  51. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_exportdb.py +0 -0
  52. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_importdb.py +0 -0
  53. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_init_instance.py +0 -0
  54. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_migrate.py +0 -0
  55. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_register_instance.py +0 -0
  56. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_schema.py +0 -0
  57. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_schema_metadata.py +0 -0
  58. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_set_managed_storage.py +0 -0
  59. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/_silence_loggers.py +0 -0
  60. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/__init__.py +0 -0
  61. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_aws_credentials.py +0 -0
  62. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_aws_storage.py +0 -0
  63. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_deprecated.py +0 -0
  64. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_docs.py +0 -0
  65. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_hub_crud.py +0 -0
  66. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_hub_utils.py +0 -0
  67. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_private_django_api.py +0 -0
  68. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings.py +0 -0
  69. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_instance.py +0 -0
  70. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_save.py +0 -0
  71. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_settings_storage.py +0 -0
  72. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/_setup_bionty_sources.py +0 -0
  73. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
  74. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/django.py +0 -0
  75. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/exceptions.py +0 -0
  76. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/hashing.py +0 -0
  77. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/types.py +0 -0
  78. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/lamindb_setup/core/upath.py +0 -0
  79. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/pyproject.toml +0 -0
  80. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/scripts/script-to-fail-managed-storage.py +0 -0
  81. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_delete_instance.py +0 -0
  82. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_fail_managed_storage.py +0 -0
  83. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_init_instance.py +0 -0
  84. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_migrate.py +0 -0
  85. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-cloud/test_set_storage.py +0 -0
  86. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-local/conftest.py +0 -0
  87. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-local/test_all.py +0 -0
  88. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-local/test_update_schema_in_hub.py +0 -0
  89. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-prod/conftest.py +0 -0
  90. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-prod/test_django.py +0 -0
  91. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-prod/test_global_settings.py +0 -0
  92. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
  93. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/hub-prod/test_upath.py +0 -0
  94. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/storage/test_hashing.py +0 -0
  95. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/storage/test_storage_access.py +0 -0
  96. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/storage/test_storage_basis.py +0 -0
  97. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/storage/test_storage_stats.py +0 -0
  98. {lamindb_setup-0.76.8 → lamindb_setup-0.77.1}/tests/storage/test_to_url.py +0 -0
@@ -19,7 +19,7 @@ jobs:
19
19
  with:
20
20
  python-version: "3.10" # run one job on 3.9
21
21
  cache: "pip"
22
- - uses: aws-actions/configure-aws-credentials@v2
22
+ - uses: aws-actions/configure-aws-credentials@v4
23
23
  with:
24
24
  aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
25
25
  aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -45,7 +45,7 @@ jobs:
45
45
  python-version: "3.10" # test on 3.9
46
46
  timeout-minutes: 7
47
47
  steps:
48
- - uses: aws-actions/configure-aws-credentials@v2
48
+ - uses: aws-actions/configure-aws-credentials@v4
49
49
  with:
50
50
  aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
51
51
  aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -62,12 +62,12 @@ jobs:
62
62
  token: ${{ secrets.GH_TOKEN_DEPLOY_LAMINAPP }}
63
63
  path: laminhub
64
64
  ref: main
65
- - uses: actions/cache@v3
65
+ - uses: actions/cache@v4
66
66
  with:
67
67
  path: ~/.cache/pre-commit
68
68
  key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
69
69
  - id: cache-postgres
70
- uses: actions/cache@v3
70
+ uses: actions/cache@v4
71
71
  with:
72
72
  path: ~/postgres.tar
73
73
  key: cache-postgres-0
@@ -118,7 +118,7 @@ jobs:
118
118
  runs-on: ubuntu-latest
119
119
  timeout-minutes: 6
120
120
  steps:
121
- - uses: aws-actions/configure-aws-credentials@v2
121
+ - uses: aws-actions/configure-aws-credentials@v4
122
122
  with:
123
123
  aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
124
124
  aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -144,7 +144,7 @@ jobs:
144
144
  - run: pip install "laminci@git+https://x-access-token:${{ secrets.LAMIN_BUILD_DOCS }}@github.com/laminlabs/laminci"
145
145
  - run: nox -s "install(group='hub-local')"
146
146
  - id: cache-supabase
147
- uses: actions/cache@v3
147
+ uses: actions/cache@v4
148
148
  with:
149
149
  path: /var/lib/docker
150
150
  key: cache-supabase
@@ -183,7 +183,7 @@ jobs:
183
183
  needs: hub-cloud
184
184
  runs-on: ubuntu-latest
185
185
  steps:
186
- - uses: aws-actions/configure-aws-credentials@v2
186
+ - uses: aws-actions/configure-aws-credentials@v4
187
187
  with:
188
188
  aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
189
189
  aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamindb_setup
3
- Version: 0.76.8
3
+ Version: 0.77.1
4
4
  Summary: Setup & configure LaminDB.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Description-Content-Type: text/markdown
@@ -16,22 +16,26 @@
16
16
  "# this shouldn't run in a notebook, but in the unit tests\n",
17
17
  "# currently still limited because of inability to load multiple instances\n",
18
18
  "\n",
19
+ "import os\n",
19
20
  "import pytest\n",
20
21
  "import lamindb_setup as ln_setup\n",
21
- "from pathlib import Path\n",
22
+ "from upath import UPath\n",
23
+ "\n",
24
+ "name = f\"keep-artifacts-local-setup-{os.environ['LAMIN_ENV']}\"\n",
25
+ "storage = (UPath(\"s3://lamindb-ci\") / name).as_posix()\n",
22
26
  "\n",
23
27
  "ln_setup.login(\"testuser1\")\n",
24
- "ln_setup.init(storage=\"s3://lamindb-ci/keep-artifacts-local-setup\")\n",
28
+ "ln_setup.init(storage=storage)\n",
25
29
  "\n",
26
- "assert ln_setup.settings.instance.name == \"keep-artifacts-local-setup\"\n",
30
+ "assert ln_setup.settings.instance.name == name\n",
27
31
  "assert ln_setup.settings.instance.storage.type_is_cloud\n",
28
32
  "assert (\n",
29
33
  " ln_setup.settings.instance.storage.root_as_str\n",
30
- " == \"s3://lamindb-ci/keep-artifacts-local-setup\"\n",
34
+ " == storage\n",
31
35
  ")\n",
32
36
  "assert (\n",
33
37
  " ln_setup.settings.instance._sqlite_file.as_posix()\n",
34
- " == f\"s3://lamindb-ci/keep-artifacts-local-setup/{ln_setup.settings.instance._id.hex}.lndb\" # noqa\n",
38
+ " == f\"{storage}/{ln_setup.settings.instance._id.hex}.lndb\" # noqa\n",
35
39
  ")"
36
40
  ]
37
41
  },
@@ -68,12 +72,12 @@
68
72
  "\n",
69
73
  "assert (\n",
70
74
  " ln_setup.settings.instance.storage_local.root.as_posix()\n",
71
- " == Path(\"./my_storage_local\").resolve().as_posix()\n",
75
+ " == UPath(\"./my_storage_local\").resolve().as_posix()\n",
72
76
  ")\n",
73
77
  "assert (ln_setup.settings.instance.storage_local.root / \".lamindb/_is_initialized\").read_text() == ln_setup.settings.instance.storage_local.uid\n",
74
78
  "assert ln_setup.settings.instance.storage_local is not None\n",
75
79
  "# the remote storage location is still in the regular slot\n",
76
- "assert ln_setup.settings.instance.storage.root.as_posix() == \"s3://lamindb-ci/keep-artifacts-local-setup\""
80
+ "assert ln_setup.settings.instance.storage.root.as_posix() == storage"
77
81
  ]
78
82
  },
79
83
  {
@@ -100,7 +104,7 @@
100
104
  "source": [
101
105
  "assert (\n",
102
106
  " ln_setup.settings.instance.storage_local.root.as_posix()\n",
103
- " == Path(\"./my_storage_local2\").resolve().as_posix()\n",
107
+ " == UPath(\"./my_storage_local2\").resolve().as_posix()\n",
104
108
  ")\n",
105
109
  "assert (ln_setup.settings.instance.storage_local.root / \".lamindb/_is_initialized\").read_text() == ln_setup.settings.instance.storage_local.uid"
106
110
  ]
@@ -170,7 +174,7 @@
170
174
  "outputs": [],
171
175
  "source": [
172
176
  "with pytest.raises(ln_setup.core.upath.InstanceNotEmpty):\n",
173
- " ln_setup.delete(\"keep-artifacts-local-setup\", force=True)"
177
+ " ln_setup.delete(name, force=True)"
174
178
  ]
175
179
  },
176
180
  {
@@ -188,13 +192,13 @@
188
192
  "metadata": {},
189
193
  "outputs": [],
190
194
  "source": [
191
- "ln_setup.delete(\"keep-artifacts-local-setup\", force=True)"
195
+ "ln_setup.delete(name, force=True)"
192
196
  ]
193
197
  }
194
198
  ],
195
199
  "metadata": {
196
200
  "kernelspec": {
197
- "display_name": "py310",
201
+ "display_name": "Python 3 (ipykernel)",
198
202
  "language": "python",
199
203
  "name": "python3"
200
204
  },
@@ -208,7 +212,7 @@
208
212
  "name": "python",
209
213
  "nbconvert_exporter": "python",
210
214
  "pygments_lexer": "ipython3",
211
- "version": "3.10.13"
215
+ "version": "3.9.17"
212
216
  }
213
217
  },
214
218
  "nbformat": 4,
@@ -0,0 +1,140 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "c4107648",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import lamindb_setup as ln_setup"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "markdown",
15
+ "id": "8587fb8e",
16
+ "metadata": {},
17
+ "source": [
18
+ "Check current user."
19
+ ]
20
+ },
21
+ {
22
+ "cell_type": "code",
23
+ "execution_count": null,
24
+ "id": "66c361b1",
25
+ "metadata": {},
26
+ "outputs": [],
27
+ "source": [
28
+ "ln_setup.login(\"testuser2\")\n",
29
+ "assert ln_setup.settings.user.handle == \"testuser2\""
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "markdown",
34
+ "id": "c6cc67f2",
35
+ "metadata": {},
36
+ "source": [
37
+ "logout and check that the user info was updated."
38
+ ]
39
+ },
40
+ {
41
+ "cell_type": "code",
42
+ "execution_count": null,
43
+ "id": "7a572ee2",
44
+ "metadata": {},
45
+ "outputs": [],
46
+ "source": [
47
+ "ln_setup.logout()\n",
48
+ "assert ln_setup.settings.user.handle == \"anonymous\""
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "markdown",
53
+ "id": "4b8b119f",
54
+ "metadata": {},
55
+ "source": [
56
+ "Init a local instance anonymously."
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "execution_count": null,
62
+ "id": "f8663b52",
63
+ "metadata": {},
64
+ "outputs": [],
65
+ "source": [
66
+ "!lamin close\n",
67
+ "!lamin init --storage ./test-anonymous-init --schema bionty"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "markdown",
72
+ "id": "a9f53d46",
73
+ "metadata": {},
74
+ "source": [
75
+ "Load the instance and check."
76
+ ]
77
+ },
78
+ {
79
+ "cell_type": "code",
80
+ "execution_count": null,
81
+ "id": "1bb37c25",
82
+ "metadata": {},
83
+ "outputs": [],
84
+ "source": [
85
+ "ln_setup.load(\"test-anonymous-init\")\n",
86
+ "assert ln_setup.settings.instance.name == \"test-anonymous-init\"\n",
87
+ "assert ln_setup.settings.instance.owner == \"anonymous\""
88
+ ]
89
+ },
90
+ {
91
+ "cell_type": "markdown",
92
+ "id": "9c19ede8",
93
+ "metadata": {},
94
+ "source": [
95
+ "Clean up."
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": null,
101
+ "id": "b37256df",
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "ln_setup.delete(\"test-anonymous-init\", force=True)"
106
+ ]
107
+ },
108
+ {
109
+ "cell_type": "code",
110
+ "execution_count": null,
111
+ "id": "c1eea364",
112
+ "metadata": {},
113
+ "outputs": [],
114
+ "source": [
115
+ "ln_setup.login(\"testuser2\")"
116
+ ]
117
+ }
118
+ ],
119
+ "metadata": {
120
+ "kernelspec": {
121
+ "display_name": "Python 3 (ipykernel)",
122
+ "language": "python",
123
+ "name": "python3"
124
+ },
125
+ "language_info": {
126
+ "codemirror_mode": {
127
+ "name": "ipython",
128
+ "version": 3
129
+ },
130
+ "file_extension": ".py",
131
+ "mimetype": "text/x-python",
132
+ "name": "python",
133
+ "nbconvert_exporter": "python",
134
+ "pygments_lexer": "ipython3",
135
+ "version": "3.9.17"
136
+ }
137
+ },
138
+ "nbformat": 4,
139
+ "nbformat_minor": 5
140
+ }
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "cells": [
3
3
  {
4
- "attachments": {},
5
4
  "cell_type": "markdown",
6
5
  "metadata": {},
7
6
  "source": [
@@ -33,7 +32,6 @@
33
32
  ]
34
33
  },
35
34
  {
36
- "attachments": {},
37
35
  "cell_type": "markdown",
38
36
  "metadata": {},
39
37
  "source": [
@@ -46,16 +44,15 @@
46
44
  "metadata": {},
47
45
  "outputs": [],
48
46
  "source": [
49
- "with pytest.raises(TypeError):\n",
47
+ "with pytest.raises(ValueError):\n",
50
48
  " ln_setup.login()"
51
49
  ]
52
50
  },
53
51
  {
54
- "attachments": {},
55
52
  "cell_type": "markdown",
56
53
  "metadata": {},
57
54
  "source": [
58
- "If we add an email or handle it looks up the password from the stored env file (`lamin login testuser1@lamin.ai`):"
55
+ "If we add an email or handle it looks up credentials from the stored env file (`lamin login testuser1@lamin.ai`):"
59
56
  ]
60
57
  },
61
58
  {
@@ -68,7 +65,6 @@
68
65
  ]
69
66
  },
70
67
  {
71
- "attachments": {},
72
68
  "cell_type": "markdown",
73
69
  "metadata": {},
74
70
  "source": [
@@ -89,7 +85,6 @@
89
85
  ]
90
86
  },
91
87
  {
92
- "attachments": {},
93
88
  "cell_type": "markdown",
94
89
  "metadata": {},
95
90
  "source": [
@@ -102,16 +97,15 @@
102
97
  "metadata": {},
103
98
  "outputs": [],
104
99
  "source": [
105
- "with pytest.raises(RuntimeError):\n",
106
- " ln_setup.login(\"testuser1\", password=\"dummy\")"
100
+ "with pytest.raises(SystemExit):\n",
101
+ " ln_setup.login(\"testuser1\", key=\"dummy\")"
107
102
  ]
108
103
  },
109
104
  {
110
- "attachments": {},
111
105
  "cell_type": "markdown",
112
106
  "metadata": {},
113
107
  "source": [
114
- "If we try to login without password, this will error:"
108
+ "If we try to login without key, this will error:"
115
109
  ]
116
110
  },
117
111
  {
@@ -120,16 +114,15 @@
120
114
  "metadata": {},
121
115
  "outputs": [],
122
116
  "source": [
123
- "with pytest.raises(RuntimeError):\n",
117
+ "with pytest.raises(SystemExit):\n",
124
118
  " ln_setup.login(\"testuser1@lamin.ai\")"
125
119
  ]
126
120
  },
127
121
  {
128
- "attachments": {},
129
122
  "cell_type": "markdown",
130
123
  "metadata": {},
131
124
  "source": [
132
- "If we try login with a wrong password, this will error:"
125
+ "If we try login with a wrong key, this will error:"
133
126
  ]
134
127
  },
135
128
  {
@@ -186,7 +179,7 @@
186
179
  "name": "python",
187
180
  "nbconvert_exporter": "python",
188
181
  "pygments_lexer": "ipython3",
189
- "version": "3.10.13"
182
+ "version": "3.9.17"
190
183
  },
191
184
  "nbproject": {
192
185
  "id": "vLOmzd6d4Jow",
@@ -11,24 +11,24 @@
11
11
  {
12
12
  "cell_type": "code",
13
13
  "execution_count": null,
14
- "id": "89b7057a",
14
+ "id": "69eeefee",
15
15
  "metadata": {},
16
16
  "outputs": [],
17
17
  "source": [
18
- "!lamin login testuser2"
18
+ "import pytest\n",
19
+ "import lamindb_setup as ln_setup\n",
20
+ "from lamindb_setup.core.cloud_sqlite_locker import Locker, InstanceLockedException\n",
21
+ "from lamindb_setup.core.upath import UPath"
19
22
  ]
20
23
  },
21
24
  {
22
25
  "cell_type": "code",
23
26
  "execution_count": null,
24
- "id": "69eeefee",
27
+ "id": "5605dfcd",
25
28
  "metadata": {},
26
29
  "outputs": [],
27
30
  "source": [
28
- "import pytest\n",
29
- "import lamindb_setup as ln_setup\n",
30
- "from lamindb_setup.core.cloud_sqlite_locker import Locker, InstanceLockedException\n",
31
- "from lamindb_setup.core.upath import UPath"
31
+ "ln_setup.login(\"testuser2\")"
32
32
  ]
33
33
  },
34
34
  {
@@ -17,6 +17,7 @@ hub-prod/test-empty-init
17
17
  hub-prod/test-import-schema
18
18
  hub-prod/test-invalid-schema
19
19
  hub-prod/test-insufficient-user-info
20
+ hub-prod/test-init-load-local-anonymously
20
21
  hub-prod/test-connect-anonymously
21
22
  hub-prod/test-sqlite-lock
22
23
  hub-prod/test-cloud-sync
@@ -34,10 +34,10 @@ Modules & settings:
34
34
 
35
35
  """
36
36
 
37
- __version__ = "0.76.8" # denote a release candidate for 0.1.0 with 0.1rc1
37
+ __version__ = "0.77.1" # denote a release candidate for 0.1.0 with 0.1rc1
38
38
 
39
- import sys
40
- from os import name as _os_name
39
+ import os as _os
40
+ import sys as _sys
41
41
 
42
42
  from . import core
43
43
  from ._check_setup import _check_instance_setup
@@ -45,18 +45,18 @@ from ._close import close
45
45
  from ._connect_instance import connect, load
46
46
  from ._delete import delete
47
47
  from ._django import django
48
+ from ._entry_points import call_registered_entry_points as _call_registered_entry_points
48
49
  from ._init_instance import init
49
50
  from ._migrate import migrate
50
51
  from ._register_instance import register
51
52
  from ._setup_user import login, logout
52
53
  from .core._settings import settings
53
54
 
54
- dev = core # backward compat
55
- _TESTING = False # used in lamindb tests
55
+ _TESTING = _os.getenv("LAMIN_TESTING") is not None
56
56
 
57
57
  # hide the supabase error in a thread on windows
58
- if _os_name == "nt":
59
- if sys.version_info.minor > 7:
58
+ if _os.name == "nt":
59
+ if _sys.version_info.minor > 7:
60
60
  import threading
61
61
 
62
62
  _original_excepthook = threading.excepthook
@@ -69,4 +69,7 @@ if _os_name == "nt":
69
69
 
70
70
  threading.excepthook = _except_hook
71
71
 
72
+ # provide a way for other packages to run custom code on import
73
+ _call_registered_entry_points("lamindb_setup.on_import")
74
+
72
75
  settings.__doc__ = """Global :class:`~lamindb.setup.core.SetupSettings`."""
@@ -124,7 +124,11 @@ def _connect_instance(
124
124
  if make_hub_request:
125
125
  # the following will return a string if the instance does not exist
126
126
  # on the hub
127
- hub_result = load_instance_from_hub(owner=owner, name=name)
127
+ # do not call hub if the user is anonymous
128
+ if owner != "anonymous":
129
+ hub_result = load_instance_from_hub(owner=owner, name=name)
130
+ else:
131
+ hub_result = "anonymous-user"
128
132
  # if hub_result is not a string, it means it made a request
129
133
  # that successfully returned metadata
130
134
  if not isinstance(hub_result, str):
@@ -155,9 +159,12 @@ def _connect_instance(
155
159
  )
156
160
  check_whether_migrations_in_sync(instance_result["lamindb_version"])
157
161
  else:
158
- message = INSTANCE_NOT_FOUND_MESSAGE.format(
159
- owner=owner, name=name, hub_result=hub_result
160
- )
162
+ if hub_result != "anonymous-user":
163
+ message = INSTANCE_NOT_FOUND_MESSAGE.format(
164
+ owner=owner, name=name, hub_result=hub_result
165
+ )
166
+ else:
167
+ message = "It is not possible to load an anonymous-owned instance from the hub"
161
168
  if settings_file.exists():
162
169
  isettings = load_instance_settings(settings_file)
163
170
  if isettings.is_remote:
@@ -0,0 +1,22 @@
1
+ import sys
2
+ import warnings
3
+ from importlib.metadata import entry_points
4
+
5
+
6
+ def call_registered_entry_points(group, **kwargs):
7
+ """load and call entry points registered under group."""
8
+ if sys.version_info >= (3, 10):
9
+ eps = entry_points(group=group)
10
+ else:
11
+ eps = entry_points().get(group, [])
12
+
13
+ for ep in eps:
14
+ func = ep.load()
15
+ try:
16
+ func(**kwargs)
17
+ except BaseException as e:
18
+ warnings.warn(
19
+ f"Error loading entry point of group {group!r}: {ep} -> {e}",
20
+ RuntimeWarning,
21
+ stacklevel=2,
22
+ )
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Optional, Union
3
+ import os
4
+ from typing import TYPE_CHECKING, Optional, Union
4
5
 
5
6
  from lamin_utils import logger
6
7
 
@@ -15,8 +16,11 @@ from .core._settings_store import (
15
16
  user_settings_file_handle,
16
17
  )
17
18
 
19
+ if TYPE_CHECKING:
20
+ from lamindb_setup.core._settings_save import UserSettings
18
21
 
19
- def load_user(email: str | None = None, handle: str | None = None) -> str | None:
22
+
23
+ def load_user(email: str | None = None, handle: str | None = None) -> UserSettings:
20
24
  if email is not None:
21
25
  settings_file = user_settings_file_email(email)
22
26
  if handle is not None:
@@ -28,8 +32,8 @@ def load_user(email: str | None = None, handle: str | None = None) -> str | None
28
32
  else:
29
33
  user_settings = load_or_create_user_settings()
30
34
  if email is None:
31
- raise RuntimeError(
32
- "Use your email for your first login in a compute environment. "
35
+ raise SystemExit(
36
+ "Use your email for your first login in a compute environment. "
33
37
  "After that, you can use your handle."
34
38
  )
35
39
  user_settings.email = email
@@ -40,59 +44,68 @@ def load_user(email: str | None = None, handle: str | None = None) -> str | None
40
44
 
41
45
  settings._user_settings = None # this is to refresh a settings instance
42
46
 
43
- return None
47
+ return user_settings
44
48
 
45
49
 
46
50
  def login(
47
- user: str,
48
- *,
49
- key: str | None = None,
50
- password: str | None = None, # for backward compat
51
+ user: str | None = None, *, key: str | None = None, api_key: str | None = None
51
52
  ) -> None:
52
53
  """Log in user.
53
54
 
54
55
  Args:
55
56
  user: handle or email
56
- key: API key or legacy passward
57
- password: Backward compat, will be removed
57
+ key: API key
58
+ api_key: Beta API key
58
59
  """
59
- if "@" in user:
60
- email, handle = user, None
60
+ if user is None and api_key is None:
61
+ if "LAMIN_API_KEY" in os.environ:
62
+ api_key = os.environ["LAMIN_API_KEY"]
63
+ else:
64
+ raise ValueError("Both `user` and `api_key` should not be `None`.")
65
+
66
+ if api_key is None:
67
+ if "@" in user: # type: ignore
68
+ email, handle = user, None
69
+ else:
70
+ email, handle = None, user
71
+ user_settings = load_user(email, handle)
72
+
73
+ if key is not None:
74
+ # within UserSettings, we still call it "password" for a while
75
+ user_settings.password = key
76
+
77
+ if user_settings.email is None:
78
+ raise SystemExit(f"✗ No stored user email, please call: lamin login {user}")
79
+
80
+ if user_settings.password is None:
81
+ raise SystemExit(
82
+ "✗ No stored API key, please call: lamin login <your-email> --key <API-key>"
83
+ )
61
84
  else:
62
- email, handle = None, user
63
- load_user(email, handle)
64
-
65
- user_settings = load_or_create_user_settings()
66
-
67
- if password is not None:
68
- logger.warning(
69
- "please use --key instead of --password, "
70
- "passwords are deprecated and replaced with API keys"
71
- )
72
- key = password
73
-
74
- if key is not None:
75
- # within UserSettings, we still call it "password" for a while
76
- user_settings.password = key
85
+ user_settings = load_or_create_user_settings()
77
86
 
78
- if user_settings.email is None:
79
- raise RuntimeError("No stored user email, please call: lamin login {user}")
87
+ from .core._hub_core import sign_in_hub, sign_in_hub_api_key
80
88
 
81
- if user_settings.password is None:
82
- raise RuntimeError(
83
- "No stored API key, please call: lamin login <your-email> --key <API-key>"
89
+ if api_key is None:
90
+ response = sign_in_hub(
91
+ user_settings.email, # type: ignore
92
+ user_settings.password, # type: ignore
93
+ user_settings.handle,
84
94
  )
95
+ else:
96
+ response = sign_in_hub_api_key(api_key)
85
97
 
86
- from .core._hub_core import sign_in_hub
87
-
88
- response = sign_in_hub(
89
- user_settings.email, user_settings.password, user_settings.handle
90
- )
91
98
  if isinstance(response, Exception):
92
99
  raise response
100
+ elif isinstance(response, str):
101
+ raise SystemExit(f"✗ Unsuccessful login: {response}.")
93
102
  else:
94
103
  user_uuid, user_id, user_handle, user_name, access_token = response
95
- if handle is None:
104
+ if api_key is not None:
105
+ logger.success(
106
+ f"logged in with API key (handle: {user_handle}, uid: {user_id})"
107
+ )
108
+ elif handle is None:
96
109
  logger.success(f"logged in with handle {user_handle} (uid: {user_id})")
97
110
  else:
98
111
  logger.success(f"logged in with email {user_settings.email} (uid: {user_id})")
@@ -101,6 +114,7 @@ def login(
101
114
  user_settings.name = user_name
102
115
  user_settings._uuid = user_uuid
103
116
  user_settings.access_token = access_token
117
+ user_settings.api_key = api_key
104
118
  save_user_settings(user_settings)
105
119
 
106
120
  if settings._instance_exists and _check_instance_setup():
@@ -113,6 +127,8 @@ def login(
113
127
  def logout():
114
128
  if current_user_settings_file().exists():
115
129
  current_user_settings_file().unlink()
130
+ # update user info
131
+ settings._user_settings = None
116
132
  logger.success("logged out")
117
133
  else:
118
134
  logger.important("already logged out")