lamindb_setup 0.74.1__tar.gz → 0.74.3__tar.gz

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 (93) hide show
  1. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/.github/workflows/build.yml +1 -1
  2. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/.pre-commit-config.yaml +0 -6
  3. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/PKG-INFO +3 -3
  4. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/04-test-bionty.ipynb +3 -3
  5. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/__init__.py +1 -1
  6. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_connect_instance.py +3 -2
  7. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_exportdb.py +1 -1
  8. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_init_instance.py +4 -1
  9. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_hub_client.py +4 -2
  10. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_hub_core.py +20 -16
  11. lamindb_setup-0.74.3/lamindb_setup/core/_hub_utils.py +109 -0
  12. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_load.py +1 -1
  13. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_save.py +2 -0
  14. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_store.py +3 -9
  15. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_setup_bionty_sources.py +10 -17
  16. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/noxfile.py +5 -1
  17. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/pyproject.toml +2 -2
  18. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-local/test_all.py +2 -1
  19. lamindb_setup-0.74.1/lamindb_setup/core/_hub_utils.py +0 -76
  20. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/.github/workflows/doc-changes.yml +0 -0
  21. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/.gitignore +0 -0
  22. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/LICENSE +0 -0
  23. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/README.md +0 -0
  24. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/changelog.md +0 -0
  25. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/01-init-local-instance.ipynb +0 -0
  26. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/02-connect-local-instance.ipynb +0 -0
  27. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/03-add-managed-storage.ipynb +0 -0
  28. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/05-init-hosted-instance.ipynb +0 -0
  29. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/06-connect-hosted-instance.ipynb +0 -0
  30. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/07-keep-artifacts-local.ipynb +0 -0
  31. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/test-multi-session.ipynb +0 -0
  32. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-cloud/test_notebooks.py +0 -0
  33. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-cache-management.ipynb +0 -0
  34. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-cloud-sync.ipynb +0 -0
  35. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-connect-anonymously.ipynb +0 -0
  36. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-empty-init.ipynb +0 -0
  37. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-import-schema.ipynb +0 -0
  38. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-insufficient-user-info.ipynb +0 -0
  39. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-invalid-schema.ipynb +0 -0
  40. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test-sqlite-lock.ipynb +0 -0
  41. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/hub-prod/test_notebooks2.py +0 -0
  42. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/index.md +0 -0
  43. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/notebooks.md +0 -0
  44. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/docs/reference.md +0 -0
  45. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_cache.py +0 -0
  46. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_check.py +0 -0
  47. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_check_setup.py +0 -0
  48. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_close.py +0 -0
  49. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_delete.py +0 -0
  50. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_django.py +0 -0
  51. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_importdb.py +0 -0
  52. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_migrate.py +0 -0
  53. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_register_instance.py +0 -0
  54. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_schema.py +0 -0
  55. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_schema_metadata.py +0 -0
  56. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_set_managed_storage.py +0 -0
  57. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_setup_user.py +0 -0
  58. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/_silence_loggers.py +0 -0
  59. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/__init__.py +0 -0
  60. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_aws_credentials.py +0 -0
  61. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_aws_storage.py +0 -0
  62. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_deprecated.py +0 -0
  63. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_docs.py +0 -0
  64. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_hub_crud.py +0 -0
  65. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_private_django_api.py +0 -0
  66. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings.py +0 -0
  67. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_instance.py +0 -0
  68. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_storage.py +0 -0
  69. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/_settings_user.py +0 -0
  70. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/cloud_sqlite_locker.py +0 -0
  71. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/django.py +0 -0
  72. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/exceptions.py +0 -0
  73. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/hashing.py +0 -0
  74. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/types.py +0 -0
  75. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/lamindb_setup/core/upath.py +0 -0
  76. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_connect_instance.py +0 -0
  77. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_delete_instance.py +0 -0
  78. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_init_instance.py +0 -0
  79. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_login.py +0 -0
  80. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_migrate.py +0 -0
  81. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-cloud/test_set_storage.py +0 -0
  82. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-local/conftest.py +0 -0
  83. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-local/test_update_schema_in_hub.py +0 -0
  84. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-prod/conftest.py +0 -0
  85. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-prod/test_django.py +0 -0
  86. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-prod/test_global_settings.py +0 -0
  87. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-prod/test_switch_and_fallback_env.py +0 -0
  88. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/hub-prod/test_upath.py +0 -0
  89. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/storage/test_hashing.py +0 -0
  90. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/storage/test_storage_access.py +0 -0
  91. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/storage/test_storage_basis.py +0 -0
  92. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/storage/test_storage_stats.py +0 -0
  93. {lamindb_setup-0.74.1 → lamindb_setup-0.74.3}/tests/storage/test_to_url.py +0 -0
@@ -43,7 +43,7 @@ jobs:
43
43
  python-version: "3.11"
44
44
  - lamin_env: "staging"
45
45
  python-version: "3.10" # test on 3.9
46
- timeout-minutes: 6
46
+ timeout-minutes: 7
47
47
  steps:
48
48
  - uses: aws-actions/configure-aws-credentials@v2
49
49
  with:
@@ -44,9 +44,3 @@ repos:
44
44
  (?x)(
45
45
  tests/hub-local/conftest.py
46
46
  )
47
- - repo: https://github.com/pycqa/pydocstyle
48
- rev: 6.1.1
49
- hooks:
50
- - id: pydocstyle
51
- args: # google style + __init__, see http://www.pydocstyle.org/en/stable/error_codes.html
52
- - --ignore=D100,D101,D102,D103,D104,D106,D107,D203,D204,D213,D215,D400,D401,D403,D404,D406,D407,D408,D409,D412,D413,D417
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamindb_setup
3
- Version: 0.74.1
3
+ Version: 0.74.3
4
4
  Summary: Setup & configure LaminDB.
5
- Author-email: Lamin Labs <laminlabs@gmail.com>
5
+ Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Description-Content-Type: text/markdown
7
7
  Requires-Dist: lnschema_core>=0.51.0
8
8
  Requires-Dist: lamin_utils>=0.3.3
9
9
  Requires-Dist: django>4.2,<5.3.0
10
10
  Requires-Dist: dj_database_url>=1.3.0,<3.0.0
11
- Requires-Dist: pydantic[dotenv]<2.0.0
11
+ Requires-Dist: pydantic-settings
12
12
  Requires-Dist: appdirs<2.0.0
13
13
  Requires-Dist: requests
14
14
  Requires-Dist: universal_pathlib==0.2.2
@@ -49,7 +49,7 @@
49
49
  "metadata": {},
50
50
  "outputs": [],
51
51
  "source": [
52
- "from lnschema_bionty import PublicSource"
52
+ "from lnschema_bionty import Source"
53
53
  ]
54
54
  },
55
55
  {
@@ -58,7 +58,7 @@
58
58
  "metadata": {},
59
59
  "outputs": [],
60
60
  "source": [
61
- "sources_df = pd.DataFrame(PublicSource.objects.all().values())\n",
61
+ "sources_df = pd.DataFrame(Source.objects.all().values())\n",
62
62
  "sources_df.head()"
63
63
  ]
64
64
  },
@@ -124,7 +124,7 @@
124
124
  "metadata": {},
125
125
  "outputs": [],
126
126
  "source": [
127
- "sources_df = pd.DataFrame(PublicSource.objects.all().values())\n",
127
+ "sources_df = pd.DataFrame(Source.objects.all().values())\n",
128
128
  "sources_df.head()"
129
129
  ]
130
130
  },
@@ -34,7 +34,7 @@ Modules & settings:
34
34
 
35
35
  """
36
36
 
37
- __version__ = "0.74.1" # denote a release candidate for 0.1.0 with 0.1rc1
37
+ __version__ = "0.74.3" # denote a release candidate for 0.1.0 with 0.1rc1
38
38
 
39
39
  import sys
40
40
  from os import name as _os_name
@@ -74,7 +74,8 @@ def update_db_using_local(
74
74
  # read from a cached settings file in case the hub result is only
75
75
  # read level or inexistent
76
76
  elif settings_file.exists() and (
77
- "read" in db_dsn_hub.db.user or db_dsn_hub.db.user is None
77
+ db_dsn_hub.db.user is None
78
+ or (db_dsn_hub.db.user is not None and "read" in db_dsn_hub.db.user)
78
79
  ):
79
80
  isettings = load_instance_settings(settings_file)
80
81
  db_dsn_local = LaminDsnModel(db=isettings.db)
@@ -101,7 +102,7 @@ def update_db_using_local(
101
102
  scheme=db_dsn_hub.db.scheme,
102
103
  user=db_dsn_local.db.user,
103
104
  password=db_dsn_local.db.password,
104
- host=db_dsn_hub.db.host,
105
+ host=db_dsn_hub.db.host, # type: ignore
105
106
  port=db_dsn_hub.db.port,
106
107
  database=db_dsn_hub.db.database,
107
108
  )
@@ -29,7 +29,7 @@ MODELS = {
29
29
  # "ExperimentalFactor": False,
30
30
  # "DevelopmentalStage": False,
31
31
  # "Ethnicity": False,
32
- # "PublicSource": False,
32
+ # "Source": False,
33
33
  # },
34
34
  # "wetlab": {
35
35
  # "ExperimentType": False,
@@ -245,7 +245,10 @@ def init(
245
245
  if instance_state == "connected":
246
246
  settings.auto_connect = True # we can also debate this switch here
247
247
  return None
248
- ssettings = init_storage(storage, instance_id=instance_id)
248
+ # cannot past instance_id here because instance does not yet exist!
249
+ # the instance_id field of the storage table is populated at the end of
250
+ # init_instance_hub
251
+ ssettings = init_storage(storage)
249
252
  isettings = InstanceSettings(
250
253
  id=instance_id, # type: ignore
251
254
  owner=settings.user.handle,
@@ -5,7 +5,7 @@ from urllib.request import urlretrieve
5
5
 
6
6
  from gotrue.errors import AuthUnknownError
7
7
  from lamin_utils import logger
8
- from pydantic import BaseSettings
8
+ from pydantic_settings import BaseSettings
9
9
  from supabase import Client, create_client # type: ignore
10
10
  from supabase.lib.client_options import ClientOptions
11
11
 
@@ -59,9 +59,11 @@ class Environment:
59
59
 
60
60
  # runs ~0.5s
61
61
  def connect_hub(
62
- fallback_env: bool = False, client_options: ClientOptions = ClientOptions()
62
+ fallback_env: bool = False, client_options: ClientOptions | None = None
63
63
  ) -> Client:
64
64
  env = Environment(fallback=fallback_env)
65
+ if client_options is None:
66
+ client_options = ClientOptions(auto_refresh_token=False)
65
67
  return create_client(env.supabase_api_url, env.supabase_anon_key, client_options)
66
68
 
67
69
 
@@ -93,20 +93,21 @@ def _select_storage(
93
93
  return False
94
94
  else:
95
95
  existing_storage = response.data[0]
96
- if ssettings._instance_id is not None:
97
- # consider storage settings that are meant to be managed by an instance
98
- if UUID(existing_storage["instance_id"]) != ssettings._instance_id:
99
- # everything is alright if the instance_id matches
100
- # we're probably just switching storage locations
101
- # below can be turned into a warning and then delegate the error
102
- # to a unique constraint violation below
103
- raise ValueError(
104
- f"Storage root {root} is already managed by instance {existing_storage['instance_id']}."
105
- )
106
- else:
107
- # if the request is agnostic of the instance, that's alright,
108
- # we'll update the instance_id with what's stored in the hub
109
- ssettings._instance_id = UUID(existing_storage["instance_id"])
96
+ if existing_storage["instance_id"] is not None:
97
+ if ssettings._instance_id is not None:
98
+ # consider storage settings that are meant to be managed by an instance
99
+ if UUID(existing_storage["instance_id"]) != ssettings._instance_id:
100
+ # everything is alright if the instance_id matches
101
+ # we're probably just switching storage locations
102
+ # below can be turned into a warning and then delegate the error
103
+ # to a unique constraint violation below
104
+ raise ValueError(
105
+ f"Storage root {root} is already managed by instance {existing_storage['instance_id']}."
106
+ )
107
+ else:
108
+ # if the request is agnostic of the instance, that's alright,
109
+ # we'll update the instance_id with what's stored in the hub
110
+ ssettings._instance_id = UUID(existing_storage["instance_id"])
110
111
  ssettings._uuid_ = UUID(existing_storage["id"])
111
112
  if update_uid:
112
113
  ssettings._uid = existing_storage["lnid"]
@@ -145,11 +146,14 @@ def _init_storage(ssettings: StorageSettings, client: Client) -> None:
145
146
  id = uuid.uuid5(uuid.NAMESPACE_URL, root)
146
147
  else:
147
148
  id = uuid.uuid4()
148
- if ssettings._instance_id is None:
149
+ if ssettings._instance_id is None and settings._instance_exists:
149
150
  logger.warning(
150
151
  f"will manage storage location {ssettings.root_as_str} with instance {settings.instance.slug}"
151
152
  )
152
153
  ssettings._instance_id = settings.instance._id
154
+ instance_id_hex = (
155
+ None if ssettings._instance_id is None else ssettings._instance_id.hex
156
+ )
153
157
  fields = {
154
158
  "id": id.hex,
155
159
  "lnid": ssettings.uid,
@@ -157,7 +161,7 @@ def _init_storage(ssettings: StorageSettings, client: Client) -> None:
157
161
  "root": root,
158
162
  "region": ssettings.region,
159
163
  "type": ssettings.type,
160
- "instance_id": ssettings._instance_id.hex,
164
+ "instance_id": instance_id_hex,
161
165
  # the empty string is important as we want the user flow to be through LaminHub
162
166
  # if this errors with unique constraint error, the user has to update
163
167
  # the description in LaminHub
@@ -0,0 +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}
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Optional
4
4
  from uuid import UUID, uuid4
5
5
 
6
6
  from lamin_utils import logger
7
- from pydantic.error_wrappers import ValidationError
7
+ from pydantic import ValidationError
8
8
 
9
9
  from ._settings_instance import InstanceSettings
10
10
  from ._settings_storage import StorageSettings
@@ -44,6 +44,8 @@ def save_settings(
44
44
  if type == Optional[bool]:
45
45
  type = bool
46
46
  if "__" not in store_key:
47
+ if store_key == "model_config":
48
+ continue
47
49
  if store_key == "storage_root":
48
50
  value = settings.storage.root_as_str
49
51
  elif store_key == "storage_region":
@@ -2,7 +2,7 @@ import os
2
2
  from pathlib import Path
3
3
  from typing import Optional
4
4
 
5
- from pydantic import BaseSettings
5
+ from pydantic_settings import BaseSettings, SettingsConfigDict
6
6
 
7
7
  if "LAMIN_SETTINGS_DIR" in os.environ:
8
8
  # Needed when running with AWS Lambda, as only tmp/ directory has a write access
@@ -58,10 +58,7 @@ class InstanceSettingsStore(BaseSettings):
58
58
  id: str
59
59
  git_repo: Optional[str]
60
60
  keep_artifacts_local: Optional[bool]
61
-
62
- class Config:
63
- env_prefix = "lamindb_instance_"
64
- env_file = ".env"
61
+ model_config = SettingsConfigDict(env_prefix="lamindb_instance_", env_file=".env")
65
62
 
66
63
 
67
64
  class UserSettingsStore(BaseSettings):
@@ -72,7 +69,4 @@ class UserSettingsStore(BaseSettings):
72
69
  uuid: str
73
70
  handle: str
74
71
  name: str
75
-
76
- class Config:
77
- env_prefix = "lamin_user_"
78
- env_file = ".env"
72
+ model_config = SettingsConfigDict(env_prefix="lamin_user_", env_file=".env")
@@ -9,14 +9,14 @@ if TYPE_CHECKING:
9
9
 
10
10
 
11
11
  def write_bionty_sources(isettings: InstanceSettings) -> None:
12
- """Write bionty sources to PublicSource table."""
12
+ """Write bionty sources to Source table."""
13
13
  if "bionty" not in isettings.schema:
14
14
  return None
15
15
  import shutil
16
16
 
17
17
  import bionty_base
18
18
  from bionty_base.dev._handle_sources import parse_sources_yaml
19
- from lnschema_bionty.models import PublicSource
19
+ from lnschema_bionty.models import Source
20
20
 
21
21
  shutil.copy(
22
22
  bionty_base.settings.current_sources, bionty_base.settings.lamindb_sources
@@ -32,16 +32,11 @@ def write_bionty_sources(isettings: InstanceSettings) -> None:
32
32
  .set_index(["entity", key])
33
33
  )
34
34
 
35
- try:
36
- currently_used = _get_currently_used("organism")
37
- key = "organism"
38
- except KeyError:
39
- currently_used = _get_currently_used("species")
40
- key = "species"
35
+ currently_used = _get_currently_used("organism")
41
36
 
42
37
  all_records = []
43
38
  for kwargs in all_sources_dict:
44
- act = currently_used.loc[(kwargs["entity"], kwargs[key])].to_dict()
39
+ act = currently_used.loc[(kwargs["entity"], kwargs["organism"])].to_dict()
45
40
  if (act["source"] == kwargs["source"]) and (
46
41
  act["version"] == kwargs["version"]
47
42
  ):
@@ -49,15 +44,13 @@ def write_bionty_sources(isettings: InstanceSettings) -> None:
49
44
 
50
45
  # when the database is not yet migrated but setup is updated
51
46
  # won't need this once lamindb is released with the new pin
52
- if hasattr(PublicSource, "species") and "organism" in kwargs:
53
- kwargs["species"] = kwargs.pop("organism")
54
- elif hasattr(PublicSource, "organism") and "species" in kwargs:
55
- kwargs["organism"] = kwargs.pop("species")
56
47
  kwargs["run"] = None # can't yet access tracking information
57
- record = PublicSource(**kwargs)
48
+ kwargs["in_db"] = False
49
+ # kwargs["name"] = kwargs.pop("source")
50
+ record = Source(**kwargs)
58
51
  all_records.append(record)
59
52
 
60
- PublicSource.objects.bulk_create(all_records, ignore_conflicts=True)
53
+ Source.objects.bulk_create(all_records, ignore_conflicts=True)
61
54
 
62
55
 
63
56
  def load_bionty_sources(isettings: InstanceSettings):
@@ -68,11 +61,11 @@ def load_bionty_sources(isettings: InstanceSettings):
68
61
  import bionty_base
69
62
  from bionty_base.dev._handle_sources import parse_currently_used_sources
70
63
  from bionty_base.dev._io import write_yaml
71
- from lnschema_bionty.models import PublicSource
64
+ from lnschema_bionty.models import Source
72
65
 
73
66
  try:
74
67
  # need try except because of integer primary key migration
75
- active_records = PublicSource.objects.filter(currently_used=True).all().values()
68
+ active_records = Source.objects.filter(currently_used=True).all().values()
76
69
  write_yaml(
77
70
  parse_currently_used_sources(active_records),
78
71
  bionty_base.settings.lamindb_sources,
@@ -45,10 +45,14 @@ uv pip install --system --no-deps {no_deps_packages}
45
45
  cmds = ""
46
46
  cmds += schema_deps.strip()
47
47
  elif group == "hub-local":
48
- cmds = schema_deps + """uv pip install --system -e ./laminhub/rest-hub"""
48
+ cmds = schema_deps.strip()
49
49
  # current package
50
50
  cmds += """\nuv pip install --system -e '.[aws,dev]' lamin-cli"""
51
51
 
52
+ # above downgrades django, I don't understand why, try this
53
+ if group == "hub-local":
54
+ cmds += "\nuv pip install --system -e ./laminhub/rest-hub"
55
+
52
56
  [run(session, line) for line in cmds.splitlines()]
53
57
 
54
58
 
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "lamindb_setup"
7
- authors = [{name = "Lamin Labs", email = "laminlabs@gmail.com"}]
7
+ authors = [{name = "Lamin Labs", email = "open-source@lamin.ai"}]
8
8
  readme = "README.md"
9
9
  dynamic = ["version", "description"]
10
10
  dependencies = [
@@ -13,7 +13,7 @@ dependencies = [
13
13
  # External dependencies
14
14
  "django>4.2,<5.3.0",
15
15
  "dj_database_url>=1.3.0,<3.0.0",
16
- "pydantic[dotenv]<2.0.0",
16
+ "pydantic-settings",
17
17
  "appdirs<2.0.0",
18
18
  "requests",
19
19
  "universal_pathlib==0.2.2", # is still experimental, need pinning
@@ -118,8 +118,9 @@ def create_myinstance(create_testadmin1_session): # -> Dict
118
118
  id=instance_id,
119
119
  owner=usettings.handle,
120
120
  name="myinstance",
121
+ # cannot yet pass instance_id here as it does not yet exist
121
122
  storage=init_storage_base(
122
- "s3://lamindb-ci/myinstance", instance_id=instance_id
123
+ "s3://lamindb-ci/myinstance",
123
124
  ),
124
125
  db=db_str,
125
126
  )
@@ -1,76 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Optional
4
-
5
- from pydantic import BaseModel, validator
6
- from pydantic.networks import MultiHostDsn
7
-
8
-
9
- def validate_schema_arg(schema: str | None = None) -> str:
10
- if schema is None or schema == "":
11
- return ""
12
- # currently no actual validation, can add back if we see a need
13
- # the following just strips white spaces
14
- to_be_validated = [s.strip() for s in schema.split(",")]
15
- return ",".join(to_be_validated)
16
-
17
-
18
- def validate_db_arg(db: str | None) -> None:
19
- if db is not None:
20
- LaminDsnModel(db=db)
21
-
22
-
23
- class LaminDsn(MultiHostDsn):
24
- """Custom DSN Type for Lamin.
25
-
26
- This class allows us to customize the allowed schemes for databases
27
- and also handles the parsing and building of DSN strings with the
28
- database name instead of URL path.
29
- """
30
-
31
- allowed_schemes = {
32
- "postgresql",
33
- # future enabled schemes
34
- # "snowflake",
35
- # "bigquery"
36
- }
37
- user_required = True
38
- __slots__ = ()
39
-
40
- @property
41
- def database(self):
42
- return self.path[1:]
43
-
44
- @classmethod
45
- def build(
46
- cls,
47
- *,
48
- scheme: str,
49
- user: str | None = None,
50
- password: str | None = None,
51
- host: str,
52
- port: str | None = None,
53
- database: str | None = None,
54
- query: str | None = None,
55
- fragment: str | None = None,
56
- **_kwargs: str,
57
- ) -> str:
58
- return super().build(
59
- scheme=scheme,
60
- user=user,
61
- password=password,
62
- host=host,
63
- port=str(port),
64
- path=f"/{database}",
65
- query=query,
66
- fragment=fragment,
67
- )
68
-
69
-
70
- class LaminDsnModel(BaseModel):
71
- db: LaminDsn
72
-
73
- @validator("db")
74
- def check_db_name(cls, v):
75
- assert v.path and len(v.path) > 1, "database must be provided"
76
- return v
File without changes
File without changes