lamindb 0.76.8__py3-none-any.whl → 0.76.9__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.
Files changed (61) hide show
  1. lamindb/__init__.py +113 -113
  2. lamindb/_artifact.py +1205 -1205
  3. lamindb/_can_validate.py +579 -579
  4. lamindb/_collection.py +389 -387
  5. lamindb/_curate.py +1601 -1601
  6. lamindb/_feature.py +155 -155
  7. lamindb/_feature_set.py +242 -242
  8. lamindb/_filter.py +23 -23
  9. lamindb/_finish.py +256 -256
  10. lamindb/_from_values.py +382 -382
  11. lamindb/_is_versioned.py +40 -40
  12. lamindb/_parents.py +476 -476
  13. lamindb/_query_manager.py +125 -125
  14. lamindb/_query_set.py +362 -362
  15. lamindb/_record.py +649 -649
  16. lamindb/_run.py +57 -57
  17. lamindb/_save.py +308 -308
  18. lamindb/_storage.py +14 -14
  19. lamindb/_transform.py +127 -127
  20. lamindb/_ulabel.py +56 -56
  21. lamindb/_utils.py +9 -9
  22. lamindb/_view.py +72 -72
  23. lamindb/core/__init__.py +94 -94
  24. lamindb/core/_context.py +574 -574
  25. lamindb/core/_data.py +438 -438
  26. lamindb/core/_feature_manager.py +867 -867
  27. lamindb/core/_label_manager.py +253 -253
  28. lamindb/core/_mapped_collection.py +631 -597
  29. lamindb/core/_settings.py +187 -187
  30. lamindb/core/_sync_git.py +138 -138
  31. lamindb/core/_track_environment.py +27 -27
  32. lamindb/core/datasets/__init__.py +59 -59
  33. lamindb/core/datasets/_core.py +581 -571
  34. lamindb/core/datasets/_fake.py +36 -36
  35. lamindb/core/exceptions.py +90 -90
  36. lamindb/core/fields.py +12 -12
  37. lamindb/core/loaders.py +164 -164
  38. lamindb/core/schema.py +56 -56
  39. lamindb/core/storage/__init__.py +25 -25
  40. lamindb/core/storage/_anndata_accessor.py +740 -740
  41. lamindb/core/storage/_anndata_sizes.py +41 -41
  42. lamindb/core/storage/_backed_access.py +98 -98
  43. lamindb/core/storage/_tiledbsoma.py +204 -204
  44. lamindb/core/storage/_valid_suffixes.py +21 -21
  45. lamindb/core/storage/_zarr.py +110 -110
  46. lamindb/core/storage/objects.py +62 -62
  47. lamindb/core/storage/paths.py +172 -172
  48. lamindb/core/subsettings/__init__.py +12 -12
  49. lamindb/core/subsettings/_creation_settings.py +38 -38
  50. lamindb/core/subsettings/_transform_settings.py +21 -21
  51. lamindb/core/types.py +19 -19
  52. lamindb/core/versioning.py +158 -158
  53. lamindb/integrations/__init__.py +12 -12
  54. lamindb/integrations/_vitessce.py +107 -107
  55. lamindb/setup/__init__.py +14 -14
  56. lamindb/setup/core/__init__.py +4 -4
  57. {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/LICENSE +201 -201
  58. {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/METADATA +4 -4
  59. lamindb-0.76.9.dist-info/RECORD +60 -0
  60. {lamindb-0.76.8.dist-info → lamindb-0.76.9.dist-info}/WHEEL +1 -1
  61. lamindb-0.76.8.dist-info/RECORD +0 -60
lamindb/_transform.py CHANGED
@@ -1,127 +1,127 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from lamin_utils import logger
6
- from lamindb_setup.core._docs import doc_args
7
- from lnschema_core.models import Run, Transform
8
-
9
- from ._parents import _view_parents
10
- from ._run import delete_run_artifacts
11
- from .core.versioning import message_update_key_in_version_family, process_revises
12
-
13
- if TYPE_CHECKING:
14
- from lnschema_core.types import TransformType
15
-
16
-
17
- def __init__(transform: Transform, *args, **kwargs):
18
- if len(args) == len(transform._meta.concrete_fields):
19
- super(Transform, transform).__init__(*args, **kwargs)
20
- return None
21
- name: str | None = kwargs.pop("name") if "name" in kwargs else None
22
- key: str | None = kwargs.pop("key") if "key" in kwargs else None
23
- revises: Transform | None = kwargs.pop("revises") if "revises" in kwargs else None
24
- version: str | None = kwargs.pop("version") if "version" in kwargs else None
25
- type: TransformType | None = kwargs.pop("type") if "type" in kwargs else "pipeline"
26
- reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
27
- reference_type: str | None = (
28
- kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
- )
30
- if "is_new_version_of" in kwargs:
31
- logger.warning("`is_new_version_of` will be removed soon, please use `revises`")
32
- revises = kwargs.pop("is_new_version_of")
33
- # below is internal use that we'll hopefully be able to eliminate
34
- uid: str | None = kwargs.pop("uid") if "uid" in kwargs else None
35
- if not len(kwargs) == 0:
36
- raise ValueError(
37
- "Only name, key, version, type, revises, reference, "
38
- f"reference_type can be passed, but you passed: {kwargs}"
39
- )
40
- if revises is None:
41
- if key is not None:
42
- revises = (
43
- Transform.filter(key=key, is_latest=True)
44
- .order_by("-created_at")
45
- .first()
46
- )
47
- elif uid is not None:
48
- revises = (
49
- Transform.filter(uid__startswith=uid[:-4], is_latest=True)
50
- .order_by("-created_at")
51
- .first()
52
- )
53
- if revises is not None and uid is not None and uid == revises.uid:
54
- from ._record import init_self_from_db, update_attributes
55
-
56
- init_self_from_db(transform, revises)
57
- update_attributes(transform, {"name": name})
58
- return None
59
- if revises is not None and key is not None and revises.key != key:
60
- note = message_update_key_in_version_family(
61
- suid=revises.stem_uid,
62
- existing_key=revises.key,
63
- new_key=key,
64
- registry="Artifact",
65
- )
66
- raise ValueError(
67
- f"`key` is {key}, but `revises.key` is '{revises.key}'\n\n Either do *not* pass `key`.\n\n{note}"
68
- )
69
- new_uid, version, name, revises = process_revises(revises, version, name, Transform)
70
- # this is only because the user-facing constructor allows passing a uid
71
- # most others don't
72
- if uid is None:
73
- has_consciously_provided_uid = False
74
- uid = new_uid
75
- else:
76
- has_consciously_provided_uid = True
77
- super(Transform, transform).__init__(
78
- uid=uid,
79
- name=name,
80
- key=key,
81
- type=type,
82
- version=version,
83
- reference=reference,
84
- reference_type=reference_type,
85
- _has_consciously_provided_uid=has_consciously_provided_uid,
86
- revises=revises,
87
- )
88
-
89
-
90
- def delete(self) -> None:
91
- _source_code_artifact = None
92
- if self._source_code_artifact is not None:
93
- _source_code_artifact = self._source_code_artifact
94
- self._source_code_artifact = None
95
- self.save()
96
- if _source_code_artifact is not None:
97
- _source_code_artifact.delete(permanent=True)
98
- # query all runs and delete their artifacts
99
- runs = Run.filter(transform=self)
100
- for run in runs:
101
- delete_run_artifacts(run)
102
- # at this point, all artifacts have been taken care of
103
- # we can now leverage CASCADE delete
104
- super(Transform, self).delete()
105
-
106
-
107
- @property # type: ignore
108
- @doc_args(Transform.latest_run.__doc__)
109
- def latest_run(self) -> Run:
110
- """{}""" # noqa: D415
111
- return self.runs.order_by("-started_at").first()
112
-
113
-
114
- def view_lineage(self, with_successors: bool = False, distance: int = 5):
115
- return _view_parents(
116
- record=self,
117
- field="name",
118
- with_children=with_successors,
119
- distance=distance,
120
- attr_name="predecessors",
121
- )
122
-
123
-
124
- Transform.__init__ = __init__
125
- Transform.delete = delete
126
- Transform.latest_run = latest_run
127
- Transform.view_lineage = view_lineage
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from lamin_utils import logger
6
+ from lamindb_setup.core._docs import doc_args
7
+ from lnschema_core.models import Run, Transform
8
+
9
+ from ._parents import _view_parents
10
+ from ._run import delete_run_artifacts
11
+ from .core.versioning import message_update_key_in_version_family, process_revises
12
+
13
+ if TYPE_CHECKING:
14
+ from lnschema_core.types import TransformType
15
+
16
+
17
+ def __init__(transform: Transform, *args, **kwargs):
18
+ if len(args) == len(transform._meta.concrete_fields):
19
+ super(Transform, transform).__init__(*args, **kwargs)
20
+ return None
21
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
22
+ key: str | None = kwargs.pop("key") if "key" in kwargs else None
23
+ revises: Transform | None = kwargs.pop("revises") if "revises" in kwargs else None
24
+ version: str | None = kwargs.pop("version") if "version" in kwargs else None
25
+ type: TransformType | None = kwargs.pop("type") if "type" in kwargs else "pipeline"
26
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
27
+ reference_type: str | None = (
28
+ kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
+ )
30
+ if "is_new_version_of" in kwargs:
31
+ logger.warning("`is_new_version_of` will be removed soon, please use `revises`")
32
+ revises = kwargs.pop("is_new_version_of")
33
+ # below is internal use that we'll hopefully be able to eliminate
34
+ uid: str | None = kwargs.pop("uid") if "uid" in kwargs else None
35
+ if not len(kwargs) == 0:
36
+ raise ValueError(
37
+ "Only name, key, version, type, revises, reference, "
38
+ f"reference_type can be passed, but you passed: {kwargs}"
39
+ )
40
+ if revises is None:
41
+ if key is not None:
42
+ revises = (
43
+ Transform.filter(key=key, is_latest=True)
44
+ .order_by("-created_at")
45
+ .first()
46
+ )
47
+ elif uid is not None:
48
+ revises = (
49
+ Transform.filter(uid__startswith=uid[:-4], is_latest=True)
50
+ .order_by("-created_at")
51
+ .first()
52
+ )
53
+ if revises is not None and uid is not None and uid == revises.uid:
54
+ from ._record import init_self_from_db, update_attributes
55
+
56
+ init_self_from_db(transform, revises)
57
+ update_attributes(transform, {"name": name})
58
+ return None
59
+ if revises is not None and key is not None and revises.key != key:
60
+ note = message_update_key_in_version_family(
61
+ suid=revises.stem_uid,
62
+ existing_key=revises.key,
63
+ new_key=key,
64
+ registry="Artifact",
65
+ )
66
+ raise ValueError(
67
+ f"`key` is {key}, but `revises.key` is '{revises.key}'\n\n Either do *not* pass `key`.\n\n{note}"
68
+ )
69
+ new_uid, version, name, revises = process_revises(revises, version, name, Transform)
70
+ # this is only because the user-facing constructor allows passing a uid
71
+ # most others don't
72
+ if uid is None:
73
+ has_consciously_provided_uid = False
74
+ uid = new_uid
75
+ else:
76
+ has_consciously_provided_uid = True
77
+ super(Transform, transform).__init__(
78
+ uid=uid,
79
+ name=name,
80
+ key=key,
81
+ type=type,
82
+ version=version,
83
+ reference=reference,
84
+ reference_type=reference_type,
85
+ _has_consciously_provided_uid=has_consciously_provided_uid,
86
+ revises=revises,
87
+ )
88
+
89
+
90
+ def delete(self) -> None:
91
+ _source_code_artifact = None
92
+ if self._source_code_artifact is not None:
93
+ _source_code_artifact = self._source_code_artifact
94
+ self._source_code_artifact = None
95
+ self.save()
96
+ if _source_code_artifact is not None:
97
+ _source_code_artifact.delete(permanent=True)
98
+ # query all runs and delete their artifacts
99
+ runs = Run.filter(transform=self)
100
+ for run in runs:
101
+ delete_run_artifacts(run)
102
+ # at this point, all artifacts have been taken care of
103
+ # we can now leverage CASCADE delete
104
+ super(Transform, self).delete()
105
+
106
+
107
+ @property # type: ignore
108
+ @doc_args(Transform.latest_run.__doc__)
109
+ def latest_run(self) -> Run:
110
+ """{}""" # noqa: D415
111
+ return self.runs.order_by("-started_at").first()
112
+
113
+
114
+ def view_lineage(self, with_successors: bool = False, distance: int = 5):
115
+ return _view_parents(
116
+ record=self,
117
+ field="name",
118
+ with_children=with_successors,
119
+ distance=distance,
120
+ attr_name="predecessors",
121
+ )
122
+
123
+
124
+ Transform.__init__ = __init__
125
+ Transform.delete = delete
126
+ Transform.latest_run = latest_run
127
+ Transform.view_lineage = view_lineage
lamindb/_ulabel.py CHANGED
@@ -1,56 +1,56 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- import lamindb_setup as ln_setup
6
- from lamindb_setup.core._docs import doc_args
7
- from lnschema_core import ULabel
8
-
9
- from lamindb._utils import attach_func_to_class_method
10
-
11
- if TYPE_CHECKING:
12
- from lnschema_core.types import ListLike
13
-
14
-
15
- def __init__(self, *args, **kwargs):
16
- if len(args) == len(self._meta.concrete_fields):
17
- super(ULabel, self).__init__(*args, **kwargs)
18
- return None
19
- # now we proceed with the user-facing constructor
20
- if len(args) > 0:
21
- raise ValueError("Only one non-keyword arg allowed")
22
- name: str | None = kwargs.pop("name") if "name" in kwargs else None
23
- description: str | None = (
24
- kwargs.pop("description") if "description" in kwargs else None
25
- )
26
- reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
27
- reference_type: str | None = (
28
- kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
- )
30
- if len(kwargs) > 0:
31
- raise ValueError(
32
- "Only name, description, reference, reference_type are valid keyword arguments"
33
- )
34
- super(ULabel, self).__init__(
35
- name=name,
36
- description=description,
37
- reference=reference,
38
- reference_type=reference_type,
39
- )
40
-
41
-
42
- METHOD_NAMES = [
43
- "__init__",
44
- ]
45
-
46
- if ln_setup._TESTING:
47
- from inspect import signature
48
-
49
- SIGS = {
50
- name: signature(getattr(ULabel, name))
51
- for name in METHOD_NAMES
52
- if name != "__init__"
53
- }
54
-
55
- for name in METHOD_NAMES:
56
- attach_func_to_class_method(name, ULabel, globals())
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ import lamindb_setup as ln_setup
6
+ from lamindb_setup.core._docs import doc_args
7
+ from lnschema_core import ULabel
8
+
9
+ from lamindb._utils import attach_func_to_class_method
10
+
11
+ if TYPE_CHECKING:
12
+ from lnschema_core.types import ListLike
13
+
14
+
15
+ def __init__(self, *args, **kwargs):
16
+ if len(args) == len(self._meta.concrete_fields):
17
+ super(ULabel, self).__init__(*args, **kwargs)
18
+ return None
19
+ # now we proceed with the user-facing constructor
20
+ if len(args) > 0:
21
+ raise ValueError("Only one non-keyword arg allowed")
22
+ name: str | None = kwargs.pop("name") if "name" in kwargs else None
23
+ description: str | None = (
24
+ kwargs.pop("description") if "description" in kwargs else None
25
+ )
26
+ reference: str | None = kwargs.pop("reference") if "reference" in kwargs else None
27
+ reference_type: str | None = (
28
+ kwargs.pop("reference_type") if "reference_type" in kwargs else None
29
+ )
30
+ if len(kwargs) > 0:
31
+ raise ValueError(
32
+ "Only name, description, reference, reference_type are valid keyword arguments"
33
+ )
34
+ super(ULabel, self).__init__(
35
+ name=name,
36
+ description=description,
37
+ reference=reference,
38
+ reference_type=reference_type,
39
+ )
40
+
41
+
42
+ METHOD_NAMES = [
43
+ "__init__",
44
+ ]
45
+
46
+ if ln_setup._TESTING:
47
+ from inspect import signature
48
+
49
+ SIGS = {
50
+ name: signature(getattr(ULabel, name))
51
+ for name in METHOD_NAMES
52
+ if name != "__init__"
53
+ }
54
+
55
+ for name in METHOD_NAMES:
56
+ attach_func_to_class_method(name, ULabel, globals())
lamindb/_utils.py CHANGED
@@ -1,9 +1,9 @@
1
- def attach_func_to_class_method(func_name, cls, globals):
2
- implementation = globals[func_name]
3
- target = getattr(cls, func_name)
4
- # assigning the original class definition docstring
5
- # to the implementation only has an effect for regular methods
6
- # not for class methods
7
- # this is why we need @doc_args for class methods
8
- implementation.__doc__ = target.__doc__
9
- setattr(cls, func_name, implementation)
1
+ def attach_func_to_class_method(func_name, cls, globals):
2
+ implementation = globals[func_name]
3
+ target = getattr(cls, func_name)
4
+ # assigning the original class definition docstring
5
+ # to the implementation only has an effect for regular methods
6
+ # not for class methods
7
+ # this is why we need @doc_args for class methods
8
+ implementation.__doc__ = target.__doc__
9
+ setattr(cls, func_name, implementation)
lamindb/_view.py CHANGED
@@ -1,72 +1,72 @@
1
- from __future__ import annotations
2
-
3
- import builtins
4
- import importlib
5
- import inspect
6
-
7
- from lamin_utils import colors, logger
8
- from lamindb_setup import settings
9
- from lamindb_setup._init_instance import get_schema_module_name
10
- from lnschema_core import Record
11
-
12
- is_run_from_ipython = getattr(builtins, "__IPYTHON__", False)
13
-
14
-
15
- def view(
16
- n: int = 7, schema: str | None = None, registries: list[str] | None = None
17
- ) -> None:
18
- """View latest metadata state.
19
-
20
- Args:
21
- n: Display the last `n` rows of a registry.
22
- schema: Schema module to view. Default's to
23
- `None` and displays all schema modules.
24
- registries: List of Record names. Defaults to
25
- `None` and lists all registries.
26
-
27
- Examples:
28
- >>> ln.view()
29
- """
30
- if is_run_from_ipython:
31
- from IPython.display import display as show
32
- else:
33
- show = logger.print
34
-
35
- if schema is not None:
36
- schema_names = [schema]
37
- else:
38
- schema_names = ["core"] + list(settings.instance.schema)
39
-
40
- for schema_name in schema_names:
41
- schema_module = importlib.import_module(get_schema_module_name(schema_name))
42
-
43
- all_registries = {
44
- registry
45
- for registry in schema_module.__dict__.values()
46
- if inspect.isclass(registry)
47
- and issubclass(registry, Record)
48
- and registry is not Record
49
- }
50
- if registries is not None:
51
- filtered_registries = {
52
- registry
53
- for registry in all_registries
54
- if registry.__name__ in registries
55
- }
56
- else:
57
- filtered_registries = all_registries
58
- if len(schema_names) > 1:
59
- section = f"* module: {colors.green(colors.bold(schema_name))} *"
60
- section_no_color = f"* module: {schema_name} *"
61
- logger.print("*" * len(section_no_color))
62
- logger.print(section)
63
- logger.print("*" * len(section_no_color))
64
- for registry in sorted(filtered_registries, key=lambda x: x.__name__):
65
- if hasattr(registry, "updated_at"):
66
- df = registry.filter().order_by("-updated_at")[:n].df()
67
- else:
68
- # need to adjust in the future
69
- df = registry.df().iloc[-n:]
70
- if df.shape[0] > 0:
71
- logger.print(colors.blue(colors.bold(registry.__name__)))
72
- show(df)
1
+ from __future__ import annotations
2
+
3
+ import builtins
4
+ import importlib
5
+ import inspect
6
+
7
+ from lamin_utils import colors, logger
8
+ from lamindb_setup import settings
9
+ from lamindb_setup._init_instance import get_schema_module_name
10
+ from lnschema_core import Record
11
+
12
+ is_run_from_ipython = getattr(builtins, "__IPYTHON__", False)
13
+
14
+
15
+ def view(
16
+ n: int = 7, schema: str | None = None, registries: list[str] | None = None
17
+ ) -> None:
18
+ """View latest metadata state.
19
+
20
+ Args:
21
+ n: Display the last `n` rows of a registry.
22
+ schema: Schema module to view. Default's to
23
+ `None` and displays all schema modules.
24
+ registries: List of Record names. Defaults to
25
+ `None` and lists all registries.
26
+
27
+ Examples:
28
+ >>> ln.view()
29
+ """
30
+ if is_run_from_ipython:
31
+ from IPython.display import display as show
32
+ else:
33
+ show = logger.print
34
+
35
+ if schema is not None:
36
+ schema_names = [schema]
37
+ else:
38
+ schema_names = ["core"] + list(settings.instance.schema)
39
+
40
+ for schema_name in schema_names:
41
+ schema_module = importlib.import_module(get_schema_module_name(schema_name))
42
+
43
+ all_registries = {
44
+ registry
45
+ for registry in schema_module.__dict__.values()
46
+ if inspect.isclass(registry)
47
+ and issubclass(registry, Record)
48
+ and registry is not Record
49
+ }
50
+ if registries is not None:
51
+ filtered_registries = {
52
+ registry
53
+ for registry in all_registries
54
+ if registry.__name__ in registries
55
+ }
56
+ else:
57
+ filtered_registries = all_registries
58
+ if len(schema_names) > 1:
59
+ section = f"* module: {colors.green(colors.bold(schema_name))} *"
60
+ section_no_color = f"* module: {schema_name} *"
61
+ logger.print("*" * len(section_no_color))
62
+ logger.print(section)
63
+ logger.print("*" * len(section_no_color))
64
+ for registry in sorted(filtered_registries, key=lambda x: x.__name__):
65
+ if hasattr(registry, "updated_at"):
66
+ df = registry.filter().order_by("-updated_at")[:n].df()
67
+ else:
68
+ # need to adjust in the future
69
+ df = registry.df().iloc[-n:]
70
+ if df.shape[0] > 0:
71
+ logger.print(colors.blue(colors.bold(registry.__name__)))
72
+ show(df)