openadr3-client-gac-compliance 1.4.0__tar.gz → 2.0.0__tar.gz
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.
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/PKG-INFO +6 -3
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/__init__.py +2 -2
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/config.py +5 -2
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/gac20/__init__.py +1 -1
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/gac20/event_gac_compliant.py +39 -48
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/gac20/program_gac_compliant.py +19 -13
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/gac20/ven_gac_compliant.py +7 -7
- openadr3_client_gac_compliance-2.0.0/pyproject.toml +80 -0
- openadr3_client_gac_compliance-1.4.0/pyproject.toml +0 -28
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/LICENSE.md +0 -0
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/README.md +0 -0
- {openadr3_client_gac_compliance-1.4.0 → openadr3_client_gac_compliance-2.0.0}/openadr3_client_gac_compliance/gac21/__init__.py +0 -0
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: openadr3-client-gac-compliance
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary:
|
|
5
|
+
License-File: LICENSE.md
|
|
5
6
|
Author: Nick van der Burgt
|
|
6
7
|
Author-email: nick.van.der.burgt@elaad.nl
|
|
7
8
|
Requires-Python: >=3.12, <4
|
|
8
9
|
Classifier: Programming Language :: Python :: 3
|
|
9
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
-
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: openadr3-client (>=0.0.11,<1.0.0)
|
|
12
14
|
Requires-Dist: pycountry (>=24.6.1,<25.0.0)
|
|
13
15
|
Requires-Dist: pydantic (>=2.11.2,<3.0.0)
|
|
16
|
+
Requires-Dist: python-decouple (>=3.8,<4.0)
|
|
14
17
|
Description-Content-Type: text/markdown
|
|
15
18
|
|
|
16
19
|
# OpenADR3 client
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from openadr3_client_gac_compliance.config import GAC_VERSION
|
|
2
2
|
|
|
3
3
|
if GAC_VERSION == "2.0":
|
|
4
|
-
import openadr3_client_gac_compliance.gac20.
|
|
5
|
-
import openadr3_client_gac_compliance.gac20.
|
|
4
|
+
import openadr3_client_gac_compliance.gac20.event_gac_compliant
|
|
5
|
+
import openadr3_client_gac_compliance.gac20.program_gac_compliant
|
|
6
6
|
import openadr3_client_gac_compliance.gac20.ven_gac_compliant # noqa: F401
|
|
@@ -6,7 +6,8 @@ VALID_GAC_VERSIONS: list[str] = ["2.0"]
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def _gac_version_cast(value: str) -> str:
|
|
9
|
-
"""
|
|
9
|
+
"""
|
|
10
|
+
Cast the GAC version to a string.
|
|
10
11
|
|
|
11
12
|
Args:
|
|
12
13
|
value (str): The GAC version to cast.
|
|
@@ -16,9 +17,11 @@ def _gac_version_cast(value: str) -> str:
|
|
|
16
17
|
|
|
17
18
|
Returns:
|
|
18
19
|
str: The GAC version.
|
|
20
|
+
|
|
19
21
|
"""
|
|
20
22
|
if value not in VALID_GAC_VERSIONS:
|
|
21
|
-
|
|
23
|
+
msg = f"Invalid GAC version: {value}"
|
|
24
|
+
raise ValueError(msg)
|
|
22
25
|
return value
|
|
23
26
|
|
|
24
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# This module imports all the GAC 3.0 compliance validators.
|
|
2
2
|
|
|
3
|
+
import openadr3_client_gac_compliance.gac20.event_gac_compliant
|
|
3
4
|
import openadr3_client_gac_compliance.gac20.program_gac_compliant # noqa: F401
|
|
4
|
-
import openadr3_client_gac_compliance.gac20.event_gac_compliant # noqa: F401
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Module which implements GAC compliance validators for the event OpenADR3 types.
|
|
2
3
|
|
|
3
4
|
This module validates all the object constraints and requirements on the OpenADR3 events resource
|
|
4
5
|
as specified in the Grid aware charging (GAC) specification.
|
|
@@ -11,34 +12,35 @@ that a safe mode event is present in a program. And it cannot be validated on th
|
|
|
11
12
|
as the program object does not contain the events, these are stored seperately in the VTN.
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
|
-
from itertools import pairwise
|
|
15
15
|
import re
|
|
16
|
-
from
|
|
17
|
-
|
|
16
|
+
from itertools import pairwise
|
|
17
|
+
|
|
18
18
|
from openadr3_client.models.event.event import Event
|
|
19
19
|
from openadr3_client.models.event.event_payload import EventPayloadType
|
|
20
|
-
|
|
20
|
+
from openadr3_client.models.model import Model as ValidatorModel
|
|
21
|
+
from openadr3_client.models.model import ValidatorRegistry
|
|
21
22
|
from pydantic import ValidationError
|
|
22
23
|
from pydantic_core import InitErrorDetails, PydanticCustomError
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def _continuous_or_seperated(self: Event) ->
|
|
26
|
-
"""
|
|
26
|
+
def _continuous_or_seperated(self: Event) -> tuple[Event, list[InitErrorDetails]]:
|
|
27
|
+
"""
|
|
28
|
+
Enforces that events either have consistent interval definitions compliant with GAC.
|
|
27
29
|
|
|
28
30
|
the Grid aware charging (GAC) specification allows for two types of (mutually exclusive)
|
|
29
31
|
interval definitions:
|
|
30
32
|
|
|
31
33
|
1. Continuous
|
|
32
|
-
2.
|
|
34
|
+
2. Separated
|
|
33
35
|
|
|
34
|
-
The
|
|
36
|
+
The continuous implementation can be used when all intervals have the same duration.
|
|
35
37
|
In this case, only the top-level intervalPeriod of the event can be used, and the intervalPeriods
|
|
36
38
|
of the individual intervals must be None.
|
|
37
39
|
|
|
38
|
-
In the
|
|
39
|
-
and the top-level intervalPeriod of the event must be None. This
|
|
40
|
+
In the separated intervalDefinition approach, the intervalPeriods must be set on each individual intervals,
|
|
41
|
+
and the top-level intervalPeriod of the event must be None. This separated approach is used when events have differing
|
|
40
42
|
durations.
|
|
41
|
-
"""
|
|
43
|
+
""" # noqa: E501
|
|
42
44
|
validation_errors: list[InitErrorDetails] = []
|
|
43
45
|
|
|
44
46
|
intervals = self.intervals or ()
|
|
@@ -52,7 +54,7 @@ def _continuous_or_seperated(self: Event) -> Tuple[Event, list[InitErrorDetails]
|
|
|
52
54
|
InitErrorDetails(
|
|
53
55
|
type=PydanticCustomError(
|
|
54
56
|
"value_error",
|
|
55
|
-
"Either 'interval_period' must be set on the event once, or every interval must have its own 'interval_period'.",
|
|
57
|
+
"Either 'interval_period' must be set on the event once, or every interval must have its own 'interval_period'.", # noqa: E501
|
|
56
58
|
),
|
|
57
59
|
loc=("intervals",),
|
|
58
60
|
input=self.intervals,
|
|
@@ -62,15 +64,13 @@ def _continuous_or_seperated(self: Event) -> Tuple[Event, list[InitErrorDetails]
|
|
|
62
64
|
else:
|
|
63
65
|
# interval period set at top level of the event.
|
|
64
66
|
# Ensure that all intervals do not have the interval_period defined, to comply with the GAC specification.
|
|
65
|
-
duplicate_interval_period = [
|
|
66
|
-
i for i in intervals if i.interval_period is not None
|
|
67
|
-
]
|
|
67
|
+
duplicate_interval_period = [i for i in intervals if i.interval_period is not None]
|
|
68
68
|
if duplicate_interval_period:
|
|
69
69
|
validation_errors.append(
|
|
70
70
|
InitErrorDetails(
|
|
71
71
|
type=PydanticCustomError(
|
|
72
72
|
"value_error",
|
|
73
|
-
"Either 'interval_period' must be set on the event once, or every interval must have its own 'interval_period'.",
|
|
73
|
+
"Either 'interval_period' must be set on the event once, or every interval must have its own 'interval_period'.", # noqa: E501
|
|
74
74
|
),
|
|
75
75
|
loc=("intervals",),
|
|
76
76
|
input=self.intervals,
|
|
@@ -81,8 +81,9 @@ def _continuous_or_seperated(self: Event) -> Tuple[Event, list[InitErrorDetails]
|
|
|
81
81
|
return self, validation_errors
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
def _targets_compliant(self: Event) ->
|
|
85
|
-
"""
|
|
84
|
+
def _targets_compliant(self: Event) -> tuple[Event, list[InitErrorDetails]]:
|
|
85
|
+
"""
|
|
86
|
+
Enforces that the targets of the event are compliant with GAC.
|
|
86
87
|
|
|
87
88
|
GAC enforces the following constraints for targets:
|
|
88
89
|
|
|
@@ -149,12 +150,7 @@ def _targets_compliant(self: Event) -> Tuple[Event, list[InitErrorDetails]]:
|
|
|
149
150
|
)
|
|
150
151
|
)
|
|
151
152
|
|
|
152
|
-
if (
|
|
153
|
-
power_service_locations
|
|
154
|
-
and ven_names
|
|
155
|
-
and len(power_service_locations) == 1
|
|
156
|
-
and len(ven_names) == 1
|
|
157
|
-
):
|
|
153
|
+
if power_service_locations and ven_names and len(power_service_locations) == 1 and len(ven_names) == 1:
|
|
158
154
|
power_service_location = power_service_locations[0]
|
|
159
155
|
ven_name = ven_names[0]
|
|
160
156
|
|
|
@@ -171,9 +167,7 @@ def _targets_compliant(self: Event) -> Tuple[Event, list[InitErrorDetails]]:
|
|
|
171
167
|
)
|
|
172
168
|
)
|
|
173
169
|
|
|
174
|
-
if not all(
|
|
175
|
-
re.fullmatch(r"^EAN\d{15}$", v) for v in power_service_location.values
|
|
176
|
-
):
|
|
170
|
+
if not all(re.fullmatch(r"^\d{18}$", v) for v in power_service_location.values):
|
|
177
171
|
validation_errors.append(
|
|
178
172
|
InitErrorDetails(
|
|
179
173
|
type=PydanticCustomError(
|
|
@@ -199,12 +193,12 @@ def _targets_compliant(self: Event) -> Tuple[Event, list[InitErrorDetails]]:
|
|
|
199
193
|
)
|
|
200
194
|
)
|
|
201
195
|
|
|
202
|
-
if not all(1 <= len(v) <= 128 for v in ven_name.values):
|
|
196
|
+
if not all(1 <= len(v) <= 128 for v in ven_name.values): # noqa: PLR2004
|
|
203
197
|
validation_errors.append(
|
|
204
198
|
InitErrorDetails(
|
|
205
199
|
type=PydanticCustomError(
|
|
206
200
|
"value_error",
|
|
207
|
-
"The VEN_NAME target value must be a list of 'ven object name' values (between 1 and 128 characters).",
|
|
201
|
+
"The VEN_NAME target value must be a list of 'ven object name' values (between 1 and 128 characters).", # noqa: E501
|
|
208
202
|
),
|
|
209
203
|
loc=("targets",),
|
|
210
204
|
input=self.targets,
|
|
@@ -215,10 +209,11 @@ def _targets_compliant(self: Event) -> Tuple[Event, list[InitErrorDetails]]:
|
|
|
215
209
|
return self, validation_errors
|
|
216
210
|
|
|
217
211
|
|
|
218
|
-
def
|
|
212
|
+
def _payload_descriptors_gac_compliant(
|
|
219
213
|
self: Event,
|
|
220
|
-
) ->
|
|
221
|
-
"""
|
|
214
|
+
) -> tuple[Event, list[InitErrorDetails]]:
|
|
215
|
+
"""
|
|
216
|
+
Enforces that the payload descriptor is GAC compliant.
|
|
222
217
|
|
|
223
218
|
GAC enforces the following constraints for payload descriptors:
|
|
224
219
|
|
|
@@ -255,9 +250,9 @@ def _payload_descriptor_gac_compliant(
|
|
|
255
250
|
)
|
|
256
251
|
)
|
|
257
252
|
|
|
258
|
-
|
|
253
|
+
payload_descriptors = self.payload_descriptors[0]
|
|
259
254
|
|
|
260
|
-
if
|
|
255
|
+
if payload_descriptors.payload_type != EventPayloadType.IMPORT_CAPACITY_LIMIT:
|
|
261
256
|
validation_errors.append(
|
|
262
257
|
InitErrorDetails(
|
|
263
258
|
type=PydanticCustomError(
|
|
@@ -270,7 +265,7 @@ def _payload_descriptor_gac_compliant(
|
|
|
270
265
|
)
|
|
271
266
|
)
|
|
272
267
|
|
|
273
|
-
if
|
|
268
|
+
if payload_descriptors.units != "KW":
|
|
274
269
|
validation_errors.append(
|
|
275
270
|
InitErrorDetails(
|
|
276
271
|
type=PydanticCustomError(
|
|
@@ -286,8 +281,9 @@ def _payload_descriptor_gac_compliant(
|
|
|
286
281
|
return self, validation_errors
|
|
287
282
|
|
|
288
283
|
|
|
289
|
-
def _event_interval_gac_compliant(self: Event) ->
|
|
290
|
-
"""
|
|
284
|
+
def _event_interval_gac_compliant(self: Event) -> tuple[Event, list[InitErrorDetails]]:
|
|
285
|
+
"""
|
|
286
|
+
Enforces that the event interval is GAC compliant.
|
|
291
287
|
|
|
292
288
|
GAC enforces the following constraints for event intervals:
|
|
293
289
|
|
|
@@ -370,7 +366,8 @@ def _event_interval_gac_compliant(self: Event) -> Tuple[Event, list[InitErrorDet
|
|
|
370
366
|
|
|
371
367
|
@ValidatorRegistry.register(Event, ValidatorModel())
|
|
372
368
|
def event_gac_compliant(self: Event) -> Event:
|
|
373
|
-
"""
|
|
369
|
+
"""
|
|
370
|
+
Enforces that events are GAC compliant.
|
|
374
371
|
|
|
375
372
|
GAC enforces the following constraints for events:
|
|
376
373
|
|
|
@@ -398,19 +395,13 @@ def event_gac_compliant(self: Event) -> Event:
|
|
|
398
395
|
targets_validated, errors = _targets_compliant(interval_periods_validated)
|
|
399
396
|
validation_errors.extend(errors)
|
|
400
397
|
|
|
401
|
-
payload_descriptor_validated, errors =
|
|
402
|
-
targets_validated
|
|
403
|
-
)
|
|
398
|
+
payload_descriptor_validated, errors = _payload_descriptors_gac_compliant(targets_validated)
|
|
404
399
|
validation_errors.extend(errors)
|
|
405
400
|
|
|
406
|
-
event_interval_validated, errors = _event_interval_gac_compliant(
|
|
407
|
-
payload_descriptor_validated
|
|
408
|
-
)
|
|
401
|
+
event_interval_validated, errors = _event_interval_gac_compliant(payload_descriptor_validated)
|
|
409
402
|
validation_errors.extend(errors)
|
|
410
403
|
|
|
411
404
|
if validation_errors:
|
|
412
|
-
raise ValidationError.from_exception_data(
|
|
413
|
-
title=self.__class__.__name__, line_errors=validation_errors
|
|
414
|
-
)
|
|
405
|
+
raise ValidationError.from_exception_data(title=self.__class__.__name__, line_errors=validation_errors)
|
|
415
406
|
|
|
416
407
|
return event_interval_validated
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"""Module which implements GAC compliance validators for the program OpenADR3 types."""
|
|
2
2
|
|
|
3
|
-
from openadr3_client.models.program.program import Program
|
|
4
|
-
from openadr3_client.models.model import ValidatorRegistry, Model as ValidatorModel
|
|
5
|
-
|
|
6
3
|
import re
|
|
7
4
|
|
|
5
|
+
from openadr3_client.models.model import Model as ValidatorModel
|
|
6
|
+
from openadr3_client.models.model import ValidatorRegistry
|
|
7
|
+
from openadr3_client.models.program.program import Program
|
|
8
8
|
from pydantic import ValidationError
|
|
9
9
|
from pydantic_core import InitErrorDetails, PydanticCustomError
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@ValidatorRegistry.register(Program, ValidatorModel())
|
|
13
13
|
def program_gac_compliant(self: Program) -> Program:
|
|
14
|
-
"""
|
|
14
|
+
"""
|
|
15
|
+
Enforces that the program is GAC compliant.
|
|
15
16
|
|
|
16
17
|
GAC enforces the following constraints for programs:
|
|
17
18
|
- The program must have a retailer name
|
|
@@ -20,10 +21,19 @@ def program_gac_compliant(self: Program) -> Program:
|
|
|
20
21
|
- The programType MUST equal "DSO_CPO_INTERFACE-x.x.x, where x.x.x is the version as defined in the GAC specification.
|
|
21
22
|
- The program MUST have bindingEvents set to True.
|
|
22
23
|
are allowed there.
|
|
23
|
-
"""
|
|
24
|
+
""" # noqa: E501
|
|
24
25
|
validation_errors: list[InitErrorDetails] = []
|
|
25
26
|
|
|
26
|
-
program_type_regex =
|
|
27
|
+
program_type_regex = (
|
|
28
|
+
r"^DSO_CPO_INTERFACE-"
|
|
29
|
+
r"(0|[1-9]\d*)\."
|
|
30
|
+
r"(0|[1-9]\d*)\."
|
|
31
|
+
r"(0|[1-9]\d*)"
|
|
32
|
+
r"(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)"
|
|
33
|
+
r"(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))"
|
|
34
|
+
r"?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"
|
|
35
|
+
r"$"
|
|
36
|
+
)
|
|
27
37
|
|
|
28
38
|
if self.retailer_name is None:
|
|
29
39
|
validation_errors.append(
|
|
@@ -39,7 +49,7 @@ def program_gac_compliant(self: Program) -> Program:
|
|
|
39
49
|
)
|
|
40
50
|
|
|
41
51
|
if self.retailer_name is not None and (
|
|
42
|
-
len(self.retailer_name) < 2 or len(self.retailer_name) > 128
|
|
52
|
+
len(self.retailer_name) < 2 or len(self.retailer_name) > 128 # noqa: PLR2004
|
|
43
53
|
):
|
|
44
54
|
validation_errors.append(
|
|
45
55
|
InitErrorDetails(
|
|
@@ -65,9 +75,7 @@ def program_gac_compliant(self: Program) -> Program:
|
|
|
65
75
|
ctx={},
|
|
66
76
|
)
|
|
67
77
|
)
|
|
68
|
-
if self.program_type is not None and not re.fullmatch(
|
|
69
|
-
program_type_regex, self.program_type
|
|
70
|
-
):
|
|
78
|
+
if self.program_type is not None and not re.fullmatch(program_type_regex, self.program_type):
|
|
71
79
|
validation_errors.append(
|
|
72
80
|
InitErrorDetails(
|
|
73
81
|
type=PydanticCustomError(
|
|
@@ -94,8 +102,6 @@ def program_gac_compliant(self: Program) -> Program:
|
|
|
94
102
|
)
|
|
95
103
|
|
|
96
104
|
if validation_errors:
|
|
97
|
-
raise ValidationError.from_exception_data(
|
|
98
|
-
title=self.__class__.__name__, line_errors=validation_errors
|
|
99
|
-
)
|
|
105
|
+
raise ValidationError.from_exception_data(title=self.__class__.__name__, line_errors=validation_errors)
|
|
100
106
|
|
|
101
107
|
return self
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from openadr3_client.models.model import ValidatorRegistry, Model as ValidatorModel
|
|
3
|
-
from openadr3_client.models.ven.ven import Ven
|
|
4
|
-
import pycountry
|
|
5
2
|
|
|
3
|
+
import pycountry
|
|
4
|
+
from openadr3_client.models.model import Model as ValidatorModel
|
|
5
|
+
from openadr3_client.models.model import ValidatorRegistry
|
|
6
|
+
from openadr3_client.models.ven.ven import Ven
|
|
6
7
|
from pydantic import ValidationError
|
|
7
8
|
from pydantic_core import InitErrorDetails, PydanticCustomError
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
@ValidatorRegistry.register(Ven, ValidatorModel())
|
|
11
12
|
def ven_gac_compliant(self: Ven) -> Ven:
|
|
12
|
-
"""
|
|
13
|
+
"""
|
|
14
|
+
Enforces that the ven is GAC compliant.
|
|
13
15
|
|
|
14
16
|
GAC enforces the following constraints for vens:
|
|
15
17
|
- The ven must have a ven name
|
|
@@ -48,8 +50,6 @@ def ven_gac_compliant(self: Ven) -> Ven:
|
|
|
48
50
|
)
|
|
49
51
|
|
|
50
52
|
if validation_errors:
|
|
51
|
-
raise ValidationError.from_exception_data(
|
|
52
|
-
title=self.__class__.__name__, line_errors=validation_errors
|
|
53
|
-
)
|
|
53
|
+
raise ValidationError.from_exception_data(title=self.__class__.__name__, line_errors=validation_errors)
|
|
54
54
|
|
|
55
55
|
return self
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "openadr3-client-gac-compliance"
|
|
3
|
+
version = "2.0.0"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Nick van der Burgt", email = "nick.van.der.burgt@elaad.nl"}
|
|
7
|
+
]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.12, <4"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"pydantic (>=2.11.2,<3.0.0)",
|
|
12
|
+
"openadr3-client (>=0.0.11,<1.0.0)",
|
|
13
|
+
"pycountry (>=24.6.1,<25.0.0)",
|
|
14
|
+
"python-decouple (>=3.8,<4.0)",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
19
|
+
build-backend = "poetry.core.masonry.api"
|
|
20
|
+
|
|
21
|
+
[tool.poetry.group.dev.dependencies]
|
|
22
|
+
mypy = "^1.15.0"
|
|
23
|
+
ruff = "^0.11.4"
|
|
24
|
+
pytest = "^8.3.5"
|
|
25
|
+
pytest-cov = "^6.1.1"
|
|
26
|
+
taskipy = "^1.14.1"
|
|
27
|
+
|
|
28
|
+
[[tool.mypy.overrides]]
|
|
29
|
+
module = ["openadr3_client", "decouple"]
|
|
30
|
+
ignore_missing_imports = true
|
|
31
|
+
|
|
32
|
+
[tool.taskipy.tasks]
|
|
33
|
+
local-ci = "task check && task format && task mypy && task test"
|
|
34
|
+
fix = "task check-fix && task format-fix && task mypy"
|
|
35
|
+
check = "ruff check ."
|
|
36
|
+
check-fix = "ruff check --fix ."
|
|
37
|
+
check-ci = "ruff check --output-format=github --no-cache ."
|
|
38
|
+
mypy = "mypy . --check-untyped-defs"
|
|
39
|
+
format = "ruff format . --diff"
|
|
40
|
+
format-fix = "ruff format ."
|
|
41
|
+
format-ci = "ruff format --diff --no-cache ."
|
|
42
|
+
test = "pytest --cov"
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
line-length = 120
|
|
46
|
+
|
|
47
|
+
[tool.ruff.lint]
|
|
48
|
+
select = ["ALL"]
|
|
49
|
+
|
|
50
|
+
# Do not require docstrings for functions, methods and classes
|
|
51
|
+
ignore = [
|
|
52
|
+
# From:https://github.com/wemake-services/wemake-django-template/blob/master/pyproject.toml
|
|
53
|
+
"A005", # allow to shadow stdlib and builtin module names
|
|
54
|
+
"COM812", # trailing comma, conflicts with `ruff format`
|
|
55
|
+
# Different doc rules that we don't really care about:
|
|
56
|
+
"D100",
|
|
57
|
+
"D104",
|
|
58
|
+
"D106",
|
|
59
|
+
"D203",
|
|
60
|
+
"D212",
|
|
61
|
+
"D401",
|
|
62
|
+
"D404",
|
|
63
|
+
"D405",
|
|
64
|
+
"ISC001", # implicit string concat conflicts with `ruff format`
|
|
65
|
+
"ISC003", # prefer explicit string concat over implicit concat
|
|
66
|
+
"PLR09", # we have our own complexity rules
|
|
67
|
+
# "PLR2004", # do not report magic numbers -> I do want to report magic numbers
|
|
68
|
+
"PLR6301", # do not require classmethod / staticmethod when self not used
|
|
69
|
+
"TRY003", # long exception messages from `tryceratops`
|
|
70
|
+
# Start of own error codes
|
|
71
|
+
"ANN002", # Ignore unused *args
|
|
72
|
+
"ANN003", # Ignore unused **kwargs
|
|
73
|
+
"D107", # Allow undocumented __init__
|
|
74
|
+
"TC001", # Move to type checking block (does not play nice with pydantic models)
|
|
75
|
+
"TC002", # Move to type checking block (does not play nice with pydantic models)
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# Ignores S101 ("Use of 'assert' detected") for the tests.
|
|
79
|
+
[tool.ruff.lint.per-file-ignores]
|
|
80
|
+
"tests/*" = ["S101", "ANN201", "SLF001", "S106", "S105", "S311", "PLR2004", "PT018"]
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "openadr3-client-gac-compliance"
|
|
3
|
-
version = "1.4.0"
|
|
4
|
-
description = ""
|
|
5
|
-
authors = [
|
|
6
|
-
{name = "Nick van der Burgt", email = "nick.van.der.burgt@elaad.nl"}
|
|
7
|
-
]
|
|
8
|
-
readme = "README.md"
|
|
9
|
-
requires-python = ">=3.12, <4"
|
|
10
|
-
dependencies = [
|
|
11
|
-
"pydantic (>=2.11.2,<3.0.0)",
|
|
12
|
-
"openadr3-client (>=0.0.7,<1.0.0)",
|
|
13
|
-
"pycountry (>=24.6.1,<25.0.0)",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
[build-system]
|
|
17
|
-
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
18
|
-
build-backend = "poetry.core.masonry.api"
|
|
19
|
-
|
|
20
|
-
[tool.poetry.group.dev.dependencies]
|
|
21
|
-
mypy = "^1.15.0"
|
|
22
|
-
ruff = "^0.11.4"
|
|
23
|
-
pytest = "^8.3.5"
|
|
24
|
-
pytest-cov = "^6.1.1"
|
|
25
|
-
|
|
26
|
-
[[tool.mypy.overrides]]
|
|
27
|
-
module = ["openadr3_client", "decouple"]
|
|
28
|
-
ignore_missing_imports = true
|
|
File without changes
|
|
File without changes
|