shapeshifter-uftp 1.1.1.dev2__tar.gz → 1.2.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.
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/PKG-INFO +1 -1
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/README.rst +7 -0
- shapeshifter-uftp-1.2.0/pyproject.toml +18 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/setup.py +40 -40
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/base_client.py +7 -5
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/dso_agr_client.py +4 -11
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/dso_cro_client.py +1 -1
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/base_service.py +11 -23
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/cro_dso.py +8 -7
- shapeshifter-uftp-1.2.0/shapeshifter_uftp/uftp/parsing.py +8 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/validations.py +32 -29
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/PKG-INFO +1 -1
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/SOURCES.txt +2 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/requires.txt +5 -5
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_communications.py +54 -57
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/setup.cfg +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/__init__.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/cli.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/__init__.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/agr_cro_client.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/agr_dso_client.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/cro_agr_client.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/cro_dso_client.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/exceptions.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/logging.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/__init__.py +1 -1
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/agr_service.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/cro_service.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/dso_service.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/transport.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/__init__.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/agr_cro.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/agr_dso.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/common.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/defaults.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/metering.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/dependency_links.txt +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/entry_points.txt +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/top_level.txt +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_cli.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_client_errors.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_client_with_workers.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_clients_from_service.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_default_responses.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_message_destination.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_presence_of_client_methods.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_presence_of_service_methods.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_roundtrip_serialization.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_seal_and_unseal.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_service_errors.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_snake_case.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_ttl_cache.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_validations.py +0 -0
- {shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_xml_schema_compliance.py +0 -0
|
@@ -41,6 +41,13 @@ Version History
|
|
|
41
41
|
+-------------+-------------------+----------------------------------+
|
|
42
42
|
| Version | Release Date | Release Notes |
|
|
43
43
|
+=============+===================+==================================+
|
|
44
|
+
| 1.2.0 | 2024-04-04 | Upgrade to latest FastAPI and |
|
|
45
|
+
| | | Pydantic. |
|
|
46
|
+
+-------------+-------------------+----------------------------------+
|
|
47
|
+
| 1.1.2 | 2024-03-12 | Pinned dependencies after a |
|
|
48
|
+
| | | breaking update to fastapi-xml |
|
|
49
|
+
| | | was released. |
|
|
50
|
+
+-------------+-------------------+----------------------------------+
|
|
44
51
|
| 1.1.0 | 2023-08-30 | Use the published 3.0.0 spec |
|
|
45
52
|
| | | for the XSD validation and |
|
|
46
53
|
| | | objects. |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[tool.pytest.ini_options]
|
|
2
|
+
addopts = "-v --cov --cov-report html"
|
|
3
|
+
|
|
4
|
+
[tool.coverage.run]
|
|
5
|
+
include = [
|
|
6
|
+
"shapeshifter_uftp/**/*.py",
|
|
7
|
+
]
|
|
8
|
+
omit = [
|
|
9
|
+
"application/asgi.py",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
[tool.coverage.report]
|
|
13
|
+
skip_empty = true
|
|
14
|
+
|
|
15
|
+
[tool.coverage.html]
|
|
16
|
+
directory = "test_coverage"
|
|
17
|
+
|
|
18
|
+
[tool.pylint.DESIGN]
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
from setuptools import setup
|
|
2
|
-
|
|
3
|
-
setup(
|
|
4
|
-
name="shapeshifter-uftp",
|
|
5
|
-
version="1.
|
|
6
|
-
python_requires=">=3.10",
|
|
7
|
-
description="Allows connections between DSO, AGR and CRO using the Shapeshifter (UFTP) protocol.",
|
|
8
|
-
packages=[
|
|
9
|
-
"shapeshifter_uftp",
|
|
10
|
-
"shapeshifter_uftp.uftp",
|
|
11
|
-
"shapeshifter_uftp.client",
|
|
12
|
-
"shapeshifter_uftp.service",
|
|
13
|
-
],
|
|
14
|
-
install_requires=[
|
|
15
|
-
"xsdata[lxml]",
|
|
16
|
-
"pynacl",
|
|
17
|
-
"dnspython",
|
|
18
|
-
"fastapi
|
|
19
|
-
"fastapi-xml",
|
|
20
|
-
"requests",
|
|
21
|
-
"uvicorn",
|
|
22
|
-
"termcolor",
|
|
23
|
-
],
|
|
24
|
-
extras_require={
|
|
25
|
-
"dev": [
|
|
26
|
-
"xmlschema",
|
|
27
|
-
"pytest",
|
|
28
|
-
"pytest-cov",
|
|
29
|
-
"pylint",
|
|
30
|
-
"sphinx",
|
|
31
|
-
"sphinx-rtd-theme",
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
entry_points={
|
|
35
|
-
"console_scripts": [
|
|
36
|
-
"shapeshifter-keypair = shapeshifter_uftp.cli:generate_signing_keypair",
|
|
37
|
-
"shapeshifter-lookup = shapeshifter_uftp.cli:perform_lookup",
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
)
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="shapeshifter-uftp",
|
|
5
|
+
version="1.2.0",
|
|
6
|
+
python_requires=">=3.10",
|
|
7
|
+
description="Allows connections between DSO, AGR and CRO using the Shapeshifter (UFTP) protocol.",
|
|
8
|
+
packages=[
|
|
9
|
+
"shapeshifter_uftp",
|
|
10
|
+
"shapeshifter_uftp.uftp",
|
|
11
|
+
"shapeshifter_uftp.client",
|
|
12
|
+
"shapeshifter_uftp.service",
|
|
13
|
+
],
|
|
14
|
+
install_requires=[
|
|
15
|
+
"xsdata[lxml]==24.4",
|
|
16
|
+
"pynacl==1.5.0",
|
|
17
|
+
"dnspython==2.6.1",
|
|
18
|
+
"fastapi==0.110",
|
|
19
|
+
"fastapi-xml==1.1.0",
|
|
20
|
+
"requests",
|
|
21
|
+
"uvicorn",
|
|
22
|
+
"termcolor",
|
|
23
|
+
],
|
|
24
|
+
extras_require={
|
|
25
|
+
"dev": [
|
|
26
|
+
"xmlschema",
|
|
27
|
+
"pytest",
|
|
28
|
+
"pytest-cov",
|
|
29
|
+
"pylint",
|
|
30
|
+
"sphinx",
|
|
31
|
+
"sphinx-rtd-theme",
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
entry_points={
|
|
35
|
+
"console_scripts": [
|
|
36
|
+
"shapeshifter-keypair = shapeshifter_uftp.cli:generate_signing_keypair",
|
|
37
|
+
"shapeshifter-lookup = shapeshifter_uftp.cli:perform_lookup",
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
)
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/base_client.py
RENAMED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
from datetime import datetime, timezone
|
|
2
1
|
import sched
|
|
3
2
|
import time
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
4
|
from queue import Queue
|
|
5
|
-
from threading import
|
|
5
|
+
from threading import Event, Thread
|
|
6
6
|
from uuid import uuid4
|
|
7
|
+
|
|
7
8
|
import requests
|
|
8
|
-
|
|
9
|
-
from ..logging import logger
|
|
10
|
-
from ..exceptions import ClientTransportException
|
|
9
|
+
|
|
11
10
|
from .. import transport
|
|
11
|
+
from ..exceptions import ClientTransportException
|
|
12
|
+
from ..logging import logger
|
|
13
|
+
from ..uftp import PayloadMessage, PayloadMessageResponse, SignedMessage
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class ShapeshifterClient():
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/dso_agr_client.py
RENAMED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
+
from ..uftp import (DPrognosisResponse, FlexOfferResponse,
|
|
2
|
+
FlexOfferRevocationResponse, FlexOrder, FlexRequest,
|
|
3
|
+
FlexReservationUpdate, FlexSettlement, MeteringResponse,
|
|
4
|
+
PayloadMessageResponse)
|
|
1
5
|
from .base_client import ShapeshifterClient
|
|
2
|
-
from ..uftp import (
|
|
3
|
-
DPrognosisResponse,
|
|
4
|
-
FlexRequest,
|
|
5
|
-
FlexOfferResponse,
|
|
6
|
-
FlexOrder,
|
|
7
|
-
FlexReservationUpdate,
|
|
8
|
-
FlexOfferRevocationResponse,
|
|
9
|
-
FlexSettlement,
|
|
10
|
-
PayloadMessageResponse,
|
|
11
|
-
MeteringResponse,
|
|
12
|
-
)
|
|
13
6
|
|
|
14
7
|
|
|
15
8
|
class ShapeshifterDsoAgrClient(ShapeshifterClient):
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/base_service.py
RENAMED
|
@@ -1,31 +1,22 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from datetime import datetime, timezone
|
|
2
3
|
from queue import Queue
|
|
3
|
-
from uuid import uuid4
|
|
4
|
-
from time import sleep
|
|
5
4
|
from threading import Thread
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
from time import sleep
|
|
6
|
+
from uuid import uuid4
|
|
8
7
|
|
|
8
|
+
import uvicorn
|
|
9
9
|
from fastapi import FastAPI
|
|
10
10
|
from fastapi.exceptions import HTTPException
|
|
11
|
-
from fastapi_xml import XmlAppResponse,
|
|
12
|
-
import uvicorn
|
|
11
|
+
from fastapi_xml import XmlAppResponse, XmlRoute
|
|
13
12
|
|
|
13
|
+
from .. import transport
|
|
14
14
|
from ..client import client_map
|
|
15
|
-
from ..
|
|
16
|
-
|
|
17
|
-
PayloadMessage,
|
|
18
|
-
PayloadMessageResponse,
|
|
19
|
-
AcceptedRejected,
|
|
20
|
-
)
|
|
21
|
-
from ..exceptions import (
|
|
22
|
-
FunctionalException,
|
|
23
|
-
TransportException,
|
|
24
|
-
InvalidSenderException,
|
|
25
|
-
InvalidMessageException,
|
|
26
|
-
)
|
|
15
|
+
from ..exceptions import (FunctionalException, InvalidMessageException,
|
|
16
|
+
InvalidSenderException, TransportException)
|
|
27
17
|
from ..logging import logger
|
|
28
|
-
from .. import
|
|
18
|
+
from ..uftp import (AcceptedRejected, PayloadMessage, PayloadMessageResponse,
|
|
19
|
+
SignedMessage)
|
|
29
20
|
|
|
30
21
|
|
|
31
22
|
class ShapeshifterService():
|
|
@@ -89,7 +80,7 @@ class ShapeshifterService():
|
|
|
89
80
|
# (one) endpoint, and by virtue of FastAPI-XML convert the
|
|
90
81
|
# python-friendly objects into XML and vice versa.
|
|
91
82
|
self.app = FastAPI(default_response_class=XmlAppResponse)
|
|
92
|
-
self.app.router.route_class =
|
|
83
|
+
self.app.router.route_class = XmlRoute
|
|
93
84
|
self.app.router.add_api_route(
|
|
94
85
|
path,
|
|
95
86
|
endpoint=self._receive_message,
|
|
@@ -251,9 +242,6 @@ class ShapeshifterService():
|
|
|
251
242
|
f"An error occurred during the post-processing of a {message.__class__.__name__} message."
|
|
252
243
|
f"{err.__class__.__name__}: {err}"
|
|
253
244
|
)
|
|
254
|
-
logger.error(
|
|
255
|
-
traceback.format_exc()
|
|
256
|
-
)
|
|
257
245
|
finally:
|
|
258
246
|
self.inbound_queue.task_done()
|
|
259
247
|
|
|
@@ -265,13 +265,6 @@ class DsoPortfolioQueryResponse(PayloadMessageResponse):
|
|
|
265
265
|
class Meta:
|
|
266
266
|
name = "DSOPortfolioQueryResponse"
|
|
267
267
|
|
|
268
|
-
congestion_point: Optional[DsoPortfolioQueryCongestionPoint] = field(
|
|
269
|
-
default=None,
|
|
270
|
-
metadata={
|
|
271
|
-
"name": "CongestionPoint",
|
|
272
|
-
"type": "Element",
|
|
273
|
-
}
|
|
274
|
-
)
|
|
275
268
|
dso_portfolio_query_message_id: str = field(
|
|
276
269
|
metadata={
|
|
277
270
|
"name": "DSOPortfolioQueryMessageID",
|
|
@@ -280,6 +273,14 @@ class DsoPortfolioQueryResponse(PayloadMessageResponse):
|
|
|
280
273
|
"pattern": r"[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}",
|
|
281
274
|
}
|
|
282
275
|
)
|
|
276
|
+
|
|
277
|
+
congestion_point: Optional[DsoPortfolioQueryCongestionPoint] = field(
|
|
278
|
+
default=None,
|
|
279
|
+
metadata={
|
|
280
|
+
"name": "CongestionPoint",
|
|
281
|
+
"type": "Element",
|
|
282
|
+
}
|
|
283
|
+
)
|
|
283
284
|
time_zone: str = field(
|
|
284
285
|
default=DEFAULT_TIME_ZONE,
|
|
285
286
|
metadata={
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/uftp/validations.py
RENAMED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
-
from decimal import Decimal, InvalidOperation
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def validate_decimal(name: str, value: int | float | Decimal | str, digits: int):
|
|
5
|
-
"""
|
|
6
|
-
Validates that the decimal is acceptable, and returns it with the correct number of digits.
|
|
7
|
-
"""
|
|
8
|
-
if isinstance(value, str):
|
|
9
|
-
try:
|
|
10
|
-
value = Decimal(value)
|
|
11
|
-
except InvalidOperation as exc:
|
|
12
|
-
raise ValueError(f"{name} must be a valid numeric value, not '{value}'") from exc
|
|
13
|
-
if not isinstance(value, (int, float, Decimal)):
|
|
14
|
-
raise TypeError(f"'{name}' must be a numeric type, not {type(value)}")
|
|
15
|
-
return Decimal(f"{value:.{digits}f}")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def validate_list(name, value, item_type, length):
|
|
19
|
-
"""
|
|
20
|
-
Validates that the list is of the correct type, length and content type.
|
|
21
|
-
"""
|
|
22
|
-
if not isinstance(value, list):
|
|
23
|
-
raise TypeError(f"'{name}' must be a list, not {type(value)}")
|
|
24
|
-
if len(value) < length:
|
|
25
|
-
raise ValueError(f"'Length of list '{name}' must be {length} or greater, not {len(value)}")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
from decimal import Decimal, InvalidOperation
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def validate_decimal(name: str, value: int | float | Decimal | str, digits: int):
|
|
5
|
+
"""
|
|
6
|
+
Validates that the decimal is acceptable, and returns it with the correct number of digits.
|
|
7
|
+
"""
|
|
8
|
+
if isinstance(value, str):
|
|
9
|
+
try:
|
|
10
|
+
value = Decimal(value)
|
|
11
|
+
except InvalidOperation as exc:
|
|
12
|
+
raise ValueError(f"{name} must be a valid numeric value, not '{value}'") from exc
|
|
13
|
+
if not isinstance(value, (int, float, Decimal)):
|
|
14
|
+
raise TypeError(f"'{name}' must be a numeric type, not {type(value)}")
|
|
15
|
+
return Decimal(f"{value:.{digits}f}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def validate_list(name, value, item_type, length):
|
|
19
|
+
"""
|
|
20
|
+
Validates that the list is of the correct type, length and content type.
|
|
21
|
+
"""
|
|
22
|
+
if not isinstance(value, list):
|
|
23
|
+
raise TypeError(f"'{name}' must be a list, not {type(value)}")
|
|
24
|
+
if len(value) < length:
|
|
25
|
+
raise ValueError(f"'Length of list '{name}' must be {length} or greater, not {len(value)}")
|
|
26
|
+
for index, item in enumerate(value):
|
|
27
|
+
if not isinstance(item, item_type):
|
|
28
|
+
raise TypeError(
|
|
29
|
+
f"Not all items of property {name} were of type {item_type}: "
|
|
30
|
+
f"item at index {index} was of type {type(item)}"
|
|
31
|
+
)
|
|
32
|
+
return value
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/SOURCES.txt
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
README.rst
|
|
2
|
+
pyproject.toml
|
|
2
3
|
setup.py
|
|
3
4
|
shapeshifter_uftp/__init__.py
|
|
4
5
|
shapeshifter_uftp/cli.py
|
|
@@ -31,6 +32,7 @@ shapeshifter_uftp/uftp/common.py
|
|
|
31
32
|
shapeshifter_uftp/uftp/cro_dso.py
|
|
32
33
|
shapeshifter_uftp/uftp/defaults.py
|
|
33
34
|
shapeshifter_uftp/uftp/metering.py
|
|
35
|
+
shapeshifter_uftp/uftp/parsing.py
|
|
34
36
|
shapeshifter_uftp/uftp/validations.py
|
|
35
37
|
test/test_cli.py
|
|
36
38
|
test/test_client_errors.py
|
|
@@ -1,57 +1,54 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
from time import sleep
|
|
3
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
4
|
-
|
|
5
|
-
from shapeshifter_uftp.uftp import routing_map, PayloadMessageResponse, AcceptedRejected
|
|
6
|
-
from shapeshifter_uftp.service.base_service import snake_case
|
|
7
|
-
from .helpers.messages import messages
|
|
8
|
-
from .helpers.services import DummyAgrService, DummyCroService, DummyDsoService
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# These fixtures allow us to only start up the services once and use
|
|
12
|
-
# them for all the parametrized test cases, which speeds up testing.
|
|
13
|
-
@pytest.fixture(scope='module')
|
|
14
|
-
def agr_service():
|
|
15
|
-
with DummyAgrService() as service:
|
|
16
|
-
yield service
|
|
17
|
-
|
|
18
|
-
@pytest.fixture(scope='module')
|
|
19
|
-
def cro_service():
|
|
20
|
-
with DummyCroService() as service:
|
|
21
|
-
yield service
|
|
22
|
-
|
|
23
|
-
@pytest.fixture(scope='module')
|
|
24
|
-
def dso_service():
|
|
25
|
-
with DummyDsoService() as service:
|
|
26
|
-
yield service
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@pytest.mark.parametrize(
|
|
30
|
-
'message',
|
|
31
|
-
messages,
|
|
32
|
-
ids=[message.__class__.__name__ for message in messages]
|
|
33
|
-
)
|
|
34
|
-
def test_communications(message, agr_service, cro_service, dso_service):
|
|
35
|
-
service_map = {
|
|
36
|
-
"AGR": agr_service,
|
|
37
|
-
"CRO": cro_service,
|
|
38
|
-
"DSO": dso_service,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
sender_role, recipient_role = routing_map[type(message)]
|
|
42
|
-
sender = service_map[sender_role]
|
|
43
|
-
recipient = service_map[recipient_role]
|
|
44
|
-
client_method = f"{recipient.sender_role.lower()}_client"
|
|
45
|
-
with ThreadPoolExecutor() as executor:
|
|
46
|
-
with getattr(sender, client_method)(recipient.sender_domain) as client:
|
|
47
|
-
sending_method = f"send_{snake_case(message.__class__.__name__)}"
|
|
48
|
-
main_future = executor.submit(getattr(client, sending_method), message)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
recipient.response_futures[f"pre_process_{snake_case(message.__class__.__name__)}"].set_result(response_message)
|
|
56
|
-
assert recipient.request_futures[f"process_{snake_case(message.__class__.__name__)}"].result() == message
|
|
57
|
-
assert main_future.result().result == AcceptedRejected.ACCEPTED
|
|
1
|
+
import pytest
|
|
2
|
+
from time import sleep
|
|
3
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
4
|
+
|
|
5
|
+
from shapeshifter_uftp.uftp import routing_map, PayloadMessageResponse, AcceptedRejected
|
|
6
|
+
from shapeshifter_uftp.service.base_service import snake_case
|
|
7
|
+
from .helpers.messages import messages
|
|
8
|
+
from .helpers.services import DummyAgrService, DummyCroService, DummyDsoService
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# These fixtures allow us to only start up the services once and use
|
|
12
|
+
# them for all the parametrized test cases, which speeds up testing.
|
|
13
|
+
@pytest.fixture(scope='module')
|
|
14
|
+
def agr_service():
|
|
15
|
+
with DummyAgrService() as service:
|
|
16
|
+
yield service
|
|
17
|
+
|
|
18
|
+
@pytest.fixture(scope='module')
|
|
19
|
+
def cro_service():
|
|
20
|
+
with DummyCroService() as service:
|
|
21
|
+
yield service
|
|
22
|
+
|
|
23
|
+
@pytest.fixture(scope='module')
|
|
24
|
+
def dso_service():
|
|
25
|
+
with DummyDsoService() as service:
|
|
26
|
+
yield service
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.mark.parametrize(
|
|
30
|
+
'message',
|
|
31
|
+
messages,
|
|
32
|
+
ids=[message.__class__.__name__ for message in messages]
|
|
33
|
+
)
|
|
34
|
+
def test_communications(message, agr_service, cro_service, dso_service):
|
|
35
|
+
service_map = {
|
|
36
|
+
"AGR": agr_service,
|
|
37
|
+
"CRO": cro_service,
|
|
38
|
+
"DSO": dso_service,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
sender_role, recipient_role = routing_map[type(message)]
|
|
42
|
+
sender = service_map[sender_role]
|
|
43
|
+
recipient = service_map[recipient_role]
|
|
44
|
+
client_method = f"{recipient.sender_role.lower()}_client"
|
|
45
|
+
with ThreadPoolExecutor() as executor:
|
|
46
|
+
with getattr(sender, client_method)(recipient.sender_domain) as client:
|
|
47
|
+
sending_method = f"send_{snake_case(message.__class__.__name__)}"
|
|
48
|
+
main_future = executor.submit(getattr(client, sending_method), message)
|
|
49
|
+
|
|
50
|
+
assert recipient.request_futures[f"pre_process_{snake_case(message.__class__.__name__)}"].result() == message
|
|
51
|
+
response_message = PayloadMessageResponse()
|
|
52
|
+
recipient.response_futures[f"pre_process_{snake_case(message.__class__.__name__)}"].set_result(response_message)
|
|
53
|
+
assert recipient.request_futures[f"process_{snake_case(message.__class__.__name__)}"].result() == message
|
|
54
|
+
assert main_future.result().result == AcceptedRejected.ACCEPTED
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/__init__.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/agr_cro_client.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/agr_dso_client.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/cro_agr_client.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/client/cro_dso_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/__init__.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .agr_service import ShapeshifterAgrService
|
|
2
|
+
from .base_service import snake_case
|
|
2
3
|
from .cro_service import ShapeshifterCroService
|
|
3
4
|
from .dso_service import ShapeshifterDsoService
|
|
4
|
-
from .base_service import snake_case
|
|
5
5
|
|
|
6
6
|
__all__ = [
|
|
7
7
|
"ShapeshifterAgrService",
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/agr_service.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/cro_service.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp/service/dso_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/shapeshifter_uftp.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_presence_of_client_methods.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_presence_of_service_methods.py
RENAMED
|
File without changes
|
{shapeshifter-uftp-1.1.1.dev2 → shapeshifter-uftp-1.2.0}/test/test_roundtrip_serialization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|