lamindb_setup 1.18.2__py3-none-any.whl → 1.19.1__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 (50) hide show
  1. lamindb_setup/__init__.py +4 -19
  2. lamindb_setup/_cache.py +87 -87
  3. lamindb_setup/_check.py +7 -7
  4. lamindb_setup/_check_setup.py +131 -131
  5. lamindb_setup/_connect_instance.py +443 -438
  6. lamindb_setup/_delete.py +155 -151
  7. lamindb_setup/_disconnect.py +38 -38
  8. lamindb_setup/_django.py +39 -39
  9. lamindb_setup/_entry_points.py +19 -19
  10. lamindb_setup/_init_instance.py +423 -429
  11. lamindb_setup/_migrate.py +331 -327
  12. lamindb_setup/_register_instance.py +32 -32
  13. lamindb_setup/_schema.py +27 -27
  14. lamindb_setup/_schema_metadata.py +451 -451
  15. lamindb_setup/_set_managed_storage.py +81 -80
  16. lamindb_setup/_setup_user.py +198 -198
  17. lamindb_setup/_silence_loggers.py +46 -46
  18. lamindb_setup/core/__init__.py +25 -34
  19. lamindb_setup/core/_aws_options.py +276 -266
  20. lamindb_setup/core/_aws_storage.py +57 -55
  21. lamindb_setup/core/_clone.py +50 -50
  22. lamindb_setup/core/_deprecated.py +62 -62
  23. lamindb_setup/core/_docs.py +14 -14
  24. lamindb_setup/core/_hub_client.py +288 -294
  25. lamindb_setup/core/_hub_core.py +0 -2
  26. lamindb_setup/core/_hub_crud.py +247 -247
  27. lamindb_setup/core/_hub_utils.py +100 -100
  28. lamindb_setup/core/_private_django_api.py +80 -80
  29. lamindb_setup/core/_settings.py +440 -434
  30. lamindb_setup/core/_settings_instance.py +32 -7
  31. lamindb_setup/core/_settings_load.py +162 -159
  32. lamindb_setup/core/_settings_save.py +108 -96
  33. lamindb_setup/core/_settings_storage.py +433 -433
  34. lamindb_setup/core/_settings_store.py +162 -92
  35. lamindb_setup/core/_settings_user.py +55 -55
  36. lamindb_setup/core/_setup_bionty_sources.py +44 -44
  37. lamindb_setup/core/cloud_sqlite_locker.py +240 -240
  38. lamindb_setup/core/django.py +414 -413
  39. lamindb_setup/core/exceptions.py +1 -1
  40. lamindb_setup/core/hashing.py +134 -134
  41. lamindb_setup/core/types.py +1 -1
  42. lamindb_setup/core/upath.py +1031 -1028
  43. lamindb_setup/errors.py +72 -70
  44. lamindb_setup/io.py +423 -416
  45. lamindb_setup/types.py +17 -17
  46. {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info}/METADATA +4 -2
  47. lamindb_setup-1.19.1.dist-info/RECORD +51 -0
  48. {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info}/WHEEL +1 -1
  49. {lamindb_setup-1.18.2.dist-info → lamindb_setup-1.19.1.dist-info/licenses}/LICENSE +201 -201
  50. lamindb_setup-1.18.2.dist-info/RECORD +0 -51
@@ -1,294 +1,288 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- import os
5
- from contextlib import contextmanager
6
- from datetime import datetime
7
- from typing import Literal
8
- from urllib.request import urlretrieve
9
-
10
- import httpx
11
- from httpx_retries import Retry, RetryTransport
12
- from lamin_utils import logger
13
- from pydantic_settings import BaseSettings
14
- from supabase import Client, ClientOptions, create_client
15
-
16
- from ._settings_save import save_user_settings
17
-
18
-
19
- class Connector(BaseSettings):
20
- url: str
21
- key: str
22
-
23
-
24
- def load_fallback_connector() -> Connector:
25
- url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
26
- connector_file, _ = urlretrieve(url)
27
- connector = Connector(_env_file=connector_file)
28
- return connector
29
-
30
-
31
- PROD_URL = "https://hub.lamin.ai"
32
- PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c"
33
-
34
-
35
- class Environment:
36
- def __init__(self, fallback: bool = False):
37
- lamin_env = os.getenv("LAMIN_ENV")
38
- if lamin_env is None:
39
- lamin_env = "prod"
40
- # set public key
41
- if lamin_env == "prod":
42
- if not fallback:
43
- url = PROD_URL
44
- key = PROD_ANON_KEY
45
- else:
46
- connector = load_fallback_connector()
47
- url = connector.url
48
- key = connector.key
49
- elif lamin_env == "staging":
50
- url = "https://amvrvdwndlqdzgedrqdv.supabase.co"
51
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0"
52
- elif lamin_env == "staging-test":
53
- url = "https://iugyyajllqftbpidapak.supabase.co"
54
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90"
55
- elif lamin_env == "prod-test":
56
- url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
57
- key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4"
58
- else:
59
- url = os.environ["SUPABASE_API_URL"]
60
- key = os.environ["SUPABASE_ANON_KEY"]
61
- self.lamin_env: str = lamin_env
62
- self.supabase_api_url: str = url
63
- self.supabase_anon_key: str = key
64
-
65
-
66
- DEFAULT_TIMEOUT = 12
67
-
68
-
69
- # needed to log retries
70
- class LogRetry(Retry):
71
- def increment(self):
72
- new = super().increment()
73
- now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
74
- # new.attempts_made is the 1-based retry count
75
- logger.warning(f"{now} HTTP retry attempt {new.attempts_made}/{new.total}")
76
- return new
77
-
78
-
79
- # runs ~0.5s
80
- def connect_hub(
81
- fallback_env: bool = False, client_options: ClientOptions | None = None
82
- ) -> Client:
83
- env = Environment(fallback=fallback_env)
84
- if client_options is None:
85
- client_options = ClientOptions(
86
- auto_refresh_token=False,
87
- function_client_timeout=DEFAULT_TIMEOUT,
88
- postgrest_client_timeout=DEFAULT_TIMEOUT,
89
- )
90
- client = create_client(env.supabase_api_url, env.supabase_anon_key, client_options)
91
- # needed to enable retries for http requests in supabase
92
- # these are separate clients and need separate transports
93
- transports = []
94
- for _ in range(2):
95
- transports.append(
96
- RetryTransport(
97
- retry=LogRetry(total=2, backoff_factor=0.2),
98
- transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
99
- )
100
- )
101
- # this overwrites transports of existing httpx clients
102
- # if proxies are set, the default transports that were created on clients init
103
- # will be used, irrespective of these re-settings
104
- client.auth._http_client._transport = transports[0]
105
- client.postgrest.session._transport = transports[1]
106
- # POST is not retryable by default, but for our functions it should be safe to retry
107
- client.functions._client._transport = RetryTransport(
108
- retry=LogRetry(
109
- total=2,
110
- backoff_factor=0.2,
111
- allowed_methods=[
112
- "HEAD",
113
- "GET",
114
- "PUT",
115
- "DELETE",
116
- "OPTIONS",
117
- "TRACE",
118
- "POST",
119
- ],
120
- ),
121
- transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
122
- )
123
- return client
124
-
125
-
126
- def connect_hub_with_auth(
127
- fallback_env: bool = False,
128
- renew_token: bool = False,
129
- access_token: str | None = None,
130
- ) -> Client:
131
- hub = connect_hub(fallback_env=fallback_env)
132
- if access_token is None:
133
- from lamindb_setup import settings
134
-
135
- if renew_token:
136
- settings.user.access_token = get_access_token(
137
- settings.user.email, settings.user.password, settings.user.api_key
138
- )
139
- access_token = settings.user.access_token
140
- hub.postgrest.auth(access_token)
141
- hub.functions.set_auth(access_token)
142
- return hub
143
-
144
-
145
- # runs ~0.5s
146
- def get_access_token(
147
- email: str | None = None, password: str | None = None, api_key: str | None = None
148
- ):
149
- hub = connect_hub()
150
- try:
151
- if api_key is not None:
152
- auth_response = hub.functions.invoke(
153
- "get-jwt-v1",
154
- invoke_options={"body": {"api_key": api_key}},
155
- )
156
- return json.loads(auth_response)["accessToken"]
157
- auth_response = hub.auth.sign_in_with_password(
158
- {
159
- "email": email,
160
- "password": password,
161
- }
162
- )
163
- return auth_response.session.access_token
164
- except Exception as e:
165
- # we need to log the problem here because the exception is usually caught outside
166
- # in call_with_fallback_auth
167
- logger.warning(f"failed to update your lamindb access token: {e}")
168
- raise e
169
- finally:
170
- hub.auth.sign_out(options={"scope": "local"})
171
-
172
-
173
- def call_with_fallback_auth(
174
- callable,
175
- **kwargs,
176
- ):
177
- access_token = kwargs.pop("access_token", None)
178
-
179
- if access_token is not None:
180
- client = None
181
- try:
182
- client = connect_hub_with_auth(access_token=access_token)
183
- result = callable(**kwargs, client=client)
184
- finally:
185
- if client is not None:
186
- client.auth.sign_out(options={"scope": "local"})
187
-
188
- return result
189
-
190
- for renew_token, fallback_env in [(False, False), (True, False), (False, True)]:
191
- client = None
192
- try:
193
- client = connect_hub_with_auth(
194
- renew_token=renew_token, fallback_env=fallback_env
195
- )
196
- result = callable(**kwargs, client=client)
197
- # we update access_token here
198
- # because at this point the call has been successfully resolved
199
- if renew_token:
200
- from lamindb_setup import settings
201
-
202
- # here settings.user contains an updated access_token
203
- save_user_settings(settings.user)
204
- break
205
- # we use Exception here as the ways in which the client fails upon 401
206
- # are not consistent and keep changing
207
- # because we ultimately raise the error, it's OK I'd say
208
- except Exception as e:
209
- if fallback_env:
210
- raise e
211
- finally:
212
- if client is not None:
213
- client.auth.sign_out(options={"scope": "local"})
214
-
215
- return result
216
-
217
-
218
- def call_with_fallback(
219
- callable,
220
- **kwargs,
221
- ):
222
- for fallback_env in [False, True]:
223
- client = None
224
- try:
225
- client = connect_hub(fallback_env=fallback_env)
226
- result = callable(**kwargs, client=client)
227
- break
228
- except Exception as e:
229
- if fallback_env:
230
- raise e
231
- finally:
232
- if client is not None:
233
- # in case there was sign in
234
- client.auth.sign_out(options={"scope": "local"})
235
- return result
236
-
237
-
238
- @contextmanager
239
- def httpx_client():
240
- client = None
241
- try:
242
- # local is used in tests
243
- if os.environ.get("LAMIN_ENV", "prod") == "local":
244
- from fastapi.testclient import TestClient
245
- from laminhub_rest.main import app
246
-
247
- client = TestClient(app)
248
- else:
249
- transport = RetryTransport(
250
- retry=LogRetry(total=2, backoff_factor=0.2),
251
- transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
252
- )
253
- # first we create a client to build the proxy map from the env variables
254
- # if proxies are set, the default transports will be used
255
- # otherwise the RetryTransport object that we assign below
256
- client = httpx.Client(trust_env=True)
257
- client._transport = transport
258
- yield client
259
- finally:
260
- if client is not None:
261
- client.close()
262
-
263
-
264
- def request_with_auth(
265
- url: str,
266
- method: Literal["get", "post", "put", "delete", "head", "options"],
267
- access_token: str,
268
- renew_token: bool = True,
269
- **kwargs,
270
- ):
271
- headers = kwargs.pop("headers", {})
272
- headers["Authorization"] = f"Bearer {access_token}"
273
- timeout = kwargs.pop("timeout", DEFAULT_TIMEOUT)
274
-
275
- with httpx_client() as client:
276
- make_request = getattr(client, method)
277
- response = make_request(url, headers=headers, timeout=timeout, **kwargs)
278
- status_code = response.status_code
279
- # update access_token and try again if failed
280
- if not (200 <= status_code < 300) and renew_token:
281
- from lamindb_setup import settings
282
-
283
- logger.debug(f"{method} {url} failed: {status_code} {response.text}")
284
-
285
- access_token = get_access_token(
286
- settings.user.email, settings.user.password, settings.user.api_key
287
- )
288
-
289
- settings.user.access_token = access_token
290
- save_user_settings(settings.user)
291
-
292
- headers["Authorization"] = f"Bearer {access_token}"
293
- response = make_request(url, headers=headers, timeout=timeout, **kwargs)
294
- return response
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ from contextlib import contextmanager
6
+ from datetime import datetime
7
+ from typing import Literal
8
+ from urllib.request import urlretrieve
9
+
10
+ import httpx
11
+ from httpx_retries import Retry, RetryTransport
12
+ from lamin_utils import logger
13
+ from supabase import Client, ClientOptions, create_client
14
+
15
+ from ._settings_save import save_user_settings
16
+ from ._settings_store import Connector
17
+
18
+
19
+ def load_fallback_connector() -> Connector:
20
+ url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
21
+ connector_file, _ = urlretrieve(url)
22
+ return Connector.from_env_file(connector_file, "")
23
+
24
+
25
+ PROD_URL = "https://hub.lamin.ai"
26
+ PROD_ANON_KEY = "sb_publishable_YVa4h8hQ-yBhXpfa2cP39w_PhoLW6Nu"
27
+
28
+
29
+ class Environment:
30
+ def __init__(self, fallback: bool = False):
31
+ lamin_env = os.getenv("LAMIN_ENV")
32
+ if lamin_env is None:
33
+ lamin_env = "prod"
34
+ # set public key
35
+ if lamin_env == "prod":
36
+ if not fallback:
37
+ url = PROD_URL
38
+ key = PROD_ANON_KEY
39
+ else:
40
+ connector = load_fallback_connector()
41
+ url = connector.url
42
+ key = connector.key
43
+ elif lamin_env == "staging":
44
+ url = "https://amvrvdwndlqdzgedrqdv.supabase.co"
45
+ key = "sb_publishable_amVjtilv_Yj4VmGLmxtq6A_sYlLoQx5"
46
+ elif lamin_env == "staging-test":
47
+ url = "https://iugyyajllqftbpidapak.supabase.co"
48
+ key = "sb_publishable_XmXroXqTLQw-eeT5kysCww_k8vJv-4L"
49
+ elif lamin_env == "prod-test":
50
+ url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
51
+ key = "sb_publishable_G-pyO5aW6VFErTzJyVvM5w_NAv1_Mf7"
52
+ else:
53
+ url = os.environ["SUPABASE_API_URL"]
54
+ key = os.environ["SUPABASE_ANON_KEY"]
55
+ self.lamin_env: str = lamin_env
56
+ self.supabase_api_url: str = url
57
+ self.supabase_anon_key: str = key
58
+
59
+
60
+ DEFAULT_TIMEOUT = 12
61
+
62
+
63
+ # needed to log retries
64
+ class LogRetry(Retry):
65
+ def increment(self):
66
+ new = super().increment()
67
+ now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
68
+ # new.attempts_made is the 1-based retry count
69
+ logger.warning(f"{now} HTTP retry attempt {new.attempts_made}/{new.total}")
70
+ return new
71
+
72
+
73
+ # runs ~0.5s
74
+ def connect_hub(
75
+ fallback_env: bool = False, client_options: ClientOptions | None = None
76
+ ) -> Client:
77
+ env = Environment(fallback=fallback_env)
78
+ if client_options is None:
79
+ client_options = ClientOptions(
80
+ auto_refresh_token=False,
81
+ function_client_timeout=DEFAULT_TIMEOUT,
82
+ postgrest_client_timeout=DEFAULT_TIMEOUT,
83
+ )
84
+ client = create_client(env.supabase_api_url, env.supabase_anon_key, client_options)
85
+ # needed to enable retries for http requests in supabase
86
+ # these are separate clients and need separate transports
87
+ transports = []
88
+ for _ in range(2):
89
+ transports.append(
90
+ RetryTransport(
91
+ retry=LogRetry(total=2, backoff_factor=0.2),
92
+ transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
93
+ )
94
+ )
95
+ # this overwrites transports of existing httpx clients
96
+ # if proxies are set, the default transports that were created on clients init
97
+ # will be used, irrespective of these re-settings
98
+ client.auth._http_client._transport = transports[0]
99
+ client.postgrest.session._transport = transports[1]
100
+ # POST is not retryable by default, but for our functions it should be safe to retry
101
+ client.functions._client._transport = RetryTransport(
102
+ retry=LogRetry(
103
+ total=2,
104
+ backoff_factor=0.2,
105
+ allowed_methods=[
106
+ "HEAD",
107
+ "GET",
108
+ "PUT",
109
+ "DELETE",
110
+ "OPTIONS",
111
+ "TRACE",
112
+ "POST",
113
+ ],
114
+ ),
115
+ transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
116
+ )
117
+ return client
118
+
119
+
120
+ def connect_hub_with_auth(
121
+ fallback_env: bool = False,
122
+ renew_token: bool = False,
123
+ access_token: str | None = None,
124
+ ) -> Client:
125
+ hub = connect_hub(fallback_env=fallback_env)
126
+ if access_token is None:
127
+ from lamindb_setup import settings
128
+
129
+ if renew_token:
130
+ settings.user.access_token = get_access_token(
131
+ settings.user.email, settings.user.password, settings.user.api_key
132
+ )
133
+ access_token = settings.user.access_token
134
+ hub.postgrest.auth(access_token)
135
+ hub.functions.set_auth(access_token)
136
+ return hub
137
+
138
+
139
+ # runs ~0.5s
140
+ def get_access_token(
141
+ email: str | None = None, password: str | None = None, api_key: str | None = None
142
+ ):
143
+ hub = connect_hub()
144
+ try:
145
+ if api_key is not None:
146
+ auth_response = hub.functions.invoke(
147
+ "get-jwt-v1",
148
+ invoke_options={"body": {"api_key": api_key}},
149
+ )
150
+ return json.loads(auth_response)["accessToken"]
151
+ auth_response = hub.auth.sign_in_with_password(
152
+ {
153
+ "email": email,
154
+ "password": password,
155
+ }
156
+ )
157
+ return auth_response.session.access_token
158
+ except Exception as e:
159
+ # we need to log the problem here because the exception is usually caught outside
160
+ # in call_with_fallback_auth
161
+ logger.warning(f"failed to update your lamindb access token: {e}")
162
+ raise e
163
+ finally:
164
+ hub.auth.sign_out(options={"scope": "local"})
165
+
166
+
167
+ def call_with_fallback_auth(
168
+ callable,
169
+ **kwargs,
170
+ ):
171
+ access_token = kwargs.pop("access_token", None)
172
+
173
+ if access_token is not None:
174
+ client = None
175
+ try:
176
+ client = connect_hub_with_auth(access_token=access_token)
177
+ result = callable(**kwargs, client=client)
178
+ finally:
179
+ if client is not None:
180
+ client.auth.sign_out(options={"scope": "local"})
181
+
182
+ return result
183
+
184
+ for renew_token, fallback_env in [(False, False), (True, False), (False, True)]:
185
+ client = None
186
+ try:
187
+ client = connect_hub_with_auth(
188
+ renew_token=renew_token, fallback_env=fallback_env
189
+ )
190
+ result = callable(**kwargs, client=client)
191
+ # we update access_token here
192
+ # because at this point the call has been successfully resolved
193
+ if renew_token:
194
+ from lamindb_setup import settings
195
+
196
+ # here settings.user contains an updated access_token
197
+ save_user_settings(settings.user)
198
+ break
199
+ # we use Exception here as the ways in which the client fails upon 401
200
+ # are not consistent and keep changing
201
+ # because we ultimately raise the error, it's OK I'd say
202
+ except Exception as e:
203
+ if fallback_env:
204
+ raise e
205
+ finally:
206
+ if client is not None:
207
+ client.auth.sign_out(options={"scope": "local"})
208
+
209
+ return result
210
+
211
+
212
+ def call_with_fallback(
213
+ callable,
214
+ **kwargs,
215
+ ):
216
+ for fallback_env in [False, True]:
217
+ client = None
218
+ try:
219
+ client = connect_hub(fallback_env=fallback_env)
220
+ result = callable(**kwargs, client=client)
221
+ break
222
+ except Exception as e:
223
+ if fallback_env:
224
+ raise e
225
+ finally:
226
+ if client is not None:
227
+ # in case there was sign in
228
+ client.auth.sign_out(options={"scope": "local"})
229
+ return result
230
+
231
+
232
+ @contextmanager
233
+ def httpx_client():
234
+ client = None
235
+ try:
236
+ # local is used in tests
237
+ if os.environ.get("LAMIN_ENV", "prod") == "local":
238
+ from fastapi.testclient import TestClient
239
+ from laminhub_rest.main import app
240
+
241
+ client = TestClient(app)
242
+ else:
243
+ transport = RetryTransport(
244
+ retry=LogRetry(total=2, backoff_factor=0.2),
245
+ transport=httpx.HTTPTransport(verify=True, http2=True, trust_env=True),
246
+ )
247
+ # first we create a client to build the proxy map from the env variables
248
+ # if proxies are set, the default transports will be used
249
+ # otherwise the RetryTransport object that we assign below
250
+ client = httpx.Client(trust_env=True)
251
+ client._transport = transport
252
+ yield client
253
+ finally:
254
+ if client is not None:
255
+ client.close()
256
+
257
+
258
+ def request_with_auth(
259
+ url: str,
260
+ method: Literal["get", "post", "put", "delete", "head", "options"],
261
+ access_token: str,
262
+ renew_token: bool = True,
263
+ **kwargs,
264
+ ):
265
+ headers = kwargs.pop("headers", {})
266
+ headers["Authorization"] = f"Bearer {access_token}"
267
+ timeout = kwargs.pop("timeout", DEFAULT_TIMEOUT)
268
+
269
+ with httpx_client() as client:
270
+ make_request = getattr(client, method)
271
+ response = make_request(url, headers=headers, timeout=timeout, **kwargs)
272
+ status_code = response.status_code
273
+ # update access_token and try again if failed
274
+ if not (200 <= status_code < 300) and renew_token:
275
+ from lamindb_setup import settings
276
+
277
+ logger.debug(f"{method} {url} failed: {status_code} {response.text}")
278
+
279
+ access_token = get_access_token(
280
+ settings.user.email, settings.user.password, settings.user.api_key
281
+ )
282
+
283
+ settings.user.access_token = access_token
284
+ save_user_settings(settings.user)
285
+
286
+ headers["Authorization"] = f"Bearer {access_token}"
287
+ response = make_request(url, headers=headers, timeout=timeout, **kwargs)
288
+ return response
@@ -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",