diff --git a/duniterpy/api/client.py b/duniterpy/api/client.py index 336447f040be2301bcef3307033ccc59354eee46..6dc1ce688708836c7ad582e52e9514a5b1897e80 100644 --- a/duniterpy/api/client.py +++ b/duniterpy/api/client.py @@ -301,7 +301,7 @@ class Client: return result - def connect_ws(self, path: str = '') -> _WSRequestContextManager: + def connect_ws(self, path: str = "") -> _WSRequestContextManager: """ Connect to a websocket in order to use API parameters diff --git a/duniterpy/api/endpoint.py b/duniterpy/api/endpoint.py index 08792235636ac3562ef23eb9ff7455daf906dd5e..c2452d9b2b15e673c395572bc16ca73c9fb0fc69 100644 --- a/duniterpy/api/endpoint.py +++ b/duniterpy/api/endpoint.py @@ -389,12 +389,20 @@ class WS2PEndpoint(Endpoint): :param proxy: Proxy url :return: """ - http_scheme = 'http' - websocket_scheme = 'ws' + http_scheme = "http" + websocket_scheme = "ws" if self.port == 443: - http_scheme += 's' - websocket_scheme += 's' - return ConnectionHandler(http_scheme, websocket_scheme, self.server, self.port, self.path, session, proxy) + http_scheme += "s" + websocket_scheme += "s" + return ConnectionHandler( + http_scheme, + websocket_scheme, + self.server, + self.port, + self.path, + session, + proxy, + ) def __str__(self) -> str: return self.inline() diff --git a/duniterpy/api/ws2p/network.py b/duniterpy/api/ws2p/network.py index 6774bcc77ed89508f307a1a619d08ca05d950947..d560573037a8a6a56aef70aaf6f34746dc695bf1 100644 --- a/duniterpy/api/ws2p/network.py +++ b/duniterpy/api/ws2p/network.py @@ -21,7 +21,7 @@ from duniterpy.api.client import Client logger = logging.getLogger("duniter/network") -MODULE = 'network' +MODULE = "network" WS2P_HEADS_SCHEMA = { "type": "object", @@ -31,27 +31,17 @@ WS2P_HEADS_SCHEMA = { "items": { "type": "object", "properties": { - "message": { - "type": "string" - }, - "sig": { - "type": "string", - }, - "messageV2": { - "type": "string" - }, - "sigV2": { - "type": "string", - }, - "step": { - "type": "number", - }, + "message": {"type": "string"}, + "sig": {"type": "string"}, + "messageV2": {"type": "string"}, + "sigV2": {"type": "string"}, + "step": {"type": "number"}, }, - "required": ["message", "sig"] - } + "required": ["message", "sig"], + }, } }, - "required": ["heads"] + "required": ["heads"], } @@ -62,59 +52,36 @@ def heads(client: Client): :param client: Client to connect to the api :rtype: dict """ - return client.get(MODULE + '/ws2p/heads', schema=WS2P_HEADS_SCHEMA) + return client.get(MODULE + "/ws2p/heads", schema=WS2P_HEADS_SCHEMA) WS2P_CONNECT_MESSAGE_SCHEMA = { "type": "object", "properties": { - "auth": { - "type": "string", - "pattern": "^CONNECT$" - }, - "challenge": { - "type": "string", - }, - "currency": { - "type": "string", - }, - "pub": { - "type": "string", - }, - "sig": { - "type": "string", - }, + "auth": {"type": "string", "pattern": "^CONNECT$"}, + "challenge": {"type": "string"}, + "currency": {"type": "string"}, + "pub": {"type": "string"}, + "sig": {"type": "string"}, }, - "required": ["auth", "challenge", "currency", "pub", "sig"] + "required": ["auth", "challenge", "currency", "pub", "sig"], } WS2P_ACK_MESSAGE_SCHEMA = { "type": "object", "properties": { - "auth": { - "type": "string", - "pattern": "^ACK$" - }, - "pub": { - "type": "string", - }, - "sig": { - "type": "string", - } + "auth": {"type": "string", "pattern": "^ACK$"}, + "pub": {"type": "string"}, + "sig": {"type": "string"}, }, - "required": ["auth", "pub", "sig"] + "required": ["auth", "pub", "sig"], } WS2P_OK_MESSAGE_SCHEMA = { "type": "object", "properties": { - "auth": { - "type": "string", - "pattern": "^OK$" - }, - "sig": { - "type": "string", - } + "auth": {"type": "string", "pattern": "^OK$"}, + "sig": {"type": "string"}, }, - "required": ["auth", "sig"] + "required": ["auth", "sig"], } diff --git a/duniterpy/api/ws2p/requests.py b/duniterpy/api/ws2p/requests.py index 2586253cb1d5374eeb785a66fbc17e2bb3755203..425def89a6a70e738542d71362eb6da61bb316dd 100644 --- a/duniterpy/api/ws2p/requests.py +++ b/duniterpy/api/ws2p/requests.py @@ -5,37 +5,28 @@ from duniterpy.api.bma.blockchain import BLOCK_SCHEMA, BLOCKS_SCHEMA ERROR_RESPONSE_SCHEMA = { "type": "object", "properties": { - "resId": { - "type": "string", - "pattern": "^[0-9,a-z,A-Z]{8}$" - }, - "err": {"type": "string"} + "resId": {"type": "string", "pattern": "^[0-9,a-z,A-Z]{8}$"}, + "err": {"type": "string"}, }, - "required": ["resId", "err"] + "required": ["resId", "err"], } BLOCK_RESPONSE_SCHEMA = { "type": "object", "properties": { - "resId": { - "type": "string", - "pattern": "^[0-9,a-z,A-Z]{8}$" - }, - "body": BLOCK_SCHEMA + "resId": {"type": "string", "pattern": "^[0-9,a-z,A-Z]{8}$"}, + "body": BLOCK_SCHEMA, }, - "required": ["resId", "body"] + "required": ["resId", "body"], } BLOCKS_RESPONSE_SCHEMA = { "type": "object", "properties": { - "resId": { - "type": "string", - "pattern": "^[0-9,a-z,A-Z]{8}$" - }, - "body": BLOCKS_SCHEMA + "resId": {"type": "string", "pattern": "^[0-9,a-z,A-Z]{8}$"}, + "body": BLOCKS_SCHEMA, }, - "required": ["resId", "body"] + "required": ["resId", "body"], } REQUIREMENTS_SCHEMA = { @@ -51,46 +42,24 @@ REQUIREMENTS_SCHEMA = { "items": { "type": "object", "properties": { - "from": { - "type": "string" - }, - "to": { - "type": "string" - }, - "expiresIn": { - "type": "number" - }, - "timestamp": { - "type": "number" - } + "from": {"type": "string"}, + "to": {"type": "string"}, + "expiresIn": {"type": "number"}, + "timestamp": {"type": "number"}, }, - "required": ["from", "to", "expiresIn", "timestamp"] - } - }, - "expired": { - "type": "boolean" - }, - "isSentry": { - "type": "boolean" - }, - "membershipExpiresIn": { - "type": "number" - }, - "membershipPendingExpiresIn": { - "type": "number" + "required": ["from", "to", "expiresIn", "timestamp"], + }, }, + "expired": {"type": "boolean"}, + "isSentry": {"type": "boolean"}, + "membershipExpiresIn": {"type": "number"}, + "membershipPendingExpiresIn": {"type": "number"}, "meta": { "type": "object", - "properties": { - "timestamp": { - "type": "string" - } - }, - "required": ["timestamp"] - }, - "outdistanced": { - "type": "boolean" + "properties": {"timestamp": {"type": "string"}}, + "required": ["timestamp"], }, + "outdistanced": {"type": "boolean"}, "pendingCerts": { "type": "array", "items": { @@ -108,10 +77,16 @@ REQUIREMENTS_SCHEMA = { "target": {"type": "string"}, "to": {"type": "string"}, "written": {"type": "boolean", "const": False}, - "written_block": {"type": ["string", "null"], "const": None}, - "written_hash": {"type": ["string", "null"], "const": None} - } - } + "written_block": { + "type": ["string", "null"], + "const": None, + }, + "written_hash": { + "type": ["string", "null"], + "const": None, + }, + }, + }, }, "pendingMemberships": { "type": "array", @@ -135,48 +110,50 @@ REQUIREMENTS_SCHEMA = { "type": {"type": "string"}, "userid": {"type": "string"}, "linked": {"type": "boolean", "const": False}, - "written_number": {"type": ["number", "null"], "const": None}, - } - } - }, - "pubkey": { - "type": "string" - }, - "revokation_sig": { - "type": ["string", "null"] - }, - "revoked": { - "type": "boolean" - }, - "sig": { - "type": "string" - }, - "uid": { - "type": "string" - }, - "wasMember": { - "type": "boolean" + "written_number": { + "type": ["number", "null"], + "const": None, + }, + }, + }, }, + "pubkey": {"type": "string"}, + "revokation_sig": {"type": ["string", "null"]}, + "revoked": {"type": "boolean"}, + "sig": {"type": "string"}, + "uid": {"type": "string"}, + "wasMember": {"type": "boolean"}, }, - "required": ["certifications", "expired", "isSentry", "membershipExpiresIn", - "membershipPendingExpiresIn", "meta", "outdistanced", "pendingCerts", - "pendingMemberships", "pubkey", "revocation_sig", "revoked", "sig", "uid", "wasMember"] - } + "required": [ + "certifications", + "expired", + "isSentry", + "membershipExpiresIn", + "membershipPendingExpiresIn", + "meta", + "outdistanced", + "pendingCerts", + "pendingMemberships", + "pubkey", + "revocation_sig", + "revoked", + "sig", + "uid", + "wasMember", + ], + }, } }, - "required": ["identities"] + "required": ["identities"], } REQUIREMENTS_RESPONSE_SCHEMA = { "type": "object", "properties": { - "resId": { - "type": "string", - "pattern": "^[0-9,a-z,A-Z]{8}$" - }, - "body": REQUIREMENTS_SCHEMA + "resId": {"type": "string", "pattern": "^[0-9,a-z,A-Z]{8}$"}, + "body": REQUIREMENTS_SCHEMA, }, - "required": ["resId", "body"] + "required": ["resId", "body"], } @@ -188,13 +165,7 @@ def get_current(request_id: str) -> str: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): raise Exception("Invalid ws2p request unique id") - return json.dumps({ - "reqId": request_id, - "body": { - "name": "CURRENT", - "params": {} - } - }) + return json.dumps({"reqId": request_id, "body": {"name": "CURRENT", "params": {}}}) def get_block(request_id: str, block_number: int) -> str: @@ -205,15 +176,12 @@ def get_block(request_id: str, block_number: int) -> str: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): raise Exception("Invalid ws2p request unique id") - return json.dumps({ - "reqId": request_id, - "body": { - "name": "BLOCK_BY_NUMBER", - "params": { - "number": block_number - } + return json.dumps( + { + "reqId": request_id, + "body": {"name": "BLOCK_BY_NUMBER", "params": {"number": block_number}}, } - }) + ) def get_blocks(request_id: str, from_number: int, count: int) -> str: @@ -224,16 +192,15 @@ def get_blocks(request_id: str, from_number: int, count: int) -> str: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): raise Exception("Invalid ws2p request unique id") - return json.dumps({ - "reqId": request_id, - "body": { - "name": "BLOCKS_CHUNK", - "params": { - "fromNumber": from_number, - "count": count - } + return json.dumps( + { + "reqId": request_id, + "body": { + "name": "BLOCKS_CHUNK", + "params": {"fromNumber": from_number, "count": count}, + }, } - }) + ) def get_requirements_pending(request_id: str, min_cert: int) -> str: @@ -244,12 +211,12 @@ def get_requirements_pending(request_id: str, min_cert: int) -> str: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): raise Exception("Invalid ws2p request unique id") - return json.dumps({ - "reqId": request_id, - "body": { - "name": "WOT_REQUIREMENTS_OF_PENDING", - "params": { - "minCert": min_cert - } + return json.dumps( + { + "reqId": request_id, + "body": { + "name": "WOT_REQUIREMENTS_OF_PENDING", + "params": {"minCert": min_cert}, + }, } - }) + ) diff --git a/duniterpy/documents/ws2p/messages.py b/duniterpy/documents/ws2p/messages.py index 5e03a25f9da6040f8d45c10ff0f9a32372cccf57..ff80fc6a3c0efa3a4a1ad978bea0f7e76809993b 100644 --- a/duniterpy/documents/ws2p/messages.py +++ b/duniterpy/documents/ws2p/messages.py @@ -11,8 +11,13 @@ class Connect(Document): version = 2 auth = "CONNECT" - def __init__(self, currency: str, pubkey: str, challenge: Optional[str] = None, - signature: Optional[str] = None) -> None: + def __init__( + self, + currency: str, + pubkey: str, + challenge: Optional[str] = None, + signature: Optional[str] = None, + ) -> None: """ Init Connect message document @@ -47,8 +52,9 @@ class Connect(Document): :return: """ - return "WS2P:CONNECT:{currency}:{pub}:{challenge}".format(currency=self.currency, pub=self.pubkey, - challenge=self.challenge) + return "WS2P:CONNECT:{currency}:{pub}:{challenge}".format( + currency=self.currency, pub=self.pubkey, challenge=self.challenge + ) def get_signed_json(self, signing_key: SigningKey) -> str: """ @@ -63,7 +69,7 @@ class Connect(Document): "auth": self.auth, "pub": self.pubkey, "challenge": self.challenge, - "sig": self.signatures[0] + "sig": self.signatures[0], } return json.dumps(data) @@ -75,8 +81,13 @@ class Ack(Document): version = 2 auth = "ACK" - def __init__(self, currency: str, pubkey: str, challenge: str, - signature: Optional[str] = None) -> None: + def __init__( + self, + currency: str, + pubkey: str, + challenge: str, + signature: Optional[str] = None, + ) -> None: """ Init Ack message document @@ -106,8 +117,9 @@ class Ack(Document): :return: """ - return "WS2P:ACK:{currency}:{pub}:{challenge}".format(currency=self.currency, pub=self.pubkey, - challenge=self.challenge) + return "WS2P:ACK:{currency}:{pub}:{challenge}".format( + currency=self.currency, pub=self.pubkey, challenge=self.challenge + ) def get_signed_json(self, signing_key: SigningKey) -> str: """ @@ -118,11 +130,7 @@ class Ack(Document): :return: """ self.sign([signing_key]) - data = { - "auth": self.auth, - "pub": self.pubkey, - "sig": self.signatures[0] - } + data = {"auth": self.auth, "pub": self.pubkey, "sig": self.signatures[0]} return json.dumps(data) def __str__(self) -> str: @@ -133,8 +141,13 @@ class Ok(Document): version = 2 auth = "OK" - def __init__(self, currency: str, pubkey: str, challenge: str, - signature: Optional[str] = None) -> None: + def __init__( + self, + currency: str, + pubkey: str, + challenge: str, + signature: Optional[str] = None, + ) -> None: """ Init Ok message document @@ -163,8 +176,9 @@ class Ok(Document): :return: """ - return "WS2P:OK:{currency}:{pub}:{challenge}".format(currency=self.currency, pub=self.pubkey, - challenge=self.challenge) + return "WS2P:OK:{currency}:{pub}:{challenge}".format( + currency=self.currency, pub=self.pubkey, challenge=self.challenge + ) def get_signed_json(self, signing_key: SigningKey) -> str: """ @@ -175,10 +189,7 @@ class Ok(Document): :return: """ self.sign([signing_key]) - data = { - "auth": self.auth, - "sig": self.signatures[0] - } + data = {"auth": self.auth, "sig": self.signatures[0]} return json.dumps(data) def __str__(self) -> str: @@ -199,7 +210,7 @@ class DocumentMessage: 2: "membership", 3: "certification", 4: "identity", - 5: "block" + 5: "block", } def get_json(self, document_type_id: int, document: str) -> str: @@ -212,7 +223,7 @@ class DocumentMessage: data = { "body": { "name": document_type_id, - self.DOCUMENT_TYPE_NAMES[document_type_id]: document + self.DOCUMENT_TYPE_NAMES[document_type_id]: document, } } return json.dumps(data) diff --git a/examples/request_ws2p.py b/examples/request_ws2p.py index 6104d9bc6003123b23cb4ccaecc8c2827395f46c..b77ef48c7d34c6e2eb49214ee52de1692c82fab9 100644 --- a/examples/request_ws2p.py +++ b/examples/request_ws2p.py @@ -83,24 +83,35 @@ async def main(): # print(msg.data) try: # Validate json string with jsonschema and return a dict - data = parse_text(msg.data, ws2p.network.WS2P_CONNECT_MESSAGE_SCHEMA) + data = parse_text( + msg.data, ws2p.network.WS2P_CONNECT_MESSAGE_SCHEMA + ) except jsonschema.exceptions.ValidationError: try: # Validate json string with jsonschema and return a dict - data = parse_text(msg.data, ws2p.network.WS2P_ACK_MESSAGE_SCHEMA) + data = parse_text( + msg.data, ws2p.network.WS2P_ACK_MESSAGE_SCHEMA + ) except jsonschema.exceptions.ValidationError: try: # Validate json string with jsonschema and return a dict - data = parse_text(msg.data, ws2p.network.WS2P_OK_MESSAGE_SCHEMA) + data = parse_text( + msg.data, ws2p.network.WS2P_OK_MESSAGE_SCHEMA + ) except jsonschema.exceptions.ValidationError: continue print("Received a OK message") - Ok(CURRENCY, remote_connect_document.pubkey, connect_document.challenge, data["sig"]) + Ok( + CURRENCY, + remote_connect_document.pubkey, + connect_document.challenge, + data["sig"], + ) print("Received OK message signature is valid") # END HANDSHAKE ####################################################### @@ -116,11 +127,17 @@ async def main(): print("Received a ACK message") # Create ACK document from ACK response to verify signature - Ack(CURRENCY, data["pub"], connect_document.challenge, data["sig"]) + Ack( + CURRENCY, + data["pub"], + connect_document.challenge, + data["sig"], + ) print("Received ACK message signature is valid") # If ACK response is ok, create OK message - ok_message = Ok(CURRENCY, signing_key.pubkey, connect_document.challenge).get_signed_json( - signing_key) + ok_message = Ok( + CURRENCY, signing_key.pubkey, connect_document.challenge + ).get_signed_json(signing_key) # Send OK message print("Send OK message...") @@ -129,12 +146,14 @@ async def main(): print("Received a CONNECT message") - remote_connect_document = Connect(CURRENCY, data["pub"], data["challenge"], data["sig"]) + remote_connect_document = Connect( + CURRENCY, data["pub"], data["challenge"], data["sig"] + ) print("Received CONNECT message signature is valid") - ack_message = Ack(CURRENCY, signing_key.pubkey, - remote_connect_document.challenge).get_signed_json( - signing_key) + ack_message = Ack( + CURRENCY, signing_key.pubkey, remote_connect_document.challenge + ).get_signed_json(signing_key) # Send ACK message print("Send ACK message...") await ws.send_str(ack_message) @@ -154,7 +173,9 @@ async def main(): # Wait response with request id response_str = await ws.receive_str() while "resId" not in json.loads(response_str) or ( - "resId" in json.loads(response_str) and json.loads(response_str)["resId"] != request_id): + "resId" in json.loads(response_str) + and json.loads(response_str)["resId"] != request_id + ): response_str = await ws.receive_str() time.sleep(1) try: @@ -181,7 +202,9 @@ async def main(): # Wait response with request id response_str = await ws.receive_str() while "resId" not in json.loads(response_str) or ( - "resId" in json.loads(response_str) and json.loads(response_str)["resId"] != request_id): + "resId" in json.loads(response_str) + and json.loads(response_str)["resId"] != request_id + ): response_str = await ws.receive_str() time.sleep(1) try: @@ -208,7 +231,9 @@ async def main(): # Wait response with request id response_str = await ws.receive_str() while "resId" not in json.loads(response_str) or ( - "resId" in json.loads(response_str) and json.loads(response_str)["resId"] != request_id): + "resId" in json.loads(response_str) + and json.loads(response_str)["resId"] != request_id + ): response_str = await ws.receive_str() time.sleep(1) try: @@ -234,7 +259,9 @@ async def main(): # Wait response with request id response_str = await ws.receive_str() while "resId" not in json.loads(response_str) or ( - "resId" in json.loads(response_str) and json.loads(response_str)["resId"] != request_id): + "resId" in json.loads(response_str) + and json.loads(response_str)["resId"] != request_id + ): response_str = await ws.receive_str() time.sleep(1) try: diff --git a/tests/api/ws2p/test_ws2p.py b/tests/api/ws2p/test_ws2p.py index 90aba0ee3ad330e8302d3072f50d743c7e22f888..975f2737f35981038bb0bdb8788b2964d9cff07f 100644 --- a/tests/api/ws2p/test_ws2p.py +++ b/tests/api/ws2p/test_ws2p.py @@ -5,15 +5,18 @@ import jsonschema from duniterpy.api.client import parse_text from duniterpy.api.ws2p.network import WS2P_HEADS_SCHEMA -from duniterpy.api.ws2p.requests import BLOCK_RESPONSE_SCHEMA, ERROR_RESPONSE_SCHEMA, BLOCKS_RESPONSE_SCHEMA, \ - REQUIREMENTS_RESPONSE_SCHEMA +from duniterpy.api.ws2p.requests import ( + BLOCK_RESPONSE_SCHEMA, + ERROR_RESPONSE_SCHEMA, + BLOCKS_RESPONSE_SCHEMA, + REQUIREMENTS_RESPONSE_SCHEMA, +) from duniterpy.documents import Identity, BlockUID from duniterpy.documents.ws2p.messages import DocumentMessage from tests.api.webserver import WebFunctionalSetupMixin class TestWs2p(WebFunctionalSetupMixin, unittest.TestCase): - def test_block(self): json_sample = { "heads": [ @@ -25,7 +28,7 @@ class TestWs2p(WebFunctionalSetupMixin, unittest.TestCase): 102102-000002C0694C7D373A78B095419C86584B81804CFB9641B7EBC3A18040B6FEE6:e66254bf:\ duniter:1.6.20:1:15:14", "sigV2": "ReXzbgUya9jo4dL/R4g19Y+RE9BGB0xDkw7mrBWoldlRLkq3KFyRkAf9VthVx1UUb/AINr3nxImZKVQiVH9+DQ==", - "step": 0 + "step": 0, }, { "message": "WS2POCAIC:HEAD:1:2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ:\ @@ -35,7 +38,7 @@ class TestWs2p(WebFunctionalSetupMixin, unittest.TestCase): 102102-000002C0694C7D373A78B095419C86584B81804CFB9641B7EBC3A18040B6FEE6:a0a45ed2:\ duniter:1.6.21:1:34:28", "sigV2": "p5f7/KfQqjTaCYSMUXpjUDH7uF2DafetHNgphGzkOXgxM+Upeii0Fz2RFBwnZvN+Gjp81hAqSuH48PJP6HJSAw==", - "step": 1 + "step": 1, }, { "message": "WS2POCA:HEAD:1:GRBPV3Y7PQnB9LaZhSGuS3BqBJbSHyibzYq65kTh1nQ4:\ @@ -45,7 +48,7 @@ class TestWs2p(WebFunctionalSetupMixin, unittest.TestCase): 102102-000002C0694C7D373A78B095419C86584B81804CFB9641B7EBC3A18040B6FEE6:6d0e96f9:\ duniter:1.6.21:1:20:20", "sigV2": "VsyQmXOUYrfHWy0FeS4rJrIJCUBI+3BergbSYQ78icJWV6MQzZSw7Z+Yl7urujCYZriDQM76D6GW+6F0EELpBQ==", - "step": 2 + "step": 2, }, ] } @@ -170,11 +173,17 @@ class TestWs2p(WebFunctionalSetupMixin, unittest.TestCase): document_message = DocumentMessage() # prepare document identity_document = Identity( - 10, "beta_brousouf", "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd", "lolcat", + 10, + "beta_brousouf", + "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd", + "lolcat", BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"), - "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci") + "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci", + ) # get json string message - json_document_message = document_message.get_json(DocumentMessage.IDENTITY_TYPE_ID, identity_document.inline()) + json_document_message = document_message.get_json( + DocumentMessage.IDENTITY_TYPE_ID, identity_document.inline() + ) # convert to dict to verify dict_document_message = json.loads(json_document_message)