mms-client 1.5.1__py3-none-any.whl → 1.6.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.
- mms_client/services/base.py +6 -1
- mms_client/services/market.py +33 -0
- mms_client/types/reserve.py +71 -0
- mms_client/utils/errors.py +15 -0
- {mms_client-1.5.1.dist-info → mms_client-1.6.0.dist-info}/METADATA +2 -1
- {mms_client-1.5.1.dist-info → mms_client-1.6.0.dist-info}/RECORD +8 -7
- {mms_client-1.5.1.dist-info → mms_client-1.6.0.dist-info}/LICENSE +0 -0
- {mms_client-1.5.1.dist-info → mms_client-1.6.0.dist-info}/WHEEL +0 -0
mms_client/services/base.py
CHANGED
|
@@ -28,6 +28,7 @@ from mms_client.types.transport import RequestType
|
|
|
28
28
|
from mms_client.types.transport import ResponseDataType
|
|
29
29
|
from mms_client.utils.errors import AudienceError
|
|
30
30
|
from mms_client.utils.errors import MMSClientError
|
|
31
|
+
from mms_client.utils.errors import MMSServerError
|
|
31
32
|
from mms_client.utils.errors import MMSValidationError
|
|
32
33
|
from mms_client.utils.serialization import Serializer
|
|
33
34
|
from mms_client.utils.web import ClientType
|
|
@@ -459,7 +460,11 @@ class BaseClient: # pylint: disable=too-many-instance-attributes
|
|
|
459
460
|
MMSClientError: If the response is not valid.
|
|
460
461
|
"""
|
|
461
462
|
# Verify that the response is in the correct format. If it's not, raise an error.
|
|
462
|
-
if
|
|
463
|
+
# NOTE: We're disabling the no-else-raise rule here because both comparisons are on the same enum so if one is
|
|
464
|
+
# removed then the other will raise an error. This is a false positive.
|
|
465
|
+
if resp.data_type == ResponseDataType.TXT: # pylint: disable=no-else-raise
|
|
466
|
+
raise MMSServerError(config.name, resp.payload.decode("UTF-8"))
|
|
467
|
+
elif resp.data_type != ResponseDataType.XML:
|
|
463
468
|
raise MMSClientError(
|
|
464
469
|
config.name,
|
|
465
470
|
f"Invalid MMS response data type: {resp.data_type.name}. Only XML is supported.",
|
mms_client/services/market.py
CHANGED
|
@@ -18,6 +18,8 @@ from mms_client.types.market import MarketType
|
|
|
18
18
|
from mms_client.types.offer import OfferCancel
|
|
19
19
|
from mms_client.types.offer import OfferData
|
|
20
20
|
from mms_client.types.offer import OfferQuery
|
|
21
|
+
from mms_client.types.reserve import ReserveRequirement
|
|
22
|
+
from mms_client.types.reserve import ReserveRequirementQuery
|
|
21
23
|
from mms_client.types.transport import RequestType
|
|
22
24
|
from mms_client.utils.serialization import SchemaType
|
|
23
25
|
from mms_client.utils.serialization import Serializer
|
|
@@ -34,6 +36,35 @@ class MarketClientMixin: # pylint: disable=unused-argument
|
|
|
34
36
|
# The configuration for the market service
|
|
35
37
|
config = ServiceConfiguration(Interface.MI, Serializer(SchemaType.MARKET, "MarketData"))
|
|
36
38
|
|
|
39
|
+
@mms_endpoint(
|
|
40
|
+
"MarketQuery_ReserveRequirementQuery",
|
|
41
|
+
config,
|
|
42
|
+
RequestType.INFO,
|
|
43
|
+
resp_envelope_type=MarketSubmit,
|
|
44
|
+
resp_data_type=ReserveRequirement,
|
|
45
|
+
)
|
|
46
|
+
def query_reserve_requirements(
|
|
47
|
+
self: ClientProto, request: ReserveRequirementQuery, date: Optional[Date] = None
|
|
48
|
+
) -> List[ReserveRequirement]:
|
|
49
|
+
"""Query the MMS server for reserve requirements.
|
|
50
|
+
|
|
51
|
+
This endpoint is accessible to all client types.
|
|
52
|
+
|
|
53
|
+
Arguments:
|
|
54
|
+
request (ReserveRequirementQuery): The query to submit to the MMS server.
|
|
55
|
+
date (Date): The date of the transaction in the format "YYYY-MM-DD". This value defaults
|
|
56
|
+
to the current date.
|
|
57
|
+
|
|
58
|
+
Returns: A list of reserve requirements that match the query.
|
|
59
|
+
"""
|
|
60
|
+
# NOTE: The return type does not match the method definition but the decorator will return the correct type
|
|
61
|
+
return MarketQuery( # type: ignore[return-value]
|
|
62
|
+
date=date or Date.today(),
|
|
63
|
+
participant=self.participant,
|
|
64
|
+
user=self.user,
|
|
65
|
+
days=1,
|
|
66
|
+
)
|
|
67
|
+
|
|
37
68
|
@mms_endpoint("MarketSubmit_OfferData", config, RequestType.INFO, [ClientType.BSP])
|
|
38
69
|
def put_offer(
|
|
39
70
|
self: ClientProto, request: OfferData, market_type: MarketType, days: int, date: Optional[Date] = None
|
|
@@ -124,6 +155,8 @@ class MarketClientMixin: # pylint: disable=unused-argument
|
|
|
124
155
|
days (int): The number of days ahead for which the data is being cancelled.
|
|
125
156
|
date (Date): The date of the transaction in the format "YYYY-MM-DD". This value defaults to the
|
|
126
157
|
current date.
|
|
158
|
+
|
|
159
|
+
Returns: Data identifying the offer that was cancelled.
|
|
127
160
|
"""
|
|
128
161
|
# NOTE: The return type does not match the method definition but the decorator will return the correct type
|
|
129
162
|
return MarketCancel( # type: ignore[return-value]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Contains objects for MMS reserve requirements."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic_extra_types.pendulum_dt import DateTime
|
|
7
|
+
from pydantic_xml import attr
|
|
8
|
+
from pydantic_xml import element
|
|
9
|
+
|
|
10
|
+
from mms_client.types.base import Payload
|
|
11
|
+
from mms_client.types.enums import AreaCode
|
|
12
|
+
from mms_client.types.enums import Direction
|
|
13
|
+
from mms_client.types.fields import power_positive
|
|
14
|
+
from mms_client.types.market import MarketType
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Requirement(Payload):
|
|
18
|
+
"""Represents a reserve requirement."""
|
|
19
|
+
|
|
20
|
+
# The start block of the requirement
|
|
21
|
+
start: DateTime = attr(name="StartTime")
|
|
22
|
+
|
|
23
|
+
# The end block of the requirement
|
|
24
|
+
end: DateTime = attr(name="EndTime")
|
|
25
|
+
|
|
26
|
+
# The direction of the requirement
|
|
27
|
+
direction: Direction = attr(name="Direction")
|
|
28
|
+
|
|
29
|
+
# The primary reserve quantity in kW
|
|
30
|
+
primary_qty_kw: Optional[int] = power_positive("PrimaryReserveQuantityInKw", True)
|
|
31
|
+
|
|
32
|
+
# The first secondary reserve quantity in kW
|
|
33
|
+
secondary_1_qty_kw: Optional[int] = power_positive("Secondary1ReserveQuantityInKw", True)
|
|
34
|
+
|
|
35
|
+
# The second secondary reserve quantity in kW
|
|
36
|
+
secondary_2_qty_kw: Optional[int] = power_positive("Secondary2ReserveQuantityInKw", True)
|
|
37
|
+
|
|
38
|
+
# The first tertiary reserve quantity in kW
|
|
39
|
+
tertiary_1_qty_kw: Optional[int] = power_positive("Tertiary1ReserveQuantityInKw", True)
|
|
40
|
+
|
|
41
|
+
# The second tertiary reserve quantity in kW
|
|
42
|
+
tertiary_2_qty_kw: Optional[int] = power_positive("Tertiary2ReserveQuantityInKw", True)
|
|
43
|
+
|
|
44
|
+
# The minimum reserve of compound primary and secondary 1 in kW
|
|
45
|
+
primary_secondary_1_qty_kw: Optional[int] = power_positive("CompoundPriSec1ReserveQuantityInKw", True)
|
|
46
|
+
|
|
47
|
+
# The minimum reserve of compound primary and secondary 2 in kW
|
|
48
|
+
primary_secondary_2_qty_kw: Optional[int] = power_positive("CompoundPriSec2ReserveQuantityInKw", True)
|
|
49
|
+
|
|
50
|
+
# The minimum reserve of compound primary and tertiary 1 in kW
|
|
51
|
+
primary_tertiary_1_qty_kw: Optional[int] = power_positive("CompoundPriTer1ReserveQuantityInKw", True)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ReserveRequirement(Payload):
|
|
55
|
+
"""Represents a set of reserve requirements."""
|
|
56
|
+
|
|
57
|
+
# The area for which the reserve requirement applies
|
|
58
|
+
area: AreaCode = attr(name="Area")
|
|
59
|
+
|
|
60
|
+
# The requirements associated with the area
|
|
61
|
+
requirements: List[Requirement] = element(tag="Requirement", min_length=1)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ReserveRequirementQuery(Payload):
|
|
65
|
+
"""Represents a request to query reserve requirements."""
|
|
66
|
+
|
|
67
|
+
# The market type for which to query reserve requirements
|
|
68
|
+
market_type: MarketType = attr(name="MarketType")
|
|
69
|
+
|
|
70
|
+
# The area for which to query reserve requirements
|
|
71
|
+
area: Optional[AreaCode] = attr(default=None, name="Area")
|
mms_client/utils/errors.py
CHANGED
|
@@ -38,6 +38,21 @@ class AudienceError(ValueError):
|
|
|
38
38
|
super().__init__(self.message)
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
class MMSServerError(RuntimeError):
|
|
42
|
+
"""Error raised when the MMS server returns an error."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, method: str, message: str):
|
|
45
|
+
"""Initialize the error.
|
|
46
|
+
|
|
47
|
+
Arguments:
|
|
48
|
+
method (str): The method that caused the error.
|
|
49
|
+
message (str): The error message.
|
|
50
|
+
"""
|
|
51
|
+
super().__init__(f"{method}: {message}")
|
|
52
|
+
self.message = message
|
|
53
|
+
self.method = method
|
|
54
|
+
|
|
55
|
+
|
|
41
56
|
class MMSClientError(RuntimeError):
|
|
42
57
|
"""Base class for MMS client errors."""
|
|
43
58
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mms-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: API client for accessing the MMS
|
|
5
5
|
Home-page: https://github.com/ElectroRoute-Japan/mms-client
|
|
6
6
|
Author: Ryan Wood
|
|
@@ -209,6 +209,7 @@ This same input allows for the user to create their own plugins and add them to
|
|
|
209
209
|
|
|
210
210
|
# Completeness
|
|
211
211
|
This client is not complete. Currently, it supports the following endpoints:
|
|
212
|
+
- MarketQuery_ReserveRequirementQuery
|
|
212
213
|
- MarketSubmit_OfferData
|
|
213
214
|
- MarketQuery_OfferQuery
|
|
214
215
|
- MarketCancel_OfferCancel
|
|
@@ -12,8 +12,8 @@ mms_client/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
12
12
|
mms_client/security/certs.py,sha256=kNCUFmy18YIxkWKu3mdMmlxmHdft4a6BvtyJ46rA9I4,1489
|
|
13
13
|
mms_client/security/crypto.py,sha256=M7aIllM3_ZwZgm9nH6QQ6Ig14XCAd6e6WGwqqUbbI1Q,2149
|
|
14
14
|
mms_client/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
mms_client/services/base.py,sha256=
|
|
16
|
-
mms_client/services/market.py,sha256=
|
|
15
|
+
mms_client/services/base.py,sha256=DavXAfWqSqcxfgbAFDj-9nj2DYL5YTMTPWHUM8aaL9s,26309
|
|
16
|
+
mms_client/services/market.py,sha256=7eVqbgkfSip-GAAFnjetFbtmFILOGI6Gb8YISTiMh6w,9031
|
|
17
17
|
mms_client/services/omi.py,sha256=UG1zYkFz0sFsEbhE6P0CLoAOZZOyEshkZ_b7D_e3CjQ,626
|
|
18
18
|
mms_client/services/registration.py,sha256=ryj2WKJoBzRU1r6Svbl2MyGOG0H5aEYAK6HQWL9kYaA,3815
|
|
19
19
|
mms_client/services/report.py,sha256=ZXYDaknPCnSYZI857QHbkzst1Pez_PrKFudVF9bQB7Q,642
|
|
@@ -25,14 +25,15 @@ mms_client/types/fields.py,sha256=pa5qvQVwEr8dh44IGHyYqgJYTYyTIeAjBW6CylXrkP0,14
|
|
|
25
25
|
mms_client/types/market.py,sha256=IbXsH4Q5MJI-CEvGvZlzv2S36mX_Ea02U11Ik-NwSxQ,2706
|
|
26
26
|
mms_client/types/offer.py,sha256=KosFiKRMnt7XwlLBUfjHUGHiWzrMJUPPhGQMxgdeepM,6791
|
|
27
27
|
mms_client/types/registration.py,sha256=Nir73S3ffpk0O_fnTD2alFaqV1k67_8dcyyduXvPBI4,1381
|
|
28
|
+
mms_client/types/reserve.py,sha256=pLV47w_749EIVhj0tUuJdWdHBBEl0-v10oVioccgxnU,2667
|
|
28
29
|
mms_client/types/resource.py,sha256=TQnY3JLHRgQhQrG6ISquw-BQgKSr8TGuqn9ItWxWz_w,65974
|
|
29
30
|
mms_client/types/transport.py,sha256=DPjWs34UW915GkUCJWKuDZmsjS6mRdRXgcGISduN_Bc,4399
|
|
30
31
|
mms_client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
32
|
mms_client/utils/auditing.py,sha256=JDcvNo4ul66xPtDeeocn568yIe8fhh-jM11MWP-Kfes,2057
|
|
32
|
-
mms_client/utils/errors.py,sha256=
|
|
33
|
+
mms_client/utils/errors.py,sha256=6k-NOjGZyTbTUISzN7B4JrmU2P8cwjpFFmFC7kJOQFQ,3005
|
|
33
34
|
mms_client/utils/serialization.py,sha256=k0_fBm-yoRZV2AMiickSyauoDyA8i7uIPU6JjfQWx4Q,29638
|
|
34
35
|
mms_client/utils/web.py,sha256=-abdVxSi7c6xQYsZObbj0yXwGI5VWthr5KtWDyLBCM4,10156
|
|
35
|
-
mms_client-1.
|
|
36
|
-
mms_client-1.
|
|
37
|
-
mms_client-1.
|
|
38
|
-
mms_client-1.
|
|
36
|
+
mms_client-1.6.0.dist-info/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
|
37
|
+
mms_client-1.6.0.dist-info/METADATA,sha256=FSz-AvooX7RCU5vZ8BC1nhXINBlF3EFhitTc3ZngIh8,16025
|
|
38
|
+
mms_client-1.6.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
39
|
+
mms_client-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|