Skip to content

Config

sereto.models.config

Config

Bases: SeretoBaseModel

Model representing the full project configuration.

Attributes:

Name Type Description
sereto_version SeretoVersion

Version of SeReTo which produced the config.

version_configs dict[ProjectVersion, VersionConfig]

Configuration for each version of the Project.

Source code in sereto/models/config.py
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
class Config(SeretoBaseModel):
    """Model representing the full project configuration.

    Attributes:
        sereto_version: Version of SeReTo which produced the config.
        version_configs: Configuration for each version of the Project.
    """

    sereto_version: SeretoVersion
    version_configs: dict[ProjectVersion, VersionConfig]

    @classmethod
    @validate_call
    def load_from(cls, file: FilePath) -> Self:
        """Load the configuration from a JSON file.

        Args:
            file: 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(file.read_bytes())
        except FileNotFoundError:
            raise SeretoPathError(f"file not found at '{file}'") from None
        except PermissionError:
            raise SeretoPathError(f"permission denied for '{file}'") from None
        except ValidationError as e:
            raise SeretoValueError(f"invalid config\n\n{e}") from e

    @validate_call
    def dump_json(self, file: FilePath | NewPath) -> None:
        """Write project configuration to a JSON file.

        Args:
            file: The path to the configuration file.
        """
        file.write_text(self.model_dump_json(indent=2) + "\n")

    def iter(self) -> Iterable[VersionConfig]:
        """Iterate over all version configurations."""
        for version in self.versions():
            yield self.version_configs[version]

    @validate_call
    def add_config(self, version: ProjectVersion, config: VersionConfig) -> Self:
        """Add a configuration for a specific version.

        Args:
            version: The version of the configuration.
            config: The configuration.

        Returns:
            The configuration with the added version configuration.
        """
        if version in self.version_configs:
            raise SeretoValueError(f"version '{version}' already exists")

        self.version_configs[version] = config
        return self

    def first_config(self) -> VersionConfig:
        """Get the configuration for the first project version.

        Returns:
            The configuration for the last project version.
        """
        return self.at_version(self.first_version())

    def last_config(self) -> VersionConfig:
        """Get the configuration for the last project version.

        Returns:
            The configuration for the last project version.
        """
        return self.at_version(self.last_version())

    @validate_call
    def update_paths(self, project_path: DirectoryPath) -> Self:
        """Update the full paths of the individual config components.

        When the configuration is loaded, it has no knowledge of the project path. This method updates the paths in the
        individual config components.

        Args:
            project_path: The path to the project directory.

        Returns:
            The configuration with updated paths.
        """
        for version_config in self.iter():
            for target in version_config.targets:
                target.path = project_path / target.uname

        return self

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

        Returns:
            A list of project versions.
        """
        return sorted(list(self.version_configs.keys()))

    @validate_call
    def first_version(self) -> ProjectVersion:
        """Get the first project version present in the configuration.

        Returns:
            The first project version.
        """
        return self.versions()[0]

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

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

    @validate_call
    def at_version(self, version: str | ProjectVersion) -> VersionConfig:
        """Return the configuration at a specific version.

        Args:
            version: Selects which version of the configuration should be returned.

        Returns:
            Configuration for the project at the specified version.

        Raises:
            SeretoValueError: If the specified version is unknown.
        """
        if isinstance(version, str):
            version = ProjectVersion.from_str(version)

        if version not in self.version_configs:
            raise SeretoValueError(f"version '{version}' not found")

        return self.version_configs[version]

add_config(version, config)

Add a configuration for a specific version.

Parameters:

Name Type Description Default
version ProjectVersion

The version of the configuration.

required
config VersionConfig

The configuration.

required

Returns:

Type Description
Self

The configuration with the added version configuration.

Source code in sereto/models/config.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
@validate_call
def add_config(self, version: ProjectVersion, config: VersionConfig) -> Self:
    """Add a configuration for a specific version.

    Args:
        version: The version of the configuration.
        config: The configuration.

    Returns:
        The configuration with the added version configuration.
    """
    if version in self.version_configs:
        raise SeretoValueError(f"version '{version}' already exists")

    self.version_configs[version] = config
    return self

at_version(version)

Return the configuration at a specific version.

Parameters:

Name Type Description Default
version str | ProjectVersion

Selects which version of the configuration should be returned.

required

Returns:

Type Description
VersionConfig

Configuration for the project at the specified version.

Raises:

Type Description
SeretoValueError

If the specified version is unknown.

Source code in sereto/models/config.py
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
@validate_call
def at_version(self, version: str | ProjectVersion) -> VersionConfig:
    """Return the configuration at a specific version.

    Args:
        version: Selects which version of the configuration should be returned.

    Returns:
        Configuration for the project at the specified version.

    Raises:
        SeretoValueError: If the specified version is unknown.
    """
    if isinstance(version, str):
        version = ProjectVersion.from_str(version)

    if version not in self.version_configs:
        raise SeretoValueError(f"version '{version}' not found")

    return self.version_configs[version]

dump_json(file)

Write project configuration to a JSON file.

Parameters:

Name Type Description Default
file FilePath | NewPath

The path to the configuration file.

required
Source code in sereto/models/config.py
316
317
318
319
320
321
322
323
@validate_call
def dump_json(self, file: FilePath | NewPath) -> None:
    """Write project configuration to a JSON file.

    Args:
        file: The path to the configuration file.
    """
    file.write_text(self.model_dump_json(indent=2) + "\n")

first_config()

Get the configuration for the first project version.

Returns:

Type Description
VersionConfig

The configuration for the last project version.

Source code in sereto/models/config.py
347
348
349
350
351
352
353
def first_config(self) -> VersionConfig:
    """Get the configuration for the first project version.

    Returns:
        The configuration for the last project version.
    """
    return self.at_version(self.first_version())

first_version()

Get the first project version present in the configuration.

Returns:

Type Description
ProjectVersion

The first project version.

Source code in sereto/models/config.py
391
392
393
394
395
396
397
398
@validate_call
def first_version(self) -> ProjectVersion:
    """Get the first project version present in the configuration.

    Returns:
        The first project version.
    """
    return self.versions()[0]

iter()

Iterate over all version configurations.

Source code in sereto/models/config.py
325
326
327
328
def iter(self) -> Iterable[VersionConfig]:
    """Iterate over all version configurations."""
    for version in self.versions():
        yield self.version_configs[version]

last_config()

Get the configuration for the last project version.

Returns:

Type Description
VersionConfig

The configuration for the last project version.

Source code in sereto/models/config.py
355
356
357
358
359
360
361
def last_config(self) -> VersionConfig:
    """Get the configuration for the last project version.

    Returns:
        The configuration for the last project version.
    """
    return self.at_version(self.last_version())

last_version()

Get the last project version present in the configuration.

Returns:

Type Description
ProjectVersion

The last project version.

Source code in sereto/models/config.py
400
401
402
403
404
405
406
407
@validate_call
def last_version(self) -> ProjectVersion:
    """Get the last project version present in the configuration.

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

load_from(file) classmethod

Load the configuration from a JSON file.

Parameters:

Name Type Description Default
file FilePath

The path to the configuration file.

required

Returns:

Type Description
Self

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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@classmethod
@validate_call
def load_from(cls, file: FilePath) -> Self:
    """Load the configuration from a JSON file.

    Args:
        file: 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(file.read_bytes())
    except FileNotFoundError:
        raise SeretoPathError(f"file not found at '{file}'") from None
    except PermissionError:
        raise SeretoPathError(f"permission denied for '{file}'") from None
    except ValidationError as e:
        raise SeretoValueError(f"invalid config\n\n{e}") from e

update_paths(project_path)

Update the full paths of the individual config components.

When the configuration is loaded, it has no knowledge of the project path. This method updates the paths in the individual config components.

Parameters:

Name Type Description Default
project_path DirectoryPath

The path to the project directory.

required

Returns:

Type Description
Self

The configuration with updated paths.

Source code in sereto/models/config.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
@validate_call
def update_paths(self, project_path: DirectoryPath) -> Self:
    """Update the full paths of the individual config components.

    When the configuration is loaded, it has no knowledge of the project path. This method updates the paths in the
    individual config components.

    Args:
        project_path: The path to the project directory.

    Returns:
        The configuration with updated paths.
    """
    for version_config in self.iter():
        for target in version_config.targets:
            target.path = project_path / target.uname

    return self

versions()

Get a sorted list of project versions in ascending order.

Returns:

Type Description
list[ProjectVersion]

A list of project versions.

Source code in sereto/models/config.py
382
383
384
385
386
387
388
389
@validate_call
def versions(self) -> list[ProjectVersion]:
    """Get a sorted list of project versions in ascending order.

    Returns:
        A list of project versions.
    """
    return sorted(list(self.version_configs.keys()))

VersionConfig

Bases: SeretoBaseModel

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

Attributes:

Name Type Description
id str

The ID of the project.

name str

The name of the project.

version_description str

The description of the version (e.g. "retest").

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
 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
 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
class VersionConfig(SeretoBaseModel):
    """Model with core attributes for a specific version of the project configuration.

    Attributes:
        id: The ID of the project.
        name: The name of the project.
        version_description: The description of the version (e.g. "retest").
        targets: List of targets.
        dates: List of dates.
        people: List of people.
    """

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

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

    @validate_call
    def filter_targets(
        self,
        category: str | Iterable[str] | None = None,
        name: str | None = None,
        inverse: bool = False,
    ) -> list[Target]:
        """Filter targets based on specified criteria.

        The regular expressions support the syntax of Python's `re` module.

        Args:
            category: The category of the target. Can be a single category, a list of categories, or None.
            name: Regular expression to match the name of the target.
            inverse: If True, return the inverse of the usual results.

        Returns:
            A list of targets matching the criteria.
        """
        if isinstance(category, str):
            category = [category]

        filtered_targets = [
            t
            for t in self.targets
            if (category is None or t.category in category) and (name is None or re.search(name, t.name))
        ]

        if inverse:
            return [t for t in self.targets if t not in filtered_targets]
        return filtered_targets

    @validate_call
    def filter_dates(
        self,
        type: str | DateType | Iterable[str] | Iterable[DateType] | None = None,
        start: str | SeretoDate | None = None,
        end: str | SeretoDate | None = None,
        inverse: bool = False,
    ) -> list[Date]:
        """Filter dates based on specified criteria.

        The start and end dates are inclusive. For date ranges, a date is considered matching if it completely overlaps
        with the specified range.

        Args:
            type: The type of the date. Can be a single type, a list of types, or None.
            start: Only dates on or after this date will be included.
            end: Only dates on or before this date will be included.
            inverse: If True, return the inverse of the usual results.

        Returns:
            A list of dates matching the criteria.
        """
        match type:
            case str():
                type = [DateType(type)]
            case Iterable():
                type = [DateType(t) for t in type]
            case None:
                pass

        if isinstance(start, str):
            start = SeretoDate.from_str(start)
        if isinstance(end, str):
            end = SeretoDate.from_str(end)

        filtered_dates = [
            d
            for d in self.dates
            if (type is None or d.type in type)
            and (
                start is None
                or (isinstance(d.date, SeretoDate) and d.date >= start)
                or (isinstance(d.date, DateRange) and d.date.start >= start)
            )
            and (
                end is None
                or (isinstance(d.date, SeretoDate) and d.date <= end)
                or (isinstance(d.date, DateRange) and d.date.end <= end)
            )
        ]

        if inverse:
            return [d for d in self.dates if d not in filtered_dates]
        return filtered_dates

    @validate_call
    def filter_people(
        self,
        type: str | PersonType | Iterable[str] | Iterable[PersonType] | None = None,
        name: str | None = None,
        business_unit: str | None = None,
        email: str | None = None,
        role: str | None = None,
        inverse: bool = False,
    ) -> list[Person]:
        """Filter people based on specified criteria.

        The regular expressions support the syntax of Python's `re` module.

        Args:
            type: The type of the person. Can be a single type, a list of types, or None.
            name: Regular expression to match the name of the person.
            business_unit: Regular expression to match the business unit of the person.
            email: Regular expression to match the email of the person.
            role: Regular expression to match the role of the person.
            inverse: If True, return the inverse of the usual results.

        Returns:
            A list of people matching the criteria.
        """
        match type:
            case str():
                type = [PersonType(type)]
            case Iterable():
                type = [PersonType(t) for t in type]
            case None:
                pass

        filtered_people = [
            p
            for p in self.people
            if (type is None or p.type in type)
            and (name is None or (p.name is not None and re.search(name, p.name)))
            and (business_unit is None or (p.business_unit is not None and re.search(business_unit, p.business_unit)))
            and (email is None or (p.email is not None and re.search(email, p.email)))
            and (role is None or (p.role is not None and re.search(role, p.role)))
        ]

        if inverse:
            return [p for p in self.people if p not in filtered_people]
        return filtered_people

    @validate_call
    def add_target(self, target: Target) -> Self:
        """Add a target to the configuration.

        Args:
            target: The target to add.

        Returns:
            The configuration with the added target.
        """
        self.targets.append(target)
        return self

    @validate_call
    def delete_target(self, index: int) -> Self:
        """Delete a target from the configuration.

        Args:
            index: The index of the target to delete. First item is 1.

        Returns:
            The configuration with the target deleted.
        """
        # Convert to 0-based index
        index -= 1

        # Check if the index is in the allowed range
        if not 0 <= index <= len(self.targets) - 1:
            raise SeretoValueError("index out of range")

        # Delete the target
        del self.targets[index]

        return self

    @validate_call
    def add_date(self, date: Date) -> Self:
        """Add a date to the configuration.

        Args:
            date: The date to add.

        Returns:
            The configuration with the added date.
        """
        self.dates.append(date)
        return self

    @validate_call
    def delete_date(self, index: int) -> Self:
        """Delete a date from the configuration.

        Args:
            index: The index of the date to delete. First item is 1.

        Returns:
            The configuration with the date deleted.
        """
        # Convert to 0-based index
        index -= 1

        # Check if the index is in the allowed range
        if not 0 <= index <= len(self.dates) - 1:
            raise SeretoValueError("index out of range")

        # Delete the date
        del self.dates[index]

        return self

    @validate_call
    def add_person(self, person: Person) -> Self:
        """Add a person to the configuration.

        Args:
            person: The person to add.

        Returns:
            The configuration with the added person.
        """
        self.people.append(person)
        return self

    @validate_call
    def delete_person(self, index: int) -> Self:
        """Delete a person from the configuration.

        Args:
            index: The index of the person to delete. First item is 1.

        Returns:
            The configuration with the person deleted.
        """
        # Convert to 0-based index
        index -= 1

        # Check if the index is in the allowed range
        if not 0 <= index <= len(self.people) - 1:
            raise SeretoValueError("index out of range")

        # Delete the person
        del self.people[index]

        return self

add_date(date)

Add a date to the configuration.

Parameters:

Name Type Description Default
date Date

The date to add.

required

Returns:

Type Description
Self

The configuration with the added date.

Source code in sereto/models/config.py
210
211
212
213
214
215
216
217
218
219
220
221
@validate_call
def add_date(self, date: Date) -> Self:
    """Add a date to the configuration.

    Args:
        date: The date to add.

    Returns:
        The configuration with the added date.
    """
    self.dates.append(date)
    return self

add_person(person)

Add a person to the configuration.

Parameters:

Name Type Description Default
person Person

The person to add.

required

Returns:

Type Description
Self

The configuration with the added person.

Source code in sereto/models/config.py
245
246
247
248
249
250
251
252
253
254
255
256
@validate_call
def add_person(self, person: Person) -> Self:
    """Add a person to the configuration.

    Args:
        person: The person to add.

    Returns:
        The configuration with the added person.
    """
    self.people.append(person)
    return self

add_target(target)

Add a target to the configuration.

Parameters:

Name Type Description Default
target Target

The target to add.

required

Returns:

Type Description
Self

The configuration with the added target.

Source code in sereto/models/config.py
175
176
177
178
179
180
181
182
183
184
185
186
@validate_call
def add_target(self, target: Target) -> Self:
    """Add a target to the configuration.

    Args:
        target: The target to add.

    Returns:
        The configuration with the added target.
    """
    self.targets.append(target)
    return self

delete_date(index)

Delete a date from the configuration.

Parameters:

Name Type Description Default
index int

The index of the date to delete. First item is 1.

required

Returns:

Type Description
Self

The configuration with the date deleted.

Source code in sereto/models/config.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
@validate_call
def delete_date(self, index: int) -> Self:
    """Delete a date from the configuration.

    Args:
        index: The index of the date to delete. First item is 1.

    Returns:
        The configuration with the date deleted.
    """
    # Convert to 0-based index
    index -= 1

    # Check if the index is in the allowed range
    if not 0 <= index <= len(self.dates) - 1:
        raise SeretoValueError("index out of range")

    # Delete the date
    del self.dates[index]

    return self

delete_person(index)

Delete a person from the configuration.

Parameters:

Name Type Description Default
index int

The index of the person to delete. First item is 1.

required

Returns:

Type Description
Self

The configuration with the person deleted.

Source code in sereto/models/config.py
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
@validate_call
def delete_person(self, index: int) -> Self:
    """Delete a person from the configuration.

    Args:
        index: The index of the person to delete. First item is 1.

    Returns:
        The configuration with the person deleted.
    """
    # Convert to 0-based index
    index -= 1

    # Check if the index is in the allowed range
    if not 0 <= index <= len(self.people) - 1:
        raise SeretoValueError("index out of range")

    # Delete the person
    del self.people[index]

    return self

delete_target(index)

Delete a target from the configuration.

Parameters:

Name Type Description Default
index int

The index of the target to delete. First item is 1.

required

Returns:

Type Description
Self

The configuration with the target deleted.

Source code in sereto/models/config.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
@validate_call
def delete_target(self, index: int) -> Self:
    """Delete a target from the configuration.

    Args:
        index: The index of the target to delete. First item is 1.

    Returns:
        The configuration with the target deleted.
    """
    # Convert to 0-based index
    index -= 1

    # Check if the index is in the allowed range
    if not 0 <= index <= len(self.targets) - 1:
        raise SeretoValueError("index out of range")

    # Delete the target
    del self.targets[index]

    return self

filter_dates(type=None, start=None, end=None, inverse=False)

Filter dates based on specified criteria.

The start and end dates are inclusive. For date ranges, a date is considered matching if it completely overlaps with the specified range.

Parameters:

Name Type Description Default
type str | DateType | Iterable[str] | Iterable[DateType] | None

The type of the date. Can be a single type, a list of types, or None.

None
start str | SeretoDate | None

Only dates on or after this date will be included.

None
end str | SeretoDate | None

Only dates on or before this date will be included.

None
inverse bool

If True, return the inverse of the usual results.

False

Returns:

Type Description
list[Date]

A list of dates matching the criteria.

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
 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
@validate_call
def filter_dates(
    self,
    type: str | DateType | Iterable[str] | Iterable[DateType] | None = None,
    start: str | SeretoDate | None = None,
    end: str | SeretoDate | None = None,
    inverse: bool = False,
) -> list[Date]:
    """Filter dates based on specified criteria.

    The start and end dates are inclusive. For date ranges, a date is considered matching if it completely overlaps
    with the specified range.

    Args:
        type: The type of the date. Can be a single type, a list of types, or None.
        start: Only dates on or after this date will be included.
        end: Only dates on or before this date will be included.
        inverse: If True, return the inverse of the usual results.

    Returns:
        A list of dates matching the criteria.
    """
    match type:
        case str():
            type = [DateType(type)]
        case Iterable():
            type = [DateType(t) for t in type]
        case None:
            pass

    if isinstance(start, str):
        start = SeretoDate.from_str(start)
    if isinstance(end, str):
        end = SeretoDate.from_str(end)

    filtered_dates = [
        d
        for d in self.dates
        if (type is None or d.type in type)
        and (
            start is None
            or (isinstance(d.date, SeretoDate) and d.date >= start)
            or (isinstance(d.date, DateRange) and d.date.start >= start)
        )
        and (
            end is None
            or (isinstance(d.date, SeretoDate) and d.date <= end)
            or (isinstance(d.date, DateRange) and d.date.end <= end)
        )
    ]

    if inverse:
        return [d for d in self.dates if d not in filtered_dates]
    return filtered_dates

filter_people(type=None, name=None, business_unit=None, email=None, role=None, inverse=False)

Filter people based on specified criteria.

The regular expressions support the syntax of Python's re module.

Parameters:

Name Type Description Default
type str | PersonType | Iterable[str] | Iterable[PersonType] | None

The type of the person. Can be a single type, a list of types, or None.

None
name str | None

Regular expression to match the name of the person.

None
business_unit str | None

Regular expression to match the business unit of the person.

None
email str | None

Regular expression to match the email of the person.

None
role str | None

Regular expression to match the role of the person.

None
inverse bool

If True, return the inverse of the usual results.

False

Returns:

Type Description
list[Person]

A list of people matching the criteria.

Source code in sereto/models/config.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
@validate_call
def filter_people(
    self,
    type: str | PersonType | Iterable[str] | Iterable[PersonType] | None = None,
    name: str | None = None,
    business_unit: str | None = None,
    email: str | None = None,
    role: str | None = None,
    inverse: bool = False,
) -> list[Person]:
    """Filter people based on specified criteria.

    The regular expressions support the syntax of Python's `re` module.

    Args:
        type: The type of the person. Can be a single type, a list of types, or None.
        name: Regular expression to match the name of the person.
        business_unit: Regular expression to match the business unit of the person.
        email: Regular expression to match the email of the person.
        role: Regular expression to match the role of the person.
        inverse: If True, return the inverse of the usual results.

    Returns:
        A list of people matching the criteria.
    """
    match type:
        case str():
            type = [PersonType(type)]
        case Iterable():
            type = [PersonType(t) for t in type]
        case None:
            pass

    filtered_people = [
        p
        for p in self.people
        if (type is None or p.type in type)
        and (name is None or (p.name is not None and re.search(name, p.name)))
        and (business_unit is None or (p.business_unit is not None and re.search(business_unit, p.business_unit)))
        and (email is None or (p.email is not None and re.search(email, p.email)))
        and (role is None or (p.role is not None and re.search(role, p.role)))
    ]

    if inverse:
        return [p for p in self.people if p not in filtered_people]
    return filtered_people

filter_targets(category=None, name=None, inverse=False)

Filter targets based on specified criteria.

The regular expressions support the syntax of Python's re module.

Parameters:

Name Type Description Default
category str | Iterable[str] | None

The category of the target. Can be a single category, a list of categories, or None.

None
name str | None

Regular expression to match the name of the target.

None
inverse bool

If True, return the inverse of the usual results.

False

Returns:

Type Description
list[Target]

A list of targets matching the criteria.

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
@validate_call
def filter_targets(
    self,
    category: str | Iterable[str] | None = None,
    name: str | None = None,
    inverse: bool = False,
) -> list[Target]:
    """Filter targets based on specified criteria.

    The regular expressions support the syntax of Python's `re` module.

    Args:
        category: The category of the target. Can be a single category, a list of categories, or None.
        name: Regular expression to match the name of the target.
        inverse: If True, return the inverse of the usual results.

    Returns:
        A list of targets matching the criteria.
    """
    if isinstance(category, str):
        category = [category]

    filtered_targets = [
        t
        for t in self.targets
        if (category is None or t.category in category) and (name is None or re.search(name, t.name))
    ]

    if inverse:
        return [t for t in self.targets if t not in filtered_targets]
    return filtered_targets