lamindb 0.76.8__py3-none-any.whl → 0.76.10__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 (62) hide show
  1. lamindb/__init__.py +114 -113
  2. lamindb/_artifact.py +1206 -1205
  3. lamindb/_can_validate.py +621 -579
  4. lamindb/_collection.py +390 -387
  5. lamindb/_curate.py +1603 -1601
  6. lamindb/_feature.py +155 -155
  7. lamindb/_feature_set.py +244 -242
  8. lamindb/_filter.py +23 -23
  9. lamindb/_finish.py +250 -256
  10. lamindb/_from_values.py +403 -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 +364 -362
  15. lamindb/_record.py +668 -649
  16. lamindb/_run.py +60 -57
  17. lamindb/_save.py +310 -308
  18. lamindb/_storage.py +14 -14
  19. lamindb/_transform.py +130 -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 +590 -574
  25. lamindb/core/_data.py +510 -438
  26. lamindb/core/_django.py +209 -0
  27. lamindb/core/_feature_manager.py +994 -867
  28. lamindb/core/_label_manager.py +289 -253
  29. lamindb/core/_mapped_collection.py +631 -597
  30. lamindb/core/_settings.py +188 -187
  31. lamindb/core/_sync_git.py +138 -138
  32. lamindb/core/_track_environment.py +27 -27
  33. lamindb/core/datasets/__init__.py +59 -59
  34. lamindb/core/datasets/_core.py +581 -571
  35. lamindb/core/datasets/_fake.py +36 -36
  36. lamindb/core/exceptions.py +90 -90
  37. lamindb/core/fields.py +12 -12
  38. lamindb/core/loaders.py +164 -164
  39. lamindb/core/schema.py +56 -56
  40. lamindb/core/storage/__init__.py +25 -25
  41. lamindb/core/storage/_anndata_accessor.py +741 -740
  42. lamindb/core/storage/_anndata_sizes.py +41 -41
  43. lamindb/core/storage/_backed_access.py +98 -98
  44. lamindb/core/storage/_tiledbsoma.py +204 -204
  45. lamindb/core/storage/_valid_suffixes.py +21 -21
  46. lamindb/core/storage/_zarr.py +110 -110
  47. lamindb/core/storage/objects.py +62 -62
  48. lamindb/core/storage/paths.py +172 -172
  49. lamindb/core/subsettings/__init__.py +12 -12
  50. lamindb/core/subsettings/_creation_settings.py +38 -38
  51. lamindb/core/subsettings/_transform_settings.py +21 -21
  52. lamindb/core/types.py +19 -19
  53. lamindb/core/versioning.py +146 -158
  54. lamindb/integrations/__init__.py +12 -12
  55. lamindb/integrations/_vitessce.py +107 -107
  56. lamindb/setup/__init__.py +14 -14
  57. lamindb/setup/core/__init__.py +4 -4
  58. {lamindb-0.76.8.dist-info → lamindb-0.76.10.dist-info}/LICENSE +201 -201
  59. {lamindb-0.76.8.dist-info → lamindb-0.76.10.dist-info}/METADATA +8 -8
  60. lamindb-0.76.10.dist-info/RECORD +61 -0
  61. {lamindb-0.76.8.dist-info → lamindb-0.76.10.dist-info}/WHEEL +1 -1
  62. lamindb-0.76.8.dist-info/RECORD +0 -60
@@ -1,62 +1,62 @@
1
- from __future__ import annotations
2
-
3
- from pathlib import PurePosixPath
4
- from typing import TYPE_CHECKING
5
-
6
- from anndata import AnnData
7
- from pandas import DataFrame
8
-
9
- if TYPE_CHECKING:
10
- from lamindb_setup.core.types import UPathStr
11
-
12
-
13
- def _mudata_is_installed():
14
- try:
15
- import mudata
16
- except ImportError:
17
- return False
18
- return True
19
-
20
-
21
- def infer_suffix(dmem, adata_format: str | None = None):
22
- """Infer LaminDB storage file suffix from a data object."""
23
- if isinstance(dmem, AnnData):
24
- if adata_format is not None:
25
- if adata_format not in {"h5ad", "zarr", "anndata.zarr"}:
26
- raise ValueError(
27
- "Error when specifying AnnData storage format, it should be"
28
- f" 'h5ad', 'zarr', not '{adata_format}'. Check 'format'"
29
- " or the suffix of 'key'."
30
- )
31
- return "." + adata_format
32
- return ".h5ad"
33
- elif isinstance(dmem, DataFrame):
34
- return ".parquet"
35
- else:
36
- if _mudata_is_installed():
37
- from mudata import MuData
38
-
39
- if isinstance(dmem, MuData):
40
- return ".h5mu"
41
- raise NotImplementedError
42
-
43
-
44
- def write_to_disk(dmem, filepath: UPathStr):
45
- if isinstance(dmem, AnnData):
46
- suffix = PurePosixPath(filepath).suffix
47
- if suffix == ".h5ad":
48
- dmem.write_h5ad(filepath)
49
- elif suffix == ".zarr":
50
- dmem.write_zarr(filepath)
51
- else:
52
- raise NotImplementedError
53
- elif isinstance(dmem, DataFrame):
54
- dmem.to_parquet(filepath)
55
- else:
56
- if _mudata_is_installed():
57
- from mudata import MuData
58
-
59
- if isinstance(dmem, MuData):
60
- dmem.write(filepath)
61
- return
62
- raise NotImplementedError
1
+ from __future__ import annotations
2
+
3
+ from pathlib import PurePosixPath
4
+ from typing import TYPE_CHECKING
5
+
6
+ from anndata import AnnData
7
+ from pandas import DataFrame
8
+
9
+ if TYPE_CHECKING:
10
+ from lamindb_setup.core.types import UPathStr
11
+
12
+
13
+ def _mudata_is_installed():
14
+ try:
15
+ import mudata
16
+ except ImportError:
17
+ return False
18
+ return True
19
+
20
+
21
+ def infer_suffix(dmem, adata_format: str | None = None):
22
+ """Infer LaminDB storage file suffix from a data object."""
23
+ if isinstance(dmem, AnnData):
24
+ if adata_format is not None:
25
+ if adata_format not in {"h5ad", "zarr", "anndata.zarr"}:
26
+ raise ValueError(
27
+ "Error when specifying AnnData storage format, it should be"
28
+ f" 'h5ad', 'zarr', not '{adata_format}'. Check 'format'"
29
+ " or the suffix of 'key'."
30
+ )
31
+ return "." + adata_format
32
+ return ".h5ad"
33
+ elif isinstance(dmem, DataFrame):
34
+ return ".parquet"
35
+ else:
36
+ if _mudata_is_installed():
37
+ from mudata import MuData
38
+
39
+ if isinstance(dmem, MuData):
40
+ return ".h5mu"
41
+ raise NotImplementedError
42
+
43
+
44
+ def write_to_disk(dmem, filepath: UPathStr):
45
+ if isinstance(dmem, AnnData):
46
+ suffix = PurePosixPath(filepath).suffix
47
+ if suffix == ".h5ad":
48
+ dmem.write_h5ad(filepath)
49
+ elif suffix == ".zarr":
50
+ dmem.write_zarr(filepath)
51
+ else:
52
+ raise NotImplementedError
53
+ elif isinstance(dmem, DataFrame):
54
+ dmem.to_parquet(filepath)
55
+ else:
56
+ if _mudata_is_installed():
57
+ from mudata import MuData
58
+
59
+ if isinstance(dmem, MuData):
60
+ dmem.write(filepath)
61
+ return
62
+ raise NotImplementedError
@@ -1,172 +1,172 @@
1
- from __future__ import annotations
2
-
3
- import shutil
4
- from typing import TYPE_CHECKING
5
-
6
- import anndata as ad
7
- import pandas as pd
8
- from lamin_utils import logger
9
- from lamindb_setup.core import StorageSettings
10
- from lamindb_setup.core.upath import (
11
- LocalPathClasses,
12
- UPath,
13
- create_path,
14
- infer_filesystem,
15
- )
16
- from lnschema_core.models import Artifact, Storage
17
-
18
- from lamindb.core._settings import settings
19
-
20
- if TYPE_CHECKING:
21
- from pathlib import Path
22
-
23
- from lamindb_setup.core.types import UPathStr
24
-
25
-
26
- AUTO_KEY_PREFIX = ".lamindb/"
27
-
28
-
29
- # add type annotations back asap when re-organizing the module
30
- def auto_storage_key_from_artifact(artifact: Artifact):
31
- if artifact.key is None or artifact._key_is_virtual:
32
- is_dir = artifact.n_objects is not None
33
- return auto_storage_key_from_artifact_uid(artifact.uid, artifact.suffix, is_dir)
34
- else:
35
- return artifact.key
36
-
37
-
38
- def auto_storage_key_from_artifact_uid(uid: str, suffix: str, is_dir: bool) -> str:
39
- assert isinstance(suffix, str) # noqa: S101 Suffix cannot be None.
40
- if is_dir:
41
- uid_storage = uid[:16] # 16 chars, leave 4 chars for versioning
42
- else:
43
- uid_storage = uid
44
- storage_key = f"{AUTO_KEY_PREFIX}{uid_storage}{suffix}"
45
- return storage_key
46
-
47
-
48
- def check_path_is_child_of_root(path: Path | UPath, root: Path | UPath | None) -> bool:
49
- # str is needed to eliminate UPath storage_options
50
- # from the equality checks below
51
- path = UPath(str(path))
52
- root = UPath(str(root))
53
- return root.resolve() in path.resolve().parents
54
-
55
-
56
- # returns filepath and root of the storage
57
- def attempt_accessing_path(
58
- artifact: Artifact,
59
- storage_key: str,
60
- using_key: str | None = None,
61
- access_token: str | None = None,
62
- ) -> tuple[UPath, StorageSettings]:
63
- # check whether the file is in the default db and whether storage
64
- # matches default storage
65
- if (
66
- artifact._state.db in ("default", None)
67
- and artifact.storage_id == settings._storage_settings.id
68
- ):
69
- if access_token is None:
70
- storage_settings = settings._storage_settings
71
- else:
72
- storage_settings = StorageSettings(
73
- settings.storage.root, access_token=access_token
74
- )
75
- else:
76
- if artifact._state.db not in ("default", None) and using_key is None:
77
- storage = Storage.using(artifact._state.db).get(id=artifact.storage_id)
78
- else:
79
- storage = Storage.objects.using(using_key).get(id=artifact.storage_id)
80
- # find a better way than passing None to instance_settings in the future!
81
- storage_settings = StorageSettings(storage.root, access_token=access_token)
82
- path = storage_settings.key_to_filepath(storage_key)
83
- return path, storage_settings
84
-
85
-
86
- def filepath_from_artifact(
87
- artifact: Artifact, using_key: str | None = None
88
- ) -> tuple[UPath, StorageSettings | None]:
89
- if hasattr(artifact, "_local_filepath") and artifact._local_filepath is not None:
90
- return artifact._local_filepath.resolve(), None
91
- storage_key = auto_storage_key_from_artifact(artifact)
92
- path, storage_settings = attempt_accessing_path(
93
- artifact, storage_key, using_key=using_key
94
- )
95
- return path, storage_settings
96
-
97
-
98
- # virtual key is taken into consideration
99
- # only if the version is latest
100
- def _cache_key_from_artifact_storage(
101
- artifact: Artifact, storage_settings: StorageSettings | None
102
- ):
103
- cache_key = None
104
- if (
105
- artifact._key_is_virtual
106
- and artifact.key is not None
107
- and storage_settings is not None
108
- and artifact.is_latest
109
- ):
110
- cache_key = (storage_settings.root / artifact.key).path
111
- return cache_key
112
-
113
-
114
- # return filepath and cache_key if needed
115
- def filepath_cache_key_from_artifact(
116
- artifact: Artifact, using_key: str | None = None
117
- ) -> tuple[UPath, str | None]:
118
- filepath, storage_settings = filepath_from_artifact(artifact, using_key)
119
- if isinstance(filepath, LocalPathClasses):
120
- return filepath, None
121
- cache_key = _cache_key_from_artifact_storage(artifact, storage_settings)
122
- return filepath, cache_key
123
-
124
-
125
- def store_file_or_folder(
126
- local_path: UPathStr, storage_path: UPath, print_progress: bool = True
127
- ) -> None:
128
- """Store file or folder (localpath) at storagepath."""
129
- local_path = UPath(local_path)
130
- if not isinstance(storage_path, LocalPathClasses):
131
- # this uploads files and directories
132
- create_folder = False if local_path.is_dir() else None
133
- storage_path.upload_from(
134
- local_path, create_folder=create_folder, print_progress=print_progress
135
- )
136
- else: # storage path is local
137
- if local_path.resolve().as_posix() == storage_path.resolve().as_posix():
138
- return None
139
- storage_path.parent.mkdir(parents=True, exist_ok=True)
140
- if local_path.is_file():
141
- shutil.copyfile(local_path, storage_path)
142
- else:
143
- if storage_path.exists():
144
- shutil.rmtree(storage_path)
145
- shutil.copytree(local_path, storage_path)
146
-
147
-
148
- def delete_storage_using_key(
149
- artifact: Artifact, storage_key: str, using_key: str | None
150
- ):
151
- filepath, _ = attempt_accessing_path(artifact, storage_key, using_key=using_key)
152
- delete_storage(filepath)
153
-
154
-
155
- def delete_storage(
156
- storagepath: Path, raise_file_not_found_error: bool = True
157
- ) -> None | str:
158
- """Delete arbitrary artifact."""
159
- if storagepath.is_file():
160
- storagepath.unlink()
161
- elif storagepath.is_dir():
162
- if isinstance(storagepath, LocalPathClasses) or not isinstance(
163
- storagepath, UPath
164
- ):
165
- shutil.rmtree(storagepath)
166
- else:
167
- storagepath.rmdir()
168
- elif raise_file_not_found_error:
169
- raise FileNotFoundError(f"{storagepath} is not an existing path!")
170
- else:
171
- logger.warning(f"{storagepath} is not an existing path!")
172
- return None
1
+ from __future__ import annotations
2
+
3
+ import shutil
4
+ from typing import TYPE_CHECKING
5
+
6
+ import anndata as ad
7
+ import pandas as pd
8
+ from lamin_utils import logger
9
+ from lamindb_setup.core import StorageSettings
10
+ from lamindb_setup.core.upath import (
11
+ LocalPathClasses,
12
+ UPath,
13
+ create_path,
14
+ infer_filesystem,
15
+ )
16
+ from lnschema_core.models import Artifact, Storage
17
+
18
+ from lamindb.core._settings import settings
19
+
20
+ if TYPE_CHECKING:
21
+ from pathlib import Path
22
+
23
+ from lamindb_setup.core.types import UPathStr
24
+
25
+
26
+ AUTO_KEY_PREFIX = ".lamindb/"
27
+
28
+
29
+ # add type annotations back asap when re-organizing the module
30
+ def auto_storage_key_from_artifact(artifact: Artifact):
31
+ if artifact.key is None or artifact._key_is_virtual:
32
+ is_dir = artifact.n_objects is not None
33
+ return auto_storage_key_from_artifact_uid(artifact.uid, artifact.suffix, is_dir)
34
+ else:
35
+ return artifact.key
36
+
37
+
38
+ def auto_storage_key_from_artifact_uid(uid: str, suffix: str, is_dir: bool) -> str:
39
+ assert isinstance(suffix, str) # noqa: S101 Suffix cannot be None.
40
+ if is_dir:
41
+ uid_storage = uid[:16] # 16 chars, leave 4 chars for versioning
42
+ else:
43
+ uid_storage = uid
44
+ storage_key = f"{AUTO_KEY_PREFIX}{uid_storage}{suffix}"
45
+ return storage_key
46
+
47
+
48
+ def check_path_is_child_of_root(path: Path | UPath, root: Path | UPath | None) -> bool:
49
+ # str is needed to eliminate UPath storage_options
50
+ # from the equality checks below
51
+ path = UPath(str(path))
52
+ root = UPath(str(root))
53
+ return root.resolve() in path.resolve().parents
54
+
55
+
56
+ # returns filepath and root of the storage
57
+ def attempt_accessing_path(
58
+ artifact: Artifact,
59
+ storage_key: str,
60
+ using_key: str | None = None,
61
+ access_token: str | None = None,
62
+ ) -> tuple[UPath, StorageSettings]:
63
+ # check whether the file is in the default db and whether storage
64
+ # matches default storage
65
+ if (
66
+ artifact._state.db in ("default", None)
67
+ and artifact.storage_id == settings._storage_settings.id
68
+ ):
69
+ if access_token is None:
70
+ storage_settings = settings._storage_settings
71
+ else:
72
+ storage_settings = StorageSettings(
73
+ settings.storage.root, access_token=access_token
74
+ )
75
+ else:
76
+ if artifact._state.db not in ("default", None) and using_key is None:
77
+ storage = Storage.using(artifact._state.db).get(id=artifact.storage_id)
78
+ else:
79
+ storage = Storage.objects.using(using_key).get(id=artifact.storage_id)
80
+ # find a better way than passing None to instance_settings in the future!
81
+ storage_settings = StorageSettings(storage.root, access_token=access_token)
82
+ path = storage_settings.key_to_filepath(storage_key)
83
+ return path, storage_settings
84
+
85
+
86
+ def filepath_from_artifact(
87
+ artifact: Artifact, using_key: str | None = None
88
+ ) -> tuple[UPath, StorageSettings | None]:
89
+ if hasattr(artifact, "_local_filepath") and artifact._local_filepath is not None:
90
+ return artifact._local_filepath.resolve(), None
91
+ storage_key = auto_storage_key_from_artifact(artifact)
92
+ path, storage_settings = attempt_accessing_path(
93
+ artifact, storage_key, using_key=using_key
94
+ )
95
+ return path, storage_settings
96
+
97
+
98
+ # virtual key is taken into consideration
99
+ # only if the version is latest
100
+ def _cache_key_from_artifact_storage(
101
+ artifact: Artifact, storage_settings: StorageSettings | None
102
+ ):
103
+ cache_key = None
104
+ if (
105
+ artifact._key_is_virtual
106
+ and artifact.key is not None
107
+ and storage_settings is not None
108
+ and artifact.is_latest
109
+ ):
110
+ cache_key = (storage_settings.root / artifact.key).path
111
+ return cache_key
112
+
113
+
114
+ # return filepath and cache_key if needed
115
+ def filepath_cache_key_from_artifact(
116
+ artifact: Artifact, using_key: str | None = None
117
+ ) -> tuple[UPath, str | None]:
118
+ filepath, storage_settings = filepath_from_artifact(artifact, using_key)
119
+ if isinstance(filepath, LocalPathClasses):
120
+ return filepath, None
121
+ cache_key = _cache_key_from_artifact_storage(artifact, storage_settings)
122
+ return filepath, cache_key
123
+
124
+
125
+ def store_file_or_folder(
126
+ local_path: UPathStr, storage_path: UPath, print_progress: bool = True
127
+ ) -> None:
128
+ """Store file or folder (localpath) at storagepath."""
129
+ local_path = UPath(local_path)
130
+ if not isinstance(storage_path, LocalPathClasses):
131
+ # this uploads files and directories
132
+ create_folder = False if local_path.is_dir() else None
133
+ storage_path.upload_from(
134
+ local_path, create_folder=create_folder, print_progress=print_progress
135
+ )
136
+ else: # storage path is local
137
+ if local_path.resolve().as_posix() == storage_path.resolve().as_posix():
138
+ return None
139
+ storage_path.parent.mkdir(parents=True, exist_ok=True)
140
+ if local_path.is_file():
141
+ shutil.copyfile(local_path, storage_path)
142
+ else:
143
+ if storage_path.exists():
144
+ shutil.rmtree(storage_path)
145
+ shutil.copytree(local_path, storage_path)
146
+
147
+
148
+ def delete_storage_using_key(
149
+ artifact: Artifact, storage_key: str, using_key: str | None
150
+ ):
151
+ filepath, _ = attempt_accessing_path(artifact, storage_key, using_key=using_key)
152
+ delete_storage(filepath)
153
+
154
+
155
+ def delete_storage(
156
+ storagepath: Path, raise_file_not_found_error: bool = True
157
+ ) -> None | str:
158
+ """Delete arbitrary artifact."""
159
+ if storagepath.is_file():
160
+ storagepath.unlink()
161
+ elif storagepath.is_dir():
162
+ if isinstance(storagepath, LocalPathClasses) or not isinstance(
163
+ storagepath, UPath
164
+ ):
165
+ shutil.rmtree(storagepath)
166
+ else:
167
+ storagepath.rmdir()
168
+ elif raise_file_not_found_error:
169
+ raise FileNotFoundError(f"{storagepath} is not an existing path!")
170
+ else:
171
+ logger.warning(f"{storagepath} is not an existing path!")
172
+ return None
@@ -1,12 +1,12 @@
1
- """Sub settings.
2
-
3
- .. autosummary::
4
- :toctree: .
5
-
6
- TransformSettings
7
- CreationSettings
8
-
9
- """
10
-
11
- from ._creation_settings import CreationSettings
12
- from ._transform_settings import TransformSettings
1
+ """Sub settings.
2
+
3
+ .. autosummary::
4
+ :toctree: .
5
+
6
+ TransformSettings
7
+ CreationSettings
8
+
9
+ """
10
+
11
+ from ._creation_settings import CreationSettings
12
+ from ._transform_settings import TransformSettings
@@ -1,38 +1,38 @@
1
- from typing import Literal
2
-
3
-
4
- class CreationSettings:
5
- artifact_if_hash_exists: Literal[
6
- "warn_return_existing", "error", "warn_create_new"
7
- ] = "warn_return_existing"
8
- """Behavior if file hash exists (default `"warn_return_existing"`).
9
-
10
- One of `["warn_return_existing", "error", "warn_create_new"]`.
11
-
12
- FAQ: :doc:`/faq/idempotency`
13
- """
14
- artifact_skip_size_hash: bool = False
15
- """To speed up registering high numbers of files (default `False`).
16
-
17
- This bypasses queries for size and hash to AWS & GCP.
18
-
19
- It speeds up file creation by about a factor 100.
20
- """
21
- search_names: bool = True
22
- """To speed up creating records (default `True`).
23
-
24
- If `True`, search for alternative names.
25
-
26
- FAQ: :doc:`/faq/idempotency`
27
- """
28
- artifact_silence_missing_run_warning: bool = False
29
- """Silence warning about missing run & transform during artifact creation."""
30
- _artifact_use_virtual_keys: bool = True
31
- """Treat `key` parameter in :class:`~lamindb.Artifact` as virtual.
32
-
33
- If `True`, the `key` is **not** used to construct file paths, but file paths are
34
- based on the `uid` of artifact.
35
- """
36
-
37
-
38
- creation_settings = CreationSettings()
1
+ from typing import Literal
2
+
3
+
4
+ class CreationSettings:
5
+ artifact_if_hash_exists: Literal[
6
+ "warn_return_existing", "error", "warn_create_new"
7
+ ] = "warn_return_existing"
8
+ """Behavior if file hash exists (default `"warn_return_existing"`).
9
+
10
+ One of `["warn_return_existing", "error", "warn_create_new"]`.
11
+
12
+ FAQ: :doc:`/faq/idempotency`
13
+ """
14
+ artifact_skip_size_hash: bool = False
15
+ """To speed up registering high numbers of files (default `False`).
16
+
17
+ This bypasses queries for size and hash to AWS & GCP.
18
+
19
+ It speeds up file creation by about a factor 100.
20
+ """
21
+ search_names: bool = True
22
+ """To speed up creating records (default `True`).
23
+
24
+ If `True`, search for alternative names.
25
+
26
+ FAQ: :doc:`/faq/idempotency`
27
+ """
28
+ artifact_silence_missing_run_warning: bool = False
29
+ """Silence warning about missing run & transform during artifact creation."""
30
+ _artifact_use_virtual_keys: bool = True
31
+ """Treat `key` parameter in :class:`~lamindb.Artifact` as virtual.
32
+
33
+ If `True`, the `key` is **not** used to construct file paths, but file paths are
34
+ based on the `uid` of artifact.
35
+ """
36
+
37
+
38
+ creation_settings = CreationSettings()
@@ -1,21 +1,21 @@
1
- from __future__ import annotations
2
-
3
-
4
- class TransformSettings:
5
- stem_uid: str | None = None
6
- """Defines the version family of the transform.
7
-
8
- For example, all notebooks of the same family have a uid that starts with
9
- `"FPnfDtJz8qbE"`.
10
-
11
- The full uids of the notebooks in this family are of form
12
- `"{stem_uid}{suffix_uid}"` where the `suffix_uid` encodes the semantic
13
- `version`.
14
- """
15
- version: str | None = None
16
- """The version."""
17
- name: str | None = None
18
- """A name like a notebook or script title."""
19
-
20
-
21
- transform_settings = TransformSettings()
1
+ from __future__ import annotations
2
+
3
+
4
+ class TransformSettings:
5
+ stem_uid: str | None = None
6
+ """Defines the version family of the transform.
7
+
8
+ For example, all notebooks of the same family have a uid that starts with
9
+ `"FPnfDtJz8qbE"`.
10
+
11
+ The full uids of the notebooks in this family are of form
12
+ `"{stem_uid}{suffix_uid}"` where the `suffix_uid` encodes the semantic
13
+ `version`.
14
+ """
15
+ version: str | None = None
16
+ """The version."""
17
+ name: str | None = None
18
+ """A name like a notebook or script title."""
19
+
20
+
21
+ transform_settings = TransformSettings()
lamindb/core/types.py CHANGED
@@ -1,19 +1,19 @@
1
- """Types.
2
-
3
- .. autosummary::
4
- :toctree: .
5
-
6
- UPathStr
7
- StrField
8
- ListLike
9
- TransformType
10
- ArtifactType
11
- """
12
-
13
- from lamindb_setup.core.types import UPathStr
14
- from lnschema_core.types import (
15
- ArtifactType,
16
- ListLike,
17
- StrField,
18
- TransformType,
19
- )
1
+ """Types.
2
+
3
+ .. autosummary::
4
+ :toctree: .
5
+
6
+ UPathStr
7
+ StrField
8
+ ListLike
9
+ TransformType
10
+ ArtifactType
11
+ """
12
+
13
+ from lamindb_setup.core.types import UPathStr
14
+ from lnschema_core.types import (
15
+ ArtifactType,
16
+ ListLike,
17
+ StrField,
18
+ TransformType,
19
+ )