lamindb 1.11.0__py3-none-any.whl → 1.11.1__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/__init__.py CHANGED
@@ -114,7 +114,7 @@ Backwards compatibility.
114
114
 
115
115
  # ruff: noqa: I001
116
116
  # denote a release candidate for 0.1.0 with 0.1rc1, 0.1a1, 0.1b1, etc.
117
- __version__ = "1.11.0"
117
+ __version__ = "1.11.1"
118
118
 
119
119
  import warnings as _warnings
120
120
 
lamindb/core/_context.py CHANGED
@@ -600,9 +600,11 @@ class Context:
600
600
  if pypackages is None:
601
601
  pypackages = True
602
602
  description = None
603
+ if path.suffix == ".ipynb" and path.stem.startswith("Untitled"):
604
+ raise RuntimeError(
605
+ "Your notebook is untitled, please rename it before tracking"
606
+ )
603
607
  path_str = path.as_posix()
604
- if path_str.endswith("Untitled.ipynb"):
605
- raise RuntimeError("Please rename your notebook before tracking it")
606
608
  if path_str.startswith("/fileId="):
607
609
  logger.warning("tracking on Google Colab is experimental")
608
610
  path_str = get_notebook_key_colab()
@@ -10,7 +10,7 @@ import fsspec
10
10
  import lamindb_setup as ln_setup
11
11
  import pandas as pd
12
12
  from anndata import AnnData
13
- from django.db import connections, models
13
+ from django.db import ProgrammingError, connections, models
14
14
  from django.db.models import CASCADE, PROTECT, Q
15
15
  from django.db.models.functions import Length
16
16
  from lamin_utils import colors, logger
@@ -32,7 +32,7 @@ from lamindb.base.fields import (
32
32
  CharField,
33
33
  ForeignKey,
34
34
  )
35
- from lamindb.errors import FieldValidationError, UnknownStorageLocation
35
+ from lamindb.errors import FieldValidationError, NoWriteAccess, UnknownStorageLocation
36
36
  from lamindb.models.query_set import QuerySet
37
37
 
38
38
  from ..base.users import current_user_id
@@ -294,6 +294,7 @@ def process_data(
294
294
 
295
295
  def get_stat_or_artifact(
296
296
  path: UPath,
297
+ storage: Record,
297
298
  key: str | None = None,
298
299
  check_hash: bool = True,
299
300
  is_replace: bool = False,
@@ -331,14 +332,14 @@ def get_stat_or_artifact(
331
332
  else:
332
333
  result = (
333
334
  Artifact.objects.using(instance)
334
- .filter(Q(hash=hash) | Q(key=key, storage=settings.storage.record))
335
+ .filter(Q(hash=hash) | Q(key=key, storage=storage))
335
336
  .order_by("-created_at")
336
337
  .all()
337
338
  )
338
339
  artifact_with_same_hash_exists = result.filter(hash=hash).count() > 0
339
340
  if not artifact_with_same_hash_exists and len(result) > 0:
340
341
  logger.important(
341
- f"creating new artifact version for key='{key}' (storage: '{settings.storage.root_as_str}')"
342
+ f"creating new artifact version for key='{key}' (storage: '{storage.root}')"
342
343
  )
343
344
  previous_artifact_version = result[0]
344
345
  if artifact_with_same_hash_exists:
@@ -438,6 +439,7 @@ def get_artifact_kwargs_from_data(
438
439
 
439
440
  stat_or_artifact = get_stat_or_artifact(
440
441
  path=path,
442
+ storage=storage,
441
443
  key=key,
442
444
  instance=using_key,
443
445
  is_replace=is_replace,
@@ -3072,8 +3074,12 @@ def _track_run_input(
3072
3074
  )
3073
3075
  data.save()
3074
3076
  is_valid = True
3077
+ data_run_id, run_id = data.run_id, run.id
3078
+ different_runs = (data_run_id != run_id) or (
3079
+ data_run_id is None and run_id is None
3080
+ )
3075
3081
  return (
3076
- data.run_id != run.id
3082
+ different_runs
3077
3083
  and not data._state.adding # this seems duplicated with data._state.db is None
3078
3084
  and is_valid
3079
3085
  )
@@ -3118,8 +3124,9 @@ def _track_run_input(
3118
3124
  if track_run_input:
3119
3125
  if run is None:
3120
3126
  raise ValueError("No run context set. Call `ln.track()`.")
3121
- # avoid adding the same run twice
3122
- run.save()
3127
+ if run._state.adding:
3128
+ # avoid adding the same run twice
3129
+ run.save()
3123
3130
  if data_class_name == "artifact":
3124
3131
  IsLink = run.input_artifacts.through
3125
3132
  links = [
@@ -3131,7 +3138,41 @@ def _track_run_input(
3131
3138
  IsLink(run_id=run.id, collection_id=data_id)
3132
3139
  for data_id in input_data_ids
3133
3140
  ]
3134
- IsLink.objects.bulk_create(links, ignore_conflicts=True)
3141
+ try:
3142
+ IsLink.objects.bulk_create(links, ignore_conflicts=True)
3143
+ except ProgrammingError as e:
3144
+ if "new row violates row-level security policy" in str(e):
3145
+ instance = setup_settings.instance
3146
+ available_spaces = instance.available_spaces
3147
+ if available_spaces is None:
3148
+ raise NoWriteAccess(
3149
+ f"You’re not allowed to write to the instance {instance.slug}.\n"
3150
+ "Please contact administrators of the instance if you need write access."
3151
+ ) from None
3152
+ write_access_spaces = (
3153
+ available_spaces["admin"] + available_spaces["write"]
3154
+ )
3155
+ no_write_access_spaces = {
3156
+ data_space
3157
+ for data in input_data
3158
+ if (data_space := data.space) not in write_access_spaces
3159
+ }
3160
+ if (run_space := run.space) not in write_access_spaces:
3161
+ no_write_access_spaces.add(run_space)
3162
+ if len(no_write_access_spaces) > 1:
3163
+ name_msg = ", ".join(
3164
+ f"'{space.name}'" for space in no_write_access_spaces
3165
+ )
3166
+ space_msg = "spaces"
3167
+ else:
3168
+ name_msg = f"'{no_write_access_spaces.pop().name}'"
3169
+ space_msg = "space"
3170
+ raise NoWriteAccess(
3171
+ f"You’re not allowed to write to the {space_msg} {name_msg}.\n"
3172
+ f"Please contact administrators of the {space_msg} if you need write access."
3173
+ ) from None
3174
+ else:
3175
+ raise e
3135
3176
 
3136
3177
 
3137
3178
  # privates currently dealt with separately
@@ -918,7 +918,7 @@ class BaseSQLRecord(models.Model, metaclass=Registry):
918
918
  ):
919
919
  raise NoWriteAccess(
920
920
  f"You’re not allowed to write to the space '{self.space.name}'.\n"
921
- "Please contact an administrator of the space if you need write access."
921
+ "Please contact administrators of the space if you need write access."
922
922
  ) from None
923
923
  else:
924
924
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lamindb
3
- Version: 1.11.0
3
+ Version: 1.11.1
4
4
  Summary: A data framework for biology.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Requires-Python: >=3.10,<3.14
@@ -129,7 +129,7 @@ Conversely, you can query artifacts by the script that created them.
129
129
  ln.Artifact.get(transform__key="create-fasta.py") # query artifact by transform key
130
130
  ```
131
131
 
132
- Data lineage is just one type of metadata to help analysis and model training through queries, validation, and annotation. Here is a more [comprehensive example](https://lamin.ai/laminlabs/lamindata/artifact/fgKBV8qdSnbIga0i).
132
+ Data lineage is just one type of metadata to help analysis and model training through queries, validation, and annotation. Here is a more [comprehensive example](https://lamin.ai/laminlabs/lamindata/artifact/9K1dteZ6Qx0EXK8g).
133
133
 
134
134
  <img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/6sofuDVvTANB0f480001.png" width="850">
135
135
 
@@ -1,4 +1,4 @@
1
- lamindb/__init__.py,sha256=iD3JsR1_pxWQ_61vYJRqY3W04strzBiwxhGMBksNvys,3241
1
+ lamindb/__init__.py,sha256=jO-XCxfKHm4hUoqFpHDOPFPoKbknvdkm0oImBWGod8A,3241
2
2
  lamindb/_finish.py,sha256=4KkFyb9d-GEGjDw_zDrnGt_bq3auQ_OQu0hV-2U73AQ,21355
3
3
  lamindb/_tracked.py,sha256=fls9yd7EEGO9Ni51kA_pcBkeLpzm2HZrWtwYGQequNE,4395
4
4
  lamindb/_view.py,sha256=GOKTfwnEaly9fdeWo9SlhYRc3UWEyLDmTlIUzjFXMYY,4960
@@ -13,7 +13,7 @@ lamindb/base/uids.py,sha256=cLBi5mIlsf1ltkTb17r1FLzlOjlGmjvsCygoVJHQ-A8,2116
13
13
  lamindb/base/users.py,sha256=8MSmAvCKoUF15YsDE6BGLBXsFWpfoEEg8iDTKZ7kD48,848
14
14
  lamindb/core/__init__.py,sha256=I9F-GugBMZwFLpUPb1MXyLfccIVAj021Gb_00h_18MY,633
15
15
  lamindb/core/_compat.py,sha256=NLnKk1qk4xdgMV-QwFDnBnbio02ujjlF86icvhpdv4c,2029
16
- lamindb/core/_context.py,sha256=5edP0M5_m8zgNXu7-1XaRLOv20i5LaWHBkEvMHsSiB0,40376
16
+ lamindb/core/_context.py,sha256=wPRNcQ0tPrwvYkYbHxZz0VzdxeBZEuorWOIqpucnbFk,40444
17
17
  lamindb/core/_mapped_collection.py,sha256=osquwC6ee0wJ_I6O-8AZwnQUa_r9zqa0MN82Q-nBI3Y,25746
18
18
  lamindb/core/_settings.py,sha256=519bOSopRb7_nE874KDJB263v1xFlk4TOqhBNNeO4yw,10992
19
19
  lamindb/core/_sync_git.py,sha256=Z7keuyS5X7CAj285sEbZIFExZF9mtjGH8DzKwz3xhHw,5881
@@ -120,7 +120,7 @@ lamindb/models/_from_values.py,sha256=ymR8b0Qa3ZiTFTIuMsFYiBNH16ggDPlYeFjCaFgGET
120
120
  lamindb/models/_is_versioned.py,sha256=zCnn5Z5HehBlKX-NXFhqfr3lbVOMRhlvG4ljtLbXl4A,7590
121
121
  lamindb/models/_label_manager.py,sha256=12RV8uEpWILGUkNHb7JMccF341ArmrIbHfI9KAo742Q,12118
122
122
  lamindb/models/_relations.py,sha256=zHYLujy9vkuB9jVq5844TpzLSP__iYNCQcsl-FzK1Jw,3700
123
- lamindb/models/artifact.py,sha256=V_uLsa73xNll7iFqUjJl0lAI1s7Q6qycG6ufWP4pvYo,123158
123
+ lamindb/models/artifact.py,sha256=L0DF6HFU1MXHXC3MqE7vWQrRefg4T9A5SFkzA4Sh-J8,125097
124
124
  lamindb/models/artifact_set.py,sha256=TfRxmuY9mRzkIeG_vWIDxq4_R_efnXuTbz4xxz7S5Kg,5389
125
125
  lamindb/models/can_curate.py,sha256=_w7k8-gPju7owHzX79phtcL7VRy7wAaz-90MzOz8UUQ,29313
126
126
  lamindb/models/collection.py,sha256=OqPhDppzCx2y7xEqtmV83el4iNrvOO1KvkE-y8ZEvm4,27372
@@ -133,7 +133,7 @@ lamindb/models/record.py,sha256=2eKEDqpiX5-aN2kUVXLuTVvQUspqQ5h10onbQM6Ta7g,1304
133
133
  lamindb/models/run.py,sha256=LVZ2z5QV4aVYYsqGcLmMfqvPpKj4EGGHVts_RR8_c-E,14443
134
134
  lamindb/models/save.py,sha256=gBt74RqfwgTa8PnTE153p17PruTAt6WGmGk9ZEBrojI,16719
135
135
  lamindb/models/schema.py,sha256=LQuPQhyLitloRGxq6DWZMHcR-xDZY1NctPHjrC6t1iw,49827
136
- lamindb/models/sqlrecord.py,sha256=3ueIE0_1CY8BUkHNigOhpsPf7WnulAytjEaINnOmS2I,72681
136
+ lamindb/models/sqlrecord.py,sha256=L_-60qCyWuG00IZvGiXA_bcVbYd2GKv-ax2TDQcn8IA,72679
137
137
  lamindb/models/storage.py,sha256=n7jth0RQ19K0W8ICbrAO942d5jBm1-h7DsrSjMJgAB0,15551
138
138
  lamindb/models/transform.py,sha256=FcIPqmSk1hahg2Cr8q6lm1kKpbdvu2JUceSlPIV9Dww,12780
139
139
  lamindb/models/ulabel.py,sha256=UznidEEoiIns_KetWgCbDejXuM5hmzF6F49yqf2kLpQ,9495
@@ -142,7 +142,7 @@ lamindb/setup/_switch.py,sha256=njZJN__JOhVrBFGClQG1wobdhJJp6l_XzPGKtKSCrfU,434
142
142
  lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
143
143
  lamindb/setup/errors/__init__.py,sha256=bAHTxOUJW1rm4zpF0Pvqkftn8W6iMGnQ-uyNBu13Nfg,171
144
144
  lamindb/setup/types/__init__.py,sha256=ATaosOi6q-cDWB52T69_sRmLMqj8cHfc-vljzZsrJNw,169
145
- lamindb-1.11.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
146
- lamindb-1.11.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
147
- lamindb-1.11.0.dist-info/METADATA,sha256=lda7anilPXNn2C-lxekpQAR_AekrD8gU6vYzCxp76TM,4865
148
- lamindb-1.11.0.dist-info/RECORD,,
145
+ lamindb-1.11.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
146
+ lamindb-1.11.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
147
+ lamindb-1.11.1.dist-info/METADATA,sha256=rrGmUwB5UIBBj-3k8HznNPlWCsAf2mHkQEK5aMSinUY,4865
148
+ lamindb-1.11.1.dist-info/RECORD,,