-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathartifact.py
More file actions
78 lines (57 loc) · 2.3 KB
/
artifact.py
File metadata and controls
78 lines (57 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""Interface definition of the payload used to associate an artifact with a project."""
from abc import ABC, abstractmethod
from contextlib import AbstractContextManager, nullcontext
from functools import cached_property
from typing import cast
from pydantic import BaseModel, ConfigDict, Field, computed_field
from skore_hub_project.artifact.upload import upload
from skore_hub_project.project.project import Project
Content = str | bytes | None
class Artifact(BaseModel, ABC):
"""
Interface definition of the payload used to associate an artifact with a project.
Attributes
----------
project : Project
The project to which the artifact's payload must be associated.
content_type : str
The content-type of the artifact content.
Notes
-----
It triggers the upload of the content of the artifact, in a lazy way. It is uploaded
as a file to the ``hub`` artifacts storage.
"""
model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)
project: Project = Field(repr=False, exclude=True)
content_type: str = Field(init=False)
@abstractmethod
def content_to_upload(self) -> Content | AbstractContextManager[Content]:
"""
Content of the artifact to upload.
Example
-------
You can implement this ``abstractmethod`` to return directly the content:
def content_to_upload(self) -> str:
return "<str>"
or to yield the content, as a ``contextmanager`` would:
from contextlib import contextmanager
@contextmanager
def content_to_upload(self) -> Generator[str, None, None]:
yield "<str>"
"""
@computed_field
@cached_property
def checksum(self) -> str | None:
"""Checksum used to identify the content of the artifact."""
contextmanager = self.content_to_upload()
if not isinstance(contextmanager, AbstractContextManager):
contextmanager = nullcontext(contextmanager)
with contextmanager as content:
if content is None:
return None
content = cast(str | bytes, content)
return upload(
project=self.project,
content=content,
content_type=self.content_type,
)