lamindb_setup 0.77.4__py2.py3-none-any.whl → 0.77.5__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 (46) hide show
  1. lamindb_setup/__init__.py +1 -1
  2. lamindb_setup/_cache.py +34 -34
  3. lamindb_setup/_check.py +7 -7
  4. lamindb_setup/_check_setup.py +79 -79
  5. lamindb_setup/_close.py +35 -35
  6. lamindb_setup/_connect_instance.py +431 -444
  7. lamindb_setup/_django.py +41 -41
  8. lamindb_setup/_entry_points.py +22 -22
  9. lamindb_setup/_exportdb.py +68 -68
  10. lamindb_setup/_importdb.py +50 -50
  11. lamindb_setup/_init_instance.py +417 -374
  12. lamindb_setup/_migrate.py +239 -239
  13. lamindb_setup/_register_instance.py +36 -36
  14. lamindb_setup/_schema.py +27 -27
  15. lamindb_setup/_schema_metadata.py +411 -411
  16. lamindb_setup/_set_managed_storage.py +55 -55
  17. lamindb_setup/_setup_user.py +137 -137
  18. lamindb_setup/_silence_loggers.py +44 -44
  19. lamindb_setup/core/__init__.py +21 -21
  20. lamindb_setup/core/_aws_credentials.py +151 -151
  21. lamindb_setup/core/_aws_storage.py +48 -48
  22. lamindb_setup/core/_deprecated.py +55 -55
  23. lamindb_setup/core/_docs.py +14 -14
  24. lamindb_setup/core/_hub_core.py +611 -590
  25. lamindb_setup/core/_hub_crud.py +211 -211
  26. lamindb_setup/core/_hub_utils.py +109 -109
  27. lamindb_setup/core/_private_django_api.py +88 -88
  28. lamindb_setup/core/_settings.py +138 -138
  29. lamindb_setup/core/_settings_instance.py +480 -467
  30. lamindb_setup/core/_settings_load.py +105 -105
  31. lamindb_setup/core/_settings_save.py +81 -81
  32. lamindb_setup/core/_settings_storage.py +412 -405
  33. lamindb_setup/core/_settings_store.py +75 -75
  34. lamindb_setup/core/_settings_user.py +53 -53
  35. lamindb_setup/core/_setup_bionty_sources.py +101 -101
  36. lamindb_setup/core/cloud_sqlite_locker.py +237 -232
  37. lamindb_setup/core/django.py +114 -114
  38. lamindb_setup/core/exceptions.py +12 -12
  39. lamindb_setup/core/hashing.py +114 -114
  40. lamindb_setup/core/types.py +19 -19
  41. lamindb_setup/core/upath.py +779 -779
  42. {lamindb_setup-0.77.4.dist-info → lamindb_setup-0.77.5.dist-info}/METADATA +1 -1
  43. lamindb_setup-0.77.5.dist-info/RECORD +47 -0
  44. {lamindb_setup-0.77.4.dist-info → lamindb_setup-0.77.5.dist-info}/WHEEL +1 -1
  45. lamindb_setup-0.77.4.dist-info/RECORD +0 -47
  46. {lamindb_setup-0.77.4.dist-info → lamindb_setup-0.77.5.dist-info}/LICENSE +0 -0
@@ -1,211 +1,211 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
- from uuid import UUID, uuid4
5
-
6
- from lamin_utils import logger
7
- from supabase.client import Client # noqa
8
-
9
-
10
- def select_instance_by_owner_name(
11
- owner: str,
12
- name: str,
13
- client: Client,
14
- ) -> dict | None:
15
- try:
16
- data = (
17
- client.table("instance")
18
- .select(
19
- "*, account!inner!instance_account_id_28936e8f_fk_account_id(*),"
20
- " storage!inner!storage_instance_id_359fca71_fk_instance_id(*)"
21
- )
22
- .eq("name", name)
23
- .eq("account.handle", owner)
24
- .eq("storage.is_default", True)
25
- .execute()
26
- .data
27
- )
28
- except Exception:
29
- return None
30
- if len(data) == 0:
31
- return None
32
- result = data[0]
33
- # this is now a list
34
- # assume only one default storage
35
- result["storage"] = result["storage"][0]
36
- return result
37
-
38
-
39
- # --------------- ACCOUNT ----------------------
40
- def select_account_by_handle(
41
- handle: str,
42
- client: Client,
43
- ):
44
- data = client.table("account").select("*").eq("handle", handle).execute().data
45
- if len(data) == 0:
46
- return None
47
- return data[0]
48
-
49
-
50
- def select_account_handle_name_by_lnid(lnid: str, client: Client):
51
- data = (
52
- client.table("account").select("handle, name").eq("lnid", lnid).execute().data
53
- )
54
- if not data:
55
- return None
56
- return data[0]
57
-
58
-
59
- # --------------- INSTANCE ----------------------
60
- def select_instance_by_name(
61
- account_id: str,
62
- name: str,
63
- client: Client,
64
- ):
65
- data = (
66
- client.table("instance")
67
- .select("*")
68
- .eq("account_id", account_id)
69
- .eq("name", name)
70
- .execute()
71
- .data
72
- )
73
- if len(data) == 0:
74
- return None
75
- return data[0]
76
-
77
-
78
- def select_instance_by_id(
79
- instance_id: str,
80
- client: Client,
81
- ):
82
- response = client.table("instance").select("*").eq("id", instance_id).execute()
83
- if len(response.data) == 0:
84
- return None
85
- return response.data[0]
86
-
87
-
88
- def select_instance_by_id_with_storage(
89
- instance_id: str,
90
- client: Client,
91
- ):
92
- response = (
93
- client.table("instance")
94
- .select("*, storage!instance_storage_id_87963cc8_fk_storage_id(*)")
95
- .eq("id", instance_id)
96
- .execute()
97
- )
98
- if len(response.data) == 0:
99
- return None
100
- return response.data[0]
101
-
102
-
103
- def update_instance(instance_id: str, instance_fields: dict, client: Client):
104
- response = (
105
- client.table("instance").update(instance_fields).eq("id", instance_id).execute()
106
- )
107
- if len(response.data) == 0:
108
- raise PermissionError(
109
- f"Update of instance with {instance_id} was not successful. Probably, you"
110
- " don't have sufficient permissions."
111
- )
112
- return response.data[0]
113
-
114
-
115
- # --------------- COLLABORATOR ----------------------
116
-
117
-
118
- def select_collaborator(
119
- instance_id: str,
120
- account_id: str,
121
- client: Client,
122
- ):
123
- data = (
124
- client.table("account_instance")
125
- .select("*")
126
- .eq("instance_id", instance_id)
127
- .eq("account_id", account_id)
128
- .execute()
129
- .data
130
- )
131
- if len(data) == 0:
132
- return None
133
- return data[0]
134
-
135
-
136
- # --------------- STORAGE ----------------------
137
-
138
-
139
- def select_default_storage_by_instance_id(
140
- instance_id: str, client: Client
141
- ) -> dict | None:
142
- try:
143
- data = (
144
- client.table("storage")
145
- .select("*")
146
- .eq("instance_id", instance_id)
147
- .eq("is_default", True)
148
- .execute()
149
- .data
150
- )
151
- except Exception:
152
- return None
153
- if len(data) == 0:
154
- return None
155
- return data[0]
156
-
157
-
158
- # --------------- DBUser ----------------------
159
-
160
-
161
- def insert_db_user(
162
- *,
163
- name: str,
164
- db_user_name: str,
165
- db_user_password: str,
166
- instance_id: UUID,
167
- client: Client,
168
- ) -> None:
169
- fields = (
170
- {
171
- "id": uuid4().hex,
172
- "instance_id": instance_id.hex,
173
- "name": name,
174
- "db_user_name": db_user_name,
175
- "db_user_password": db_user_password,
176
- },
177
- )
178
- data = client.table("db_user").insert(fields).execute().data
179
- return data[0]
180
-
181
-
182
- def select_db_user_by_instance(instance_id: str, client: Client):
183
- """Get db_user for which client has permission."""
184
- data = (
185
- client.table("db_user")
186
- .select("*")
187
- .eq("instance_id", instance_id)
188
- .execute()
189
- .data
190
- )
191
- if len(data) == 0:
192
- return None
193
- elif len(data) > 1:
194
- for item in data:
195
- if item["name"] == "write":
196
- return item
197
- logger.warning("found multiple db credentials, using the first one")
198
- return data[0]
199
-
200
-
201
- def _delete_instance_record(instance_id: UUID, client: Client) -> None:
202
- if not isinstance(instance_id, UUID):
203
- instance_id = UUID(instance_id)
204
- response = client.table("instance").delete().eq("id", instance_id.hex).execute()
205
- if response.data:
206
- logger.important(f"deleted instance record on hub {instance_id.hex}")
207
- else:
208
- raise PermissionError(
209
- f"Deleting of instance with {instance_id.hex} was not successful. Probably, you"
210
- " don't have sufficient permissions."
211
- )
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+ from uuid import UUID, uuid4
5
+
6
+ from lamin_utils import logger
7
+ from supabase.client import Client # noqa
8
+
9
+
10
+ def select_instance_by_owner_name(
11
+ owner: str,
12
+ name: str,
13
+ client: Client,
14
+ ) -> dict | None:
15
+ try:
16
+ data = (
17
+ client.table("instance")
18
+ .select(
19
+ "*, account!inner!instance_account_id_28936e8f_fk_account_id(*),"
20
+ " storage!inner!storage_instance_id_359fca71_fk_instance_id(*)"
21
+ )
22
+ .eq("name", name)
23
+ .eq("account.handle", owner)
24
+ .eq("storage.is_default", True)
25
+ .execute()
26
+ .data
27
+ )
28
+ except Exception:
29
+ return None
30
+ if len(data) == 0:
31
+ return None
32
+ result = data[0]
33
+ # this is now a list
34
+ # assume only one default storage
35
+ result["storage"] = result["storage"][0]
36
+ return result
37
+
38
+
39
+ # --------------- ACCOUNT ----------------------
40
+ def select_account_by_handle(
41
+ handle: str,
42
+ client: Client,
43
+ ):
44
+ data = client.table("account").select("*").eq("handle", handle).execute().data
45
+ if len(data) == 0:
46
+ return None
47
+ return data[0]
48
+
49
+
50
+ def select_account_handle_name_by_lnid(lnid: str, client: Client):
51
+ data = (
52
+ client.table("account").select("handle, name").eq("lnid", lnid).execute().data
53
+ )
54
+ if not data:
55
+ return None
56
+ return data[0]
57
+
58
+
59
+ # --------------- INSTANCE ----------------------
60
+ def select_instance_by_name(
61
+ account_id: str,
62
+ name: str,
63
+ client: Client,
64
+ ):
65
+ data = (
66
+ client.table("instance")
67
+ .select("*")
68
+ .eq("account_id", account_id)
69
+ .eq("name", name)
70
+ .execute()
71
+ .data
72
+ )
73
+ if len(data) == 0:
74
+ return None
75
+ return data[0]
76
+
77
+
78
+ def select_instance_by_id(
79
+ instance_id: str,
80
+ client: Client,
81
+ ):
82
+ response = client.table("instance").select("*").eq("id", instance_id).execute()
83
+ if len(response.data) == 0:
84
+ return None
85
+ return response.data[0]
86
+
87
+
88
+ def select_instance_by_id_with_storage(
89
+ instance_id: str,
90
+ client: Client,
91
+ ):
92
+ response = (
93
+ client.table("instance")
94
+ .select("*, storage!instance_storage_id_87963cc8_fk_storage_id(*)")
95
+ .eq("id", instance_id)
96
+ .execute()
97
+ )
98
+ if len(response.data) == 0:
99
+ return None
100
+ return response.data[0]
101
+
102
+
103
+ def update_instance(instance_id: str, instance_fields: dict, client: Client):
104
+ response = (
105
+ client.table("instance").update(instance_fields).eq("id", instance_id).execute()
106
+ )
107
+ if len(response.data) == 0:
108
+ raise PermissionError(
109
+ f"Update of instance with {instance_id} was not successful. Probably, you"
110
+ " don't have sufficient permissions."
111
+ )
112
+ return response.data[0]
113
+
114
+
115
+ # --------------- COLLABORATOR ----------------------
116
+
117
+
118
+ def select_collaborator(
119
+ instance_id: str,
120
+ account_id: str,
121
+ client: Client,
122
+ ):
123
+ data = (
124
+ client.table("account_instance")
125
+ .select("*")
126
+ .eq("instance_id", instance_id)
127
+ .eq("account_id", account_id)
128
+ .execute()
129
+ .data
130
+ )
131
+ if len(data) == 0:
132
+ return None
133
+ return data[0]
134
+
135
+
136
+ # --------------- STORAGE ----------------------
137
+
138
+
139
+ def select_default_storage_by_instance_id(
140
+ instance_id: str, client: Client
141
+ ) -> dict | None:
142
+ try:
143
+ data = (
144
+ client.table("storage")
145
+ .select("*")
146
+ .eq("instance_id", instance_id)
147
+ .eq("is_default", True)
148
+ .execute()
149
+ .data
150
+ )
151
+ except Exception:
152
+ return None
153
+ if len(data) == 0:
154
+ return None
155
+ return data[0]
156
+
157
+
158
+ # --------------- DBUser ----------------------
159
+
160
+
161
+ def insert_db_user(
162
+ *,
163
+ name: str,
164
+ db_user_name: str,
165
+ db_user_password: str,
166
+ instance_id: UUID,
167
+ client: Client,
168
+ ) -> None:
169
+ fields = (
170
+ {
171
+ "id": uuid4().hex,
172
+ "instance_id": instance_id.hex,
173
+ "name": name,
174
+ "db_user_name": db_user_name,
175
+ "db_user_password": db_user_password,
176
+ },
177
+ )
178
+ data = client.table("db_user").insert(fields).execute().data
179
+ return data[0]
180
+
181
+
182
+ def select_db_user_by_instance(instance_id: str, client: Client):
183
+ """Get db_user for which client has permission."""
184
+ data = (
185
+ client.table("db_user")
186
+ .select("*")
187
+ .eq("instance_id", instance_id)
188
+ .execute()
189
+ .data
190
+ )
191
+ if len(data) == 0:
192
+ return None
193
+ elif len(data) > 1:
194
+ for item in data:
195
+ if item["name"] == "write":
196
+ return item
197
+ logger.warning("found multiple db credentials, using the first one")
198
+ return data[0]
199
+
200
+
201
+ def _delete_instance_record(instance_id: UUID, client: Client) -> None:
202
+ if not isinstance(instance_id, UUID):
203
+ instance_id = UUID(instance_id)
204
+ response = client.table("instance").delete().eq("id", instance_id.hex).execute()
205
+ if response.data:
206
+ logger.important(f"deleted instance record on hub {instance_id.hex}")
207
+ else:
208
+ raise PermissionError(
209
+ f"Deleting of instance with {instance_id.hex} was not successful. Probably, you"
210
+ " don't have sufficient permissions."
211
+ )
@@ -1,109 +1,109 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any, ClassVar, Optional
4
- from urllib.parse import urlparse, urlunparse
5
-
6
- from pydantic import BaseModel, Field, GetCoreSchemaHandler
7
- from pydantic_core import CoreSchema, core_schema
8
-
9
-
10
- def validate_schema_arg(schema: str | None = None) -> str:
11
- if schema is None or schema == "":
12
- return ""
13
- # currently no actual validation, can add back if we see a need
14
- # the following just strips white spaces
15
- to_be_validated = [s.strip() for s in schema.split(",")]
16
- return ",".join(to_be_validated)
17
-
18
-
19
- def validate_db_arg(db: str | None) -> None:
20
- if db is not None:
21
- LaminDsnModel(db=db)
22
-
23
-
24
- class LaminDsn(str):
25
- allowed_schemes: ClassVar[set[str]] = {
26
- "postgresql",
27
- # future enabled schemes
28
- # "snowflake",
29
- # "bigquery"
30
- }
31
-
32
- @classmethod
33
- def __get_pydantic_core_schema__(
34
- cls, source_type: Any, handler: GetCoreSchemaHandler
35
- ) -> CoreSchema:
36
- return core_schema.no_info_after_validator_function(
37
- cls.validate,
38
- core_schema.str_schema(),
39
- serialization=core_schema.plain_serializer_function_ser_schema(str),
40
- )
41
-
42
- @classmethod
43
- def validate(cls, v: Any) -> LaminDsn:
44
- if isinstance(v, str):
45
- parsed = urlparse(v)
46
- if parsed.scheme not in cls.allowed_schemes:
47
- raise ValueError(f"Invalid scheme: {parsed.scheme}")
48
- return cls(v)
49
- elif isinstance(v, cls):
50
- return v
51
- else:
52
- raise ValueError(f"Invalid value for LaminDsn: {v}")
53
-
54
- @property
55
- def user(self) -> str | None:
56
- return urlparse(self).username
57
-
58
- @property
59
- def password(self) -> str | None:
60
- return urlparse(self).password
61
-
62
- @property
63
- def host(self) -> str | None:
64
- return urlparse(self).hostname
65
-
66
- @property
67
- def port(self) -> int | None:
68
- return urlparse(self).port
69
-
70
- @property
71
- def database(self) -> str:
72
- return urlparse(self).path.lstrip("/")
73
-
74
- @property
75
- def scheme(self) -> str:
76
- return urlparse(self).scheme
77
-
78
- @classmethod
79
- def build(
80
- cls,
81
- *,
82
- scheme: str,
83
- user: str | None = None,
84
- password: str | None = None,
85
- host: str,
86
- port: int | None = None,
87
- database: str | None = None,
88
- query: str | None = None,
89
- fragment: str | None = None,
90
- ) -> LaminDsn:
91
- netloc = host
92
- if port is not None:
93
- netloc = f"{netloc}:{port}"
94
- if user is not None:
95
- auth = user
96
- if password is not None:
97
- auth = f"{auth}:{password}"
98
- netloc = f"{auth}@{netloc}"
99
-
100
- path = f"/{database}" if database else ""
101
-
102
- url = urlunparse((scheme, netloc, path, "", query or "", fragment or ""))
103
- return cls(url)
104
-
105
-
106
- class LaminDsnModel(BaseModel):
107
- db: LaminDsn = Field(..., description="The database DSN")
108
-
109
- model_config = {"arbitrary_types_allowed": True}
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, ClassVar, Optional
4
+ from urllib.parse import urlparse, urlunparse
5
+
6
+ from pydantic import BaseModel, Field, GetCoreSchemaHandler
7
+ from pydantic_core import CoreSchema, core_schema
8
+
9
+
10
+ def validate_schema_arg(schema: str | None = None) -> str:
11
+ if schema is None or schema == "":
12
+ return ""
13
+ # currently no actual validation, can add back if we see a need
14
+ # the following just strips white spaces
15
+ to_be_validated = [s.strip() for s in schema.split(",")]
16
+ return ",".join(to_be_validated)
17
+
18
+
19
+ def validate_db_arg(db: str | None) -> None:
20
+ if db is not None:
21
+ LaminDsnModel(db=db)
22
+
23
+
24
+ class LaminDsn(str):
25
+ allowed_schemes: ClassVar[set[str]] = {
26
+ "postgresql",
27
+ # future enabled schemes
28
+ # "snowflake",
29
+ # "bigquery"
30
+ }
31
+
32
+ @classmethod
33
+ def __get_pydantic_core_schema__(
34
+ cls, source_type: Any, handler: GetCoreSchemaHandler
35
+ ) -> CoreSchema:
36
+ return core_schema.no_info_after_validator_function(
37
+ cls.validate,
38
+ core_schema.str_schema(),
39
+ serialization=core_schema.plain_serializer_function_ser_schema(str),
40
+ )
41
+
42
+ @classmethod
43
+ def validate(cls, v: Any) -> LaminDsn:
44
+ if isinstance(v, str):
45
+ parsed = urlparse(v)
46
+ if parsed.scheme not in cls.allowed_schemes:
47
+ raise ValueError(f"Invalid scheme: {parsed.scheme}")
48
+ return cls(v)
49
+ elif isinstance(v, cls):
50
+ return v
51
+ else:
52
+ raise ValueError(f"Invalid value for LaminDsn: {v}")
53
+
54
+ @property
55
+ def user(self) -> str | None:
56
+ return urlparse(self).username
57
+
58
+ @property
59
+ def password(self) -> str | None:
60
+ return urlparse(self).password
61
+
62
+ @property
63
+ def host(self) -> str | None:
64
+ return urlparse(self).hostname
65
+
66
+ @property
67
+ def port(self) -> int | None:
68
+ return urlparse(self).port
69
+
70
+ @property
71
+ def database(self) -> str:
72
+ return urlparse(self).path.lstrip("/")
73
+
74
+ @property
75
+ def scheme(self) -> str:
76
+ return urlparse(self).scheme
77
+
78
+ @classmethod
79
+ def build(
80
+ cls,
81
+ *,
82
+ scheme: str,
83
+ user: str | None = None,
84
+ password: str | None = None,
85
+ host: str,
86
+ port: int | None = None,
87
+ database: str | None = None,
88
+ query: str | None = None,
89
+ fragment: str | None = None,
90
+ ) -> LaminDsn:
91
+ netloc = host
92
+ if port is not None:
93
+ netloc = f"{netloc}:{port}"
94
+ if user is not None:
95
+ auth = user
96
+ if password is not None:
97
+ auth = f"{auth}:{password}"
98
+ netloc = f"{auth}@{netloc}"
99
+
100
+ path = f"/{database}" if database else ""
101
+
102
+ url = urlunparse((scheme, netloc, path, "", query or "", fragment or ""))
103
+ return cls(url)
104
+
105
+
106
+ class LaminDsnModel(BaseModel):
107
+ db: LaminDsn = Field(..., description="The database DSN")
108
+
109
+ model_config = {"arbitrary_types_allowed": True}