litdata 0.2.60__tar.gz → 0.2.64__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.
- {litdata-0.2.60/src/litdata.egg-info → litdata-0.2.64}/PKG-INFO +3 -3
- {litdata-0.2.60 → litdata-0.2.64}/setup.py +5 -2
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/__about__.py +1 -1
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/cli/commands.py +1 -1
- litdata-0.2.64/src/litdata/cli/handler/__init__.py +21 -0
- litdata-0.2.64/src/litdata/cli/handler/cache.py +32 -0
- litdata-0.2.64/src/litdata/cli/handler/optimize.py +19 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/constants.py +1 -0
- litdata-0.2.64/src/litdata/imports.py +363 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/processing/data_processor.py +1 -1
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/processing/utilities.py +8 -4
- litdata-0.2.64/src/litdata/requirements.py +192 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/client.py +90 -49
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/config.py +5 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/dataloader.py +45 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/downloader.py +16 -9
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/fs_provider.py +9 -7
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/item_loader.py +24 -8
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/reader.py +95 -45
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/resolver.py +13 -1
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/serializers.py +32 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/writer.py +5 -1
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/parquet.py +11 -3
- {litdata-0.2.60 → litdata-0.2.64/src/litdata.egg-info}/PKG-INFO +3 -3
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/SOURCES.txt +4 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/requires.txt +2 -2
- litdata-0.2.60/src/litdata/imports.py +0 -121
- {litdata-0.2.60 → litdata-0.2.64}/CONTRIBUTING.md +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/LICENSE +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/MANIFEST.in +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/README.md +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/requirements.txt +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/setup.cfg +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/__main__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/cli/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/cli/parser.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/debugger.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/helpers.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/processing/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/processing/functions.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/processing/readers.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/raw/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/raw/dataset.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/raw/indexer.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/raw/types.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/cache.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/combined.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/compression.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/dataset.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/parallel.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/sampler.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/streaming/shuffle.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/__init__.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/_pytree.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/base.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/breakpoint.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/broadcast.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/dataset_utilities.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/encryption.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/env.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/format.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/hf_dataset.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/packing.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/shuffle.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/subsample.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/torch_utils.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata/utilities/train_test_split.py +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/dependency_links.txt +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/entry_points.txt +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/not-zip-safe +0 -0
- {litdata-0.2.60 → litdata-0.2.64}/src/litdata.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: litdata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.64
|
|
4
4
|
Summary: The Deep Learning framework to train, deploy, and ship AI products Lightning fast.
|
|
5
5
|
Home-page: https://github.com/Lightning-AI/litdata
|
|
6
6
|
Download-URL: https://github.com/Lightning-AI/litdata
|
|
@@ -39,10 +39,10 @@ Requires-Dist: obstore
|
|
|
39
39
|
Provides-Extra: extras
|
|
40
40
|
Requires-Dist: fsspec; extra == "extras"
|
|
41
41
|
Requires-Dist: google-cloud-storage; extra == "extras"
|
|
42
|
-
Requires-Dist: lightning-sdk==
|
|
42
|
+
Requires-Dist: lightning-sdk==2026.2.6; extra == "extras"
|
|
43
43
|
Requires-Dist: pillow; extra == "extras"
|
|
44
44
|
Requires-Dist: polars; extra == "extras"
|
|
45
|
-
Requires-Dist: pyarrow; extra == "extras"
|
|
45
|
+
Requires-Dist: pyarrow<25.0.0; extra == "extras"
|
|
46
46
|
Requires-Dist: tqdm; extra == "extras"
|
|
47
47
|
Requires-Dist: viztracer; extra == "extras"
|
|
48
48
|
Dynamic: author
|
|
@@ -4,7 +4,6 @@ import os
|
|
|
4
4
|
from importlib.util import module_from_spec, spec_from_file_location
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
from pkg_resources import parse_requirements
|
|
8
7
|
from setuptools import find_packages, setup
|
|
9
8
|
|
|
10
9
|
_PATH_ROOT = os.path.dirname(__file__)
|
|
@@ -19,8 +18,12 @@ def _load_py_module(fname, pkg="litdata"):
|
|
|
19
18
|
return py
|
|
20
19
|
|
|
21
20
|
|
|
21
|
+
about = _load_py_module("__about__.py")
|
|
22
|
+
requirements_module = _load_py_module("requirements.py")
|
|
23
|
+
|
|
24
|
+
|
|
22
25
|
def _load_requirements(path_dir: str = _PATH_ROOT, file_name: str = "requirements.txt") -> list:
|
|
23
|
-
reqs =
|
|
26
|
+
reqs = requirements_module._parse_requirements(open(os.path.join(path_dir, file_name)).readlines())
|
|
24
27
|
return list(map(str, reqs))
|
|
25
28
|
|
|
26
29
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
from argparse import _SubParsersAction
|
|
15
15
|
|
|
16
|
+
from litdata.cli import LitFormatter
|
|
16
17
|
from litdata.cli.handler.cache import clear_cache, show_cache_path
|
|
17
18
|
from litdata.cli.handler.optimize import optimize_dataset
|
|
18
|
-
from litdata.cli.parser import LitFormatter
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def register_cache_subcommand(subparser: _SubParsersAction) -> None:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from litdata.cli.handler.cache import clear_cache, show_cache_path
|
|
15
|
+
from litdata.cli.handler.optimize import optimize_dataset
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"clear_cache",
|
|
19
|
+
"show_cache_path",
|
|
20
|
+
"optimize_dataset",
|
|
21
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
import shutil
|
|
15
|
+
from argparse import Namespace
|
|
16
|
+
|
|
17
|
+
from litdata.utilities.dataset_utilities import get_default_cache_dir
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def clear_cache(args: Namespace) -> None:
|
|
21
|
+
"""Clear default cache used for StreamingDataset and other utilities."""
|
|
22
|
+
streaming_default_cache_dir = get_default_cache_dir()
|
|
23
|
+
|
|
24
|
+
shutil.rmtree(streaming_default_cache_dir, ignore_errors=True)
|
|
25
|
+
|
|
26
|
+
print(f"Cache directory '{streaming_default_cache_dir}' cleared.")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def show_cache_path(args: Namespace) -> None:
|
|
30
|
+
"""Show the path to the cache directory."""
|
|
31
|
+
streaming_default_cache_dir = get_default_cache_dir()
|
|
32
|
+
print(f"Default cache directory: {streaming_default_cache_dir}")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from argparse import Namespace
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def optimize_dataset(args: Namespace) -> None:
|
|
18
|
+
"""Handle the optimize command."""
|
|
19
|
+
print(f"Optimizing dataset at {args.dataset}...")
|
|
@@ -49,6 +49,7 @@ _PYARROW_AVAILABLE = RequirementCache("pyarrow")
|
|
|
49
49
|
_POLARS_AVAILABLE = RequirementCache("polars>1.0.0")
|
|
50
50
|
_PIL_AVAILABLE = RequirementCache("PIL")
|
|
51
51
|
_TORCH_VISION_AVAILABLE = RequirementCache("torchvision")
|
|
52
|
+
_TORCH_VISION_LESS_THAN_0_26 = RequirementCache("torchvision<0.26.0")
|
|
52
53
|
_AV_AVAILABLE = RequirementCache("av")
|
|
53
54
|
_OBSTORE_AVAILABLE = RequirementCache("obstore")
|
|
54
55
|
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import importlib
|
|
7
|
+
import os
|
|
8
|
+
import warnings
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
from importlib.metadata import PackageNotFoundError, distribution
|
|
12
|
+
from importlib.metadata import version as _version
|
|
13
|
+
from importlib.util import find_spec
|
|
14
|
+
from types import ModuleType
|
|
15
|
+
from typing import Any, TypeVar
|
|
16
|
+
|
|
17
|
+
from packaging.requirements import Requirement
|
|
18
|
+
from packaging.version import InvalidVersion, Version
|
|
19
|
+
from typing_extensions import ParamSpec
|
|
20
|
+
|
|
21
|
+
T = TypeVar("T")
|
|
22
|
+
P = ParamSpec("P")
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from importlib import metadata
|
|
26
|
+
except ImportError:
|
|
27
|
+
# Python < 3.8
|
|
28
|
+
import importlib_metadata as metadata # type: ignore
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@lru_cache
|
|
32
|
+
def package_available(package_name: str) -> bool:
|
|
33
|
+
"""Check if a package is available in your environment.
|
|
34
|
+
|
|
35
|
+
>>> package_available('os')
|
|
36
|
+
True
|
|
37
|
+
>>> package_available('bla')
|
|
38
|
+
False
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
return find_spec(package_name) is not None
|
|
43
|
+
except ModuleNotFoundError:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@lru_cache
|
|
48
|
+
def module_available(module_path: str) -> bool:
|
|
49
|
+
"""Check if a module path is available in your environment.
|
|
50
|
+
|
|
51
|
+
>>> module_available('os')
|
|
52
|
+
True
|
|
53
|
+
>>> module_available('os.bla')
|
|
54
|
+
False
|
|
55
|
+
>>> module_available('bla.bla')
|
|
56
|
+
False
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
module_names = module_path.split(".")
|
|
60
|
+
if not package_available(module_names[0]):
|
|
61
|
+
return False
|
|
62
|
+
try:
|
|
63
|
+
importlib.import_module(module_path)
|
|
64
|
+
except ImportError:
|
|
65
|
+
return False
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def compare_version(package: str, op: Callable, version: str, use_base_version: bool = False) -> bool:
|
|
70
|
+
"""Compare package version with some requirements.
|
|
71
|
+
|
|
72
|
+
>>> compare_version("torch", operator.ge, "0.1")
|
|
73
|
+
True
|
|
74
|
+
>>> compare_version("does_not_exist", operator.ge, "0.0")
|
|
75
|
+
False
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
try:
|
|
79
|
+
pkg = importlib.import_module(package)
|
|
80
|
+
except (ImportError, RuntimeError):
|
|
81
|
+
return False
|
|
82
|
+
try:
|
|
83
|
+
# Use importlib.metadata to infer version
|
|
84
|
+
pkg_version = Version(pkg.__version__) if hasattr(pkg, "__version__") else Version(_version(package))
|
|
85
|
+
except (TypeError, PackageNotFoundError):
|
|
86
|
+
# this is mocked by Sphinx, so it should return True to generate all summaries
|
|
87
|
+
return True
|
|
88
|
+
if use_base_version:
|
|
89
|
+
pkg_version = Version(pkg_version.base_version)
|
|
90
|
+
return op(pkg_version, Version(version))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class RequirementCache:
|
|
94
|
+
"""Boolean-like class to check for requirement and module availability.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
requirement: The requirement to check, version specifiers are allowed.
|
|
98
|
+
module: The optional module to try to import if the requirement check fails.
|
|
99
|
+
|
|
100
|
+
>>> RequirementCache("torch>=0.1")
|
|
101
|
+
Requirement 'torch>=0.1' met
|
|
102
|
+
>>> bool(RequirementCache("torch>=0.1"))
|
|
103
|
+
True
|
|
104
|
+
>>> bool(RequirementCache("torch>100.0"))
|
|
105
|
+
False
|
|
106
|
+
>>> RequirementCache("torch")
|
|
107
|
+
Requirement 'torch' met
|
|
108
|
+
>>> bool(RequirementCache("torch"))
|
|
109
|
+
True
|
|
110
|
+
>>> bool(RequirementCache("unknown_package"))
|
|
111
|
+
False
|
|
112
|
+
>>> bool(RequirementCache(module="torch.utils"))
|
|
113
|
+
True
|
|
114
|
+
>>> bool(RequirementCache(module="unknown_package"))
|
|
115
|
+
False
|
|
116
|
+
>>> bool(RequirementCache(module="unknown.module.path"))
|
|
117
|
+
False
|
|
118
|
+
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def __init__(self, requirement: str | None = None, module: str | None = None) -> None:
|
|
122
|
+
if not (requirement or module):
|
|
123
|
+
raise ValueError("At least one arguments need to be set.")
|
|
124
|
+
self.requirement = requirement
|
|
125
|
+
self.module = module
|
|
126
|
+
|
|
127
|
+
def _check_requirement(self) -> None:
|
|
128
|
+
if not self.requirement:
|
|
129
|
+
raise ValueError("Requirement name is required.")
|
|
130
|
+
try:
|
|
131
|
+
req = Requirement(self.requirement)
|
|
132
|
+
pkg_version = Version(_version(req.name))
|
|
133
|
+
self.available = req.specifier.contains(pkg_version, prereleases=True) and (
|
|
134
|
+
not req.extras or self._check_extras_available(req)
|
|
135
|
+
)
|
|
136
|
+
except (PackageNotFoundError, InvalidVersion) as ex:
|
|
137
|
+
self.available = False
|
|
138
|
+
self.message = f"{ex.__class__.__name__}: {ex}. HINT: Try running `pip install -U {self.requirement!r}`"
|
|
139
|
+
|
|
140
|
+
if self.available:
|
|
141
|
+
self.message = f"Requirement {self.requirement!r} met"
|
|
142
|
+
else:
|
|
143
|
+
req_include_version = any(c in self.requirement for c in "=<>")
|
|
144
|
+
if not req_include_version or self.module is not None:
|
|
145
|
+
module = self.requirement if self.module is None else self.module
|
|
146
|
+
# Sometimes `importlib.metadata.version` fails but the module is importable
|
|
147
|
+
self.available = module_available(module)
|
|
148
|
+
if self.available:
|
|
149
|
+
self.message = f"Module {module!r} available"
|
|
150
|
+
self.message = (
|
|
151
|
+
f"Requirement {self.requirement!r} not met. HINT: Try running `pip install -U {self.requirement!r}`"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def _check_module(self) -> None:
|
|
155
|
+
if not self.module:
|
|
156
|
+
raise ValueError("Module name is required.")
|
|
157
|
+
self.available = module_available(self.module)
|
|
158
|
+
if self.available:
|
|
159
|
+
self.message = f"Module {self.module!r} available"
|
|
160
|
+
else:
|
|
161
|
+
self.message = f"Module not found: {self.module!r}. HINT: Try running `pip install -U {self.module}`"
|
|
162
|
+
|
|
163
|
+
def _check_available(self) -> None:
|
|
164
|
+
if hasattr(self, "available"):
|
|
165
|
+
return
|
|
166
|
+
if self.requirement:
|
|
167
|
+
self._check_requirement()
|
|
168
|
+
if getattr(self, "available", True) and self.module:
|
|
169
|
+
self._check_module()
|
|
170
|
+
|
|
171
|
+
def _check_extras_available(self, requirement: Requirement) -> bool:
|
|
172
|
+
if not requirement.extras:
|
|
173
|
+
return True
|
|
174
|
+
|
|
175
|
+
extra_requirements = self._get_extra_requirements(requirement)
|
|
176
|
+
|
|
177
|
+
if not extra_requirements:
|
|
178
|
+
# The specified extra is not found in the package metadata
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
# Verify each extra requirement is installed
|
|
182
|
+
for extra_req in extra_requirements:
|
|
183
|
+
try:
|
|
184
|
+
extra_dist = distribution(extra_req.name)
|
|
185
|
+
extra_installed_version = Version(extra_dist.version)
|
|
186
|
+
if extra_req.specifier and not extra_req.specifier.contains(extra_installed_version, prereleases=True):
|
|
187
|
+
return False
|
|
188
|
+
except importlib.metadata.PackageNotFoundError:
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
return True
|
|
192
|
+
|
|
193
|
+
def _get_extra_requirements(self, requirement: Requirement) -> list[Requirement]:
|
|
194
|
+
dist = distribution(requirement.name)
|
|
195
|
+
# Get the required dependencies for the specified extras
|
|
196
|
+
extra_requirements = dist.metadata.get_all("Requires-Dist") or []
|
|
197
|
+
return [Requirement(r) for r in extra_requirements if any(extra in r for extra in requirement.extras)]
|
|
198
|
+
|
|
199
|
+
def __bool__(self) -> bool:
|
|
200
|
+
"""Format as bool."""
|
|
201
|
+
self._check_available()
|
|
202
|
+
return self.available
|
|
203
|
+
|
|
204
|
+
def __str__(self) -> str:
|
|
205
|
+
"""Format as string."""
|
|
206
|
+
self._check_available()
|
|
207
|
+
return self.message
|
|
208
|
+
|
|
209
|
+
def __repr__(self) -> str:
|
|
210
|
+
"""Format as string."""
|
|
211
|
+
return self.__str__()
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class ModuleAvailableCache(RequirementCache):
|
|
215
|
+
"""Boolean-like class for check of module availability.
|
|
216
|
+
|
|
217
|
+
>>> ModuleAvailableCache("torch")
|
|
218
|
+
Module 'torch' available
|
|
219
|
+
>>> bool(ModuleAvailableCache("torch.utils"))
|
|
220
|
+
True
|
|
221
|
+
>>> bool(ModuleAvailableCache("unknown_package"))
|
|
222
|
+
False
|
|
223
|
+
>>> bool(ModuleAvailableCache("unknown.module.path"))
|
|
224
|
+
False
|
|
225
|
+
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
def __init__(self, module: str) -> None:
|
|
229
|
+
warnings.warn(
|
|
230
|
+
"`ModuleAvailableCache` is a special case of `RequirementCache`."
|
|
231
|
+
" Please use `RequirementCache(module=...)` instead.",
|
|
232
|
+
DeprecationWarning,
|
|
233
|
+
stacklevel=4,
|
|
234
|
+
)
|
|
235
|
+
super().__init__(module=module)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def get_dependency_min_version_spec(package_name: str, dependency_name: str) -> str:
|
|
239
|
+
"""Return the minimum version specifier of a dependency of a package.
|
|
240
|
+
|
|
241
|
+
>>> get_dependency_min_version_spec("pytorch-lightning==1.8.0", "jsonargparse")
|
|
242
|
+
'>=4.12.0'
|
|
243
|
+
|
|
244
|
+
"""
|
|
245
|
+
dependencies = metadata.requires(package_name) or []
|
|
246
|
+
for dep in dependencies:
|
|
247
|
+
dependency = Requirement(dep)
|
|
248
|
+
if dependency.name == dependency_name:
|
|
249
|
+
spec = [str(s) for s in dependency.specifier if str(s)[0] == ">"]
|
|
250
|
+
return spec[0] if spec else ""
|
|
251
|
+
raise ValueError(
|
|
252
|
+
"This is an internal error. Please file a GitHub issue with the error message. Dependency "
|
|
253
|
+
f"{dependency_name!r} not found in package {package_name!r}."
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class LazyModule(ModuleType):
|
|
258
|
+
"""Proxy module that lazily imports the underlying module the first time it is actually used.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
module_name: the fully-qualified module name to import
|
|
262
|
+
callback: a callback function to call before importing the module
|
|
263
|
+
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def __init__(self, module_name: str, callback: Callable | None = None) -> None:
|
|
267
|
+
super().__init__(module_name)
|
|
268
|
+
self._module: Any = None
|
|
269
|
+
self._callback = callback
|
|
270
|
+
|
|
271
|
+
def __getattr__(self, item: str) -> Any:
|
|
272
|
+
"""Lazily import the underlying module and delegate attribute access to it."""
|
|
273
|
+
if self._module is None:
|
|
274
|
+
self._import_module()
|
|
275
|
+
|
|
276
|
+
return getattr(self._module, item)
|
|
277
|
+
|
|
278
|
+
def __dir__(self) -> list[str]:
|
|
279
|
+
"""Lazily import the underlying module and return its attributes for introspection (dir())."""
|
|
280
|
+
if self._module is None:
|
|
281
|
+
self._import_module()
|
|
282
|
+
|
|
283
|
+
return dir(self._module)
|
|
284
|
+
|
|
285
|
+
def _import_module(self) -> None:
|
|
286
|
+
# Execute callback, if any
|
|
287
|
+
if self._callback is not None:
|
|
288
|
+
self._callback()
|
|
289
|
+
|
|
290
|
+
# Actually import the module
|
|
291
|
+
self._module = importlib.import_module(self.__name__)
|
|
292
|
+
|
|
293
|
+
# Update this object's dict so that attribute references are efficient
|
|
294
|
+
# (__getattr__ is only called on lookups that fail)
|
|
295
|
+
self.__dict__.update(self._module.__dict__)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def lazy_import(module_name: str, callback: Callable | None = None) -> LazyModule:
|
|
299
|
+
"""Return a proxy module object that will lazily import the given module the first time it is used.
|
|
300
|
+
|
|
301
|
+
Example usage:
|
|
302
|
+
|
|
303
|
+
# Lazy version of `import tensorflow as tf`
|
|
304
|
+
tf = lazy_import("tensorflow")
|
|
305
|
+
# Other commands
|
|
306
|
+
# Now the module is loaded
|
|
307
|
+
tf.__version__
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
module_name: the fully-qualified module name to import
|
|
311
|
+
callback: a callback function to call before importing the module
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
a proxy module object that will be lazily imported when first used
|
|
315
|
+
|
|
316
|
+
"""
|
|
317
|
+
return LazyModule(module_name, callback=callback)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def requires(*module_path_version: str, raise_exception: bool = True) -> Callable[[Callable[P, T]], Callable[P, T]]:
|
|
321
|
+
"""Decorator to check optional dependencies at call time with a clear error/warning message.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
module_path_version: Python module paths (e.g., ``"torch.cuda"``) and/or pip-style requirements
|
|
325
|
+
(e.g., ``"torch>=2.0.0"``) to verify.
|
|
326
|
+
raise_exception: If ``True``, raise ``ModuleNotFoundError`` when requirements are not satisfied;
|
|
327
|
+
otherwise emit a warning and proceed to call the function.
|
|
328
|
+
|
|
329
|
+
Example:
|
|
330
|
+
>>> @requires("libpath", raise_exception=bool(int(os.getenv("LIGHTING_TESTING", "0"))))
|
|
331
|
+
... def my_cwd():
|
|
332
|
+
... from pathlib import Path
|
|
333
|
+
... return Path(__file__).parent
|
|
334
|
+
|
|
335
|
+
>>> class MyRndPower:
|
|
336
|
+
... @requires("math", "random")
|
|
337
|
+
... def __init__(self):
|
|
338
|
+
... from math import pow
|
|
339
|
+
... from random import randint
|
|
340
|
+
... self._rnd = pow(randint(1, 9), 2)
|
|
341
|
+
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
def decorator(func: Callable[P, T]) -> Callable[P, T]:
|
|
345
|
+
reqs = [
|
|
346
|
+
ModuleAvailableCache(mod_ver) if "." in mod_ver else RequirementCache(mod_ver)
|
|
347
|
+
for mod_ver in module_path_version
|
|
348
|
+
]
|
|
349
|
+
available = all(map(bool, reqs))
|
|
350
|
+
|
|
351
|
+
@functools.wraps(func)
|
|
352
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
353
|
+
if not available:
|
|
354
|
+
missing = os.linesep.join([repr(r) for r in reqs if not bool(r)])
|
|
355
|
+
msg = f"Required dependencies not available: \n{missing}"
|
|
356
|
+
if raise_exception:
|
|
357
|
+
raise ModuleNotFoundError(msg)
|
|
358
|
+
warnings.warn(msg, stacklevel=2)
|
|
359
|
+
return func(*args, **kwargs)
|
|
360
|
+
|
|
361
|
+
return wrapper
|
|
362
|
+
|
|
363
|
+
return decorator
|
|
@@ -160,7 +160,7 @@ def _download_data_target(
|
|
|
160
160
|
if input_dir.path:
|
|
161
161
|
local_path = path.replace(input_dir.path, cache_dir)
|
|
162
162
|
|
|
163
|
-
if input_dir.url and input_dir.path:
|
|
163
|
+
if input_dir.url and input_dir.path and not os.path.isfile(path):
|
|
164
164
|
path = path.replace(input_dir.path, input_dir.url)
|
|
165
165
|
|
|
166
166
|
obj = parse.urlparse(path)
|
|
@@ -68,6 +68,10 @@ def _create_dataset(
|
|
|
68
68
|
client = LightningClient(retry=False)
|
|
69
69
|
|
|
70
70
|
try:
|
|
71
|
+
# Some strings represent protobuf strings, some protouf uint64s
|
|
72
|
+
# The uint64s need a default of None so they're not added to the
|
|
73
|
+
# request body, which avoids a 400 response due to an invalid request.
|
|
74
|
+
# The protobuf string types can default to "" just fine.
|
|
71
75
|
client.dataset_service_create_dataset(
|
|
72
76
|
body=DatasetServiceCreateDatasetBody(
|
|
73
77
|
cloud_space_id=(studio_id if lightning_app_id is None else None) or "",
|
|
@@ -77,15 +81,15 @@ def _create_dataset(
|
|
|
77
81
|
input_dir=input_dir or "",
|
|
78
82
|
lightning_app_id=lightning_app_id or "",
|
|
79
83
|
name=name or "",
|
|
80
|
-
size=size
|
|
81
|
-
num_bytes=num_bytes
|
|
84
|
+
size=size,
|
|
85
|
+
num_bytes=num_bytes,
|
|
82
86
|
data_format=(str(data_format) if data_format else data_format) or "",
|
|
83
87
|
compression=compression or "",
|
|
84
|
-
num_chunks=num_chunks
|
|
88
|
+
num_chunks=num_chunks,
|
|
85
89
|
num_bytes_per_chunk=num_bytes_per_chunk or [],
|
|
86
90
|
storage_dir=storage_dir,
|
|
87
91
|
type=dataset_type,
|
|
88
|
-
version=version
|
|
92
|
+
version=version,
|
|
89
93
|
),
|
|
90
94
|
project_id=project_id,
|
|
91
95
|
)
|