value-object-pattern 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- value_object_pattern/__init__.py +10 -0
- value_object_pattern/decorators/__init__.py +7 -0
- value_object_pattern/decorators/value_object_process.py +83 -0
- value_object_pattern/decorators/value_object_validation.py +78 -0
- value_object_pattern/models/__init__.py +3 -0
- value_object_pattern/models/value_object.py +383 -0
- value_object_pattern/py.typed +0 -0
- value_object_pattern/usables/__init__.py +54 -0
- value_object_pattern/usables/dates/__init__.py +9 -0
- value_object_pattern/usables/dates/date/__init__.py +7 -0
- value_object_pattern/usables/dates/date/date_value_object.py +162 -0
- value_object_pattern/usables/dates/date/string_date_value_object.py +201 -0
- value_object_pattern/usables/dates/datetime/__init__.py +7 -0
- value_object_pattern/usables/dates/datetime/datetime_value_object.py +193 -0
- value_object_pattern/usables/dates/datetime/string_datetime_value_object.py +237 -0
- value_object_pattern/usables/identifiers/__init__.py +7 -0
- value_object_pattern/usables/identifiers/country_ids/__init__.py +3 -0
- value_object_pattern/usables/identifiers/country_ids/spain/__init__.py +3 -0
- value_object_pattern/usables/identifiers/country_ids/spain/dni_value_object.py +63 -0
- value_object_pattern/usables/identifiers/string_uuid_value_object.py +56 -0
- value_object_pattern/usables/identifiers/uuid_value_object.py +40 -0
- value_object_pattern/usables/internet/__init__.py +38 -0
- value_object_pattern/usables/internet/api_keys/__init__.py +13 -0
- value_object_pattern/usables/internet/api_keys/aws_access_key_id_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/aws_secret_access_key_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/github_personal_access_token_value_object.py +41 -0
- value_object_pattern/usables/internet/api_keys/openai_api_key_value_object.py +40 -0
- value_object_pattern/usables/internet/api_keys/resend_api_key_value_object.py +40 -0
- value_object_pattern/usables/internet/aws_cloud_region_value_object.py +77 -0
- value_object_pattern/usables/internet/domain_value_object.py +149 -0
- value_object_pattern/usables/internet/host_value_object.py +143 -0
- value_object_pattern/usables/internet/ipv4_address_value_object.py +305 -0
- value_object_pattern/usables/internet/ipv4_network_value_object.py +165 -0
- value_object_pattern/usables/internet/ipv6_address_value_object.py +288 -0
- value_object_pattern/usables/internet/ipv6_network_value_object.py +145 -0
- value_object_pattern/usables/internet/mac_address_value_object.py +390 -0
- value_object_pattern/usables/internet/port_value_object.py +682 -0
- value_object_pattern/usables/internet/uri/__init__.py +11 -0
- value_object_pattern/usables/internet/uri/http_https_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/http_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/https_url_value_object.py +39 -0
- value_object_pattern/usables/internet/uri/url_value_object.py +396 -0
- value_object_pattern/usables/primitives/__init__.py +45 -0
- value_object_pattern/usables/primitives/boolean/__init__.py +9 -0
- value_object_pattern/usables/primitives/boolean/boolean_value_object.py +36 -0
- value_object_pattern/usables/primitives/boolean/false_value_object.py +37 -0
- value_object_pattern/usables/primitives/boolean/true_value_object.py +37 -0
- value_object_pattern/usables/primitives/bytes/__init__.py +3 -0
- value_object_pattern/usables/primitives/bytes/bytes_value_object.py +36 -0
- value_object_pattern/usables/primitives/float/__init__.py +9 -0
- value_object_pattern/usables/primitives/float/float_value_object.py +36 -0
- value_object_pattern/usables/primitives/float/negative_float_value_object.py +37 -0
- value_object_pattern/usables/primitives/float/positive_float_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/__init__.py +13 -0
- value_object_pattern/usables/primitives/integer/even_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/integer_value_object.py +36 -0
- value_object_pattern/usables/primitives/integer/negative_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/odd_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/integer/positive_integer_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/__init__.py +21 -0
- value_object_pattern/usables/primitives/string/alpha_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/alphanumeric_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/digit_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/lowercase_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/non_empty_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/printable_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/string_value_object.py +36 -0
- value_object_pattern/usables/primitives/string/trimmed_string_value_object.py +37 -0
- value_object_pattern/usables/primitives/string/uppercase_string_value_object.py +37 -0
- value_object_pattern-0.1.0.dist-info/METADATA +95 -0
- value_object_pattern-0.1.0.dist-info/RECORD +73 -0
- value_object_pattern-0.1.0.dist-info/WHEEL +4 -0
- value_object_pattern-0.1.0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
"""
|
2
|
+
StringDatetimeValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from datetime import UTC, datetime
|
6
|
+
|
7
|
+
from dateutil.parser import ParserError, parse
|
8
|
+
from dateutil.relativedelta import relativedelta
|
9
|
+
|
10
|
+
from value_object_pattern.decorators import process, validation
|
11
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
12
|
+
|
13
|
+
from .datetime_value_object import DatetimeValueObject
|
14
|
+
|
15
|
+
|
16
|
+
class StringDatetimeValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
17
|
+
"""
|
18
|
+
StringDatetimeValueObject value object ensures the provided value is a valid datetime.
|
19
|
+
|
20
|
+
Example:
|
21
|
+
```python
|
22
|
+
from value_object_pattern.usables.dates import StringDatetimeValueObject
|
23
|
+
|
24
|
+
now = '1900-01-01T00:00:00+00:00'
|
25
|
+
date = StringDatetimeValueObject(value=now)
|
26
|
+
|
27
|
+
print(repr(date))
|
28
|
+
# >>> StringDatetimeValueObject(value=1900-01-01T00:00:00+00:00)
|
29
|
+
```
|
30
|
+
"""
|
31
|
+
|
32
|
+
@process(order=0)
|
33
|
+
def _ensure_value_is_normalized(self, value: str) -> str:
|
34
|
+
"""
|
35
|
+
Ensures the value object value is normalized datetime string (ISO 8601, YYYY-MM-DDTHH:MM:SS).
|
36
|
+
|
37
|
+
Args:
|
38
|
+
value (str): Value.
|
39
|
+
|
40
|
+
Returns:
|
41
|
+
str: Value with the normalized datetime string.
|
42
|
+
"""
|
43
|
+
return self._datetime_normalize(value=value).isoformat()
|
44
|
+
|
45
|
+
@validation(order=0)
|
46
|
+
def _ensure_value_is_date(self, value: str) -> None:
|
47
|
+
"""
|
48
|
+
Ensures the value object value is a datetime.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
value (str): Value.
|
52
|
+
|
53
|
+
Raises:
|
54
|
+
ValueError: If the value is not a datetime.
|
55
|
+
"""
|
56
|
+
self._datetime_normalize(value=value)
|
57
|
+
|
58
|
+
@classmethod
|
59
|
+
def _datetime_normalize(cls, value: str) -> datetime:
|
60
|
+
"""
|
61
|
+
Normalizes the given datetime.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
value (str): datetime.
|
65
|
+
|
66
|
+
Raises:
|
67
|
+
TypeError: If the value is not a string.
|
68
|
+
ValueError: If the value is not a valid datetime.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
str: Normalized datetime.
|
72
|
+
"""
|
73
|
+
if type(value) is not str:
|
74
|
+
raise TypeError(f'StringDatetimeValueObject value <<<{value}>>> must be a string. Got <<<{type(value).__name__}>>> type.') # noqa: E501 # fmt: skip
|
75
|
+
|
76
|
+
try:
|
77
|
+
return parse(timestr=value).astimezone(tz=UTC)
|
78
|
+
|
79
|
+
except ParserError as error:
|
80
|
+
raise ValueError(f'StringDatetimeValueObject value <<<{value}>>> is not a valid datetime.') from error
|
81
|
+
|
82
|
+
def is_now(self, *, reference_datetime: datetime | None = None) -> bool:
|
83
|
+
"""
|
84
|
+
Determines whether the stored datetime value matches the current datetime.
|
85
|
+
|
86
|
+
Args:
|
87
|
+
reference_datetime (datetime | None, optional): The datetime to compare against. If None, the current
|
88
|
+
datetime (UTC) is used.
|
89
|
+
|
90
|
+
Raises:
|
91
|
+
TypeError: If the reference_datetime is not a datetime.
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
bool: True if the stored datetime matches the current datetime, False otherwise.
|
95
|
+
|
96
|
+
Example:
|
97
|
+
```python
|
98
|
+
from datetime import UTC, datetime
|
99
|
+
|
100
|
+
from value_object_pattern.usables.dates import StringDatetimeValueObject
|
101
|
+
|
102
|
+
now = '1900-01-01T08:30:00+00:00'
|
103
|
+
today = datetime(year=1900, month=1, day=1, hour=0, minute=0, second=0, tzinfo=UTC)
|
104
|
+
is_now = StringDatetimeValueObject(value=now).is_now(reference_datetime=today)
|
105
|
+
|
106
|
+
print(is_now)
|
107
|
+
# >>> False
|
108
|
+
```
|
109
|
+
"""
|
110
|
+
if reference_datetime is None:
|
111
|
+
reference_datetime = datetime.now(tz=UTC)
|
112
|
+
|
113
|
+
date_value = self._datetime_normalize(value=self.value)
|
114
|
+
DatetimeValueObject(value=reference_datetime)
|
115
|
+
|
116
|
+
return date_value == reference_datetime
|
117
|
+
|
118
|
+
def is_today(self, *, reference_datetime: datetime | None = None) -> bool:
|
119
|
+
"""
|
120
|
+
Determines whether the stored datetime value is today's datetime.
|
121
|
+
|
122
|
+
Args:
|
123
|
+
reference_datetime (datetime | None, optional): The datetime to compare against. If None, the current
|
124
|
+
datetime (UTC) is used.
|
125
|
+
|
126
|
+
Raises:
|
127
|
+
TypeError: If the reference_datetime is not a datetime.
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
bool: True if the stored datetime matches today's datetime, False otherwise.
|
131
|
+
|
132
|
+
Example:
|
133
|
+
```python
|
134
|
+
from datetime import UTC, datetime
|
135
|
+
|
136
|
+
from value_object_pattern.usables.dates import StringDatetimeValueObject
|
137
|
+
|
138
|
+
now = '1900-01-01T08:30:00+00:00'
|
139
|
+
today = datetime(year=1900, month=1, day=1, hour=0, minute=0, second=0, tzinfo=UTC)
|
140
|
+
is_today = StringDatetimeValueObject(value=now).is_today(reference_datetime=today)
|
141
|
+
|
142
|
+
print(is_today)
|
143
|
+
# >>> True
|
144
|
+
```
|
145
|
+
"""
|
146
|
+
if reference_datetime is None:
|
147
|
+
reference_datetime = datetime.now(tz=UTC)
|
148
|
+
|
149
|
+
date_value = self._datetime_normalize(value=self.value)
|
150
|
+
DatetimeValueObject(value=reference_datetime)
|
151
|
+
|
152
|
+
return date_value.date() == reference_datetime.date()
|
153
|
+
|
154
|
+
def is_in_range(self, *, start_datetime: datetime, end_datetime: datetime) -> bool:
|
155
|
+
"""
|
156
|
+
Determines whether the stored datetime value falls within the specified datetime range.
|
157
|
+
|
158
|
+
Args:
|
159
|
+
start_datetime (datetime): The beginning of the datetime range (inclusive).
|
160
|
+
end_datetime (datetime): The end of the datetime range (inclusive).
|
161
|
+
|
162
|
+
Raises:
|
163
|
+
TypeError: If start_datetime is not a datetime.
|
164
|
+
TypeError: If end_datetime is not a datetime.
|
165
|
+
ValueError: If start_datetime is later than end_datetime.
|
166
|
+
|
167
|
+
Returns:
|
168
|
+
bool: True if the stored datetime is within the range, False otherwise.
|
169
|
+
|
170
|
+
Example:
|
171
|
+
```python
|
172
|
+
from datetime import UTC, datetime
|
173
|
+
|
174
|
+
from value_object_pattern.usables.dates import StringDatetimeValueObject
|
175
|
+
|
176
|
+
now = '1900-01-01T00:00:00+00:00'
|
177
|
+
start_datetime = datetime(year=1899, month=12, day=31, hour=23, minute=59, second=59, tzinfo=UTC)
|
178
|
+
end_datetime = datetime(year=1900, month=1, day=2, hour=00, minute=00, second=00, tzinfo=UTC)
|
179
|
+
is_in_range = StringDatetimeValueObject(
|
180
|
+
value=now,
|
181
|
+
).is_in_range(
|
182
|
+
start_datetime=start_datetime,
|
183
|
+
end_datetime=end_datetime,
|
184
|
+
)
|
185
|
+
|
186
|
+
print(is_in_range)
|
187
|
+
# >>> True
|
188
|
+
```
|
189
|
+
"""
|
190
|
+
date_value = self._datetime_normalize(value=self.value)
|
191
|
+
DatetimeValueObject(value=start_datetime)
|
192
|
+
DatetimeValueObject(value=end_datetime)
|
193
|
+
|
194
|
+
if start_datetime > end_datetime:
|
195
|
+
raise ValueError(f'StringDatetimeValueObject start_datetime <<<{start_datetime.isoformat()}>>> must be earlier than or equal to end_datetime <<<{end_datetime.isoformat()}>>>.') # noqa: E501 # fmt: skip
|
196
|
+
|
197
|
+
return start_datetime <= date_value <= end_datetime
|
198
|
+
|
199
|
+
def calculate_age(self, *, reference_datetime: datetime | None = None) -> int:
|
200
|
+
"""
|
201
|
+
Calculates the age of the stored datetime value.
|
202
|
+
|
203
|
+
Args:
|
204
|
+
reference_datetime (datetime | None, optional): The datetime to calculate the age against. If None, the
|
205
|
+
current datetime (UTC) is used.
|
206
|
+
|
207
|
+
Raises:
|
208
|
+
TypeError: If the reference_datetime is not a datetime.
|
209
|
+
ValueError: If the stored datetime is later than the reference_datetime.
|
210
|
+
|
211
|
+
Returns:
|
212
|
+
int: The age in years of the stored datetime.
|
213
|
+
|
214
|
+
Example:
|
215
|
+
```python
|
216
|
+
from datetime import UTC, datetime
|
217
|
+
|
218
|
+
from value_object_pattern.usables.dates import StringDatetimeValueObject
|
219
|
+
|
220
|
+
now = '1900-01-01T00:00:00+00:00'
|
221
|
+
today = datetime(year=2000, month=1, day=1, hour=0, minute=0, second=0, tzinfo=UTC)
|
222
|
+
age = StringDatetimeValueObject(value=now).calculate_age(reference_datetime=today)
|
223
|
+
|
224
|
+
print(age)
|
225
|
+
# >>> 100
|
226
|
+
```
|
227
|
+
"""
|
228
|
+
if reference_datetime is None:
|
229
|
+
reference_datetime = datetime.now(tz=UTC)
|
230
|
+
|
231
|
+
datetime_value = self._datetime_normalize(value=self.value)
|
232
|
+
DatetimeValueObject(value=reference_datetime)
|
233
|
+
|
234
|
+
if datetime_value > reference_datetime:
|
235
|
+
raise ValueError(f'StringDatetimeValueObject value <<<{datetime_value.isoformat()}>>> must be earlier than or equal to reference_datetime <<<{reference_datetime.isoformat()}>>>.') # noqa: E501 # fmt: skip
|
236
|
+
|
237
|
+
return relativedelta(dt1=reference_datetime, dt2=datetime_value).years
|
@@ -0,0 +1,63 @@
|
|
1
|
+
"""
|
2
|
+
DniValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import process, validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class DniValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
DniValueObject value object ensures the provided value is a valid Spanish DNI.
|
14
|
+
A Spanish DNI is a string with 9 characters. The first 8 characters are numbers and the last character is a letter.
|
15
|
+
The letter is calculated using the number modulo 23 and the result is compared with a predefined list of letters.
|
16
|
+
|
17
|
+
Example:
|
18
|
+
```python
|
19
|
+
from value_object_pattern.usables.identifiers.country_ids import DniValueObject
|
20
|
+
|
21
|
+
dni = DniValueObject(value='87654321X')
|
22
|
+
|
23
|
+
print(repr(dni))
|
24
|
+
# >>> DniValueObject(value=87654321X)
|
25
|
+
```
|
26
|
+
"""
|
27
|
+
|
28
|
+
__DNI_VALUE_OBJECT_LETTERS: str = 'TRWAGMYFPDXBNJZSQVHLCKE'
|
29
|
+
__DNI_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'([0-9]{8})([a-zA-Z])')
|
30
|
+
|
31
|
+
@process(order=0)
|
32
|
+
def _ensure_value_is_upper(self, value: str) -> str:
|
33
|
+
"""
|
34
|
+
Ensures the value object `value` is an upper string.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
value (str): The provided value.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
str: Upper case value.
|
41
|
+
"""
|
42
|
+
return value.upper()
|
43
|
+
|
44
|
+
@validation(order=0)
|
45
|
+
def _ensure_value_is_dni(self, value: str) -> None:
|
46
|
+
"""
|
47
|
+
Ensures the value object `value` is a Spanish DNI.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
value (str): The provided value.
|
51
|
+
|
52
|
+
Raises:
|
53
|
+
ValueError: If the `value` is not a Spanish DNI.
|
54
|
+
"""
|
55
|
+
match = self.__DNI_VALUE_OBJECT_REGEX.fullmatch(string=value)
|
56
|
+
if not match:
|
57
|
+
raise ValueError(f'DniValueObject value <<<{value}>>> is not a valid Spanish DNI.')
|
58
|
+
|
59
|
+
number, letter = match.groups()
|
60
|
+
|
61
|
+
expected_letter = self.__DNI_VALUE_OBJECT_LETTERS[int(number) % 23]
|
62
|
+
if letter.upper() != expected_letter:
|
63
|
+
raise ValueError(f'DniValueObject value <<<{value}>>> is not a valid Spanish DNI.')
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"""
|
2
|
+
StringUuidValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
from uuid import UUID
|
8
|
+
|
9
|
+
from value_object_pattern.decorators import process, validation
|
10
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
11
|
+
|
12
|
+
|
13
|
+
class StringUuidValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
14
|
+
"""
|
15
|
+
StringUuidValueObject value object ensures the provided value is a valid UUID.
|
16
|
+
|
17
|
+
Example:
|
18
|
+
```python
|
19
|
+
from value_object_pattern.usables.identifiers import StringUuidValueObject
|
20
|
+
|
21
|
+
uuid = StringUuidValueObject(value='9908bb2d-54b4-426f-bef0-b09aa978ed21')
|
22
|
+
|
23
|
+
print(repr(uuid))
|
24
|
+
# >>> StringUuidValueObject(value=9908bb2d-54b4-426f-bef0-b09aa978ed21)
|
25
|
+
```
|
26
|
+
"""
|
27
|
+
|
28
|
+
@process(order=0)
|
29
|
+
def _ensure_value_is_lower(self, value: str) -> str:
|
30
|
+
"""
|
31
|
+
Ensures the value object `value` is lower UUID string.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (str): The provided value.
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
str: Value with the lower UUID string.
|
38
|
+
"""
|
39
|
+
return value.lower()
|
40
|
+
|
41
|
+
@validation(order=0)
|
42
|
+
def _ensure_value_is_uuid(self, value: str) -> None:
|
43
|
+
"""
|
44
|
+
Ensures the value object `value` is a UUID.
|
45
|
+
|
46
|
+
Args:
|
47
|
+
value (str): The provided value.
|
48
|
+
|
49
|
+
Raises:
|
50
|
+
ValueError: If the `value` is not a UUID.
|
51
|
+
"""
|
52
|
+
try:
|
53
|
+
UUID(hex=value)
|
54
|
+
|
55
|
+
except ValueError as error:
|
56
|
+
raise ValueError(f'StringUuidValueObject value <<<{value}>>> is not a valid UUID.') from error
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
UuidValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from uuid import UUID
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.models import ValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class UuidValueObject(ValueObject[UUID]):
|
12
|
+
"""
|
13
|
+
UuidValueObject value object ensures the provided value is a valid UUID.
|
14
|
+
|
15
|
+
Example:
|
16
|
+
```python
|
17
|
+
from uuid import uuid4
|
18
|
+
|
19
|
+
from value_object_pattern.usables.identifiers import UuidValueObject
|
20
|
+
|
21
|
+
uuid = UuidValueObject(value=uuid4())
|
22
|
+
|
23
|
+
print(repr(uuid))
|
24
|
+
# >>> UuidValueObject(value=9908bb2d-54b4-426f-bef0-b09aa978ed21)
|
25
|
+
```
|
26
|
+
"""
|
27
|
+
|
28
|
+
@validation(order=0)
|
29
|
+
def _ensure_value_is_uuid(self, value: UUID) -> None:
|
30
|
+
"""
|
31
|
+
Ensures the value object `value` is a UUID.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (UUID): The provided value.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
TypeError: If the `value` is not a UUID.
|
38
|
+
"""
|
39
|
+
if type(value) is not UUID:
|
40
|
+
raise TypeError(f'UuidValueObject value <<<{value}>>> must be a UUID. Got <<<{type(value).__name__}>>> type.') # noqa: E501 # fmt: skip
|
@@ -0,0 +1,38 @@
|
|
1
|
+
from .api_keys import (
|
2
|
+
AwsAccessKeyValueObject,
|
3
|
+
AwsSecretAccessKeyValueObject,
|
4
|
+
GitHubPersonalAccessTokenValueObject,
|
5
|
+
OpenaiApiKeyValueObject,
|
6
|
+
ResendApiKeyValueObject,
|
7
|
+
)
|
8
|
+
from .aws_cloud_region_value_object import AwsCloudRegionValueObject
|
9
|
+
from .domain_value_object import DomainValueObject
|
10
|
+
from .host_value_object import HostValueObject
|
11
|
+
from .ipv4_address_value_object import Ipv4AddressValueObject
|
12
|
+
from .ipv4_network_value_object import Ipv4NetworkValueObject
|
13
|
+
from .ipv6_address_value_object import Ipv6AddressValueObject
|
14
|
+
from .ipv6_network_value_object import Ipv6NetworkValueObject
|
15
|
+
from .mac_address_value_object import MacAddressValueObject
|
16
|
+
from .port_value_object import PortValueObject
|
17
|
+
from .uri import HttpHttpsUrlValueObject, HttpUrlValueObject, HttpsUrlValueObject, UrlValueObject
|
18
|
+
|
19
|
+
__all__ = (
|
20
|
+
'AwsAccessKeyValueObject',
|
21
|
+
'AwsCloudRegionValueObject',
|
22
|
+
'AwsSecretAccessKeyValueObject',
|
23
|
+
'DomainValueObject',
|
24
|
+
'GitHubPersonalAccessTokenValueObject',
|
25
|
+
'HostValueObject',
|
26
|
+
'HttpHttpsUrlValueObject',
|
27
|
+
'HttpUrlValueObject',
|
28
|
+
'HttpsUrlValueObject',
|
29
|
+
'Ipv4AddressValueObject',
|
30
|
+
'Ipv4NetworkValueObject',
|
31
|
+
'Ipv6AddressValueObject',
|
32
|
+
'Ipv6NetworkValueObject',
|
33
|
+
'MacAddressValueObject',
|
34
|
+
'OpenaiApiKeyValueObject',
|
35
|
+
'PortValueObject',
|
36
|
+
'ResendApiKeyValueObject',
|
37
|
+
'UrlValueObject',
|
38
|
+
)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from .aws_access_key_id_value_object import AwsAccessKeyValueObject
|
2
|
+
from .aws_secret_access_key_value_object import AwsSecretAccessKeyValueObject
|
3
|
+
from .github_personal_access_token_value_object import GitHubPersonalAccessTokenValueObject
|
4
|
+
from .openai_api_key_value_object import OpenaiApiKeyValueObject
|
5
|
+
from .resend_api_key_value_object import ResendApiKeyValueObject
|
6
|
+
|
7
|
+
__all__ = (
|
8
|
+
'AwsAccessKeyValueObject',
|
9
|
+
'AwsSecretAccessKeyValueObject',
|
10
|
+
'GitHubPersonalAccessTokenValueObject',
|
11
|
+
'OpenaiApiKeyValueObject',
|
12
|
+
'ResendApiKeyValueObject',
|
13
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
AwsAccessKeyValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class AwsAccessKeyValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
AwsAccessKeyValueObject value object ensures the provided value is a valid AWS Access Key ID.
|
14
|
+
|
15
|
+
Example:
|
16
|
+
```python
|
17
|
+
from value_object_pattern.usables.internet import AwsAccessKeyValueObject
|
18
|
+
|
19
|
+
key = AwsAccessKeyValueObject(value='AKIAIOSFODNN7EXAMPLE') # gitleaks:allow
|
20
|
+
|
21
|
+
print(repr(key))
|
22
|
+
# >>> AwsAccessKeyValueObject(value=AKIAIOSFODNN7EXAMPLE) # gitleaks:allow
|
23
|
+
```
|
24
|
+
"""
|
25
|
+
|
26
|
+
__AWS_ACCESS_KEY_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'^(AKIA|ASIA)[A-Z0-9]{16}$')
|
27
|
+
|
28
|
+
@validation(order=0)
|
29
|
+
def _ensure_value_is_valid_aws_access_key(self, value: str) -> None:
|
30
|
+
"""
|
31
|
+
Ensures the value object value is a valid AWS Access Key ID.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (str): Value.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
ValueError: If the value is not a valid AWS Access Key ID.
|
38
|
+
"""
|
39
|
+
if not self.__AWS_ACCESS_KEY_VALUE_OBJECT_REGEX.fullmatch(string=value):
|
40
|
+
raise ValueError(f'AwsAccessKeyValueObject value <<<{value}>>> is not a valid AWS Access Key ID.')
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
AwsSecretAccessKeyValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class AwsSecretAccessKeyValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
AwsSecretAccessKeyValueObject value object ensures the provided value is a valid AWS Secret Access Key.
|
14
|
+
|
15
|
+
Example:
|
16
|
+
```python
|
17
|
+
from value_object_pattern.usables.internet import AwsSecretAccessKeyValueObject
|
18
|
+
|
19
|
+
key = AwsSecretAccessKeyValueObject(value='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY') # gitleaks:allow
|
20
|
+
|
21
|
+
print(repr(key))
|
22
|
+
# >>> AwsSecretAccessKeyValueObject(value=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY) # gitleaks:allow
|
23
|
+
```
|
24
|
+
"""
|
25
|
+
|
26
|
+
__AWS_SECRET_ACCESS_KEY_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'^[a-zA-Z0-9/+=]{40}$')
|
27
|
+
|
28
|
+
@validation(order=0)
|
29
|
+
def _ensure_value_is_valid_aws_secret_access_key(self, value: str) -> None:
|
30
|
+
"""
|
31
|
+
Ensures the value object value is a valid AWS Secret Access Key.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (str): Value.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
ValueError: If the value is not a valid AWS Secret Access Key.
|
38
|
+
"""
|
39
|
+
if not self.__AWS_SECRET_ACCESS_KEY_VALUE_OBJECT_REGEX.fullmatch(string=value):
|
40
|
+
raise ValueError(f'AwsSecretAccessKeyValueObject value <<<{value}>>> is not a valid AWS Secret Access Key.')
|
@@ -0,0 +1,41 @@
|
|
1
|
+
"""
|
2
|
+
GitHubPersonalAccessTokenValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class GitHubPersonalAccessTokenValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
GitHubPersonalAccessTokenValueObject value object ensures the provided value is a valid GitHub Personal Access
|
14
|
+
Token.
|
15
|
+
|
16
|
+
Example:
|
17
|
+
```python
|
18
|
+
from value_object_pattern.usables.internet import GitHubPersonalAccessTokenValueObject
|
19
|
+
|
20
|
+
key = GitHubPersonalAccessTokenValueObject(value='ghp_cgq4ZrHmFu0lLPl7ajKAwgMPnT5zhF000000') # gitleaks:allow
|
21
|
+
|
22
|
+
print(repr(key))
|
23
|
+
# >>> GitHubPersonalAccessTokenValueObject(value=ghp_cgq4ZrHmFu0lLPl7ajKAwgMPnT5zhF000000) # gitleaks:allow
|
24
|
+
```
|
25
|
+
"""
|
26
|
+
|
27
|
+
__GITHUB_PERSONAL_ACCESS_TOKEN_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'^ghp_[a-zA-Z0-9]{36}$')
|
28
|
+
|
29
|
+
@validation(order=0)
|
30
|
+
def _ensure_value_is_valid_github_pat(self, value: str) -> None:
|
31
|
+
"""
|
32
|
+
Ensures the value object value is a valid GitHub Personal Access Token.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
value (str): Value.
|
36
|
+
|
37
|
+
Raises:
|
38
|
+
ValueError: If the value is not a valid GitHub Personal Access Token
|
39
|
+
"""
|
40
|
+
if not self.__GITHUB_PERSONAL_ACCESS_TOKEN_VALUE_OBJECT_REGEX.fullmatch(string=value):
|
41
|
+
raise ValueError(f'GitHubPersonalAccessTokenValueObject value <<<{value}>>> is not a valid GitHub Personal Access Token.') # noqa: E501 # fmt: skip
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
OpenaiApiKeyValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class OpenaiApiKeyValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
OpenaiApiKeyValueObject value object ensures the provided value is a valid OpenAI API Key.
|
14
|
+
|
15
|
+
Example:
|
16
|
+
```python
|
17
|
+
from value_object_pattern.usables.internet import OpenaiApiKeyValueObject
|
18
|
+
|
19
|
+
key = OpenaiApiKeyValueObject(value='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') # gitleaks:allow
|
20
|
+
|
21
|
+
print(repr(key))
|
22
|
+
# >>> OpenaiApiKeyValueObject(value=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) # gitleaks:allow
|
23
|
+
```
|
24
|
+
"""
|
25
|
+
|
26
|
+
__OPENAI_API_KEY_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'^sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20}$') # noqa: E501 # fmt: skip
|
27
|
+
|
28
|
+
@validation(order=0)
|
29
|
+
def _ensure_value_is_valid_openai_api_key(self, value: str) -> None:
|
30
|
+
"""
|
31
|
+
Ensures the value object value is a valid OpenAI API Key.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (str): Value.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
ValueError: If the value is not a valid OpenAI API Key.
|
38
|
+
"""
|
39
|
+
if not self.__OPENAI_API_KEY_VALUE_OBJECT_REGEX.fullmatch(string=value):
|
40
|
+
raise ValueError(f'OpenaiApiKeyValueObject value <<<{value}>>> is not a valid OpenAI API Key.')
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
ResendApiKeyValueObject value object.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from re import Pattern, compile as re_compile
|
6
|
+
|
7
|
+
from value_object_pattern.decorators import validation
|
8
|
+
from value_object_pattern.usables import NotEmptyStringValueObject, TrimmedStringValueObject
|
9
|
+
|
10
|
+
|
11
|
+
class ResendApiKeyValueObject(NotEmptyStringValueObject, TrimmedStringValueObject):
|
12
|
+
"""
|
13
|
+
ResendApiKeyValueObject value object ensures the provided value is a valid Resend API Key.
|
14
|
+
|
15
|
+
Example:
|
16
|
+
```python
|
17
|
+
from value_object_pattern.usables.internet import ResendApiKeyValueObject
|
18
|
+
|
19
|
+
key = ResendApiKeyValueObject(value='re_c1tpEyD8_NKFusih9vKVQknRAQfmFcWCv') # gitleaks:allow
|
20
|
+
|
21
|
+
print(repr(key))
|
22
|
+
# >>> ResendApiKeyValueObject(value=re_c1tpEyD8_NKFusih9vKVQknRAQfmFcWCv) # gitleaks:allow
|
23
|
+
```
|
24
|
+
"""
|
25
|
+
|
26
|
+
__RESEND_API_KEY_VALUE_OBJECT_REGEX: Pattern[str] = re_compile(pattern=r'^re_[a-zA-Z0-9-_]{30,}$')
|
27
|
+
|
28
|
+
@validation(order=0)
|
29
|
+
def _ensure_value_is_valid_resend_api_key(self, value: str) -> None:
|
30
|
+
"""
|
31
|
+
Ensures the value object value is a valid Resend API Key.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
value (str): Value.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
ValueError: If the value is not a valid Resend API Key.
|
38
|
+
"""
|
39
|
+
if not self.__RESEND_API_KEY_VALUE_OBJECT_REGEX.fullmatch(string=value):
|
40
|
+
raise ValueError(f'ResendApiKeyValueObject value <<<{value}>>> is not a valid Resend API Key.')
|