lamindb_setup 1.4.1__py3-none-any.whl → 1.5.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 CHANGED
@@ -12,7 +12,7 @@ Basic operations:
12
12
  login
13
13
  logout
14
14
  init
15
- close
15
+ disconnect
16
16
  delete
17
17
 
18
18
  Instance operations:
@@ -33,7 +33,7 @@ Modules & settings:
33
33
 
34
34
  """
35
35
 
36
- __version__ = "1.4.1" # denote a release candidate for 0.1.0 with 0.1rc1
36
+ __version__ = "1.5.0" # denote a release candidate for 0.1.0 with 0.1rc1
37
37
 
38
38
  import os
39
39
 
@@ -41,9 +41,9 @@ from packaging import version as packaging_version
41
41
 
42
42
  from . import core
43
43
  from ._check_setup import _check_instance_setup
44
- from ._close import close
45
44
  from ._connect_instance import connect, load
46
45
  from ._delete import delete
46
+ from ._disconnect import disconnect
47
47
  from ._django import django
48
48
  from ._entry_points import call_registered_entry_points as _call_registered_entry_points
49
49
  from ._init_instance import init
@@ -100,3 +100,6 @@ _TESTING = _is_CI_environment()
100
100
  _call_registered_entry_points("lamindb_setup.on_import")
101
101
 
102
102
  settings.__doc__ = """Global :class:`~lamindb.setup.core.SetupSettings`."""
103
+
104
+
105
+ close = disconnect # backward compatibility
lamindb_setup/_cache.py CHANGED
@@ -8,16 +8,16 @@ from .core._settings_save import save_system_storage_settings
8
8
 
9
9
 
10
10
  def clear_cache_dir():
11
- from lamindb_setup import close, settings
11
+ from lamindb_setup import disconnect, settings
12
12
 
13
13
  try:
14
14
  if settings.instance._is_cloud_sqlite:
15
15
  logger.warning(
16
- "Closing the current instance to update the cloud sqlite database."
16
+ "Disconnecting the current instance to update the cloud sqlite database."
17
17
  )
18
- close()
18
+ disconnect()
19
19
  except SystemExit as e:
20
- if str(e) != "No instance is loaded! Call `lamin init` or `lamin connect`":
20
+ if str(e) != "No instance connected! Call `lamin connect` or `lamin init`":
21
21
  raise e
22
22
 
23
23
  cache_dir = settings.cache_dir
@@ -163,5 +163,14 @@ def _check_instance_setup(from_module: str | None = None) -> bool:
163
163
  return django_lamin.IS_SETUP
164
164
  else:
165
165
  if from_module is not None and settings.auto_connect:
166
- logger.warning(InstanceNotSetupError.default_message)
166
+ # the below enables users to auto-connect to an instance
167
+ # simply by setting an environment variable, bypassing the
168
+ # need of calling connect() manually
169
+ if os.environ.get("LAMIN_CURRENT_INSTANCE") is not None:
170
+ from ._connect_instance import connect
171
+
172
+ connect(_write_settings=False, _reload_lamindb=False)
173
+ return django_lamin.IS_SETUP
174
+ else:
175
+ logger.warning(InstanceNotSetupError.default_message)
167
176
  return False
@@ -8,7 +8,7 @@ from uuid import UUID
8
8
  from lamin_utils import logger
9
9
 
10
10
  from ._check_setup import _check_instance_setup, _get_current_instance_settings
11
- from ._close import close as close_instance
11
+ from ._disconnect import disconnect
12
12
  from ._init_instance import (
13
13
  MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE,
14
14
  CannotSwitchDefaultInstance,
@@ -192,8 +192,8 @@ def connect(instance: str | None = None, **kwargs) -> str | tuple | None:
192
192
  """Connect to an instance.
193
193
 
194
194
  Args:
195
- instance: `None` or an instance identifier (URL, slug `account/name`, or `name` if the instance is local or in your account).
196
- If `None`, it will connect to the instance that was connected via the CLI.
195
+ instance: Pass a slug (`account/name`) or URL (`https://lamin.ai/account/name`).
196
+ If `None`, looks for an environment variable `LAMIN_CURRENT_INSTANCE` to get the instance identifier. If it doesn't find this variable, it connects to the instance that was connected with `lamin connect` through the CLI.
197
197
  """
198
198
  # validate kwargs
199
199
  valid_kwargs = {
@@ -219,12 +219,14 @@ def connect(instance: str | None = None, **kwargs) -> str | tuple | None:
219
219
  _user: UserSettings | None = kwargs.get("_user", None)
220
220
  if _user is not None:
221
221
  access_token = _user.access_token
222
+ if instance is None:
223
+ instance = os.environ.get("LAMIN_CURRENT_INSTANCE")
222
224
 
223
225
  try:
224
226
  if instance is None:
225
227
  isettings_or_none = _get_current_instance_settings()
226
228
  if isettings_or_none is None:
227
- raise SystemExit(
229
+ raise ValueError(
228
230
  "No instance was connected through the CLI, pass a value to `instance` or connect via the CLI."
229
231
  )
230
232
  isettings = isettings_or_none
@@ -246,7 +248,7 @@ def connect(instance: str | None = None, **kwargs) -> str | tuple | None:
246
248
  and settings._instance_exists
247
249
  and f"{owner}/{name}" != settings.instance.slug
248
250
  ):
249
- close_instance(mute=True)
251
+ disconnect(mute=True)
250
252
 
251
253
  try:
252
254
  isettings = _connect_instance(
@@ -299,17 +301,6 @@ def connect(instance: str | None = None, **kwargs) -> str | tuple | None:
299
301
  if _TEST_FAILED_LOAD:
300
302
  raise RuntimeError("Technical testing error.")
301
303
 
302
- # below is for backfilling the instance_uid value
303
- # we'll enable it once more people migrated to 0.71.0
304
- # ssettings_record = isettings.storage.record
305
- # if ssettings_record.instance_uid is None:
306
- # ssettings_record.instance_uid = isettings.uid
307
- # # try saving if not read-only access
308
- # try:
309
- # ssettings_record.save()
310
- # # raised by django when the access is denied
311
- # except ProgrammingError:
312
- # pass
313
304
  load_from_isettings(isettings, user=_user, write_settings=_write_settings)
314
305
  if _reload_lamindb:
315
306
  importlib.reload(importlib.import_module("lamindb"))
@@ -7,8 +7,8 @@ from .core._settings_store import current_instance_settings_file
7
7
  from .core.cloud_sqlite_locker import clear_locker
8
8
 
9
9
 
10
- def close(mute: bool = False) -> None:
11
- """Close existing instance.
10
+ def disconnect(mute: bool = False) -> None:
11
+ """Disconnect an instance.
12
12
 
13
13
  Returns `None` if succeeds, otherwise an exception is raised.
14
14
  """
@@ -26,7 +26,7 @@ def close(mute: bool = False) -> None:
26
26
  current_instance_settings_file().unlink()
27
27
  clear_locker()
28
28
  if not mute:
29
- logger.success(f"closed instance: {instance}")
29
+ logger.success(f"disconnected instance: {instance}")
30
30
  else:
31
31
  if not mute:
32
32
  logger.info("no instance loaded")
@@ -11,7 +11,7 @@ from django.core.exceptions import FieldError
11
11
  from django.db.utils import OperationalError, ProgrammingError
12
12
  from lamin_utils import logger
13
13
 
14
- from ._close import close as close_instance
14
+ from ._disconnect import disconnect
15
15
  from ._silence_loggers import silence_loggers
16
16
  from .core import InstanceSettings
17
17
  from .core._docs import doc_args
@@ -262,7 +262,7 @@ def init(
262
262
  if _check_instance_setup() and not _test:
263
263
  raise CannotSwitchDefaultInstance(MESSAGE_CANNOT_SWITCH_DEFAULT_INSTANCE)
264
264
  elif _write_settings:
265
- close_instance(mute=True)
265
+ disconnect(mute=True)
266
266
  from .core._hub_core import init_instance_hub
267
267
 
268
268
  name_str, instance_id, instance_state, _ = validate_init_args(
@@ -8,16 +8,14 @@ from lamin_utils import logger
8
8
  from ._check_setup import _check_instance_setup
9
9
  from ._init_instance import register_user
10
10
  from .core._settings import settings
11
- from .core._settings_load import load_or_create_user_settings, load_user_settings
11
+ from .core._settings_load import load_user_settings
12
12
  from .core._settings_save import save_user_settings
13
13
  from .core._settings_store import (
14
14
  current_user_settings_file,
15
15
  user_settings_file_email,
16
16
  user_settings_file_handle,
17
17
  )
18
-
19
- if TYPE_CHECKING:
20
- from lamindb_setup.core._settings_save import UserSettings
18
+ from .core._settings_user import UserSettings
21
19
 
22
20
 
23
21
  def load_user(email: str | None = None, handle: str | None = None) -> UserSettings:
@@ -30,15 +28,12 @@ def load_user(email: str | None = None, handle: str | None = None) -> UserSettin
30
28
  save_user_settings(user_settings) # needed to save to current_user.env
31
29
  assert user_settings.email is not None or user_settings.api_key is not None
32
30
  else:
33
- user_settings = load_or_create_user_settings()
34
31
  if email is None:
35
32
  raise SystemExit(
36
33
  "✗ Use your email for your first login in a compute environment. "
37
34
  "After that, you can use your handle."
38
35
  )
39
- user_settings.email = email
40
- user_settings.handle = handle
41
- save_user_settings(user_settings)
36
+ user_settings = UserSettings(handle=handle, email=email, uid="null") # type: ignore
42
37
 
43
38
  from .core._settings import settings
44
39
 
@@ -49,7 +44,7 @@ def load_user(email: str | None = None, handle: str | None = None) -> UserSettin
49
44
 
50
45
  def login(
51
46
  user: str | None = None, *, api_key: str | None = None, key: str | None = None
52
- ) -> None:
47
+ ) -> UserSettings:
53
48
  """Log in user.
54
49
 
55
50
  Args:
@@ -84,7 +79,7 @@ def login(
84
79
  elif user_settings.email is None:
85
80
  raise SystemExit(f"✗ No stored user email, please call: lamin login {user}")
86
81
  else:
87
- user_settings = load_or_create_user_settings()
82
+ user_settings = UserSettings(handle="temporary", uid="null")
88
83
 
89
84
  from .core._hub_core import sign_in_hub, sign_in_hub_api_key
90
85
 
@@ -104,14 +99,12 @@ def login(
104
99
  raise SystemExit(f"✗ Unsuccessful login: {response}.")
105
100
  else:
106
101
  user_uuid, user_id, user_handle, user_name, access_token = response
102
+
107
103
  if api_key is not None:
108
- logger.success(
109
- f"logged in with API key (handle: {user_handle}, uid: {user_id})"
110
- )
111
- elif handle is None:
112
- logger.success(f"logged in with handle {user_handle} (uid: {user_id})")
113
- else:
104
+ logger.success(f"logged in {user_handle} (uid: {user_id})")
105
+ else: # legacy flow
114
106
  logger.success(f"logged in with email {user_settings.email} (uid: {user_id})")
107
+
115
108
  user_settings.uid = user_id
116
109
  user_settings.handle = user_handle
117
110
  user_settings.name = user_name
@@ -124,14 +117,17 @@ def login(
124
117
  register_user(user_settings)
125
118
 
126
119
  settings._user_settings = None
127
- return None
120
+ return user_settings
128
121
 
129
122
 
130
123
  def logout():
131
124
  if current_user_settings_file().exists():
132
125
  current_user_settings_file().unlink()
133
- # update user info
134
126
  settings._user_settings = None
135
127
  logger.success("logged out")
136
128
  else:
137
129
  logger.important("already logged out")
130
+ if os.environ.get("LAMIN_API_KEY") is not None:
131
+ logger.warning(
132
+ "LAMIN_API_KEY is still set in your environment and will automatically log you in"
133
+ )
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import logging
3
4
  import os
4
5
  import time
5
6
 
@@ -38,7 +39,19 @@ PUBLIC_BUCKETS: tuple[str] = ("cellxgene-data-public",)
38
39
  LAMIN_ENDPOINTS: tuple[str | None] = (None,)
39
40
 
40
41
 
42
+ class NoTracebackFilter(logging.Filter):
43
+ def filter(self, record):
44
+ record.exc_info = None # Remove traceback info from the log record.
45
+ return True
46
+
47
+
41
48
  class AWSOptionsManager:
49
+ # suppress giant traceback logs from aiobotocore when failing to refresh sso etc
50
+ @staticmethod
51
+ def _suppress_aiobotocore_traceback_logging():
52
+ logger = logging.getLogger("aiobotocore.credentials")
53
+ logger.addFilter(NoTracebackFilter())
54
+
42
55
  def __init__(self):
43
56
  self._credentials_cache = {}
44
57
 
@@ -48,6 +61,9 @@ class AWSOptionsManager:
48
61
  fs = S3FileSystem(
49
62
  cache_regions=True, use_listings_cache=True, version_aware=False
50
63
  )
64
+
65
+ self._suppress_aiobotocore_traceback_logging()
66
+
51
67
  try:
52
68
  fs.connect()
53
69
  self.anon: bool = fs.session._credentials is None
@@ -34,13 +34,12 @@ from ._hub_utils import (
34
34
  LaminDsnModel,
35
35
  )
36
36
  from ._settings import settings
37
+ from ._settings_instance import InstanceSettings
37
38
  from ._settings_storage import StorageSettings, base62
38
39
 
39
40
  if TYPE_CHECKING:
40
41
  from supabase import Client # type: ignore
41
42
 
42
- from ._settings_instance import InstanceSettings
43
-
44
43
 
45
44
  def delete_storage_record(storage_uuid: UUID, access_token: str | None = None) -> None:
46
45
  return call_with_fallback_auth(
@@ -439,11 +438,25 @@ def _access_aws(*, storage_root: str, client: Client) -> dict[str, dict]:
439
438
  return storage_root_info
440
439
 
441
440
 
442
- def access_db(isettings: InstanceSettings, access_token: str | None = None) -> str:
441
+ def access_db(
442
+ instance: InstanceSettings | dict, access_token: str | None = None
443
+ ) -> str:
444
+ instance_id: UUID
445
+ instance_slug: str
446
+ instance_api_url: str | None
447
+ if isinstance(instance, InstanceSettings):
448
+ instance_id = instance._id
449
+ instance_slug = instance.slug
450
+ instance_api_url = instance._api_url
451
+ else:
452
+ instance_id = UUID(instance["id"])
453
+ instance_slug = instance["owner"] + "/" + instance["name"]
454
+ instance_api_url = instance["api_url"]
455
+
443
456
  if access_token is None:
444
457
  if settings.user.handle == "anonymous":
445
458
  raise RuntimeError(
446
- f"Can only get fine-grained access to {isettings.slug} if authenticated."
459
+ f"Can only get fine-grained access to {instance_slug} if authenticated."
447
460
  )
448
461
  else:
449
462
  access_token = settings.user.access_token
@@ -451,20 +464,19 @@ def access_db(isettings: InstanceSettings, access_token: str | None = None) -> s
451
464
  else:
452
465
  renew_token = False
453
466
  # local is used in tests
454
- url = f"/access_v2/instances/{isettings._id}/db_token"
467
+ url = f"/access_v2/instances/{instance_id}/db_token"
455
468
  if os.environ.get("LAMIN_ENV", "prod") != "local":
456
- api_url = isettings._api_url
457
- if api_url is None:
469
+ if instance_api_url is None:
458
470
  raise RuntimeError(
459
- f"Can only get fine-grained access to {isettings.slug} if api_url is present."
471
+ f"Can only get fine-grained access to {instance_slug} if api_url is present."
460
472
  )
461
- url = api_url + url
473
+ url = instance_api_url + url
462
474
 
463
475
  response = request_get_auth(url, access_token, renew_token) # type: ignore
464
476
  response_json = response.json()
465
477
  if response.status_code != 200:
466
478
  raise PermissionError(
467
- f"Fine-grained access to {isettings.slug} failed: {response_json}"
479
+ f"Fine-grained access to {instance_slug} failed: {response_json}"
468
480
  )
469
481
  if "token" not in response_json:
470
482
  raise RuntimeError("The response of access_db does not contain a db token.")
@@ -114,10 +114,13 @@ class SetupSettings:
114
114
  and self._user_settings_env != get_env_name()
115
115
  )
116
116
  if self._user_settings is None or env_changed:
117
- self._user_settings = load_or_create_user_settings()
117
+ # only uses LAMIN_API_KEY if there is no current_user.env
118
+ self._user_settings = load_or_create_user_settings(
119
+ api_key=os.environ.get("LAMIN_API_KEY")
120
+ )
118
121
  self._user_settings_env = get_env_name()
119
122
  if self._user_settings and self._user_settings.uid is None:
120
- raise RuntimeError("Need to login, first: lamin login <email>")
123
+ raise RuntimeError("Need to login, first: lamin login")
121
124
  return self._user_settings # type: ignore
122
125
 
123
126
  @property
@@ -286,7 +286,7 @@ class InstanceSettings:
286
286
  The core schema contained in lamindb is not included in this set.
287
287
  """
288
288
  if self._schema_str is None:
289
- return {} # type: ignore
289
+ return set()
290
290
  else:
291
291
  return {module for module in self._schema_str.split(",") if module != ""}
292
292
 
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import os
3
4
  from typing import TYPE_CHECKING
4
5
  from uuid import UUID, uuid4
5
6
 
@@ -40,7 +41,7 @@ def load_instance_settings(instance_settings_file: Path | None = None):
40
41
  if instance_settings_file is None:
41
42
  instance_settings_file = current_instance_settings_file()
42
43
  if not instance_settings_file.exists():
43
- raise SystemExit("No instance is loaded! Call `lamin init` or `lamin connect`")
44
+ raise SystemExit("No instance connected! Call `lamin connect` or `lamin init`")
44
45
  try:
45
46
  settings_store = InstanceSettingsStore(_env_file=instance_settings_file)
46
47
  except (ValidationError, TypeError) as error:
@@ -55,11 +56,21 @@ def load_instance_settings(instance_settings_file: Path | None = None):
55
56
  return isettings
56
57
 
57
58
 
58
- def load_or_create_user_settings() -> UserSettings:
59
- """Return current user settings."""
59
+ def load_or_create_user_settings(api_key: str | None = None) -> UserSettings:
60
+ """Return current user settings.
61
+
62
+ Args:
63
+ api_key: if provided and there is no current user,
64
+ perform login and return the user settings.
65
+ """
60
66
  current_user_settings = current_user_settings_file()
61
67
  if not current_user_settings.exists():
62
- logger.warning("using anonymous user (to identify, call: lamin login)")
68
+ if api_key is not None:
69
+ from lamindb_setup._setup_user import login
70
+
71
+ return login(api_key=api_key)
72
+ else:
73
+ logger.warning("using anonymous user (to identify, call: lamin login)")
63
74
  usettings = UserSettings(handle="anonymous", uid="00000000")
64
75
  from ._settings_save import save_user_settings
65
76
 
@@ -14,29 +14,101 @@ IS_MIGRATING = False
14
14
  CONN_MAX_AGE = 299
15
15
 
16
16
 
17
- def set_db_token(token: str | None, connection_name: str = "default"):
18
- # None to reset
19
- from django.db import connections
20
- from django.db.backends.base.base import BaseDatabaseWrapper
17
+ # a class to manage jwt in dbs
18
+ class DBTokenManager:
19
+ def __init__(self, debug: bool = False):
20
+ from django.db.transaction import Atomic
21
21
 
22
- connection = connections[connection_name]
23
- assert connection.vendor == "postgresql"
22
+ self.debug = debug
23
+ self.original_atomic_enter = Atomic.__enter__
24
24
 
25
- if token is not None:
25
+ self.tokens: dict[str, str] = {}
26
26
 
27
- def connect(self):
28
- BaseDatabaseWrapper.connect(self)
29
- # now the connection should be set
30
- # Use a psycopg cursor directly, bypassing Django's utilities.
31
- with self.connection.cursor() as cursor:
32
- cursor.execute("SELECT set_token(%s, false);", (token,))
33
- else:
34
- connect = BaseDatabaseWrapper.connect
27
+ def get_connection(self, connection_name: str):
28
+ from django.db import connections
35
29
 
36
- connection.connect = connect.__get__(connection, connection.__class__)
37
- # execute this to initially set or reset the token
38
- connection.close()
39
- connection.connect()
30
+ connection = connections[connection_name]
31
+ assert connection.vendor == "postgresql"
32
+
33
+ return connection
34
+
35
+ def set(self, token: str, connection_name: str = "default"):
36
+ from django.db.transaction import Atomic
37
+
38
+ # no adapt in psycopg3
39
+ from psycopg2.extensions import adapt
40
+
41
+ connection = self.get_connection(connection_name)
42
+
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
+ def set_token_wrapper(execute, sql, params, many, context):
49
+ not_in_atomic_block = (
50
+ context is None
51
+ or "connection" not in context
52
+ or not context["connection"].in_atomic_block
53
+ )
54
+ # ignore atomic blocks
55
+ if not_in_atomic_block:
56
+ sql = set_token_query + sql
57
+ elif self.debug:
58
+ print("--in atomic block--")
59
+
60
+ if self.debug:
61
+ print(sql)
62
+ result = execute(sql, params, many, context)
63
+ # this ensures that psycopg3 in the current env doesn't break this wrapper
64
+ # psycopg3 returns a cursor
65
+ # psycopg3 fetching differs from psycopg2, it returns the output of all sql statements
66
+ # not only the last one as psycopg2 does. So we shift the cursor from set_token
67
+ if (
68
+ not_in_atomic_block
69
+ and result is not None
70
+ and hasattr(result, "nextset")
71
+ ):
72
+ if self.debug:
73
+ print("(shift cursor)")
74
+ result.nextset()
75
+ return result
76
+
77
+ connection.execute_wrappers.append(set_token_wrapper)
78
+
79
+ # ensure we set the token only once for an outer atomic block
80
+ def __enter__(atomic):
81
+ self.original_atomic_enter(atomic)
82
+ is_same_connection = (
83
+ "default" if atomic.using is None else atomic.using
84
+ ) == connection_name
85
+ if is_same_connection and len(connection.atomic_blocks) == 1:
86
+ # use raw psycopg2 connection here
87
+ # atomic block ensures connection
88
+ if self.debug:
89
+ print("(set transaction token)")
90
+ connection.connection.cursor().execute(set_token_query)
91
+
92
+ Atomic.__enter__ = __enter__
93
+
94
+ self.tokens[connection_name] = token
95
+
96
+ def reset(self, connection_name: str = "default"):
97
+ from django.db.transaction import Atomic
98
+
99
+ connection = self.get_connection(connection_name)
100
+
101
+ connection.execute_wrappers = [
102
+ w
103
+ for w in connection.execute_wrappers
104
+ if getattr(w, "__name__", None) != "set_token_wrapper"
105
+ ]
106
+ Atomic.__enter__ = self.original_atomic_enter
107
+
108
+ self.tokens.pop(connection_name, None)
109
+
110
+
111
+ db_token_manager = DBTokenManager()
40
112
 
41
113
 
42
114
  def close_if_health_check_failed(self) -> None:
@@ -128,7 +200,8 @@ def setup_django(
128
200
  if isettings._fine_grained_access and isettings._db_permissions == "jwt":
129
201
  from ._hub_core import access_db
130
202
 
131
- set_db_token(access_db(isettings))
203
+ db_token = access_db(isettings)
204
+ db_token_manager.set(db_token) # sets for the default connection
132
205
 
133
206
  if configure_only:
134
207
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lamindb_setup
3
- Version: 1.4.1
3
+ Version: 1.5.0
4
4
  Summary: Setup & configure LaminDB.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Requires-Python: >=3.10
@@ -21,7 +21,7 @@ Requires-Dist: psutil
21
21
  Requires-Dist: packaging
22
22
  Requires-Dist: urllib3<2 ; extra == "aws"
23
23
  Requires-Dist: aiobotocore[boto3]>=2.5.4,<3.0.0 ; extra == "aws"
24
- Requires-Dist: s3fs>=2023.12.2,<=2025.2.0,!=2024.10.0 ; extra == "aws"
24
+ Requires-Dist: s3fs>=2023.12.2,<=2025.3.2,!=2024.10.0 ; extra == "aws"
25
25
  Requires-Dist: line_profiler ; extra == "dev"
26
26
  Requires-Dist: psycopg2-binary ; extra == "dev"
27
27
  Requires-Dist: python-dotenv ; extra == "dev"
@@ -32,7 +32,7 @@ Requires-Dist: pytest-xdist ; extra == "dev"
32
32
  Requires-Dist: nbproject-test>=0.4.3 ; extra == "dev"
33
33
  Requires-Dist: pandas ; extra == "dev"
34
34
  Requires-Dist: django-schema-graph ; extra == "erdiagram"
35
- Requires-Dist: gcsfs>=2023.12.2,<=2025.2.0 ; extra == "gcp"
35
+ Requires-Dist: gcsfs>=2023.12.2,<=2025.3.2 ; extra == "gcp"
36
36
  Project-URL: Home, https://github.com/laminlabs/lamindb-setup
37
37
  Provides-Extra: aws
38
38
  Provides-Extra: dev
@@ -1,47 +1,47 @@
1
- lamindb_setup/__init__.py,sha256=is_IPUSgYwCBU2vA_ly7eIalvGfszfaTs7uB3cZ2gLU,2692
2
- lamindb_setup/_cache.py,sha256=aszT-zk3S5dTLKp5g1W-S_FPh2E5YVCALwWSGPJLWBM,1493
1
+ lamindb_setup/__init__.py,sha256=Qu5sZWgns9oPEIp_JS4KIkLv99Q91pvZPnnEOLJq8ng,2754
2
+ lamindb_setup/_cache.py,sha256=ixasm_9pUFy-ztbhbqJRVP88uTbFclL60MwUUvZhMFs,1509
3
3
  lamindb_setup/_check.py,sha256=28PcG8Kp6OpjSLSi1r2boL2Ryeh6xkaCL87HFbjs6GA,129
4
- lamindb_setup/_check_setup.py,sha256=d1GS1Csy2G9AysfjoyVcNVY0lhHiWSwSLpfgdIQf35s,5477
5
- lamindb_setup/_close.py,sha256=SFfOO0OjYR3krvya66kK8RRQa7lPH8MnzUtE33yZ6sQ,1082
6
- lamindb_setup/_connect_instance.py,sha256=lo0EV_PA8YNlerxfPLG0u-YdmyKLAqbIIhTfzmwNDlI,18352
4
+ lamindb_setup/_check_setup.py,sha256=uveV6CGiwm9M5OMe3lxfAMDs5SU7j1EogJsQB03ZaRw,5928
5
+ lamindb_setup/_connect_instance.py,sha256=qqB-ene_OLTgqd-M7ke9_gT6u81gzNy_Gx5K7FMUaag,18007
7
6
  lamindb_setup/_delete.py,sha256=2KnZOqd5Kgr45XzjiDE9der35LODDUajZD6_hcurGtQ,5676
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=5BVHDM3qOe5_HsJGb14NqudGdCG3MjP05rcmercn9wg,14762
12
+ lamindb_setup/_init_instance.py,sha256=5RBv2X18SfnIrciHljaoVsFF25te2P7KwHx0Ww87HLw,14750
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
16
  lamindb_setup/_schema_metadata.py,sha256=cDkNHyFTFZq879UGY6i-rJEXfeBN59AN3Wz86caKnYI,14358
17
17
  lamindb_setup/_set_managed_storage.py,sha256=qC3ACD_PWG-MrzcS3fQpjDEOuxAaJBgPqCU_bDvqtXo,2043
18
- lamindb_setup/_setup_user.py,sha256=-g7Xj6510BDyM8kuqAsVBZFwehlhBa_uWBSV1rPeuM8,4586
18
+ lamindb_setup/_setup_user.py,sha256=8BSGsW5jfmB4FlkhMt5osYXBbVCdOQeAVATb-oAYxa0,4495
19
19
  lamindb_setup/_silence_loggers.py,sha256=AKF_YcHvX32eGXdsYK8MJlxEaZ-Uo2f6QDRzjKFCtws,1568
20
20
  lamindb_setup/core/__init__.py,sha256=BxIVMX5HQq8oZ1OuY_saUEJz5Tdd7gaCPngxVu5iou4,417
21
- lamindb_setup/core/_aws_options.py,sha256=Umxu_1AYd-0LJUElZxowvE9vNA7Z8kh_63g3pp1gfd8,7243
21
+ lamindb_setup/core/_aws_options.py,sha256=BLLAtasJp7T0quMG7KgH8PmfHAn62izBwA7bYFwLV88,7748
22
22
  lamindb_setup/core/_aws_storage.py,sha256=nEjeUv4xUVpoV0Lx-zjjmyb9w804bDyaeiM-OqbfwM0,1799
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=FCFvnQsPWUYLJ_GFsuQ8rINQ7Rqth71pDfNJHRjPY_0,21344
26
+ lamindb_setup/core/_hub_core.py,sha256=G5P7sZjH-2ZrWvmfQgJSB1Kw1JP01t070S4eX62mlwc,21738
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=eslFO84vb5uRRfJ3r_uu4O8677l8lU5BbpZJMSAYw6A,8244
31
- lamindb_setup/core/_settings_instance.py,sha256=iUoLJj_bl8axs4fiNA5jgLjIEvrMaJBzz-PUDWXmUwg,19395
32
- lamindb_setup/core/_settings_load.py,sha256=BaII7qH3hKbttHHtB5YECoz0c2SnxL_IcUEMZhuqHCo,4342
30
+ lamindb_setup/core/_settings.py,sha256=zkogVBqRly37pyDOReVDV019hR3oY2POImobDjs8CM8,8375
31
+ lamindb_setup/core/_settings_instance.py,sha256=ftHAFFbg_0iThuywuQM37RIiCQnMEOc1dftTig1_DZo,19382
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
35
  lamindb_setup/core/_settings_store.py,sha256=zyybc6fJXJcFNTjBrgtgbPhriInuhpmQKNoGmy8ScFA,2298
36
36
  lamindb_setup/core/_settings_user.py,sha256=lWqV3HmZCsEq2UsU_iVNW0p9ddsNg7-B6xOaMNH1aw0,1475
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=2qIt3t9Ra_24aKU7q1r30JY87TM_rT6Cvh8rNPlqRc8,4876
39
+ lamindb_setup/core/django.py,sha256=TMPRnZyFxD_BoKHJUw88aHqUNU_Dikyqg42GPNXBG-g,7414
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
43
  lamindb_setup/core/upath.py,sha256=bjKlQZFe-azlZZZ_VjH9bzfh93G6b88b_IE6E6Dg7cY,33662
44
- lamindb_setup-1.4.1.dist-info/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
45
- lamindb_setup-1.4.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
46
- lamindb_setup-1.4.1.dist-info/METADATA,sha256=F41PXuW4grUyG6yLr9g-uCSTPb9SPK0AKhI6aCmm2_8,1790
47
- lamindb_setup-1.4.1.dist-info/RECORD,,
44
+ lamindb_setup-1.5.0.dist-info/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
45
+ lamindb_setup-1.5.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
46
+ lamindb_setup-1.5.0.dist-info/METADATA,sha256=aFRhOpjfw5V8ES2LSKpz691L1HOfeFC2zVaP7yvI72I,1790
47
+ lamindb_setup-1.5.0.dist-info/RECORD,,