Skip to content

Date

sereto.models.date

Date

Bases: SeretoBaseModel

Model representing a date with its associated event.

Attributes:

Name Type Description
type DateType

Type of the event.

date SeretoDate | DateRange

Date or date range.

Source code in sereto/models/date.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class Date(SeretoBaseModel):
    """Model representing a date with its associated event.

    Attributes:
        type (DateType): Type of the event.
        date (SeretoDate | DateRange): Date or date range.
    """

    type: DateType
    date: SeretoDate | DateRange

    @model_validator(mode="after")
    def range_allowed(self) -> "Date":
        if isinstance(self.date, DateRange) and self.type not in TYPES_WITH_ALLOWED_RANGE:
            raise ValueError(f"type {self.type} does not have allowed date range, only single date")
        return self

    def __str__(self) -> str:
        match self.date:
            case SeretoDate():
                return str(self.date)
            case DateRange():
                return f"{self.date.start} to {self.date.end}"

DateRange

Bases: SeretoBaseModel

Model representing a period of time with start and end date.

start cannot be equal to end. In that case you should use SeretoDate.

Attributes:

Name Type Description
start SeretoDate

Start date of the period.

end SeretoDate

End date of the period.

Source code in sereto/models/date.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class DateRange(SeretoBaseModel):
    """Model representing a period of time with start and end date.

    `start` cannot be equal to `end`. In that case you should use `SeretoDate`.

    Attributes:
        start (SeretoDate): Start date of the period.
        end (SeretoDate): End date of the period.
    """

    start: SeretoDate
    end: SeretoDate

    @model_validator(mode="after")
    def chronological_order(self) -> "DateRange":
        if self.start >= self.end:
            raise ValueError("DateRange type forbids start after or equal to end")
        return self

DateType

Bases: str, Enum

Enum representing the event type for date.

Source code in sereto/models/date.py
61
62
63
64
65
66
67
class DateType(str, Enum):
    """Enum representing the event type for date."""

    sow_sent = "sow_sent"
    pentest_ongoing = "pentest_ongoing"
    review = "review"
    report_sent = "report_sent"

SeretoDate

Bases: RootModel[date]

Date representation for Pydantic with format %d-%b-%Y.

The %d-%b-%Y format string specifies the format of the date string as follows: - %d: Day of the month as a zero-padded decimal number (e.g. 01, 02, ..., 31). - %b: Month abbreviation in the current locale's abbreviated name (e.g. Jan, Feb, ..., Dec). - %Y: Year with century as a decimal number (e.g. 2021, 2022, ...).

Source code in sereto/models/date.py
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
@total_ordering
class SeretoDate(RootModel[date]):
    """Date representation for Pydantic with format `%d-%b-%Y`.

    The `%d-%b-%Y` format string specifies the format of the date string as follows:
     - `%d`: Day of the month as a zero-padded decimal number (e.g. 01, 02, ..., 31).
     - `%b`: Month abbreviation in the current locale's abbreviated name (e.g. Jan, Feb, ..., Dec).
     - `%Y`: Year with century as a decimal number (e.g. 2021, 2022, ...).
    """

    root: date

    @field_validator("root", mode="before")
    @classmethod
    def convert_date(cls, v: Any) -> date:
        match v:
            case SeretoDate():
                return v.root
            case str():
                return datetime.strptime(v, r"%d-%b-%Y").date()
            case _:
                raise ValueError("invalid type, use string or date")

    @classmethod
    def from_str(cls, v: str) -> "SeretoDate":
        date = datetime.strptime(v, r"%d-%b-%Y").date()
        return cls.model_construct(root=date)

    @field_serializer("root")
    def serialize_root(self, root: date, info: FieldSerializationInfo) -> str:
        return self.__str__()

    def __str__(self) -> str:
        return self.root.strftime(r"%d-%b-%Y")

    def __lt__(self, other: Any) -> bool:
        if not isinstance(other, SeretoDate):
            raise SeretoValueError("comparing SeretoDate with unsupported type")
        return self.root < other.root

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, SeretoDate):
            raise SeretoValueError("comparing SeretoDate with unsupported type")
        return self.root == other.root

    def raw(self) -> date:
        return self.root