Skip to content

Commit 2e31280

Browse files
committed
[ci skip] WIP - Add docstr
1 parent 0ca228e commit 2e31280

20 files changed

+709
-147
lines changed

skore-remote-project/pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ parallel = true
6969
omit = ["src/*", "tests/*"]
7070
show_missing = true
7171
exclude_also = [
72-
'raise NotImplementedError',
73-
'if __name__ == .__main__.:',
74-
'if TYPE_CHECKING:',
72+
"raise NotImplementedError",
73+
"if __name__ == .__main__.:",
74+
"if TYPE_CHECKING:",
7575
]
7676

7777
[tool.ruff]

skore-remote-project/src/skore_remote_project/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Package that provides APIs to communicate between ``skore`` and ``skore hub``."""
2+
13
from rich.console import Console
24
from rich.theme import Theme
35

skore-remote-project/src/skore_remote_project/item/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
Module definition of the ``Item`` classes.
3+
4+
``Item`` is an internal concept that is used as a DTO (Data Transfer Object) to exchange
5+
python objects between ``skore`` and ``skore hub``.
6+
"""
7+
18
from __future__ import annotations
29

310
from contextlib import suppress
@@ -22,6 +29,7 @@
2229

2330

2431
def object_to_item(object: Any, /) -> Item:
32+
"""Serialize any python object into an ``Item``."""
2533
for cls in (
2634
# Lexicographically sorted, the order of execution doesn't matter
2735
AltairChartItem,

skore-remote-project/src/skore_remote_project/item/altair_chart_item.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
AltairChartItem.
3+
4+
This module defines the ``AltairChartItem`` class used to serialize instances of
5+
``altair`` charts, using the ``JSON`` format.
6+
"""
7+
18
from __future__ import annotations
29

310
from json import loads
@@ -10,17 +17,29 @@
1017

1118

1219
class AltairChartItem(Item):
20+
"""Serialize instances of ``altair`` charts, using the ``JSON`` format."""
21+
1322
def __init__(self, chart_json_str: str):
23+
"""
24+
Initialize a ``AltairChartItem``.
25+
26+
Parameters
27+
----------
28+
chart_json_str : str
29+
The ``altair`` chart serialized in a str in the ``JSON`` format.
30+
"""
1431
self.chart_json_str = chart_json_str
1532

1633
@property
1734
def __raw__(self) -> AltairChart:
35+
"""Get the value from the ``AltairChartItem`` instance."""
1836
import altair
1937

2038
return altair.Chart.from_json(self.chart_json_str)
2139

2240
@property
2341
def __representation__(self) -> dict:
42+
"""Get the representation of the ``AltairChartItem`` instance."""
2443
return {
2544
"representation": {
2645
"media_type": "application/vnd.vega.v5+json",
@@ -29,8 +48,28 @@ def __representation__(self) -> dict:
2948
}
3049

3150
@classmethod
32-
def factory(cls, chart: AltairChart, /, **kwargs) -> AltairChartItem:
33-
if not lazy_is_instance(chart, "altair.vegalite.v5.schema.core.TopLevelSpec"):
34-
raise ItemTypeError(f"Type '{chart.__class__}' is not supported.")
51+
def factory(cls, value: AltairChart, /) -> AltairChartItem:
52+
"""
53+
Create a new ``AltairChartItem`` from an instance of ``altair`` chart.
54+
55+
It uses the ``JSON`` format.
56+
57+
Parameters
58+
----------
59+
value: ``altair`` chart.
60+
The value to serialize.
61+
62+
Returns
63+
-------
64+
AltairChartItem
65+
A new ``AltairChartItem`` instance.
66+
67+
Raises
68+
------
69+
ItemTypeError
70+
If ``value`` is not an instance of ``altair`` chart.
71+
"""
72+
if not lazy_is_instance(value, "altair.vegalite.v5.schema.core.TopLevelSpec"):
73+
raise ItemTypeError(f"Type '{value.__class__}' is not supported.")
3574

36-
return cls(chart.to_json(), **kwargs)
75+
return cls(value.to_json())
Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Abstract base class for all items in the ``skore`` remote project."""
2+
13
from __future__ import annotations
24

35
from abc import ABC, abstractmethod
@@ -7,30 +9,50 @@
79

810

911
def lazy_is_instance(value: Any, cls_fullname: str) -> bool:
10-
"""Return True if value is an instance of `cls_fullname`."""
12+
"""Return True if value is an instance of ``cls_fullname``."""
1113
return cls_fullname in {
1214
f"{cls.__module__}.{cls.__name__}" for cls in value.__class__.__mro__
1315
}
1416

1517

1618
def bytes_to_b64_str(literal: bytes) -> str:
17-
"""Encode the bytes-like object `literal` in a Base64 str."""
19+
"""Encode the bytes-like object ``literal`` in a Base64 str."""
1820
return b64encode(literal).decode("utf-8")
1921

2022

2123
def b64_str_to_bytes(literal: str) -> bytes:
22-
"""Decode the Base64 str object `literal` in a bytes."""
24+
"""Decode the Base64 str object ``literal`` in a bytes."""
2325
return b64decode(literal.encode("utf-8"))
2426

2527

2628
class ItemTypeError(Exception):
27-
""""""
29+
"""
30+
Item type exception.
31+
32+
Exception raised when an attempt is made to convert an object to an ``Item`` with an
33+
unsupported type.
34+
"""
2835

2936

3037
class Item(ABC):
38+
"""
39+
Abstract base class for all items in the ``skore`` remote project.
40+
41+
This class provides a common interface for all items, including the serialization of
42+
the parameters needed to recreate the instance from the remote project.
43+
44+
``Item`` is an internal concept that is used as a DTO (Data Transfer Object) to
45+
exchange python objects between ``skore`` and ``skore hub``.
46+
"""
47+
3148
@property
3249
def __parameters__(self) -> dict[str, dict[str, Any]]:
33-
""""""
50+
"""
51+
Get the parameters of the ``Item`` instance.
52+
53+
These parameters must be sufficient to recreate the instance.
54+
They are persisted in the ``skore`` remote project and retrieved as needed.
55+
"""
3456
cls = self.__class__
3557
cls_name = cls.__name__
3658
cls_parameters = inspect_signature(cls).parameters
@@ -44,19 +66,20 @@ def __parameters__(self) -> dict[str, dict[str, Any]]:
4466

4567
@property
4668
def __metadata__(self) -> dict[str, Any]:
69+
"""Get the metadata of the ``Item`` instance."""
4770
return dict()
4871

4972
@property
5073
@abstractmethod
5174
def __raw__(self) -> Any:
52-
""""""
75+
"""Get the raw python object from the ``Item`` instance."""
5376

5477
@property
5578
@abstractmethod
5679
def __representation__(self) -> dict[str, Any]:
57-
""""""
80+
"""Get the representation of the ``Item`` instance."""
5881

5982
@classmethod
6083
@abstractmethod
6184
def factory(cls, *args, **kwargs) -> Item:
62-
""""""
85+
"""Create and return a new instance of ``Item``."""

skore-remote-project/src/skore_remote_project/item/jsonable_item.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
JSONableItem.
3+
4+
This module defines the ``JSONableItem`` class used to serialize objects using the
5+
``JSON`` format.
6+
"""
7+
18
from __future__ import annotations
29

310
from json import dumps, loads
@@ -7,15 +14,27 @@
714

815

916
class JSONableItem(Item):
17+
"""Serialize objects using the ``JSON`` format."""
18+
1019
def __init__(self, value: Any):
20+
"""
21+
Initialize a ``JSONableItem``.
22+
23+
Parameters
24+
----------
25+
value : Any
26+
The value.
27+
"""
1128
self.value = value
1229

1330
@property
1431
def __raw__(self):
32+
"""Get the value from the ``JSONableItem`` instance."""
1533
return self.value
1634

1735
@property
1836
def __representation__(self) -> dict:
37+
"""Get the representation of the ``JSONableItem`` instance."""
1938
return {
2039
"representation": {
2140
"media_type": "application/json",
@@ -24,10 +43,28 @@ def __representation__(self) -> dict:
2443
}
2544

2645
@classmethod
27-
def factory(cls, value: Any, /, **kwargs) -> JSONableItem:
46+
def factory(cls, value: Any, /) -> JSONableItem:
47+
"""
48+
Create a new ``JSONableItem`` from ``value`` using the ``JSON`` format.
49+
50+
Parameters
51+
----------
52+
value: Any
53+
The value to serialize.
54+
55+
Returns
56+
-------
57+
JSONableItem
58+
A new ``JSONableItem`` instance.
59+
60+
Raises
61+
------
62+
ItemTypeError
63+
If ``value`` cannot be serialized using the ``JSON`` format.
64+
"""
2865
try:
2966
value = loads(dumps(value))
3067
except TypeError:
3168
raise ItemTypeError(f"Type '{value.__class__}' is not supported.") from None
3269

33-
return cls(value, **kwargs)
70+
return cls(value)
Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
NumpyArrayItem.
3+
4+
This module defines the ``NumpyArrayItem`` class used to serialize instances of
5+
``numpy.Array``, using binary protocols.
6+
"""
7+
18
from __future__ import annotations
29

310
from functools import cached_property
@@ -9,18 +16,31 @@
916
ItemTypeError,
1017
b64_str_to_bytes,
1118
bytes_to_b64_str,
19+
lazy_is_instance,
1220
)
1321

1422
if TYPE_CHECKING:
1523
import numpy
1624

1725

1826
class NumpyArrayItem(Item):
27+
"""Serialize instances of ``numpy.Array``, using binary protocols."""
28+
1929
def __init__(self, array_b64_str: str):
30+
"""
31+
Initialize a ``NumpyArrayItem``.
32+
33+
Parameters
34+
----------
35+
array_b64_str : str
36+
The raw bytes of the array in the ``numpy`` serialization format, encoded in
37+
base64 string.
38+
"""
2039
self.array_b64_str = array_b64_str
2140

2241
@cached_property
2342
def __raw__(self) -> numpy.ndarray:
43+
"""Get the value from the ``NumpyArrayItem``."""
2444
import numpy
2545

2646
array_bytes = b64_str_to_bytes(self.array_b64_str)
@@ -30,6 +50,7 @@ def __raw__(self) -> numpy.ndarray:
3050

3151
@property
3252
def __representation__(self) -> dict:
53+
"""Get the representation of the ``NumpyArrayItem`` instance."""
3354
return {
3455
"representation": {
3556
"media_type": "application/json",
@@ -38,19 +59,37 @@ def __representation__(self) -> dict:
3859
}
3960

4061
@classmethod
41-
def factory(cls, array: numpy.ndarray, /, **kwargs) -> NumpyArrayItem:
42-
import numpy
62+
def factory(cls, value: numpy.ndarray, /) -> NumpyArrayItem:
63+
"""
64+
Create a new ``NumpyArrayItem`` from ``value`` using binary protocols.
4365
44-
if not isinstance(array, numpy.ndarray):
45-
raise ItemTypeError(f"Type '{array.__class__}' is not supported.")
66+
Parameters
67+
----------
68+
value: Any
69+
The value to serialize.
70+
71+
Returns
72+
-------
73+
NumpyArrayItem
74+
A new ``NumpyArrayItem`` instance.
75+
76+
Raises
77+
------
78+
ItemTypeError
79+
If ``value`` is not an instance of ``numpy.Array``.
80+
"""
81+
if not lazy_is_instance(value, "numpy.ndarray"):
82+
raise ItemTypeError(f"Type '{value.__class__}' is not supported.")
83+
84+
import numpy
4685

4786
with BytesIO() as stream:
48-
numpy.save(stream, array, allow_pickle=False)
87+
numpy.save(stream, value, allow_pickle=False)
4988

5089
array_bytes = stream.getvalue()
5190
array_b64_str = bytes_to_b64_str(array_bytes)
5291

53-
instance = cls(array_b64_str, **kwargs)
54-
instance.__raw__ = array
92+
instance = cls(array_b64_str)
93+
instance.__raw__ = value
5594

5695
return instance

0 commit comments

Comments
 (0)