Skip to content

Config

sereto.models.config

BaseConfig

Bases: SeretoBaseModel

Model with core attributes for a specific version of the report configuration.

Attributes:

Name Type Description
id str

The ID of the report.

name str

The name of the report.

report_version ReportVersion

The version of the report.

targets list[Target]

List of targets.

dates list[Date]

List of dates.

people list[Person]

List of people.

Source code in sereto/models/config.py
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
class BaseConfig(SeretoBaseModel):
    """Model with core attributes for a specific version of the report configuration.

    Attributes:
        id: The ID of the report.
        name: The name of the report.
        report_version: The version of the report.
        targets: List of targets.
        dates: List of dates.
        people: List of people.
    """

    id: str
    name: str
    report_version: ReportVersion
    targets: list[Target] = []
    dates: list[Date] = []
    people: list[Person] = []

    @model_validator(mode="after")
    def unique_names(self) -> "BaseConfig":
        unames = [target.uname for target in self.targets]
        if len(unames) != len(set(unames)):
            raise ValueError("duplicate target uname")
        return self

Config

Bases: BaseConfig

Model representing the full report configuration.

Attributes:

Name Type Description
sereto_version SeretoVersion

Version of SeReTo which produced the config.

updates list[BaseConfig]

List of updates.

Source code in sereto/models/config.py
 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
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
class Config(BaseConfig):
    """Model representing the full report configuration.

    Attributes:
        sereto_version: Version of SeReTo which produced the config.
        updates: List of updates.
    """

    sereto_version: SeretoVersion
    updates: list[BaseConfig] = Field(default=[])

    @model_validator(mode="after")
    def config_validator(self) -> "Config":
        # if self.id is None or self.name is None:
        #     raise ValueError("'id' and 'name' variables cannot be None")

        previous: BaseConfig = self

        for update in self.updates:
            # report_version is incremented in subsequent update sections
            if previous.report_version >= update.report_version:
                raise ValueError(f"report_version {update.report_version!r} after {previous.report_version!r}")

            # copy values from previous versions, which are not explicitly stated
            for field in ["id", "name", "targets", "people"]:
                if not getattr(update, field):
                    setattr(update, field, deepcopy(getattr(previous, field)))

            previous = update

        return self

    @classmethod
    def from_file(cls, filepath: Path) -> "Config":
        """Load the configuration from a file.

        Args:
            filepath: The path to the configuration file.

        Returns:
            The configuration object.

        Raises:
            SeretoPathError: If the file is not found or permission is denied.
            SeretoValueError: If the configuration is invalid.
        """
        try:
            return cls.model_validate_json(filepath.read_bytes())
        except FileNotFoundError:
            raise SeretoPathError(f"file not found at '{filepath}'") from None
        except PermissionError:
            raise SeretoPathError(f"permission denied for '{filepath}'") from None
        except ValueError as e:
            raise SeretoValueError("invalid config") from e

    @validate_call
    def versions(self) -> list[ReportVersion]:
        """Get a sorted list of report versions in ascending order.

        Returns:
            A list of report versions.
        """
        return [self.report_version] + [update.report_version for update in self.updates]

    @validate_call
    def last_version(self) -> ReportVersion:
        """Get the last report version present in the configuration.

        Returns:
            The last report version.
        """
        return self.versions()[-1]

    def at_version(self, version: str | ReportVersion | None) -> BaseConfig:
        """Return the configuration at a specific version.

        Args:
            version: A version of the report configuration to return. If None is provided, return the whole config with
                all the updates sections.

        Returns:
            Configuration for the report at the specified version.

        Raises:
            SeretoValueError: If the specified version is unknown.
        """
        if version is None:
            return self
        if isinstance(version, str):
            version = ReportVersion.from_str(version)

        # For v1.0, we need to convert Config to BaseConfig (excluding extra fields)
        if self.report_version == version:  # v1.0
            cfg = BaseConfig.model_validate(self.model_dump(exclude={"sereto_version", "updates"}))
            # copy values of the excluded fields
            for t1, t2 in zip(self.targets, cfg.targets, strict=True):
                t2.path = t1.path
            return cfg

        # Otherwise, we need to find the matching update section
        if len(res := [cfg for cfg in self.updates if cfg.report_version == version]) != 1:
            raise SeretoValueError(f"version '{version}' not found")

        return res[0]

at_version(version)

Return the configuration at a specific version.

Parameters:

Name Type Description Default
version str | ReportVersion | None

A version of the report configuration to return. If None is provided, return the whole config with all the updates sections.

required

Returns:

Type Description
BaseConfig

Configuration for the report at the specified version.

Raises:

Type Description
SeretoValueError

If the specified version is unknown.

Source code in sereto/models/config.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def at_version(self, version: str | ReportVersion | None) -> BaseConfig:
    """Return the configuration at a specific version.

    Args:
        version: A version of the report configuration to return. If None is provided, return the whole config with
            all the updates sections.

    Returns:
        Configuration for the report at the specified version.

    Raises:
        SeretoValueError: If the specified version is unknown.
    """
    if version is None:
        return self
    if isinstance(version, str):
        version = ReportVersion.from_str(version)

    # For v1.0, we need to convert Config to BaseConfig (excluding extra fields)
    if self.report_version == version:  # v1.0
        cfg = BaseConfig.model_validate(self.model_dump(exclude={"sereto_version", "updates"}))
        # copy values of the excluded fields
        for t1, t2 in zip(self.targets, cfg.targets, strict=True):
            t2.path = t1.path
        return cfg

    # Otherwise, we need to find the matching update section
    if len(res := [cfg for cfg in self.updates if cfg.report_version == version]) != 1:
        raise SeretoValueError(f"version '{version}' not found")

    return res[0]

from_file(filepath) classmethod

Load the configuration from a file.

Parameters:

Name Type Description Default
filepath Path

The path to the configuration file.

required

Returns:

Type Description
Config

The configuration object.

Raises:

Type Description
SeretoPathError

If the file is not found or permission is denied.

SeretoValueError

If the configuration is invalid.

Source code in sereto/models/config.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@classmethod
def from_file(cls, filepath: Path) -> "Config":
    """Load the configuration from a file.

    Args:
        filepath: The path to the configuration file.

    Returns:
        The configuration object.

    Raises:
        SeretoPathError: If the file is not found or permission is denied.
        SeretoValueError: If the configuration is invalid.
    """
    try:
        return cls.model_validate_json(filepath.read_bytes())
    except FileNotFoundError:
        raise SeretoPathError(f"file not found at '{filepath}'") from None
    except PermissionError:
        raise SeretoPathError(f"permission denied for '{filepath}'") from None
    except ValueError as e:
        raise SeretoValueError("invalid config") from e

last_version()

Get the last report version present in the configuration.

Returns:

Type Description
ReportVersion

The last report version.

Source code in sereto/models/config.py
105
106
107
108
109
110
111
112
@validate_call
def last_version(self) -> ReportVersion:
    """Get the last report version present in the configuration.

    Returns:
        The last report version.
    """
    return self.versions()[-1]

versions()

Get a sorted list of report versions in ascending order.

Returns:

Type Description
list[ReportVersion]

A list of report versions.

Source code in sereto/models/config.py
 96
 97
 98
 99
100
101
102
103
@validate_call
def versions(self) -> list[ReportVersion]:
    """Get a sorted list of report versions in ascending order.

    Returns:
        A list of report versions.
    """
    return [self.report_version] + [update.report_version for update in self.updates]