lamindb_setup 1.5.1__py3-none-any.whl → 1.6.0__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/_connect_instance.py +19 -14
- lamindb_setup/_init_instance.py +20 -2
- lamindb_setup/_schema_metadata.py +19 -8
- lamindb_setup/core/_hub_core.py +23 -0
- lamindb_setup/core/_settings.py +11 -1
- lamindb_setup/core/_settings_store.py +6 -1
- lamindb_setup/core/_settings_user.py +1 -1
- lamindb_setup/core/django.py +96 -37
- lamindb_setup/core/upath.py +15 -0
- {lamindb_setup-1.5.1.dist-info → lamindb_setup-1.6.0.dist-info}/METADATA +1 -1
- {lamindb_setup-1.5.1.dist-info → lamindb_setup-1.6.0.dist-info}/RECORD +14 -14
- {lamindb_setup-1.5.1.dist-info → lamindb_setup-1.6.0.dist-info}/LICENSE +0 -0
- {lamindb_setup-1.5.1.dist-info → lamindb_setup-1.6.0.dist-info}/WHEEL +0 -0
lamindb_setup/__init__.py
CHANGED
|
@@ -67,10 +67,12 @@ def update_db_using_local(
|
|
|
67
67
|
db_updated = None
|
|
68
68
|
# check if postgres
|
|
69
69
|
if hub_instance_result["db_scheme"] == "postgresql":
|
|
70
|
-
db_dsn_hub = LaminDsnModel(db=hub_instance_result["db"])
|
|
71
70
|
if db is not None:
|
|
72
|
-
|
|
71
|
+
# use only the provided db if it is set
|
|
72
|
+
db_dsn_hub = LaminDsnModel(db=db)
|
|
73
|
+
db_dsn_local = db_dsn_hub
|
|
73
74
|
else:
|
|
75
|
+
db_dsn_hub = LaminDsnModel(db=hub_instance_result["db"])
|
|
74
76
|
# read directly from the environment
|
|
75
77
|
if os.getenv("LAMINDB_INSTANCE_DB") is not None:
|
|
76
78
|
logger.important("loading db URL from env variable LAMINDB_INSTANCE_DB")
|
|
@@ -78,16 +80,15 @@ def update_db_using_local(
|
|
|
78
80
|
# read from a cached settings file in case the hub result is only
|
|
79
81
|
# read level or inexistent
|
|
80
82
|
elif settings_file.exists() and (
|
|
81
|
-
db_dsn_hub.db.user
|
|
82
|
-
or (db_dsn_hub.db.user is not None and "read" in db_dsn_hub.db.user)
|
|
83
|
+
db_dsn_hub.db.user in {None, "none"} or "read" in db_dsn_hub.db.user # type:ignore
|
|
83
84
|
):
|
|
84
85
|
isettings = load_instance_settings(settings_file)
|
|
85
86
|
db_dsn_local = LaminDsnModel(db=isettings.db)
|
|
86
87
|
else:
|
|
87
88
|
# just take the default hub result and ensure there is actually a user
|
|
88
89
|
if (
|
|
89
|
-
db_dsn_hub.db.user
|
|
90
|
-
and db_dsn_hub.db.password
|
|
90
|
+
db_dsn_hub.db.user in {None, "none"}
|
|
91
|
+
and db_dsn_hub.db.password in {None, "none"}
|
|
91
92
|
and raise_permission_error
|
|
92
93
|
):
|
|
93
94
|
raise PermissionError(
|
|
@@ -95,13 +96,13 @@ def update_db_using_local(
|
|
|
95
96
|
" a DB URL and pass it via --db <db_url>"
|
|
96
97
|
)
|
|
97
98
|
db_dsn_local = db_dsn_hub
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
if not check_db_dsn_equal_up_to_credentials(db_dsn_hub.db, db_dsn_local.db):
|
|
100
|
+
raise ValueError(
|
|
101
|
+
"The local differs from the hub database information:\n"
|
|
102
|
+
"did your database get updated by an admin?\n"
|
|
103
|
+
"Consider deleting your cached database environment:\nrm"
|
|
104
|
+
f" {settings_file.as_posix()}"
|
|
105
|
+
)
|
|
105
106
|
db_updated = LaminDsn.build(
|
|
106
107
|
scheme=db_dsn_hub.db.scheme,
|
|
107
108
|
user=db_dsn_local.db.user,
|
|
@@ -345,11 +346,15 @@ def migrate_lnschema_core(
|
|
|
345
346
|
if db_type == "sqlite":
|
|
346
347
|
import sqlite3
|
|
347
348
|
|
|
349
|
+
# maybe also use LAMINDB_DJANGO_DATABASE_URL here?
|
|
348
350
|
conn = sqlite3.connect(parsed_uri.path)
|
|
349
351
|
elif db_type in ["postgresql", "postgres"]:
|
|
350
352
|
import psycopg2
|
|
351
353
|
|
|
352
|
-
|
|
354
|
+
# do not ignore LAMINDB_DJANGO_DATABASE_URL if it is set
|
|
355
|
+
conn = psycopg2.connect(
|
|
356
|
+
os.environ.get("LAMINDB_DJANGO_DATABASE_URL", isettings.db)
|
|
357
|
+
)
|
|
353
358
|
else:
|
|
354
359
|
raise ValueError("Unsupported database type. Use 'sqlite' or 'postgresql' URI.")
|
|
355
360
|
|
lamindb_setup/_init_instance.py
CHANGED
|
@@ -98,13 +98,31 @@ def register_user(usettings):
|
|
|
98
98
|
def register_initial_records(isettings: InstanceSettings, usettings):
|
|
99
99
|
"""Register space, user & storage in DB."""
|
|
100
100
|
from django.db.utils import OperationalError
|
|
101
|
-
from lamindb.models import Space
|
|
101
|
+
from lamindb.models import Branch, Space
|
|
102
102
|
|
|
103
103
|
try:
|
|
104
104
|
Space.objects.get_or_create(
|
|
105
|
+
uid="A",
|
|
105
106
|
name="All",
|
|
106
107
|
description="Every team & user with access to the instance has access.",
|
|
107
108
|
)
|
|
109
|
+
Branch.objects.get_or_create(
|
|
110
|
+
id=-1,
|
|
111
|
+
uid="T",
|
|
112
|
+
name="Trash",
|
|
113
|
+
description="The trash.",
|
|
114
|
+
)
|
|
115
|
+
Branch.objects.get_or_create(
|
|
116
|
+
id=0,
|
|
117
|
+
uid="A",
|
|
118
|
+
name="Archive",
|
|
119
|
+
description="The archive.",
|
|
120
|
+
)
|
|
121
|
+
Branch.objects.get_or_create(
|
|
122
|
+
uid="M",
|
|
123
|
+
name="Main",
|
|
124
|
+
description="The main & default branch of the instance.",
|
|
125
|
+
)
|
|
108
126
|
register_user(usettings)
|
|
109
127
|
register_storage_in_instance(isettings.storage)
|
|
110
128
|
except OperationalError as error:
|
|
@@ -206,7 +224,7 @@ class CannotSwitchDefaultInstance(SystemExit):
|
|
|
206
224
|
MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE = """
|
|
207
225
|
You cannot write to different instances in the same Python session.
|
|
208
226
|
|
|
209
|
-
Do you want to read from another instance via `
|
|
227
|
+
Do you want to read from another instance via `SQLRecord.using()`? For example:
|
|
210
228
|
|
|
211
229
|
ln.Artifact.using("laminlabs/cellxgene").filter()
|
|
212
230
|
|
|
@@ -150,6 +150,7 @@ class FieldMetadata(BaseModel):
|
|
|
150
150
|
is_link_table: bool
|
|
151
151
|
is_primary_key: bool
|
|
152
152
|
is_editable: bool
|
|
153
|
+
max_length: int | None = None
|
|
153
154
|
relation_type: RelationType | None = None
|
|
154
155
|
related_field_name: str | None = None
|
|
155
156
|
related_model_name: str | None = None
|
|
@@ -158,7 +159,7 @@ class FieldMetadata(BaseModel):
|
|
|
158
159
|
|
|
159
160
|
class _ModelHandler:
|
|
160
161
|
def __init__(self, model, module_name: str, included_modules: list[str]) -> None:
|
|
161
|
-
from lamindb.models import
|
|
162
|
+
from lamindb.models import IsLink
|
|
162
163
|
|
|
163
164
|
self.model = model
|
|
164
165
|
self.class_name = model.__name__
|
|
@@ -167,7 +168,11 @@ class _ModelHandler:
|
|
|
167
168
|
self.table_name = model._meta.db_table
|
|
168
169
|
self.included_modules = included_modules
|
|
169
170
|
self.fields = self._get_fields_metadata(self.model)
|
|
170
|
-
self.is_link_table = issubclass(model,
|
|
171
|
+
self.is_link_table = issubclass(model, IsLink)
|
|
172
|
+
self.name_field = model._name_field if hasattr(model, "_name_field") else None
|
|
173
|
+
self.ontology_id_field = (
|
|
174
|
+
model._ontology_id_field if hasattr(model, "_ontology_id_field") else None
|
|
175
|
+
)
|
|
171
176
|
|
|
172
177
|
def to_dict(self, include_django_objects: bool = True):
|
|
173
178
|
_dict = {
|
|
@@ -175,6 +180,8 @@ class _ModelHandler:
|
|
|
175
180
|
"class_name": self.class_name,
|
|
176
181
|
"table_name": self.table_name,
|
|
177
182
|
"is_link_table": self.is_link_table,
|
|
183
|
+
"name_field": self.name_field,
|
|
184
|
+
"ontology_id_field": self.ontology_id_field,
|
|
178
185
|
}
|
|
179
186
|
|
|
180
187
|
for field_name in self.fields.keys():
|
|
@@ -238,23 +245,26 @@ class _ModelHandler:
|
|
|
238
245
|
return related_fields
|
|
239
246
|
|
|
240
247
|
def _get_field_metadata(self, model, field: Field):
|
|
241
|
-
from lamindb.models import
|
|
248
|
+
from lamindb.models import IsLink
|
|
242
249
|
|
|
243
250
|
internal_type = field.get_internal_type()
|
|
244
251
|
model_name = field.model._meta.model_name
|
|
245
252
|
relation_type = self._get_relation_type(model, field)
|
|
253
|
+
|
|
254
|
+
schema_name = field.model.__get_module_name__()
|
|
255
|
+
|
|
246
256
|
if field.related_model is None:
|
|
247
|
-
schema_name = field.model.__get_module_name__()
|
|
248
257
|
related_model_name = None
|
|
249
258
|
related_schema_name = None
|
|
250
259
|
related_field_name = None
|
|
251
260
|
is_editable = field.editable
|
|
261
|
+
max_length = field.max_length
|
|
252
262
|
else:
|
|
253
263
|
related_model_name = field.related_model._meta.model_name
|
|
254
264
|
related_schema_name = field.related_model.__get_module_name__()
|
|
255
|
-
schema_name = field.model.__get_module_name__()
|
|
256
265
|
related_field_name = field.remote_field.name
|
|
257
266
|
is_editable = False
|
|
267
|
+
max_length = None
|
|
258
268
|
|
|
259
269
|
field_name = field.name
|
|
260
270
|
is_primary_key = getattr(field, "primary_key", False)
|
|
@@ -286,9 +296,10 @@ class _ModelHandler:
|
|
|
286
296
|
model_name=model_name,
|
|
287
297
|
field_name=field_name,
|
|
288
298
|
type=internal_type,
|
|
289
|
-
is_link_table=issubclass(field.model,
|
|
299
|
+
is_link_table=issubclass(field.model, IsLink),
|
|
290
300
|
is_primary_key=is_primary_key,
|
|
291
301
|
is_editable=is_editable,
|
|
302
|
+
max_length=max_length,
|
|
292
303
|
column_name=column,
|
|
293
304
|
relation_type=relation_type,
|
|
294
305
|
related_schema_name=related_schema_name
|
|
@@ -389,7 +400,7 @@ class _SchemaHandler:
|
|
|
389
400
|
return self.to_dict(include_django_objects=False)
|
|
390
401
|
|
|
391
402
|
def _get_modules_metadata(self):
|
|
392
|
-
from lamindb.models import
|
|
403
|
+
from lamindb.models import Registry, SQLRecord
|
|
393
404
|
|
|
394
405
|
all_models = {
|
|
395
406
|
module_name: {
|
|
@@ -400,7 +411,7 @@ class _SchemaHandler:
|
|
|
400
411
|
module_name
|
|
401
412
|
).models.__dict__.values()
|
|
402
413
|
if model.__class__ is Registry
|
|
403
|
-
and model is not
|
|
414
|
+
and model is not SQLRecord
|
|
404
415
|
and not model._meta.abstract
|
|
405
416
|
and model.__get_module_name__() == module_name
|
|
406
417
|
}
|
lamindb_setup/core/_hub_core.py
CHANGED
|
@@ -36,6 +36,7 @@ from ._hub_utils import (
|
|
|
36
36
|
from ._settings import settings
|
|
37
37
|
from ._settings_instance import InstanceSettings
|
|
38
38
|
from ._settings_storage import StorageSettings, base62
|
|
39
|
+
from .hashing import hash_and_encode_as_b62
|
|
39
40
|
|
|
40
41
|
if TYPE_CHECKING:
|
|
41
42
|
from supabase import Client # type: ignore
|
|
@@ -116,6 +117,28 @@ def _select_storage(
|
|
|
116
117
|
return True
|
|
117
118
|
|
|
118
119
|
|
|
120
|
+
def _select_storage_or_parent(path: str, client: Client) -> dict | None:
|
|
121
|
+
result = client.rpc("existing_root_or_child", {"_path": path}).execute().data
|
|
122
|
+
if result["root"] is None:
|
|
123
|
+
return None
|
|
124
|
+
result["uid"] = result.pop("lnid")
|
|
125
|
+
result["instance_uid"] = hash_and_encode_as_b62(
|
|
126
|
+
UUID(result.pop("instance_id")).hex
|
|
127
|
+
)[:12]
|
|
128
|
+
return result
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def select_storage_or_parent(path: str, access_token: str | None = None) -> dict | None:
|
|
132
|
+
if settings.user.handle != "anonymous" or access_token is not None:
|
|
133
|
+
return call_with_fallback_auth(
|
|
134
|
+
_select_storage_or_parent,
|
|
135
|
+
path=path,
|
|
136
|
+
access_token=access_token,
|
|
137
|
+
)
|
|
138
|
+
else:
|
|
139
|
+
return call_with_fallback(_select_storage_or_parent, path=path)
|
|
140
|
+
|
|
141
|
+
|
|
119
142
|
def init_storage_hub(
|
|
120
143
|
ssettings: StorageSettings,
|
|
121
144
|
auto_populate_instance: bool = True,
|
lamindb_setup/core/_settings.py
CHANGED
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from appdirs import AppDirs
|
|
8
|
+
from lamin_utils import logger
|
|
8
9
|
|
|
9
10
|
from ._settings_load import (
|
|
10
11
|
load_instance_settings,
|
|
@@ -162,7 +163,16 @@ class SetupSettings:
|
|
|
162
163
|
self._cache_dir = cache_dir
|
|
163
164
|
else:
|
|
164
165
|
cache_dir = self._cache_dir
|
|
165
|
-
|
|
166
|
+
try:
|
|
167
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
168
|
+
# we don not want this to error
|
|
169
|
+
# beause no actual writing happens on just getting the cache dir
|
|
170
|
+
# in cloud_to_local_no_update for example
|
|
171
|
+
# so it should not fail on read-only systems
|
|
172
|
+
except Exception as e:
|
|
173
|
+
logger.warning(
|
|
174
|
+
f"Failed to create lamin cache directory at {cache_dir}: {e}"
|
|
175
|
+
)
|
|
166
176
|
return cache_dir
|
|
167
177
|
|
|
168
178
|
@property
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
|
+
from lamin_utils import logger
|
|
5
6
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
6
7
|
|
|
7
8
|
if "LAMIN_SETTINGS_DIR" in os.environ:
|
|
@@ -12,7 +13,11 @@ else:
|
|
|
12
13
|
# hence, let's take home/.lamin
|
|
13
14
|
settings_dir = Path.home() / ".lamin"
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
settings_dir.mkdir(parents=True, exist_ok=True)
|
|
19
|
+
except Exception as e:
|
|
20
|
+
logger.warning(f"Failed to create lamin settings directory at {settings_dir}: {e}")
|
|
16
21
|
|
|
17
22
|
|
|
18
23
|
def get_settings_file_name_prefix():
|
lamindb_setup/core/django.py
CHANGED
|
@@ -3,6 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
# flake8: noqa
|
|
4
4
|
import builtins
|
|
5
5
|
import os
|
|
6
|
+
import sys
|
|
7
|
+
import importlib as il
|
|
8
|
+
import jwt
|
|
9
|
+
import time
|
|
6
10
|
from pathlib import Path
|
|
7
11
|
import time
|
|
8
12
|
from ._settings_instance import InstanceSettings
|
|
@@ -14,15 +18,47 @@ IS_MIGRATING = False
|
|
|
14
18
|
CONN_MAX_AGE = 299
|
|
15
19
|
|
|
16
20
|
|
|
21
|
+
# db token that refreshes on access if needed
|
|
22
|
+
class DBToken:
|
|
23
|
+
def __init__(
|
|
24
|
+
self, instance: InstanceSettings | dict, access_token: str | None = None
|
|
25
|
+
):
|
|
26
|
+
self.instance = instance
|
|
27
|
+
self.access_token = access_token
|
|
28
|
+
# initialized in token_query
|
|
29
|
+
self._token: str | None = None
|
|
30
|
+
self._token_query: str | None = None
|
|
31
|
+
self._expiration: float
|
|
32
|
+
|
|
33
|
+
def _refresh_token(self):
|
|
34
|
+
from ._hub_core import access_db
|
|
35
|
+
from psycopg2.extensions import adapt
|
|
36
|
+
|
|
37
|
+
self._token = access_db(self.instance, self.access_token)
|
|
38
|
+
self._token_query = (
|
|
39
|
+
f"SELECT set_token({adapt(self._token).getquoted().decode()}, true);"
|
|
40
|
+
)
|
|
41
|
+
self._expiration = jwt.decode(self._token, options={"verify_signature": False})[
|
|
42
|
+
"exp"
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def token_query(self) -> str:
|
|
47
|
+
# refresh token if needed
|
|
48
|
+
if self._token is None or time.time() >= self._expiration:
|
|
49
|
+
self._refresh_token()
|
|
50
|
+
|
|
51
|
+
return self._token_query # type: ignore
|
|
52
|
+
|
|
53
|
+
|
|
17
54
|
# a class to manage jwt in dbs
|
|
18
55
|
class DBTokenManager:
|
|
19
|
-
def __init__(self
|
|
56
|
+
def __init__(self):
|
|
20
57
|
from django.db.transaction import Atomic
|
|
21
58
|
|
|
22
|
-
self.debug = debug
|
|
23
59
|
self.original_atomic_enter = Atomic.__enter__
|
|
24
60
|
|
|
25
|
-
self.tokens: dict[str,
|
|
61
|
+
self.tokens: dict[str, DBToken] = {}
|
|
26
62
|
|
|
27
63
|
def get_connection(self, connection_name: str):
|
|
28
64
|
from django.db import connections
|
|
@@ -32,19 +68,11 @@ class DBTokenManager:
|
|
|
32
68
|
|
|
33
69
|
return connection
|
|
34
70
|
|
|
35
|
-
def set(self, token:
|
|
71
|
+
def set(self, token: DBToken, connection_name: str = "default"):
|
|
36
72
|
from django.db.transaction import Atomic
|
|
37
73
|
|
|
38
|
-
# no adapt in psycopg3
|
|
39
|
-
from psycopg2.extensions import adapt
|
|
40
|
-
|
|
41
74
|
connection = self.get_connection(connection_name)
|
|
42
75
|
|
|
43
|
-
# escape correctly to avoid wrangling with params
|
|
44
|
-
set_token_query = (
|
|
45
|
-
f"SELECT set_token({adapt(token).getquoted().decode()}, true); "
|
|
46
|
-
)
|
|
47
|
-
|
|
48
76
|
def set_token_wrapper(execute, sql, params, many, context):
|
|
49
77
|
not_in_atomic_block = (
|
|
50
78
|
context is None
|
|
@@ -53,12 +81,7 @@ class DBTokenManager:
|
|
|
53
81
|
)
|
|
54
82
|
# ignore atomic blocks
|
|
55
83
|
if not_in_atomic_block:
|
|
56
|
-
sql =
|
|
57
|
-
elif self.debug:
|
|
58
|
-
print("--in atomic block--")
|
|
59
|
-
|
|
60
|
-
if self.debug:
|
|
61
|
-
print(sql)
|
|
84
|
+
sql = token.token_query + sql
|
|
62
85
|
result = execute(sql, params, many, context)
|
|
63
86
|
# this ensures that psycopg3 in the current env doesn't break this wrapper
|
|
64
87
|
# psycopg3 returns a cursor
|
|
@@ -69,30 +92,29 @@ class DBTokenManager:
|
|
|
69
92
|
and result is not None
|
|
70
93
|
and hasattr(result, "nextset")
|
|
71
94
|
):
|
|
72
|
-
if self.debug:
|
|
73
|
-
print("(shift cursor)")
|
|
74
95
|
result.nextset()
|
|
75
96
|
return result
|
|
76
97
|
|
|
77
98
|
connection.execute_wrappers.append(set_token_wrapper)
|
|
78
99
|
|
|
100
|
+
self.tokens[connection_name] = token
|
|
101
|
+
|
|
79
102
|
# ensure we set the token only once for an outer atomic block
|
|
80
103
|
def __enter__(atomic):
|
|
81
104
|
self.original_atomic_enter(atomic)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
105
|
+
connection_name = "default" if atomic.using is None else atomic.using
|
|
106
|
+
if connection_name in self.tokens:
|
|
107
|
+
# here we don't use the connection from the closure
|
|
108
|
+
# because Atomic is a single class to manage transactions for all connections
|
|
109
|
+
connection = self.get_connection(connection_name)
|
|
110
|
+
if len(connection.atomic_blocks) == 1:
|
|
111
|
+
token = self.tokens[connection_name]
|
|
112
|
+
# use raw psycopg2 connection here
|
|
113
|
+
# atomic block ensures connection
|
|
114
|
+
connection.connection.cursor().execute(token.token_query)
|
|
91
115
|
|
|
92
116
|
Atomic.__enter__ = __enter__
|
|
93
117
|
|
|
94
|
-
self.tokens[connection_name] = token
|
|
95
|
-
|
|
96
118
|
def reset(self, connection_name: str = "default"):
|
|
97
119
|
from django.db.transaction import Atomic
|
|
98
120
|
|
|
@@ -103,7 +125,6 @@ class DBTokenManager:
|
|
|
103
125
|
for w in connection.execute_wrappers
|
|
104
126
|
if getattr(w, "__name__", None) != "set_token_wrapper"
|
|
105
127
|
]
|
|
106
|
-
Atomic.__enter__ = self.original_atomic_enter
|
|
107
128
|
|
|
108
129
|
self.tokens.pop(connection_name, None)
|
|
109
130
|
|
|
@@ -151,8 +172,7 @@ def setup_django(
|
|
|
151
172
|
|
|
152
173
|
module_names = ["core"] + list(isettings.modules)
|
|
153
174
|
raise_import_error = True if init else False
|
|
154
|
-
installed_apps = [
|
|
155
|
-
installed_apps += [
|
|
175
|
+
installed_apps = [
|
|
156
176
|
package_name
|
|
157
177
|
for name in module_names
|
|
158
178
|
if (
|
|
@@ -198,9 +218,7 @@ def setup_django(
|
|
|
198
218
|
BaseDatabaseWrapper.close_if_health_check_failed = close_if_health_check_failed
|
|
199
219
|
|
|
200
220
|
if isettings._fine_grained_access and isettings._db_permissions == "jwt":
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
db_token = access_db(isettings)
|
|
221
|
+
db_token = DBToken(isettings)
|
|
204
222
|
db_token_manager.set(db_token) # sets for the default connection
|
|
205
223
|
|
|
206
224
|
if configure_only:
|
|
@@ -225,3 +243,44 @@ def setup_django(
|
|
|
225
243
|
|
|
226
244
|
if isettings.keep_artifacts_local:
|
|
227
245
|
isettings._search_local_root()
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
# THIS IS NOT SAFE
|
|
249
|
+
# especially if lamindb is imported already
|
|
250
|
+
# django.setup fails if called for the second time
|
|
251
|
+
# reset_django() allows to call setup again,
|
|
252
|
+
# needed to connect to a different instance in the same process if connected already
|
|
253
|
+
# there could be problems if models are already imported from lamindb or other modules
|
|
254
|
+
# these 'old' models can have any number of problems
|
|
255
|
+
def reset_django():
|
|
256
|
+
from django.conf import settings
|
|
257
|
+
from django.apps import apps
|
|
258
|
+
from django.db import connections
|
|
259
|
+
|
|
260
|
+
if not settings.configured:
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
connections.close_all()
|
|
264
|
+
|
|
265
|
+
if getattr(settings, "_wrapped", None) is not None:
|
|
266
|
+
settings._wrapped = None
|
|
267
|
+
|
|
268
|
+
app_names = {"django"} | {app.name for app in apps.get_app_configs()}
|
|
269
|
+
|
|
270
|
+
apps.app_configs.clear()
|
|
271
|
+
apps.apps_ready = apps.models_ready = apps.ready = apps.loading = False
|
|
272
|
+
apps.clear_cache()
|
|
273
|
+
|
|
274
|
+
# i suspect it is enough to just drop django and all the apps from sys.modules
|
|
275
|
+
# the code above is just a precaution
|
|
276
|
+
for module_name in list(sys.modules):
|
|
277
|
+
if module_name.partition(".")[0] in app_names:
|
|
278
|
+
del sys.modules[module_name]
|
|
279
|
+
|
|
280
|
+
il.invalidate_caches()
|
|
281
|
+
|
|
282
|
+
global db_token_manager
|
|
283
|
+
db_token_manager = DBTokenManager()
|
|
284
|
+
|
|
285
|
+
global IS_SETUP
|
|
286
|
+
IS_SETUP = False
|
lamindb_setup/core/upath.py
CHANGED
|
@@ -51,6 +51,21 @@ VALID_SIMPLE_SUFFIXES = {
|
|
|
51
51
|
".xml",
|
|
52
52
|
".qs", # https://cran.r-project.org/web/packages/qs/vignettes/vignette.html
|
|
53
53
|
".rds",
|
|
54
|
+
".pt",
|
|
55
|
+
".pth",
|
|
56
|
+
".ckpt",
|
|
57
|
+
".state_dict",
|
|
58
|
+
".keras",
|
|
59
|
+
".pb",
|
|
60
|
+
".pbtxt",
|
|
61
|
+
".savedmodel",
|
|
62
|
+
".pkl",
|
|
63
|
+
".pickle",
|
|
64
|
+
".bin",
|
|
65
|
+
".safetensors",
|
|
66
|
+
".model",
|
|
67
|
+
".mlmodel",
|
|
68
|
+
".mar",
|
|
54
69
|
#
|
|
55
70
|
# with readers (see below)
|
|
56
71
|
#
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
lamindb_setup/__init__.py,sha256=
|
|
1
|
+
lamindb_setup/__init__.py,sha256=vSYZ5n67C1AL8iuvzPXKwh2fwCyIbPYmLoKuByHGsA8,2754
|
|
2
2
|
lamindb_setup/_cache.py,sha256=ixasm_9pUFy-ztbhbqJRVP88uTbFclL60MwUUvZhMFs,1509
|
|
3
3
|
lamindb_setup/_check.py,sha256=28PcG8Kp6OpjSLSi1r2boL2Ryeh6xkaCL87HFbjs6GA,129
|
|
4
4
|
lamindb_setup/_check_setup.py,sha256=uveV6CGiwm9M5OMe3lxfAMDs5SU7j1EogJsQB03ZaRw,5928
|
|
5
|
-
lamindb_setup/_connect_instance.py,sha256=
|
|
5
|
+
lamindb_setup/_connect_instance.py,sha256=Xx2d7GWBZ4qWhmk69ZAQNfehBlnAYejk9ojPL639VRA,18260
|
|
6
6
|
lamindb_setup/_delete.py,sha256=2KnZOqd5Kgr45XzjiDE9der35LODDUajZD6_hcurGtQ,5676
|
|
7
7
|
lamindb_setup/_disconnect.py,sha256=p6tRLhixU4CuSxMKqzGTr-ovKmTRlZ8aID5dWQxOsg8,1092
|
|
8
8
|
lamindb_setup/_django.py,sha256=uIQflpkp8l3axyPaKURlk3kacgpElVP5KOKmFxYSMGk,1454
|
|
9
9
|
lamindb_setup/_entry_points.py,sha256=sKwXPX9xjOotoAjvgkU5LBwjjHLWVkh0ZGdiSsrch9k,522
|
|
10
10
|
lamindb_setup/_exportdb.py,sha256=QLjoH4dEwqa01A12naKaDPglCCzl2_VLKWFfJRE_uSg,2113
|
|
11
11
|
lamindb_setup/_importdb.py,sha256=fKv9ev5OOj_-bmzC8XZ1GxOcjIjI486yrHSHDWQrJeI,1874
|
|
12
|
-
lamindb_setup/_init_instance.py,sha256=
|
|
12
|
+
lamindb_setup/_init_instance.py,sha256=S5sk1nSMYe0Kxo_gpQygu0gBsIsAF1QIfLh_d5SeEF0,15253
|
|
13
13
|
lamindb_setup/_migrate.py,sha256=ya-15sc91i4JmEWI4j00T2892x8hdy2fSW-qz4IdxLs,9739
|
|
14
14
|
lamindb_setup/_register_instance.py,sha256=X7ZGlCVOZKq4zTpi3bxML4jzo6hgN9UYmdTxxf6JLmc,1205
|
|
15
15
|
lamindb_setup/_schema.py,sha256=b3uzhhWpV5mQtDwhMINc2MabGCnGLESy51ito3yl6Wc,679
|
|
16
|
-
lamindb_setup/_schema_metadata.py,sha256=
|
|
16
|
+
lamindb_setup/_schema_metadata.py,sha256=x4u15X_X-4dsS0Zot3mOwn_IWO0e7LL0Ip8vyUOffNQ,14758
|
|
17
17
|
lamindb_setup/_set_managed_storage.py,sha256=qC3ACD_PWG-MrzcS3fQpjDEOuxAaJBgPqCU_bDvqtXo,2043
|
|
18
18
|
lamindb_setup/_setup_user.py,sha256=8BSGsW5jfmB4FlkhMt5osYXBbVCdOQeAVATb-oAYxa0,4495
|
|
19
19
|
lamindb_setup/_silence_loggers.py,sha256=AKF_YcHvX32eGXdsYK8MJlxEaZ-Uo2f6QDRzjKFCtws,1568
|
|
@@ -23,25 +23,25 @@ lamindb_setup/core/_aws_storage.py,sha256=nEjeUv4xUVpoV0Lx-zjjmyb9w804bDyaeiM-Oq
|
|
|
23
23
|
lamindb_setup/core/_deprecated.py,sha256=HN7iUBdEgahw5e4NHCd1VJooUfieNb6GRzS5x8jU-q8,2549
|
|
24
24
|
lamindb_setup/core/_docs.py,sha256=3k-YY-oVaJd_9UIY-LfBg_u8raKOCNfkZQPA73KsUhs,276
|
|
25
25
|
lamindb_setup/core/_hub_client.py,sha256=XJ9V0th11zcx87tDTDVtYf5YjnEC06_jiSRHcnbFseg,7510
|
|
26
|
-
lamindb_setup/core/_hub_core.py,sha256=
|
|
26
|
+
lamindb_setup/core/_hub_core.py,sha256=_TYVAbYzjmY1pd7egsqhIEFd31ZAycxlY0RFuYk56PQ,22551
|
|
27
27
|
lamindb_setup/core/_hub_crud.py,sha256=IAuPZes1am8OFwtcf5jSRQPGG1eKwVTEsp9Li-uq0cQ,5377
|
|
28
28
|
lamindb_setup/core/_hub_utils.py,sha256=6dyDGyzYFgVfR_lE3VN3CP1jGp98gxPtr-T91PAP05U,2687
|
|
29
29
|
lamindb_setup/core/_private_django_api.py,sha256=By63l3vIEtK1pq246FhHq3tslxsaTJGKm5VakYluWp4,2656
|
|
30
|
-
lamindb_setup/core/_settings.py,sha256=
|
|
30
|
+
lamindb_setup/core/_settings.py,sha256=rpakpthAcvjOeAmldvZquml-7NJ8i44Hu_P8pJV_coo,8790
|
|
31
31
|
lamindb_setup/core/_settings_instance.py,sha256=ftHAFFbg_0iThuywuQM37RIiCQnMEOc1dftTig1_DZo,19382
|
|
32
32
|
lamindb_setup/core/_settings_load.py,sha256=adVwwEiwglrNNpZFgoP-EENZkzxZvKOzUr3z204pe94,4658
|
|
33
33
|
lamindb_setup/core/_settings_save.py,sha256=P04ZnWFSN4Qq_QFWXNvJDs4yxrY9CjQBol_BDku_JEw,3227
|
|
34
34
|
lamindb_setup/core/_settings_storage.py,sha256=op31t12T_fCfTG8OSfnXnIxB9VCQPg8Oo2cnZHVap8Y,14203
|
|
35
|
-
lamindb_setup/core/_settings_store.py,sha256=
|
|
36
|
-
lamindb_setup/core/_settings_user.py,sha256=
|
|
35
|
+
lamindb_setup/core/_settings_store.py,sha256=Qe5tsTtQO9TJ5jqr-VgiDs6MOkFrxO6y0kYEVveCN-I,2450
|
|
36
|
+
lamindb_setup/core/_settings_user.py,sha256=5hmnMu6fxrHAcwBEtIL0P9N8V4B0SjhzIdqFQ9o3Tsg,1476
|
|
37
37
|
lamindb_setup/core/_setup_bionty_sources.py,sha256=ox3X-SHiHa2lNPSWjwZhINypbLacX6kGwH6hVVrSFZc,1505
|
|
38
38
|
lamindb_setup/core/cloud_sqlite_locker.py,sha256=i6TrT7HG0lqliPvZTlsZ_uplPaqhPBbabyfeR32SkA8,7107
|
|
39
|
-
lamindb_setup/core/django.py,sha256=
|
|
39
|
+
lamindb_setup/core/django.py,sha256=6nKn_sokPqXqWE9EdRvhNzS5tjsMo3IZSfHiwTN_HcI,9348
|
|
40
40
|
lamindb_setup/core/exceptions.py,sha256=4NpLUNUIfXYVTFX2FvLZF8RW34exk2Vn2X3G4YhnTRg,276
|
|
41
41
|
lamindb_setup/core/hashing.py,sha256=M3Q1-ywnqh4Uy5zojbQfLju19HU0ySp8Oi7FGIJXfFI,3667
|
|
42
42
|
lamindb_setup/core/types.py,sha256=zJii2le38BJUmsNVvzDrbzGYr0yaeb-9Rw9IKmsBr3k,523
|
|
43
|
-
lamindb_setup/core/upath.py,sha256=
|
|
44
|
-
lamindb_setup-1.
|
|
45
|
-
lamindb_setup-1.
|
|
46
|
-
lamindb_setup-1.
|
|
47
|
-
lamindb_setup-1.
|
|
43
|
+
lamindb_setup/core/upath.py,sha256=U5CBiHVoEBEUi-YzYd0G8wMONkO-wcXQQ9htfDWbw-s,33876
|
|
44
|
+
lamindb_setup-1.6.0.dist-info/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
|
|
45
|
+
lamindb_setup-1.6.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
46
|
+
lamindb_setup-1.6.0.dist-info/METADATA,sha256=Zf2AdqY6BlftKrFrwOY5HaWY9WSXv4GjaRuFs5D_mBQ,1792
|
|
47
|
+
lamindb_setup-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|