lazyscribe-joblib 0.1.0__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.
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.3
2
+ Name: lazyscribe-joblib
3
+ Version: 0.1.0
4
+ Summary: Joblib-based artifact handlers for Lazyscribe
5
+ Author: Akshay Gupta
6
+ Author-email: Akshay Gupta <akgcodes@gmail.com>
7
+ License: MIT license
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Natural Language :: English
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: attrs>=21.2.0,<=25.3.0
17
+ Requires-Dist: joblib>=1.2.0,<=1.5.2
18
+ Requires-Dist: lazyscribe>=1.0.0,<2
19
+ Requires-Dist: python-slugify>=5.0.0,<=8.0.4
20
+ Requires-Dist: build ; extra == 'build'
21
+ Requires-Dist: commitizen ; extra == 'build'
22
+ Requires-Dist: twine ; extra == 'build'
23
+ Requires-Dist: wheel ; extra == 'build'
24
+ Requires-Dist: lazyscribe-joblib[build] ; extra == 'dev'
25
+ Requires-Dist: lazyscribe-joblib[qa] ; extra == 'dev'
26
+ Requires-Dist: lazyscribe-joblib[tests] ; extra == 'dev'
27
+ Requires-Dist: edgetest ; extra == 'qa'
28
+ Requires-Dist: mypy ; extra == 'qa'
29
+ Requires-Dist: pre-commit ; extra == 'qa'
30
+ Requires-Dist: pyproject-fmt ; extra == 'qa'
31
+ Requires-Dist: ruff ; extra == 'qa'
32
+ Requires-Dist: types-python-slugify ; extra == 'qa'
33
+ Requires-Dist: uv ; extra == 'qa'
34
+ Requires-Dist: pytest ; extra == 'tests'
35
+ Requires-Dist: pytest-cov ; extra == 'tests'
36
+ Requires-Dist: scikit-learn ; extra == 'tests'
37
+ Requires-Dist: time-machine ; extra == 'tests'
38
+ Requires-Python: >=3.10.0
39
+ Project-URL: Documentation, https://github.com/lazyscribe/lazyscribe-joblib
40
+ Project-URL: Repository, https://github.com/lazyscribe/lazyscribe-joblib
41
+ Provides-Extra: build
42
+ Provides-Extra: dev
43
+ Provides-Extra: qa
44
+ Provides-Extra: tests
45
+ Description-Content-Type: text/markdown
46
+
47
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![PyPI](https://img.shields.io/pypi/v/lazyscribe-joblib)](https://pypi.org/project/lazyscribe-joblib/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/lazyscribe-joblib)](https://pypi.org/project/lazyscrib-joblib/) [![codecov](https://codecov.io/gh/lazyscribe/lazyscribe-joblib/graph/badge.svg?token=W5TPK7GX7G)](https://codecov.io/gh/lazyscribe/lazyscribe-joblib)
48
+
49
+ # Joblib-based artifact handling for lazyscribe
50
+
51
+ `lazyscribe-joblib` is a lightweight package that adds the following artifact handlers for `lazyscribe`:
52
+
53
+ * `joblib`
54
+
55
+ Any object that can be written with `joblib.dump` and read with `joblib.load` is compatible with this
56
+ handler. Note that we do persist the `joblib` version for runtime environment validation.
@@ -0,0 +1,10 @@
1
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![PyPI](https://img.shields.io/pypi/v/lazyscribe-joblib)](https://pypi.org/project/lazyscribe-joblib/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/lazyscribe-joblib)](https://pypi.org/project/lazyscrib-joblib/) [![codecov](https://codecov.io/gh/lazyscribe/lazyscribe-joblib/graph/badge.svg?token=W5TPK7GX7G)](https://codecov.io/gh/lazyscribe/lazyscribe-joblib)
2
+
3
+ # Joblib-based artifact handling for lazyscribe
4
+
5
+ `lazyscribe-joblib` is a lightweight package that adds the following artifact handlers for `lazyscribe`:
6
+
7
+ * `joblib`
8
+
9
+ Any object that can be written with `joblib.dump` and read with `joblib.load` is compatible with this
10
+ handler. Note that we do persist the `joblib` version for runtime environment validation.
@@ -0,0 +1,168 @@
1
+ """Joblib-based handler for pickle-serializable objects."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import Any, ClassVar
7
+
8
+ import joblib
9
+ from attrs import define, field
10
+ from importlib_metadata import packages_distributions
11
+ from importlib_metadata import version as importlib_version
12
+ from lazyscribe._utils import utcnow
13
+ from lazyscribe.artifacts.base import Artifact
14
+ from slugify import slugify
15
+
16
+ __all__: list[str] = ["JoblibArtifact"]
17
+
18
+
19
+ @define(auto_attribs=True)
20
+ class JoblibArtifact(Artifact):
21
+ """Handler for pickle-serializable objects through ``joblib`` package.
22
+
23
+ .. important::
24
+
25
+ ``joblib`` package should be installed to use this handler.
26
+
27
+ This handler will store the ``joblib`` version and the package (or the root module
28
+ of the ``value``) name and version as attributes to ensure compatibility between
29
+ the runtime environment and the artifacts.
30
+
31
+ .. important::
32
+
33
+ This class is not meant to be initialized directly. Please use the ``construct``
34
+ method.
35
+
36
+ Parameters
37
+ ----------
38
+ package : str
39
+ The root module name of the python object to be serialized.
40
+ package_version : str
41
+ The installed version of the package pertaining to the python object to be
42
+ serialized.
43
+ joblib_version : str
44
+ The version of ``joblib`` installed.
45
+ """
46
+
47
+ alias: ClassVar[str] = "joblib"
48
+ suffix: ClassVar[str] = "joblib"
49
+ binary: ClassVar[bool] = True
50
+ output_only: ClassVar[bool] = False
51
+ package: str = field()
52
+ package_version: str = field()
53
+ joblib_version: str = field()
54
+
55
+ @classmethod
56
+ def construct(
57
+ cls,
58
+ name: str,
59
+ value: Any = None,
60
+ fname: str | None = None,
61
+ created_at: datetime | None = None,
62
+ writer_kwargs: dict | None = None,
63
+ version: int = 0,
64
+ dirty: bool = True,
65
+ package: str | None = None,
66
+ **kwargs,
67
+ ):
68
+ """Construct the class with the version information.
69
+
70
+ Parameters
71
+ ----------
72
+ name : str
73
+ The name of the artifact.
74
+ value : object, optional (default None)
75
+ The value for the artifact. The default value of ``None`` is used when
76
+ an experiment is loaded from the project JSON.
77
+ fname : str, optional (default None)
78
+ The filename of the artifact. If not provided, this value will be derived from
79
+ the name of the artifact and the suffix for the class.
80
+ created_at : datetime, optional (default None)
81
+ When the artifact was created. If not supplied, :py:meth:`datetime.now` will be used.
82
+ package: str, optional (default None)
83
+ The package name or root module name of the serializable python object.
84
+ Note: this may be different from the distribution name. e.g ``scikit-learn`` is
85
+ a distribution name, where as ``sklearn`` is the corresponding package name.
86
+ writer_kwargs : dict, optional (default None)
87
+ Keyword arguments for writing an artifact to the filesystem. Provided when an artifact
88
+ is logged to an experiment.
89
+ version : int, optional (default 0)
90
+ Integer version to be used for versioning artifacts.
91
+ dirty : bool, optional (default True)
92
+ Whether or not this artifact should be saved when :py:meth:`lazyscribe.project.Project.save`
93
+ or :py:meth:`lazyscribe.repository.Repository.save` is called. This decision is based
94
+ on whether the artifact is new or has been updated.
95
+ **kwargs : dict
96
+ Other keyword arguments.
97
+ Usually class attributes obtained from a project JSON.
98
+ """
99
+ if package is None:
100
+ if value is None:
101
+ raise ValueError(
102
+ "If no ``package`` is specified, you must supply a ``value``."
103
+ )
104
+ try:
105
+ package = value.__module__.split(".")[0]
106
+ except AttributeError as err:
107
+ raise AttributeError(
108
+ "Unable to identify the package based on the supplied ``value``. "
109
+ "Please provide an argument for ``package``."
110
+ ) from err
111
+
112
+ try:
113
+ distribution = packages_distributions()[package][0]
114
+ except KeyError as err:
115
+ raise ValueError(f"{package} was not found.") from err
116
+
117
+ created_at = created_at or utcnow()
118
+ return cls( # type: ignore[call-arg]
119
+ name=name,
120
+ value=value,
121
+ fname=fname
122
+ or f"{slugify(name)}-{slugify(created_at.strftime('%Y%m%d%H%M%S'))}.{cls.suffix}",
123
+ created_at=created_at,
124
+ writer_kwargs=writer_kwargs or {},
125
+ version=version,
126
+ dirty=dirty,
127
+ package=package,
128
+ package_version=kwargs.get("package_version")
129
+ or importlib_version(distribution),
130
+ joblib_version=kwargs.get("joblib_version") or joblib.__version__,
131
+ )
132
+
133
+ @classmethod
134
+ def read(cls, buf, **kwargs):
135
+ """Read the python object.
136
+
137
+ Parameters
138
+ ----------
139
+ buf : file-like object
140
+ The buffer from the ``fsspec`` filesystem.
141
+ **kwargs : dict
142
+ Keyword arguments for ``joblib.load``.
143
+
144
+ Returns
145
+ -------
146
+ Any
147
+ The python object.
148
+ """
149
+ from joblib import load
150
+
151
+ return load(buf, **kwargs)
152
+
153
+ @classmethod
154
+ def write(cls, obj, buf, **kwargs):
155
+ """Write the python object to the filesystem.
156
+
157
+ Parameters
158
+ ----------
159
+ obj : object
160
+ The python object to write.
161
+ buf : file-like object
162
+ The buffer from the ``fsspec`` filesystem.
163
+ **kwargs : dict
164
+ Keyword arguments for :py:meth:`joblib.load`.
165
+ """
166
+ from joblib import dump
167
+
168
+ dump(obj, buf, **kwargs)
@@ -0,0 +1,3 @@
1
+ """Version."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,113 @@
1
+ [build-system]
2
+ build-backend = "uv_build"
3
+
4
+ requires = [ "uv-build>=0.8.0,<0.9.0" ]
5
+
6
+ [project]
7
+ name = "lazyscribe-joblib"
8
+ version = "0.1.0"
9
+
10
+ description = "Joblib-based artifact handlers for Lazyscribe"
11
+ readme = { file = "README.md", content-type = "text/markdown" }
12
+ license = { text = "MIT license" }
13
+ authors = [
14
+ { name = "Akshay Gupta", email = "akgcodes@gmail.com" },
15
+ ]
16
+ requires-python = ">=3.10.0"
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Natural Language :: English",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ ]
27
+ dependencies = [
28
+ "attrs>=21.2.0,<=25.3.0",
29
+ "joblib>=1.2.0,<=1.5.2",
30
+ "lazyscribe>=1.0.0,<2",
31
+ "python-slugify>=5.0.0,<=8.0.4",
32
+ ]
33
+
34
+ optional-dependencies.build = [ "build", "commitizen", "twine", "wheel" ]
35
+ optional-dependencies.dev = [
36
+ "lazyscribe-joblib[build]",
37
+ "lazyscribe-joblib[qa]",
38
+ "lazyscribe-joblib[tests]",
39
+ ]
40
+ optional-dependencies.qa = [
41
+ "edgetest",
42
+ "mypy",
43
+ "pre-commit",
44
+ "pyproject-fmt",
45
+ "ruff",
46
+ "types-python-slugify",
47
+ "uv",
48
+ ]
49
+ optional-dependencies.tests = [ "pytest", "pytest-cov", "scikit-learn", "time-machine" ]
50
+ urls."Documentation" = "https://github.com/lazyscribe/lazyscribe-joblib"
51
+ urls."Repository" = "https://github.com/lazyscribe/lazyscribe-joblib"
52
+ entry-points."lazyscribe.artifact_type".joblib = "lazyscribe_joblib:JoblibArtifact"
53
+
54
+ [tool.ruff]
55
+ target-version = "py310"
56
+
57
+ lint.select = [
58
+ "B", # flake8-bugbear
59
+ "C", # flake8-comprehensions
60
+ "D", # pydocstyle
61
+ "E", # pycodestyle errors
62
+ "F", # pyflakes
63
+ "I", # isort
64
+ "LOG", # flake8-logging
65
+ "RUF", # Ruff errors
66
+ "SIM", # flake8-simplify
67
+ "T20", # flake8-print
68
+ "TID252", # flake8-tidy-imports ban relative imports
69
+ "UP", # pyupgrade
70
+ "W", # pycodestyle warnings
71
+ ]
72
+ lint.ignore = [
73
+ "C901", # Function/method is too complex. (Add back in later.)
74
+ "E501", # Line too long. Using formatter instead.
75
+ ]
76
+ lint.per-file-ignores."**/{tests,docs}/*" = [ "ARG", "D", "E402", "F841" ]
77
+ lint.per-file-ignores."__init__.py" = [ "E402" ]
78
+ lint.per-file-ignores."tutorials/*" = [ "D", "T201" ]
79
+ lint.flake8-tidy-imports.ban-relative-imports = "all"
80
+ lint.pydocstyle.convention = "numpy"
81
+ lint.preview = true
82
+
83
+ [tool.pyproject-fmt]
84
+ column_width = 88
85
+ indent = 4
86
+ keep_full_version = true
87
+ max_supported_python = "3.13"
88
+
89
+ [tool.mypy]
90
+ python_version = "3.10"
91
+ warn_return_any = true
92
+ warn_unused_configs = true
93
+ ignore_missing_imports = true
94
+ allow_redefinition = true
95
+ check_untyped_defs = true
96
+
97
+ [tool.commitizen]
98
+ version_provider = "pep621"
99
+ tag_format = "v$version"
100
+ bump_message = "chore: version $current_version -> $new_version"
101
+ update_changelog_on_bump = true
102
+ version_files = [
103
+ "lazyscribe_joblib/_meta.py:__version__",
104
+ ]
105
+
106
+ [edgetest.envs.core]
107
+ extras = [ "tests" ]
108
+ upgrade = [ "attrs", "lazyscribe", "joblib", "python-slugify" ]
109
+ command = "pytest tests"
110
+
111
+ [tool.uv.build-backend]
112
+ module-name = "lazyscribe_joblib"
113
+ module-root = ""