lamindb_setup 0.70.0__py2.py3-none-any.whl → 0.71.1__py2.py3-none-any.whl

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 (45) hide show
  1. lamindb_setup/__init__.py +15 -15
  2. lamindb_setup/_cache.py +4 -1
  3. lamindb_setup/_check.py +3 -0
  4. lamindb_setup/_check_setup.py +13 -7
  5. lamindb_setup/_close.py +2 -0
  6. lamindb_setup/_connect_instance.py +47 -26
  7. lamindb_setup/_delete.py +72 -40
  8. lamindb_setup/_django.py +4 -1
  9. lamindb_setup/_exportdb.py +4 -2
  10. lamindb_setup/_importdb.py +5 -1
  11. lamindb_setup/_init_instance.py +61 -45
  12. lamindb_setup/_migrate.py +16 -13
  13. lamindb_setup/_register_instance.py +10 -3
  14. lamindb_setup/_schema.py +6 -3
  15. lamindb_setup/_set_managed_storage.py +37 -0
  16. lamindb_setup/_setup_user.py +7 -7
  17. lamindb_setup/_silence_loggers.py +4 -2
  18. lamindb_setup/core/__init__.py +4 -3
  19. lamindb_setup/core/_aws_storage.py +3 -0
  20. lamindb_setup/core/_deprecated.py +2 -7
  21. lamindb_setup/core/_docs.py +2 -0
  22. lamindb_setup/core/_hub_client.py +12 -10
  23. lamindb_setup/core/_hub_core.py +203 -88
  24. lamindb_setup/core/_hub_crud.py +21 -12
  25. lamindb_setup/core/_hub_utils.py +11 -8
  26. lamindb_setup/core/_settings.py +23 -26
  27. lamindb_setup/core/_settings_instance.py +149 -81
  28. lamindb_setup/core/_settings_load.py +13 -7
  29. lamindb_setup/core/_settings_save.py +13 -8
  30. lamindb_setup/core/_settings_storage.py +76 -42
  31. lamindb_setup/core/_settings_store.py +4 -2
  32. lamindb_setup/core/_settings_user.py +10 -6
  33. lamindb_setup/core/_setup_bionty_sources.py +9 -2
  34. lamindb_setup/core/cloud_sqlite_locker.py +13 -10
  35. lamindb_setup/core/django.py +3 -1
  36. lamindb_setup/core/exceptions.py +4 -2
  37. lamindb_setup/core/hashing.py +15 -5
  38. lamindb_setup/core/types.py +5 -2
  39. lamindb_setup/core/upath.py +191 -88
  40. {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.1.dist-info}/METADATA +6 -4
  41. lamindb_setup-0.71.1.dist-info/RECORD +43 -0
  42. lamindb_setup/_add_remote_storage.py +0 -50
  43. lamindb_setup-0.70.0.dist-info/RECORD +0 -43
  44. {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.1.dist-info}/LICENSE +0 -0
  45. {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.1.dist-info}/WHEEL +0 -0
@@ -1,22 +1,28 @@
1
+ from __future__ import annotations
2
+
1
3
  import importlib
4
+ import os
2
5
  import sys
3
- from typing import Optional, Union
4
6
  import uuid
7
+ from typing import TYPE_CHECKING, Literal
5
8
  from uuid import UUID
6
- import os
7
- from lamin_utils import logger
8
- from typing import Tuple, Literal
9
- from pydantic import PostgresDsn
10
- from django.db.utils import OperationalError, ProgrammingError
9
+
11
10
  from django.core.exceptions import FieldError
11
+ from django.db.utils import OperationalError, ProgrammingError
12
+ from lamin_utils import logger
13
+
12
14
  from ._close import close as close_instance
13
- from .core._settings import settings
14
15
  from ._silence_loggers import silence_loggers
15
16
  from .core import InstanceSettings
16
- from .core.types import UPathStr
17
+ from .core._settings import settings
17
18
  from .core._settings_storage import StorageSettings, init_storage
18
19
  from .core.upath import convert_pathlike
19
20
 
21
+ if TYPE_CHECKING:
22
+ from pydantic import PostgresDsn
23
+
24
+ from .core.types import UPathStr
25
+
20
26
 
21
27
  def get_schema_module_name(schema_name) -> str:
22
28
  import importlib.util
@@ -32,20 +38,26 @@ def get_schema_module_name(schema_name) -> str:
32
38
  )
33
39
 
34
40
 
35
- def register_storage(ssettings: StorageSettings):
41
+ def register_storage_in_instance(ssettings: StorageSettings):
36
42
  from lnschema_core.models import Storage
37
43
  from lnschema_core.users import current_user_id
38
44
 
39
- defaults = dict(
40
- root=ssettings.root_as_str,
41
- type=ssettings.type,
42
- region=ssettings.region,
43
- created_by_id=current_user_id(),
44
- )
45
+ from .core.hashing import hash_and_encode_as_b62
46
+
47
+ assert ssettings._instance_id is not None
48
+
49
+ # how do we ensure that this function is only called passing
50
+ # the managing instance?
51
+ defaults = {
52
+ "root": ssettings.root_as_str,
53
+ "type": ssettings.type,
54
+ "region": ssettings.region,
55
+ "instance_uid": hash_and_encode_as_b62(ssettings._instance_id.hex)[:12],
56
+ "created_by_id": current_user_id(),
57
+ }
45
58
  if ssettings._uid is not None:
46
59
  defaults["uid"] = ssettings._uid
47
-
48
- storage, created = Storage.objects.update_or_create(
60
+ storage, _ = Storage.objects.update_or_create(
49
61
  root=ssettings.root_as_str,
50
62
  defaults=defaults,
51
63
  )
@@ -60,10 +72,10 @@ def register_user(usettings):
60
72
  # need to have try except because of integer primary key migration
61
73
  user, created = User.objects.update_or_create(
62
74
  uid=usettings.uid,
63
- defaults=dict(
64
- handle=usettings.handle,
65
- name=usettings.name,
66
- ),
75
+ defaults={
76
+ "handle": usettings.handle,
77
+ "name": usettings.name,
78
+ },
67
79
  )
68
80
  # for users with only read access, except via ProgrammingError
69
81
  # ProgrammingError: permission denied for table lnschema_core_user
@@ -71,13 +83,13 @@ def register_user(usettings):
71
83
  pass
72
84
 
73
85
 
74
- def register_user_and_storage(isettings: InstanceSettings, usettings):
86
+ def register_user_and_storage_in_instance(isettings: InstanceSettings, usettings):
75
87
  """Register user & storage in DB."""
76
88
  from django.db.utils import OperationalError
77
89
 
78
90
  try:
79
91
  register_user(usettings)
80
- register_storage(isettings.storage)
92
+ register_storage_in_instance(isettings.storage)
81
93
  except OperationalError as error:
82
94
  logger.warning(f"instance seems not set up ({error})")
83
95
 
@@ -123,11 +135,11 @@ Either delete your cache ({}) or add it back to the cloud (if delete was acciden
123
135
 
124
136
 
125
137
  def process_connect_response(
126
- response: Union[Tuple, str], instance_identifier: str
127
- ) -> Tuple[
138
+ response: tuple | str, instance_identifier: str
139
+ ) -> tuple[
128
140
  UUID,
129
141
  Literal[
130
- "instance-corrupted-or-deleted", "account-not-exists", "instance-not-reachable"
142
+ "instance-corrupted-or-deleted", "account-not-exists", "instance-not-found"
131
143
  ],
132
144
  ]:
133
145
  # for internal use when creating instances through CICD
@@ -148,18 +160,18 @@ def process_connect_response(
148
160
  def validate_init_args(
149
161
  *,
150
162
  storage: UPathStr,
151
- name: Optional[str] = None,
152
- db: Optional[PostgresDsn] = None,
153
- schema: Optional[str] = None,
163
+ name: str | None = None,
164
+ db: PostgresDsn | None = None,
165
+ schema: str | None = None,
154
166
  _test: bool = False,
155
- ) -> Tuple[
167
+ ) -> tuple[
156
168
  str,
157
- Optional[UUID],
169
+ UUID | None,
158
170
  Literal[
159
171
  "connected",
160
172
  "instance-corrupted-or-deleted",
161
173
  "account-not-exists",
162
- "instance-not-reachable",
174
+ "instance-not-found",
163
175
  ],
164
176
  str,
165
177
  ]:
@@ -177,7 +189,7 @@ def validate_init_args(
177
189
  "connected",
178
190
  "instance-corrupted-or-deleted",
179
191
  "account-not-exists",
180
- "instance-not-reachable",
192
+ "instance-not-found",
181
193
  ] = "connected"
182
194
  instance_id = None
183
195
  if response is not None:
@@ -196,9 +208,9 @@ Try running on the CLI: lamin set auto-connect false
196
208
  def init(
197
209
  *,
198
210
  storage: UPathStr,
199
- name: Optional[str] = None,
200
- db: Optional[PostgresDsn] = None,
201
- schema: Optional[str] = None,
211
+ name: str | None = None,
212
+ db: PostgresDsn | None = None,
213
+ schema: str | None = None,
202
214
  _test: bool = False,
203
215
  ) -> None:
204
216
  """Create and load a LaminDB instance.
@@ -222,7 +234,7 @@ def init(
222
234
  close_instance(mute=True)
223
235
  from .core._hub_core import init_instance as init_instance_hub
224
236
 
225
- name_str, instance_id, instance_state, instance_slug = validate_init_args(
237
+ name_str, instance_id, instance_state, _ = validate_init_args(
226
238
  storage=storage,
227
239
  name=name,
228
240
  db=db,
@@ -232,7 +244,7 @@ def init(
232
244
  if instance_state == "connected":
233
245
  settings.auto_connect = True # we can also debate this switch here
234
246
  return None
235
- ssettings = init_storage(storage)
247
+ ssettings = init_storage(storage, instance_id=instance_id)
236
248
  isettings = InstanceSettings(
237
249
  id=instance_id, # type: ignore
238
250
  owner=settings.user.handle,
@@ -261,14 +273,18 @@ def init(
261
273
  settings.auto_connect = True
262
274
  except Exception as e:
263
275
  from ._delete import delete_by_isettings
264
- from .core._hub_core import delete_storage_record as delete_storage_record
265
- from .core._hub_core import delete_instance_record as delete_instance_record
276
+ from .core._hub_core import delete_instance_record, delete_storage_record
266
277
 
267
278
  if isettings is not None:
268
279
  delete_by_isettings(isettings)
269
- delete_instance_record(isettings.id)
280
+ if settings.user.handle != "anonymous" and isettings.is_on_hub:
281
+ delete_instance_record(isettings._id)
270
282
  isettings._get_settings_file().unlink(missing_ok=True) # type: ignore
271
- if ssettings is not None:
283
+ if (
284
+ ssettings is not None
285
+ and settings.user.handle != "anonymous"
286
+ and ssettings.is_on_hub
287
+ ):
272
288
  delete_storage_record(ssettings._uuid) # type: ignore
273
289
  raise e
274
290
  return None
@@ -283,7 +299,7 @@ def load_from_isettings(
283
299
 
284
300
  if init:
285
301
  # during init both user and storage need to be registered
286
- register_user_and_storage(isettings, settings.user)
302
+ register_user_and_storage_in_instance(isettings, settings.user)
287
303
  write_bionty_sources(isettings)
288
304
  isettings._update_cloud_sqlite_file(unlock_cloud_sqlite=False)
289
305
  else:
@@ -319,8 +335,8 @@ def validate_sqlite_state(isettings: InstanceSettings) -> None:
319
335
  def infer_instance_name(
320
336
  *,
321
337
  storage: UPathStr,
322
- name: Optional[str] = None,
323
- db: Optional[PostgresDsn] = None,
338
+ name: str | None = None,
339
+ db: PostgresDsn | None = None,
324
340
  ) -> str:
325
341
  if name is not None:
326
342
  if "/" in name:
lamindb_setup/_migrate.py CHANGED
@@ -1,11 +1,13 @@
1
- from typing import Optional, Dict
1
+ from __future__ import annotations
2
+
3
+ from django.db import connection
4
+ from django.db.migrations.loader import MigrationLoader
2
5
  from lamin_utils import logger
3
6
  from packaging import version
7
+
4
8
  from ._check_setup import _check_instance_setup
5
9
  from .core._settings import settings
6
10
  from .core.django import setup_django
7
- from django.db import connection
8
- from django.db.migrations.loader import MigrationLoader
9
11
 
10
12
 
11
13
  # for the django-based synching code, see laminhub_rest
@@ -68,14 +70,14 @@ class migrate:
68
70
  """Deploy a migration."""
69
71
  if _check_instance_setup():
70
72
  raise RuntimeError("Restart Python session to migrate or use CLI!")
73
+ from lamindb_setup.core._hub_client import call_with_fallback_auth
71
74
  from lamindb_setup.core._hub_crud import (
72
- update_instance,
73
- select_instance_by_id,
74
75
  select_collaborator,
76
+ select_instance_by_id,
77
+ update_instance,
75
78
  )
76
- from lamindb_setup.core._hub_client import call_with_fallback_auth
77
79
 
78
- instance_id_str = settings.instance.id.hex
80
+ instance_id_str = settings.instance._id.hex
79
81
  instance = call_with_fallback_auth(
80
82
  select_instance_by_id, instance_id=instance_id_str
81
83
  )
@@ -104,7 +106,7 @@ class migrate:
104
106
  logger.important(f"updating lamindb version in hub: {lamindb.__version__}")
105
107
  call_with_fallback_auth(
106
108
  update_instance,
107
- instance_id=settings.instance.id.hex,
109
+ instance_id=settings.instance._id.hex,
108
110
  instance_fields={"lamindb_version": lamindb.__version__},
109
111
  )
110
112
 
@@ -126,7 +128,7 @@ class migrate:
126
128
 
127
129
  @classmethod
128
130
  def squash(
129
- cls, package_name, migration_nr, start_migration_nr: Optional[str] = None
131
+ cls, package_name, migration_nr, start_migration_nr: str | None = None
130
132
  ) -> None:
131
133
  """Squash migrations."""
132
134
  from django.core.management import call_command
@@ -149,9 +151,10 @@ class migrate:
149
151
 
150
152
  @classmethod
151
153
  def defined_migrations(cls, latest: bool = False):
152
- from django.core.management import call_command
153
154
  from io import StringIO
154
155
 
156
+ from django.core.management import call_command
157
+
155
158
  def parse_migration_output(output):
156
159
  """Parse the output of the showmigrations command to get migration names."""
157
160
  lines = output.splitlines()
@@ -210,11 +213,11 @@ class migrate:
210
213
  # Load all migrations using Django's migration loader
211
214
  loader = MigrationLoader(connection)
212
215
  squashed_replacements = set()
213
- for key, migration in loader.disk_migrations.items():
216
+ for _key, migration in loader.disk_migrations.items():
214
217
  if hasattr(migration, "replaces"):
215
218
  squashed_replacements.update(migration.replaces)
216
219
 
217
- deployed_migrations: Dict = {}
220
+ deployed_migrations: dict = {}
218
221
  with connection.cursor() as cursor:
219
222
  cursor.execute(
220
223
  """
@@ -223,7 +226,7 @@ class migrate:
223
226
  ORDER BY app, deployed DESC
224
227
  """
225
228
  )
226
- for app, name, deployed in cursor.fetchall():
229
+ for app, name, _deployed in cursor.fetchall():
227
230
  # skip migrations that are part of a squashed migration
228
231
  if (app, name) in squashed_replacements:
229
232
  continue
@@ -1,13 +1,19 @@
1
- from .core.django import setup_django
1
+ from __future__ import annotations
2
+
3
+ from lamin_utils import logger
4
+
2
5
  from .core._settings import settings
3
6
  from .core._settings_storage import base62
7
+ from .core.django import setup_django
4
8
 
5
9
 
6
10
  def register(_test: bool = False):
7
11
  """Register an instance on the hub."""
12
+ from ._check_setup import _check_instance_setup
8
13
  from .core._hub_core import init_instance as init_instance_hub
9
14
  from .core._hub_core import init_storage as init_storage_hub
10
- from ._check_setup import _check_instance_setup
15
+
16
+ logger.warning("""lamin register will be removed soon""")
11
17
 
12
18
  isettings = settings.instance
13
19
  if not _check_instance_setup() and not _test:
@@ -17,6 +23,7 @@ def register(_test: bool = False):
17
23
  if ssettings._uid is None and _test:
18
24
  # because django isn't up, we can't get it from the database
19
25
  ssettings._uid = base62(8)
20
- ssettings._uuid_ = init_storage_hub(ssettings)
26
+ init_storage_hub(ssettings)
21
27
  init_instance_hub(isettings)
28
+ isettings._is_on_hub = True
22
29
  isettings._persist()
lamindb_setup/_schema.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from django.urls import path
2
4
  from lamin_utils import logger
3
5
 
@@ -13,11 +15,12 @@ urlpatterns = [
13
15
 
14
16
 
15
17
  def view():
16
- from .core.django import setup_django
17
- from .core._settings import settings
18
- from ._check_setup import _check_instance_setup
19
18
  from django.core.management import call_command
20
19
 
20
+ from ._check_setup import _check_instance_setup
21
+ from .core._settings import settings
22
+ from .core.django import setup_django
23
+
21
24
  if _check_instance_setup():
22
25
  raise RuntimeError("Restart Python session or use CLI!")
23
26
  setup_django(settings.instance, view_schema=True)
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from lamin_utils import logger
6
+
7
+ from ._init_instance import register_storage_in_instance
8
+ from .core._settings import settings
9
+ from .core._settings_storage import init_storage
10
+
11
+ if TYPE_CHECKING:
12
+ from lamindb_setup.core.types import UPathStr
13
+
14
+
15
+ def set_managed_storage(root: UPathStr, **fs_kwargs):
16
+ """Add or switch to another managed storage location.
17
+
18
+ Args:
19
+ root: `UPathStr` - The new storage root, e.g., an S3 bucket.
20
+ **fs_kwargs: Additional fsspec arguments for cloud root, e.g., profile.
21
+
22
+ """
23
+ if settings.instance.dialect == "sqlite":
24
+ raise ValueError(
25
+ "Can't add additional managed storage locations for sqlite instances."
26
+ )
27
+ if not settings.instance.is_on_hub:
28
+ raise ValueError(
29
+ "Can't add additional managed storage locations for instances that aren't managed through the hub."
30
+ )
31
+ ssettings = init_storage(
32
+ root=root, instance_id=settings.instance._id, register_hub=True
33
+ )
34
+ settings.instance._storage = ssettings
35
+ settings.instance._persist() # this also updates the settings object
36
+ register_storage_in_instance(ssettings)
37
+ settings.storage._set_fs_kwargs(**fs_kwargs)
@@ -1,4 +1,6 @@
1
- from typing import Union, Optional
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional, Union
2
4
 
3
5
  from lamin_utils import logger
4
6
 
@@ -8,15 +10,13 @@ from .core._settings import settings
8
10
  from .core._settings_load import load_or_create_user_settings, load_user_settings
9
11
  from .core._settings_save import save_user_settings
10
12
  from .core._settings_store import (
13
+ current_user_settings_file,
11
14
  user_settings_file_email,
12
15
  user_settings_file_handle,
13
- current_user_settings_file,
14
16
  )
15
17
 
16
18
 
17
- def load_user(
18
- email: Optional[str] = None, handle: Optional[str] = None
19
- ) -> Union[str, None]:
19
+ def load_user(email: str | None = None, handle: str | None = None) -> str | None:
20
20
  if email is not None:
21
21
  settings_file = user_settings_file_email(email)
22
22
  if handle is not None:
@@ -46,8 +46,8 @@ def load_user(
46
46
  def login(
47
47
  user: str,
48
48
  *,
49
- key: Optional[str] = None,
50
- password: Optional[str] = None, # for backward compat
49
+ key: str | None = None,
50
+ password: str | None = None, # for backward compat
51
51
  ) -> None:
52
52
  """Log in user.
53
53
 
@@ -1,9 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import logging
2
4
 
3
5
  silenced = False
4
6
 
5
7
 
6
- # from https://github.com/boto/boto3/blob/8c6e641bed8130a9d8cb4d97b4acbe7aa0d0657a/boto3/__init__.py#L37 # noqa
8
+ # from https://github.com/boto/boto3/blob/8c6e641bed8130a9d8cb4d97b4acbe7aa0d0657a/boto3/__init__.py#L37
7
9
  def set_stream_logger(name, level):
8
10
  logger = logging.getLogger(name)
9
11
  logger.setLevel(level)
@@ -24,7 +26,7 @@ def silence_loggers():
24
26
  set_stream_logger(name="botocore.endpoint", level=logging.WARNING)
25
27
  set_stream_logger(name="httpx", level=logging.WARNING)
26
28
  try:
27
- import aiobotocore # noqa
29
+ import aiobotocore
28
30
 
29
31
  # the 7th logging message of credentials came from aiobotocore
30
32
  set_stream_logger(name="aiobotocore.credentials", level=logging.WARNING)
@@ -1,19 +1,20 @@
1
- """Core library.
1
+ """Core setup library.
2
2
 
3
3
  Settings:
4
4
 
5
5
  .. autosummary::
6
6
  :toctree:
7
7
 
8
+ SetupSettings
8
9
  UserSettings
9
10
  InstanceSettings
10
11
  StorageSettings
11
12
 
12
13
  """
13
- from . import types
14
- from . import upath, django
14
+ from . import django, types, upath
15
15
  from ._deprecated import deprecated
16
16
  from ._docs import doc_args
17
+ from ._settings import SetupSettings
17
18
  from ._settings_instance import InstanceSettings
18
19
  from ._settings_storage import StorageSettings
19
20
  from ._settings_user import UserSettings
@@ -1,3 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+
1
4
  def get_location(ip="ipinfo.io"):
2
5
  import requests # type: ignore
3
6
 
@@ -1,22 +1,18 @@
1
- # BSD 3-Clause License
1
+ from __future__ import annotations
2
2
 
3
+ # BSD 3-Clause License
3
4
  # Copyright (c) 2017-2018 P. Angerer, F. Alexander Wolf, Theis Lab
4
5
  # All rights reserved.
5
-
6
6
  # Redistribution and use in source and binary forms, with or without
7
7
  # modification, are permitted provided that the following conditions are met:
8
-
9
8
  # * Redistributions of source code must retain the above copyright notice, this
10
9
  # list of conditions and the following disclaimer.
11
-
12
10
  # * Redistributions in binary form must reproduce the above copyright notice,
13
11
  # this list of conditions and the following disclaimer in the documentation
14
12
  # and/or other materials provided with the distribution.
15
-
16
13
  # * Neither the name of the copyright holder nor the names of its
17
14
  # contributors may be used to endorse or promote products derived from
18
15
  # this software without specific prior written permission.
19
-
20
16
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
17
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
18
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -27,7 +23,6 @@
27
23
  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
24
  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
25
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
-
31
26
  import warnings
32
27
  from functools import wraps
33
28
 
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from textwrap import dedent
2
4
 
3
5
 
@@ -1,11 +1,13 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
- from typing import Optional
3
- from supabase.lib.client_options import ClientOptions
4
4
  from urllib.request import urlretrieve
5
- from supabase import create_client, Client
6
- from pydantic import BaseSettings
5
+
7
6
  from gotrue.errors import AuthUnknownError
8
7
  from lamin_utils import logger
8
+ from pydantic import BaseSettings
9
+ from supabase import Client, create_client # type: ignore
10
+ from supabase.lib.client_options import ClientOptions
9
11
 
10
12
 
11
13
  class Connector(BaseSettings):
@@ -21,7 +23,7 @@ def load_fallback_connector() -> Connector:
21
23
 
22
24
 
23
25
  PROD_URL = "https://hub.lamin.ai"
24
- PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c" # noqa
26
+ PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c"
25
27
 
26
28
 
27
29
  class Environment:
@@ -40,13 +42,13 @@ class Environment:
40
42
  key = connector.key
41
43
  elif lamin_env == "staging":
42
44
  url = "https://amvrvdwndlqdzgedrqdv.supabase.co"
43
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0" # noqa
45
+ key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0"
44
46
  elif lamin_env == "staging-test":
45
47
  url = "https://iugyyajllqftbpidapak.supabase.co"
46
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90" # noqa
48
+ key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90"
47
49
  elif lamin_env == "prod-test":
48
50
  url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
49
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4" # noqa
51
+ key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4"
50
52
  else:
51
53
  url = os.environ["SUPABASE_API_URL"]
52
54
  key = os.environ["SUPABASE_ANON_KEY"]
@@ -66,7 +68,7 @@ def connect_hub(
66
68
  def connect_hub_with_auth(
67
69
  fallback_env: bool = False,
68
70
  renew_token: bool = False,
69
- access_token: Optional[str] = None,
71
+ access_token: str | None = None,
70
72
  ) -> Client:
71
73
  hub = connect_hub(fallback_env=fallback_env)
72
74
  if access_token is None:
@@ -83,7 +85,7 @@ def connect_hub_with_auth(
83
85
 
84
86
 
85
87
  # runs ~0.5s
86
- def get_access_token(email: Optional[str] = None, password: Optional[str] = None):
88
+ def get_access_token(email: str | None = None, password: str | None = None):
87
89
  hub = connect_hub()
88
90
  try:
89
91
  auth_response = hub.auth.sign_in_with_password(