lamindb_setup 0.76.5__py2.py3-none-any.whl → 0.76.7__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.
- lamindb_setup/__init__.py +1 -1
- lamindb_setup/_cache.py +34 -34
- lamindb_setup/_check.py +7 -7
- lamindb_setup/_check_setup.py +79 -79
- lamindb_setup/_close.py +35 -35
- lamindb_setup/_connect_instance.py +433 -433
- lamindb_setup/_delete.py +137 -137
- lamindb_setup/_django.py +41 -41
- lamindb_setup/_exportdb.py +68 -68
- lamindb_setup/_importdb.py +50 -50
- lamindb_setup/_init_instance.py +374 -374
- lamindb_setup/_migrate.py +239 -236
- lamindb_setup/_register_instance.py +36 -36
- lamindb_setup/_schema.py +27 -27
- lamindb_setup/_schema_metadata.py +391 -391
- lamindb_setup/_set_managed_storage.py +55 -55
- lamindb_setup/_setup_user.py +118 -118
- lamindb_setup/_silence_loggers.py +44 -44
- lamindb_setup/core/__init__.py +21 -21
- lamindb_setup/core/_aws_credentials.py +151 -151
- lamindb_setup/core/_aws_storage.py +48 -48
- lamindb_setup/core/_deprecated.py +55 -55
- lamindb_setup/core/_docs.py +14 -14
- lamindb_setup/core/_hub_client.py +164 -161
- lamindb_setup/core/_hub_core.py +473 -473
- lamindb_setup/core/_hub_crud.py +211 -211
- lamindb_setup/core/_hub_utils.py +109 -109
- lamindb_setup/core/_private_django_api.py +88 -88
- lamindb_setup/core/_settings.py +138 -138
- lamindb_setup/core/_settings_instance.py +461 -460
- lamindb_setup/core/_settings_load.py +100 -100
- lamindb_setup/core/_settings_save.py +81 -81
- lamindb_setup/core/_settings_storage.py +393 -389
- lamindb_setup/core/_settings_store.py +72 -72
- lamindb_setup/core/_settings_user.py +51 -51
- lamindb_setup/core/_setup_bionty_sources.py +99 -99
- lamindb_setup/core/cloud_sqlite_locker.py +232 -232
- lamindb_setup/core/django.py +113 -113
- lamindb_setup/core/exceptions.py +12 -12
- lamindb_setup/core/hashing.py +114 -114
- lamindb_setup/core/types.py +19 -19
- lamindb_setup/core/upath.py +779 -779
- {lamindb_setup-0.76.5.dist-info → lamindb_setup-0.76.7.dist-info}/METADATA +4 -3
- lamindb_setup-0.76.7.dist-info/RECORD +46 -0
- {lamindb_setup-0.76.5.dist-info → lamindb_setup-0.76.7.dist-info}/WHEEL +1 -1
- lamindb_setup-0.76.5.dist-info/RECORD +0 -46
- {lamindb_setup-0.76.5.dist-info → lamindb_setup-0.76.7.dist-info}/LICENSE +0 -0
|
@@ -1,161 +1,164 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
from urllib.request import urlretrieve
|
|
5
|
-
|
|
6
|
-
from gotrue.errors import AuthUnknownError
|
|
7
|
-
from lamin_utils import logger
|
|
8
|
-
from pydantic_settings import BaseSettings
|
|
9
|
-
from supabase import Client, create_client # type: ignore
|
|
10
|
-
from supabase.lib.client_options import ClientOptions
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Connector(BaseSettings):
|
|
14
|
-
url: str
|
|
15
|
-
key: str
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def load_fallback_connector() -> Connector:
|
|
19
|
-
url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
|
|
20
|
-
connector_file, _ = urlretrieve(url)
|
|
21
|
-
connector = Connector(_env_file=connector_file)
|
|
22
|
-
return connector
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
PROD_URL = "https://hub.lamin.ai"
|
|
26
|
-
PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c"
|
|
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 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0"
|
|
46
|
-
elif lamin_env == "staging-test":
|
|
47
|
-
url = "https://iugyyajllqftbpidapak.supabase.co"
|
|
48
|
-
key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90"
|
|
49
|
-
elif lamin_env == "prod-test":
|
|
50
|
-
url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
|
|
51
|
-
key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4"
|
|
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
|
-
# runs ~0.5s
|
|
61
|
-
def connect_hub(
|
|
62
|
-
fallback_env: bool = False, client_options: ClientOptions | None = None
|
|
63
|
-
) -> Client:
|
|
64
|
-
env = Environment(fallback=fallback_env)
|
|
65
|
-
if client_options is None:
|
|
66
|
-
client_options = ClientOptions(auto_refresh_token=False)
|
|
67
|
-
return create_client(env.supabase_api_url, env.supabase_anon_key, client_options)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def connect_hub_with_auth(
|
|
71
|
-
fallback_env: bool = False,
|
|
72
|
-
renew_token: bool = False,
|
|
73
|
-
access_token: str | None = None,
|
|
74
|
-
) -> Client:
|
|
75
|
-
hub = connect_hub(fallback_env=fallback_env)
|
|
76
|
-
if access_token is None:
|
|
77
|
-
from lamindb_setup import settings
|
|
78
|
-
|
|
79
|
-
if renew_token:
|
|
80
|
-
settings.user.access_token = get_access_token(
|
|
81
|
-
settings.user.email, settings.user.password
|
|
82
|
-
)
|
|
83
|
-
access_token = settings.user.access_token
|
|
84
|
-
hub.postgrest.auth(access_token)
|
|
85
|
-
hub.functions.set_auth(access_token)
|
|
86
|
-
return hub
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# runs ~0.5s
|
|
90
|
-
def get_access_token(email: str | None = None, password: str | None = None):
|
|
91
|
-
hub = connect_hub()
|
|
92
|
-
try:
|
|
93
|
-
auth_response = hub.auth.sign_in_with_password(
|
|
94
|
-
{
|
|
95
|
-
"email": email,
|
|
96
|
-
"password": password,
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
return auth_response.session.access_token
|
|
100
|
-
finally:
|
|
101
|
-
hub.auth.sign_out()
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def call_with_fallback_auth(
|
|
105
|
-
callable,
|
|
106
|
-
**kwargs,
|
|
107
|
-
):
|
|
108
|
-
access_token = kwargs.pop("access_token", None)
|
|
109
|
-
|
|
110
|
-
if access_token is not None:
|
|
111
|
-
try:
|
|
112
|
-
client = connect_hub_with_auth(access_token=access_token)
|
|
113
|
-
result = callable(**kwargs, client=client)
|
|
114
|
-
finally:
|
|
115
|
-
try:
|
|
116
|
-
client.auth.sign_out()
|
|
117
|
-
except NameError:
|
|
118
|
-
pass
|
|
119
|
-
return result
|
|
120
|
-
|
|
121
|
-
for renew_token, fallback_env in [(False, False), (True, False), (False, True)]:
|
|
122
|
-
try:
|
|
123
|
-
if renew_token:
|
|
124
|
-
logger.warning(
|
|
125
|
-
"renewing expired lamin token: call `lamin login` to avoid this"
|
|
126
|
-
)
|
|
127
|
-
client = connect_hub_with_auth(
|
|
128
|
-
renew_token=renew_token, fallback_env=fallback_env
|
|
129
|
-
)
|
|
130
|
-
result = callable(**kwargs, client=client)
|
|
131
|
-
break
|
|
132
|
-
# we use Exception here as the ways in which the client fails upon 401
|
|
133
|
-
# are not consistent and keep changing
|
|
134
|
-
# because we ultimately raise the error, it's OK I'd say
|
|
135
|
-
except Exception as e:
|
|
136
|
-
if fallback_env:
|
|
137
|
-
raise e
|
|
138
|
-
finally:
|
|
139
|
-
try:
|
|
140
|
-
client.auth.sign_out()
|
|
141
|
-
except NameError:
|
|
142
|
-
pass
|
|
143
|
-
return result
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def call_with_fallback(
|
|
147
|
-
callable,
|
|
148
|
-
**kwargs,
|
|
149
|
-
):
|
|
150
|
-
for fallback_env in [False, True]:
|
|
151
|
-
try:
|
|
152
|
-
client = connect_hub(fallback_env=fallback_env)
|
|
153
|
-
result = callable(**kwargs, client=client)
|
|
154
|
-
break
|
|
155
|
-
except AuthUnknownError as e:
|
|
156
|
-
if fallback_env:
|
|
157
|
-
raise e
|
|
158
|
-
finally:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from urllib.request import urlretrieve
|
|
5
|
+
|
|
6
|
+
from gotrue.errors import AuthUnknownError
|
|
7
|
+
from lamin_utils import logger
|
|
8
|
+
from pydantic_settings import BaseSettings
|
|
9
|
+
from supabase import Client, create_client # type: ignore
|
|
10
|
+
from supabase.lib.client_options import ClientOptions
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Connector(BaseSettings):
|
|
14
|
+
url: str
|
|
15
|
+
key: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_fallback_connector() -> Connector:
|
|
19
|
+
url = "https://lamin-site-assets.s3.amazonaws.com/connector.env"
|
|
20
|
+
connector_file, _ = urlretrieve(url)
|
|
21
|
+
connector = Connector(_env_file=connector_file)
|
|
22
|
+
return connector
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
PROD_URL = "https://hub.lamin.ai"
|
|
26
|
+
PROD_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxhZXNhdW1tZHlkbGxwcGdmY2h1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTY4NDA1NTEsImV4cCI6MTk3MjQxNjU1MX0.WUeCRiun0ExUxKIv5-CtjF6878H8u26t0JmCWx3_2-c"
|
|
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 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFtdnJ2ZHduZGxxZHpnZWRycWR2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzcxNTcxMzMsImV4cCI6MTk5MjczMzEzM30.Gelt3dQEi8tT4j-JA36RbaZuUvxRnczvRr3iyRtzjY0"
|
|
46
|
+
elif lamin_env == "staging-test":
|
|
47
|
+
url = "https://iugyyajllqftbpidapak.supabase.co"
|
|
48
|
+
key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Iml1Z3l5YWpsbHFmdGJwaWRhcGFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYyODMsImV4cCI6MjAwOTgwMjI4M30.s7B0gMogFhUatMSwlfuPJ95kWhdCZMn1ROhZ3t6Og90"
|
|
49
|
+
elif lamin_env == "prod-test":
|
|
50
|
+
url = "https://xtdacpwiqwpbxsatoyrv.supabase.co"
|
|
51
|
+
key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh0ZGFjcHdpcXdwYnhzYXRveXJ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQyMjYxNDIsImV4cCI6MjAwOTgwMjE0Mn0.Dbi27qujTt8Ei9gfp9KnEWTYptE5KUbZzEK6boL46k4"
|
|
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
|
+
# runs ~0.5s
|
|
61
|
+
def connect_hub(
|
|
62
|
+
fallback_env: bool = False, client_options: ClientOptions | None = None
|
|
63
|
+
) -> Client:
|
|
64
|
+
env = Environment(fallback=fallback_env)
|
|
65
|
+
if client_options is None:
|
|
66
|
+
client_options = ClientOptions(auto_refresh_token=False)
|
|
67
|
+
return create_client(env.supabase_api_url, env.supabase_anon_key, client_options)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def connect_hub_with_auth(
|
|
71
|
+
fallback_env: bool = False,
|
|
72
|
+
renew_token: bool = False,
|
|
73
|
+
access_token: str | None = None,
|
|
74
|
+
) -> Client:
|
|
75
|
+
hub = connect_hub(fallback_env=fallback_env)
|
|
76
|
+
if access_token is None:
|
|
77
|
+
from lamindb_setup import settings
|
|
78
|
+
|
|
79
|
+
if renew_token:
|
|
80
|
+
settings.user.access_token = get_access_token(
|
|
81
|
+
settings.user.email, settings.user.password
|
|
82
|
+
)
|
|
83
|
+
access_token = settings.user.access_token
|
|
84
|
+
hub.postgrest.auth(access_token)
|
|
85
|
+
hub.functions.set_auth(access_token)
|
|
86
|
+
return hub
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# runs ~0.5s
|
|
90
|
+
def get_access_token(email: str | None = None, password: str | None = None):
|
|
91
|
+
hub = connect_hub()
|
|
92
|
+
try:
|
|
93
|
+
auth_response = hub.auth.sign_in_with_password(
|
|
94
|
+
{
|
|
95
|
+
"email": email,
|
|
96
|
+
"password": password,
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
return auth_response.session.access_token
|
|
100
|
+
finally:
|
|
101
|
+
hub.auth.sign_out(options={"scope": "local"})
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def call_with_fallback_auth(
|
|
105
|
+
callable,
|
|
106
|
+
**kwargs,
|
|
107
|
+
):
|
|
108
|
+
access_token = kwargs.pop("access_token", None)
|
|
109
|
+
|
|
110
|
+
if access_token is not None:
|
|
111
|
+
try:
|
|
112
|
+
client = connect_hub_with_auth(access_token=access_token)
|
|
113
|
+
result = callable(**kwargs, client=client)
|
|
114
|
+
finally:
|
|
115
|
+
try:
|
|
116
|
+
client.auth.sign_out(options={"scope": "local"})
|
|
117
|
+
except NameError:
|
|
118
|
+
pass
|
|
119
|
+
return result
|
|
120
|
+
|
|
121
|
+
for renew_token, fallback_env in [(False, False), (True, False), (False, True)]:
|
|
122
|
+
try:
|
|
123
|
+
if renew_token:
|
|
124
|
+
logger.warning(
|
|
125
|
+
"renewing expired lamin token: call `lamin login` to avoid this"
|
|
126
|
+
)
|
|
127
|
+
client = connect_hub_with_auth(
|
|
128
|
+
renew_token=renew_token, fallback_env=fallback_env
|
|
129
|
+
)
|
|
130
|
+
result = callable(**kwargs, client=client)
|
|
131
|
+
break
|
|
132
|
+
# we use Exception here as the ways in which the client fails upon 401
|
|
133
|
+
# are not consistent and keep changing
|
|
134
|
+
# because we ultimately raise the error, it's OK I'd say
|
|
135
|
+
except Exception as e:
|
|
136
|
+
if fallback_env:
|
|
137
|
+
raise e
|
|
138
|
+
finally:
|
|
139
|
+
try:
|
|
140
|
+
client.auth.sign_out(options={"scope": "local"})
|
|
141
|
+
except NameError:
|
|
142
|
+
pass
|
|
143
|
+
return result
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def call_with_fallback(
|
|
147
|
+
callable,
|
|
148
|
+
**kwargs,
|
|
149
|
+
):
|
|
150
|
+
for fallback_env in [False, True]:
|
|
151
|
+
try:
|
|
152
|
+
client = connect_hub(fallback_env=fallback_env)
|
|
153
|
+
result = callable(**kwargs, client=client)
|
|
154
|
+
break
|
|
155
|
+
except AuthUnknownError as e:
|
|
156
|
+
if fallback_env:
|
|
157
|
+
raise e
|
|
158
|
+
finally:
|
|
159
|
+
try:
|
|
160
|
+
# in case there was sign in
|
|
161
|
+
client.auth.sign_out(options={"scope": "local"})
|
|
162
|
+
except NameError:
|
|
163
|
+
pass
|
|
164
|
+
return result
|