lamindb 0.69.2__py3-none-any.whl → 0.69.3__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/_artifact.py CHANGED
@@ -15,8 +15,7 @@ from lamindb_setup.core.types import UPathStr
15
15
  from lamindb_setup.core.upath import (
16
16
  create_path,
17
17
  extract_suffix_from_path,
18
- get_stat_dir_gs,
19
- get_stat_dir_s3,
18
+ get_stat_dir_cloud,
20
19
  get_stat_file_cloud,
21
20
  )
22
21
  from lnschema_core import Artifact, Run, Storage
@@ -192,10 +191,7 @@ def get_stat_or_artifact(
192
191
  if "ETag" in stat: # is file
193
192
  size, hash, hash_type = get_stat_file_cloud(stat)
194
193
  elif path.is_dir():
195
- if path.protocol == "s3":
196
- size, hash, hash_type, n_objects = get_stat_dir_s3(path)
197
- elif path.protocol == "gs":
198
- size, hash, hash_type, n_objects = get_stat_dir_gs(path)
194
+ size, hash, hash_type, n_objects = get_stat_dir_cloud(path)
199
195
  if hash is None:
200
196
  logger.warning(f"did not add hash for {path}")
201
197
  return size, hash, hash_type, n_objects
lamindb/_query_set.py CHANGED
@@ -243,7 +243,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
243
243
  self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
244
244
  ):
245
245
  """{}."""
246
- from ._validate import _validate
246
+ from ._can_validate import _validate
247
247
 
248
248
  return _validate(cls=self, values=values, field=field, **kwargs)
249
249
 
@@ -252,7 +252,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
252
252
  self, values: ListLike, field: Optional[Union[str, StrField]] = None, **kwargs
253
253
  ):
254
254
  """{}."""
255
- from ._validate import _inspect
255
+ from ._can_validate import _inspect
256
256
 
257
257
  return _inspect(cls=self, values=values, field=field, **kwargs)
258
258
 
@@ -261,7 +261,7 @@ class QuerySet(models.QuerySet, CanValidate, IsTree):
261
261
  self, values: Iterable, field: Optional[Union[str, StrField]] = None, **kwargs
262
262
  ):
263
263
  """{}."""
264
- from ._validate import _standardize
264
+ from ._can_validate import _standardize
265
265
 
266
266
  return _standardize(cls=self, values=values, field=field, **kwargs)
267
267
 
lamindb/core/__init__.py CHANGED
@@ -14,6 +14,9 @@ Registries:
14
14
  LabelManager
15
15
  IsTree
16
16
  IsVersioned
17
+ DataFrameAnnotator
18
+ AnnDataAnnotator
19
+ AnnotateLookup
17
20
  CanValidate
18
21
  HasParents
19
22
  InspectResult
@@ -50,6 +53,7 @@ from lnschema_core.models import (
50
53
  Registry,
51
54
  )
52
55
 
56
+ from lamindb._annotate import AnnDataAnnotator, AnnotateLookup, DataFrameAnnotator
53
57
  from lamindb._query_manager import QueryManager
54
58
  from lamindb._query_set import QuerySet, RecordsList
55
59
  from lamindb.core._feature_manager import FeatureManager
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lamindb
3
- Version: 0.69.2
3
+ Version: 0.69.3
4
4
  Summary: A data framework for biology.
5
5
  Author-email: Lamin Labs <open-source@lamin.ai>
6
6
  Requires-Python: >=3.8
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Requires-Dist: lnschema_core==0.64.1
13
- Requires-Dist: lamindb_setup==0.68.0
13
+ Requires-Dist: lamindb_setup==0.68.1
14
14
  Requires-Dist: lamin_utils==0.13.1
15
15
  Requires-Dist: lamin_cli==0.10.2
16
16
  Requires-Dist: rapidfuzz
@@ -26,7 +26,7 @@ Requires-Dist: urllib3<2 ; extra == "aws"
26
26
  Requires-Dist: aiobotocore[boto3]>=2.5.4,<3.0.0 ; extra == "aws"
27
27
  Requires-Dist: s3fs==2023.12.2 ; extra == "aws"
28
28
  Requires-Dist: fsspec[s3]==2023.12.2 ; extra == "aws"
29
- Requires-Dist: bionty==0.42.2 ; extra == "bionty"
29
+ Requires-Dist: bionty==0.42.4 ; extra == "bionty"
30
30
  Requires-Dist: pandas<2 ; extra == "dev"
31
31
  Requires-Dist: pre-commit ; extra == "dev"
32
32
  Requires-Dist: nox ; extra == "dev"
@@ -1,5 +1,7 @@
1
- lamindb/__init__.py,sha256=hJStNsXJq-qclYj7tDUz2t-4j5sDhkZdBen5URQ1_dA,2051
2
- lamindb/_artifact.py,sha256=3H8hemGysZLlyHkb02MEXCie1FluQ60LdGIBXOv13uc,35999
1
+ lamindb/__init__.py,sha256=Xy8yw0Woc26c9DxrgHP5c_UvVJpocigGwfCj8Ho_VZo,2108
2
+ lamindb/_annotate.py,sha256=k9Is43plKcQaMvGnzVw6OeWvZDWcSxw3FQ7nsQVDHzw,27744
3
+ lamindb/_artifact.py,sha256=RV36tcHMZ6wH6u65jOAQ_H4rfmFiIzZmAr8IY7kFhm0,35817
4
+ lamindb/_can_validate.py,sha256=w7lrUGTWldpvwaRiXBRrjfU_ZRidA7CooOu_r5MbocY,14569
3
5
  lamindb/_collection.py,sha256=03CQ0u8eCY_dx31pIT5ZMZsmxbbj6J5dJ9zUqJLrDGY,18427
4
6
  lamindb/_feature.py,sha256=ahRv87q1tcRLQ0UM5FA3KtcMQvIjW__fZq1yAdRAV7s,6728
5
7
  lamindb/_feature_set.py,sha256=G_Ss6mKh4D0Eji-xSfLRbKVFXwgUE82YOqIUmkV0CAA,8767
@@ -9,7 +11,7 @@ lamindb/_from_values.py,sha256=Ei11ml77Q1xubVekt2C4-mbox2-qnC7kP18B-LhCdSc,11886
9
11
  lamindb/_is_versioned.py,sha256=DXp5t-1DwErpqqMc9eb08kpQPCHOC2fNzaozMoBunR4,1337
10
12
  lamindb/_parents.py,sha256=pTDsW8HjQ_txFbPKrBU0WjjtCNH6sx2LASUuGWpJuYE,14742
11
13
  lamindb/_query_manager.py,sha256=lyYMEsstUQlns2H01oZXN5Ly0X6ug2VOPebyu9fHn4s,4008
12
- lamindb/_query_set.py,sha256=OXL5meaGoWHV5aPhT-LYUboPHFB0i1BPWfmvKTSeYF4,11306
14
+ lamindb/_query_set.py,sha256=DafHKwufvWQaWWSZsuxq24wpxae5Vfw7wD_3KCr7kLc,11318
13
15
  lamindb/_registry.py,sha256=vEsjn33BV2vxlanE3fyvDiy7AJoq7RKqEn_Sspo4_Dc,19232
14
16
  lamindb/_run.py,sha256=CvH6cAFUb83o38iOdpBsktF3JGAwmuZrDZ4p4wvUr0g,1853
15
17
  lamindb/_save.py,sha256=uIzHfNulzn7rpSKyAvUHT1OuN294OWFGC04gLmwrScY,11452
@@ -17,9 +19,8 @@ lamindb/_storage.py,sha256=VW8xq3VRv58-ciholvOdlcgvp_OIlLxx5GxLt-e2Irs,614
17
19
  lamindb/_transform.py,sha256=oZq-7MgyCs4m6Bj901HwDlbvF0JuvTpe3RxN0Zb8PgE,3515
18
20
  lamindb/_ulabel.py,sha256=euXsDPD7wC99oopLXVkT-vq7f3E6-zP4Z4akI-yh0aM,1913
19
21
  lamindb/_utils.py,sha256=LGdiW4k3GClLz65vKAVRkL6Tw-Gkx9DWAdez1jyA5bE,428
20
- lamindb/_validate.py,sha256=w7lrUGTWldpvwaRiXBRrjfU_ZRidA7CooOu_r5MbocY,14569
21
22
  lamindb/_view.py,sha256=yFMu4vnt0YqvN1q11boAkwigxCH1gdliDUSbzh3IuDw,2175
22
- lamindb/core/__init__.py,sha256=RYNsg2foVZRawpCW2J5J82vHZt6ub_Tze8wiDMxXCH8,988
23
+ lamindb/core/__init__.py,sha256=Mw4sI-xgnMXNsu84oYFQBZOF8mxxxhp6-e3BjTQqjlA,1131
23
24
  lamindb/core/_data.py,sha256=Q8w1I8pXXOaLVIxfjWBkLV6GGnzaQxCXamu9tplFgsA,17287
24
25
  lamindb/core/_feature_manager.py,sha256=II0nuxtjOdEtU_9a7eB18_Clw9d1n5k1JOqk_vHisRw,13940
25
26
  lamindb/core/_label_manager.py,sha256=zrWDSd2AkR6fKsGDxLSWqHC9fz9BcGlavPZEh92Wzjg,9063
@@ -45,13 +46,7 @@ lamindb/core/storage/file.py,sha256=WTeC4ENn_O6HEoinmTviB89W81UrJT3bSGtnpqPpIyE,
45
46
  lamindb/core/storage/object.py,sha256=MPUb2M8Fleq2j9x1Ryqr3BETmvsDKyf11Ifvbxd3NpA,1097
46
47
  lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
47
48
  lamindb/setup/core/__init__.py,sha256=LqIIvJNcONxkqjbnP6CUaP4d45Lbd6TSMAcXFp4C7_8,231
48
- lamindb/validation/__init__.py,sha256=AuonqVEhyYDXAoRqXnM9JweTUnYfAoExza8A5mQuM7Q,347
49
- lamindb/validation/_anndata_validator.py,sha256=lFCVLE4F4VN-9DTEwY9RUqSw8I2C6eTPYvXotGdKgvU,3782
50
- lamindb/validation/_lookup.py,sha256=HIGwk85e-c8yaVg4NkcvBdW4LIhnxwRI02km8uYOiFY,1545
51
- lamindb/validation/_register.py,sha256=UKsNVwXZhBl-spheZX1nkugjLF8g1yANT2vumcyzx6Y,9765
52
- lamindb/validation/_validate.py,sha256=FPQ4e_qDcP3tlKsYOVyo7-yb8nIbKyzoZHwgMbJJog0,4588
53
- lamindb/validation/_validator.py,sha256=6vzOfKIPQdA0pWwtXlRJWvjgLIjpivkBeLtgD6QODvY,7861
54
- lamindb-0.69.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
55
- lamindb-0.69.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
56
- lamindb-0.69.2.dist-info/METADATA,sha256=ly2Nwd236G0yxp4sX3DStxyzFFzqSv7sJuccmnc142Y,2856
57
- lamindb-0.69.2.dist-info/RECORD,,
49
+ lamindb-0.69.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
50
+ lamindb-0.69.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
51
+ lamindb-0.69.3.dist-info/METADATA,sha256=X4upu_QrdDsy861PJvPiQ_nw1f6N89NrVqN1Zxn6i14,2856
52
+ lamindb-0.69.3.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- """Validators built on LaminDB.
2
-
3
- Import the package::
4
-
5
- from lamindb.validation import Validator, AnnDataValidator
6
-
7
- This is the complete API reference:
8
-
9
- .. autosummary::
10
- :toctree: .
11
-
12
- Validator
13
- AnnDataValidator
14
- Lookup
15
- """
16
-
17
- from ._anndata_validator import AnnDataValidator
18
- from ._lookup import Lookup
19
- from ._validator import Validator
@@ -1,117 +0,0 @@
1
- from typing import Dict, Optional
2
-
3
- import anndata as ad
4
- from lnschema_core.types import FieldAttr
5
- from pandas.core.api import DataFrame as DataFrame
6
-
7
- import lamindb as ln
8
-
9
- from ._lookup import Lookup
10
- from ._register import register_artifact, register_labels
11
- from ._validate import validate_anndata
12
- from ._validator import ValidationError, Validator
13
-
14
-
15
- class AnnDataValidator(Validator):
16
- """Lamin AnnData validator.
17
-
18
- Args:
19
- adata: The AnnData object to validate.
20
- var_field: The registry field to validate variables index against.
21
- obs_fields: A dictionary mapping obs_column to registry_field.
22
- For example:
23
- {"cell_type_ontology_id": bt.CellType.ontology_id, "donor_id": ln.ULabel.name}
24
- using: The reference instance containing registries to validate against.
25
- """
26
-
27
- def __init__(
28
- self,
29
- adata: ad.AnnData,
30
- var_field: FieldAttr,
31
- obs_fields: Dict[str, FieldAttr],
32
- using: str = "default",
33
- verbosity: str = "hint",
34
- **kwargs,
35
- ) -> None:
36
- self._adata = adata
37
- self._var_field = var_field
38
- super().__init__(
39
- df=self._adata.obs,
40
- fields=obs_fields,
41
- using=using,
42
- verbosity=verbosity,
43
- **kwargs,
44
- )
45
- self._obs_fields = obs_fields
46
- self._register_variables()
47
-
48
- @property
49
- def var_field(self) -> FieldAttr:
50
- """Return the registry field to validate variables index against."""
51
- return self._var_field
52
-
53
- @property
54
- def obs_fields(self) -> Dict:
55
- """Return the obs fields to validate against."""
56
- return self._obs_fields
57
-
58
- def lookup(self, using: Optional[str] = None) -> Lookup:
59
- """Lookup features and labels."""
60
- fields = {
61
- **{"feature": ln.Feature.name, "variables": self.var_field},
62
- **self.obs_fields,
63
- }
64
- return Lookup(fields=fields, using=using or self._using)
65
-
66
- def _register_variables(self, validated_only: bool = True, **kwargs):
67
- """Register variable records."""
68
- self._kwargs.update(kwargs)
69
- register_labels(
70
- values=self._adata.var_names,
71
- field=self.var_field,
72
- feature_name="variables",
73
- using=self._using,
74
- validated_only=validated_only,
75
- kwargs=self._kwargs,
76
- )
77
-
78
- def validate(self, **kwargs) -> bool:
79
- """Validate variables and categorical observations."""
80
- self._kwargs.update(kwargs)
81
- self._validated = validate_anndata(
82
- self._adata,
83
- var_field=self.var_field,
84
- obs_fields=self.obs_fields,
85
- **self._kwargs,
86
- )
87
- return self._validated
88
-
89
- def register_labels(self, feature: str, validated_only: bool = True, **kwargs):
90
- """Register labels for a feature."""
91
- if feature == "variables":
92
- self._register_variables(validated_only=validated_only, **kwargs)
93
- else:
94
- super().register_labels(feature, validated_only, **kwargs)
95
-
96
- def register_artifact(self, description: str, **kwargs) -> ln.Artifact:
97
- """Register the validated AnnData and metadata.
98
-
99
- Args:
100
- description: Description of the AnnData object.
101
- **kwargs: Object level metadata.
102
-
103
- Returns:
104
- A registered artifact record.
105
- """
106
- self._kwargs.update(kwargs)
107
- if not self._validated:
108
- raise ValidationError("Please run `validate()` first!")
109
-
110
- self._artifact = register_artifact(
111
- self._adata,
112
- description=description,
113
- feature_field=self.var_field,
114
- fields=self.obs_fields,
115
- **self._kwargs,
116
- )
117
- return self._artifact
@@ -1,42 +0,0 @@
1
- from typing import Dict, Optional
2
-
3
- from lamin_utils import colors, logger
4
- from lnschema_core.types import FieldAttr
5
-
6
- import lamindb as ln
7
-
8
- from ._validate import get_registry_instance
9
-
10
-
11
- class Lookup:
12
- """Lookup features and labels from the reference instance."""
13
-
14
- def __init__(
15
- self, fields: Dict[str, FieldAttr], using: Optional[str] = None
16
- ) -> None:
17
- self._fields = fields
18
- self._using = None if using == "default" else using
19
- self._using_name = using or ln.setup.settings.instance.slug
20
- logger.debug(f"Lookup objects from the {colors.italic(self._using_name)}")
21
-
22
- def __getitem__(self, name):
23
- if name in self._fields:
24
- registry = self._fields[name].field.model
25
- if self._using == "public":
26
- return registry.public().lookup()
27
- else:
28
- return get_registry_instance(registry, self._using).lookup()
29
- raise AttributeError(
30
- f"'{self.__class__.__name__}' object has no attribute '{name}'"
31
- )
32
-
33
- def __repr__(self) -> str:
34
- if len(self._fields) > 0:
35
- fields = "\n ".join([str([key]) for key in self._fields.keys()])
36
- return (
37
- f"Lookup objects from the {colors.italic(self._using_name)}:\n {colors.green(fields)}\n\n"
38
- "Example:\n → categories = validator.lookup().['cell_type']\n"
39
- " → categories.alveolar_type_1_fibroblast_cell"
40
- )
41
- else:
42
- return colors.warning("No fields are found!")
@@ -1,265 +0,0 @@
1
- from typing import Dict, List, Optional, Tuple, Union
2
-
3
- import anndata as ad
4
- import pandas as pd
5
- from lamin_utils import colors, logger
6
- from lnschema_core.types import FieldAttr
7
-
8
- import lamindb as ln
9
-
10
- from ._validate import (
11
- check_registry_organism,
12
- get_registry_instance,
13
- standardize_and_inspect,
14
- )
15
-
16
-
17
- def register_artifact(
18
- data: Union[pd.DataFrame, ad.AnnData],
19
- description: str,
20
- fields: Dict[str, FieldAttr],
21
- feature_field: FieldAttr,
22
- **kwargs,
23
- ) -> ln.Artifact:
24
- """Register all metadata with an Artifact.
25
-
26
- Args:
27
- data: The DataFrame or AnnData object to register.
28
- description: A description of the artifact.
29
- fields: A dictionary mapping obs_column to registry_field.
30
- feature_field: The registry field to validate variables index against.
31
- kwargs: Additional keyword arguments to pass to the registry model.
32
-
33
- Returns:
34
- The registered Artifact.
35
- """
36
- if isinstance(data, ad.AnnData):
37
- artifact = ln.Artifact.from_anndata(data, description=description)
38
- artifact.n_observations = data.n_obs
39
- elif isinstance(data, pd.DataFrame):
40
- artifact = ln.Artifact.from_df(data, description=description)
41
- else:
42
- raise ValueError("data must be a DataFrame or AnnData object")
43
- artifact.save()
44
-
45
- feature_kwargs: Dict = {}
46
- organism = check_registry_organism(
47
- feature_field.field.model, kwargs.pop("organism", None)
48
- )
49
- if organism is not None:
50
- feature_kwargs["organism"] = organism
51
-
52
- if isinstance(data, ad.AnnData):
53
- artifact.features.add_from_anndata(var_field=feature_field, **feature_kwargs)
54
- else:
55
- artifact.features.add_from_df(field=feature_field, **feature_kwargs)
56
-
57
- features = ln.Feature.lookup().dict()
58
- for feature_name, field in fields.items():
59
- feature = features.get(feature_name)
60
- registry = field.field.model
61
- filter_kwargs = kwargs.copy()
62
- organism = check_registry_organism(registry, organism)
63
- if organism is not None:
64
- filter_kwargs["organism"] = organism
65
- df = data.obs if isinstance(data, ad.AnnData) else data
66
- labels = registry.from_values(df[feature_name], field=field, **filter_kwargs)
67
- artifact.labels.add(labels, feature)
68
-
69
- slug = ln.setup.settings.instance.slug
70
- logger.success(f"registered artifact in {colors.italic(slug)}")
71
- if ln.setup.settings.instance.is_remote:
72
- logger.info(f"🔗 https://lamin.ai/{slug}/artifact/{artifact.uid}")
73
-
74
- return artifact
75
-
76
-
77
- def register_labels(
78
- values: List[str],
79
- field: FieldAttr,
80
- feature_name: str,
81
- using: Optional[str] = None,
82
- validated_only: bool = True,
83
- kwargs: Optional[Dict] = None,
84
- df: Optional[pd.DataFrame] = None,
85
- ) -> None:
86
- """Register features or labels records in the default instance from the using instance.
87
-
88
- Args:
89
- values: A list of values to be registered as labels.
90
- field: The FieldAttr object representing the field for which labels are being registered.
91
- feature_name: The name of the feature to register.
92
- using: The name of the instance from which to transfer labels (if applicable).
93
- validated_only: If True, only register validated labels.
94
- kwargs: Additional keyword arguments to pass to the registry model.
95
- df: A DataFrame to register labels from.
96
- """
97
- filter_kwargs = {} if kwargs is None else kwargs.copy()
98
- registry = field.field.model
99
- if registry == ln.ULabel:
100
- validated_only = False
101
-
102
- organism = check_registry_organism(registry, filter_kwargs.pop("organism", None))
103
- if organism is not None:
104
- filter_kwargs["organism"] = organism
105
-
106
- verbosity = ln.settings.verbosity
107
- try:
108
- ln.settings.verbosity = "error"
109
- inspect_result_current = standardize_and_inspect(
110
- values=values, field=field, registry=registry, **filter_kwargs
111
- )
112
- if not inspect_result_current.non_validated:
113
- ln.settings.verbosity = verbosity
114
- return
115
-
116
- labels_registered: Dict = {"from public": [], "without reference": []}
117
-
118
- (
119
- labels_registered[f"from {using}"],
120
- non_validated_labels,
121
- ) = register_labels_from_using_instance(
122
- inspect_result_current.non_validated,
123
- field=field,
124
- using=using,
125
- kwargs=filter_kwargs,
126
- )
127
-
128
- public_records = (
129
- registry.from_values(non_validated_labels, field=field, **filter_kwargs)
130
- if non_validated_labels
131
- else []
132
- )
133
- ln.save(public_records)
134
- labels_registered["from public"] = [
135
- getattr(r, field.field.name) for r in public_records
136
- ]
137
- labels_registered["without reference"] = [
138
- i for i in non_validated_labels if i not in labels_registered["from public"]
139
- ]
140
-
141
- if not validated_only:
142
- non_validated_records = []
143
- if df is not None and registry == ln.Feature:
144
- non_validated_records = ln.Feature.from_df(df)
145
- else:
146
- if "organism" in filter_kwargs:
147
- filter_kwargs["organism"] = _register_organism(name=organism)
148
- for value in labels_registered["without reference"]:
149
- filter_kwargs[field.field.name] = value
150
- if registry == ln.Feature:
151
- filter_kwargs["type"] = "category"
152
- non_validated_records.append(registry(**filter_kwargs))
153
- ln.save(non_validated_records)
154
-
155
- if registry == ln.ULabel and field.field.name == "name":
156
- register_ulabels_with_parent(values, field=field, feature_name=feature_name)
157
- finally:
158
- ln.settings.verbosity = verbosity
159
-
160
- log_registered_labels(
161
- labels_registered,
162
- feature_name=feature_name,
163
- model_field=f"{registry.__name__}.{field.field.name}",
164
- validated_only=validated_only,
165
- )
166
-
167
-
168
- def log_registered_labels(
169
- labels_registered: Dict,
170
- feature_name: str,
171
- model_field: str,
172
- validated_only: bool = True,
173
- ) -> None:
174
- """Log the registered labels."""
175
- labels_type = "features" if feature_name == "feature" else "labels"
176
- model_field = colors.italic(model_field)
177
- for key, labels in labels_registered.items():
178
- if not labels:
179
- continue
180
-
181
- if key == "without reference" and validated_only:
182
- msg = colors.yellow(
183
- f"{len(labels)} non-validated {labels_type} are not registered with {model_field}: {labels}!"
184
- )
185
- lookup_print = f".lookup().['{feature_name}']"
186
- msg += f"\n → to lookup categories, use {lookup_print}"
187
- msg += (
188
- f"\n → to register, run {colors.yellow('register_features(validated_only=False)')}"
189
- if labels_type == "features"
190
- else f"\n → to register, set {colors.yellow('validated_only=False')}"
191
- )
192
- logger.warning(msg)
193
- else:
194
- key = "" if key == "without reference" else f"{colors.green(key)} "
195
- logger.success(
196
- f"registered {len(labels)} {labels_type} {key}with {model_field}: {labels}"
197
- )
198
-
199
-
200
- def register_ulabels_with_parent(
201
- values: List[str], field: FieldAttr, feature_name: str
202
- ) -> None:
203
- """Register a parent label for the given labels."""
204
- registry = field.field.model
205
- assert registry == ln.ULabel
206
- all_records = registry.from_values(values, field=field)
207
- is_feature = registry.filter(name=f"is_{feature_name}").one_or_none()
208
- if is_feature is None:
209
- is_feature = registry(name=f"is_{feature_name}")
210
- is_feature.save()
211
- is_feature.children.add(*all_records)
212
-
213
-
214
- def register_labels_from_using_instance(
215
- values: List[str],
216
- field: FieldAttr,
217
- using: Optional[str] = None,
218
- kwargs: Optional[Dict] = None,
219
- ) -> Tuple[List[str], List[str]]:
220
- """Register features or labels records from the using instance.
221
-
222
- Args:
223
- values: A list of values to be registered as labels.
224
- field: The FieldAttr object representing the field for which labels are being registered.
225
- using: The name of the instance from which to transfer labels (if applicable).
226
- kwargs: Additional keyword arguments to pass to the registry model.
227
-
228
- Returns:
229
- A tuple containing the list of registered labels and the list of non-registered labels.
230
- """
231
- kwargs = kwargs or {}
232
- labels_registered = []
233
- not_registered = values
234
-
235
- if using is not None and using != "default":
236
- registry = field.field.model
237
- registry_using = get_registry_instance(registry, using)
238
- inspect_result_using = standardize_and_inspect(
239
- values=values, field=field, registry=registry_using, **kwargs
240
- )
241
- labels_using = registry_using.filter(
242
- **{f"{field.field.name}__in": inspect_result_using.validated}
243
- ).all()
244
- for label_using in labels_using:
245
- label_using.save()
246
- labels_registered.append(getattr(label_using, field.field.name))
247
- not_registered = inspect_result_using.non_validated
248
-
249
- return labels_registered, not_registered
250
-
251
-
252
- def _register_organism(name: str):
253
- """Register an organism record."""
254
- import bionty as bt
255
-
256
- organism = bt.Organism.filter(name=name).one_or_none()
257
- if organism is None:
258
- organism = bt.Organism.from_public(name=name)
259
- if organism is None:
260
- raise ValueError(
261
- f"Organism '{name}' not found\n"
262
- f" → please register it: bt.Organism(name='{name}').save()"
263
- )
264
- organism.save()
265
- return organism