From a2d9c88ee6d3a6d51ea16fccefaa54d1122abe57 Mon Sep 17 00:00:00 2001 From: 650elx Date: Mon, 15 Apr 2024 12:36:30 +0200 Subject: [PATCH 01/12] feat(Verification): elegant callout methods added --- sinch/domains/verification/__init__.py | 62 ++++++++++++++++++- sinch/domains/verification/models/requests.py | 23 ++++++- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/sinch/domains/verification/__init__.py b/sinch/domains/verification/__init__.py index e32a8b2a..c96ff37f 100644 --- a/sinch/domains/verification/__init__.py +++ b/sinch/domains/verification/__init__.py @@ -38,7 +38,67 @@ class Verifications: def __init__(self, sinch): self._sinch = sinch - def start( + def start_sms( + self, + identity: dict, + method: VerificationMethod, + reference: str = None, + custom: str = None, + flash_call_options: dict = None + ) -> StartVerificationResponse: + return self._sinch.configuration.transport.request( + StartVerificationEndpoint( + request_data=StartVerificationRequest( + identity=identity, + method=method, + reference=reference, + custom=custom, + flash_call_options=flash_call_options + ) + ) + ) + + def start_flash_call( + self, + identity: dict, + method: VerificationMethod, + reference: str = None, + custom: str = None, + flash_call_options: dict = None + ) -> StartVerificationResponse: + return self._sinch.configuration.transport.request( + StartVerificationEndpoint( + request_data=StartVerificationRequest( + identity=identity, + method=method, + reference=reference, + custom=custom, + flash_call_options=flash_call_options + ) + ) + ) + + def start_callout( + self, + identity: dict, + method: VerificationMethod, + reference: str = None, + custom: str = None, + flash_call_options: dict = None + ) -> StartVerificationResponse: + return self._sinch.configuration.transport.request( + StartVerificationEndpoint( + request_data=StartVerificationRequest( + identity=identity, + method=method, + reference=reference, + custom=custom, + flash_call_options=flash_call_options + ) + ) + ) + + def start_seamless( self, identity: dict, method: VerificationMethod, diff --git a/sinch/domains/verification/models/requests.py b/sinch/domains/verification/models/requests.py index fddb010c..7a591412 100644 --- a/sinch/domains/verification/models/requests.py +++ b/sinch/domains/verification/models/requests.py @@ -6,10 +6,29 @@ @dataclass class StartVerificationRequest(SinchRequestBaseModel): identity: dict - method: VerificationMethod reference: str custom: str - flash_call_options: dict + + + +@dataclass +class StartSMSVerificationRequest(StartVerificationRequest): + method: str = VerificationMethod.SMS.value + + +@dataclass +class StartFlashCallVerificationRequest(StartVerificationRequest): + method: str = VerificationMethod.FLASHCALL.value + + +@dataclass +class StartCalloutVerificationRequest(StartVerificationRequest): + method: str = VerificationMethod.CALLOUT.value + + +@dataclass +class StartSeamlessVerificationRequest(StartVerificationRequest): + method: str = VerificationMethod.SEAMLESS.value @dataclass From 5639d0e959cdbc8810f0bbe015c8553b9cf511b7 Mon Sep 17 00:00:00 2001 From: 650elx Date: Mon, 15 Apr 2024 20:16:37 +0200 Subject: [PATCH 02/12] feat(Verification): facade and request models added --- sinch/domains/verification/__init__.py | 52 +++++++++---------- sinch/domains/verification/models/__init__.py | 7 +++ sinch/domains/verification/models/requests.py | 9 +++- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/sinch/domains/verification/__init__.py b/sinch/domains/verification/__init__.py index c96ff37f..c18ac200 100644 --- a/sinch/domains/verification/__init__.py +++ b/sinch/domains/verification/__init__.py @@ -23,7 +23,10 @@ GetVerificationStatusByReferenceResponse ) from sinch.domains.verification.models.requests import ( - StartVerificationRequest, + StartSMSVerificationRequest, + StartFlashCallVerificationRequest, + StartCalloutVerificationRequest, + StartSeamlessVerificationRequest, ReportVerificationByIdentityRequest, ReportVerificationByIdRequest, GetVerificationStatusByIdRequest, @@ -32,6 +35,7 @@ ) from sinch.domains.verification.enums import VerificationMethod +from sinch.domains.verification.models import VerificationIdentity class Verifications: @@ -40,80 +44,74 @@ def __init__(self, sinch): def start_sms( self, - identity: dict, - method: VerificationMethod, + identity: VerificationIdentity, reference: str = None, custom: str = None, - flash_call_options: dict = None + expiry: str = None, + code_type: str = None, + template: str = None ) -> StartVerificationResponse: return self._sinch.configuration.transport.request( StartVerificationEndpoint( - request_data=StartVerificationRequest( + request_data=StartSMSVerificationRequest( identity=identity, - method=method, reference=reference, custom=custom, - flash_call_options=flash_call_options + expiry=expiry, + code_type=code_type, + template=template ) ) ) def start_flash_call( self, - identity: dict, - method: VerificationMethod, + identity: VerificationIdentity, reference: str = None, custom: str = None, - flash_call_options: dict = None + dial_timeout: int = None ) -> StartVerificationResponse: return self._sinch.configuration.transport.request( StartVerificationEndpoint( - request_data=StartVerificationRequest( + request_data=StartFlashCallVerificationRequest( identity=identity, - method=method, reference=reference, custom=custom, - flash_call_options=flash_call_options + dial_timeout=dial_timeout ) ) ) def start_callout( self, - identity: dict, - method: VerificationMethod, + identity: VerificationIdentity, reference: str = None, custom: str = None, - flash_call_options: dict = None + speech_locale: str = None ) -> StartVerificationResponse: return self._sinch.configuration.transport.request( StartVerificationEndpoint( - request_data=StartVerificationRequest( + request_data=StartCalloutVerificationRequest( identity=identity, - method=method, reference=reference, custom=custom, - flash_call_options=flash_call_options + speech_locale=speech_locale ) ) ) def start_seamless( self, - identity: dict, - method: VerificationMethod, + identity: VerificationIdentity, reference: str = None, - custom: str = None, - flash_call_options: dict = None + custom: str = None ) -> StartVerificationResponse: return self._sinch.configuration.transport.request( StartVerificationEndpoint( - request_data=StartVerificationRequest( + request_data=StartSeamlessVerificationRequest( identity=identity, - method=method, reference=reference, - custom=custom, - flash_call_options=flash_call_options + custom=custom ) ) ) diff --git a/sinch/domains/verification/models/__init__.py b/sinch/domains/verification/models/__init__.py index e69de29b..f685a0c3 100644 --- a/sinch/domains/verification/models/__init__.py +++ b/sinch/domains/verification/models/__init__.py @@ -0,0 +1,7 @@ +from typing import TypedDict + + +class VerificationIdentity(TypedDict): + type: str + endpoint: str + diff --git a/sinch/domains/verification/models/requests.py b/sinch/domains/verification/models/requests.py index 7a591412..b8cb43d2 100644 --- a/sinch/domains/verification/models/requests.py +++ b/sinch/domains/verification/models/requests.py @@ -1,28 +1,33 @@ from dataclasses import dataclass from sinch.core.models.base_model import SinchRequestBaseModel from sinch.domains.verification.enums import VerificationMethod +from sinch.domains.verification.models import VerificationIdentity @dataclass class StartVerificationRequest(SinchRequestBaseModel): - identity: dict + identity: VerificationIdentity reference: str custom: str - @dataclass class StartSMSVerificationRequest(StartVerificationRequest): method: str = VerificationMethod.SMS.value + expiry: str = None + code_type: str = None + template: str = None @dataclass class StartFlashCallVerificationRequest(StartVerificationRequest): + dial_timeout: int method: str = VerificationMethod.FLASHCALL.value @dataclass class StartCalloutVerificationRequest(StartVerificationRequest): + speech_locale: str method: str = VerificationMethod.CALLOUT.value From 1ce90fec12721fd56060ee5e7c615d5968b0c958 Mon Sep 17 00:00:00 2001 From: 650elx Date: Mon, 22 Apr 2024 16:55:44 +0200 Subject: [PATCH 03/12] test(Verification): adopt e2e test --- sinch/domains/verification/models/requests.py | 8 ++++++++ tests/e2e/verification/test_start_verification.py | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sinch/domains/verification/models/requests.py b/sinch/domains/verification/models/requests.py index b8cb43d2..f7a28e64 100644 --- a/sinch/domains/verification/models/requests.py +++ b/sinch/domains/verification/models/requests.py @@ -24,6 +24,14 @@ class StartFlashCallVerificationRequest(StartVerificationRequest): dial_timeout: int method: str = VerificationMethod.FLASHCALL.value + def as_dict(self): + payload = super().as_dict() + if payload.get("dial_timeout"): + payload["flashCallOptions"] = { + "dialTimeout": payload.pop("dial_timeout") + } + return payload + @dataclass class StartCalloutVerificationRequest(StartVerificationRequest): diff --git a/tests/e2e/verification/test_start_verification.py b/tests/e2e/verification/test_start_verification.py index beee4654..894fab5d 100644 --- a/tests/e2e/verification/test_start_verification.py +++ b/tests/e2e/verification/test_start_verification.py @@ -43,13 +43,13 @@ def test_start_verification_flash_call( sinch_client_sync, phone_number ): - verification_response = sinch_client_sync.verification.verifications.start( - method=VerificationMethod.FLASHCALL.value, + verification_response = sinch_client_sync.verification.verifications.start_flash_call( identity={ "type": "number", "endpoint": phone_number }, - reference="random5" + reference="random5", + dial_timeout=5 ) assert isinstance(verification_response, StartFlashCallInitiateVerificationResponse) From 80ac8059a762fb2ab67d637202ce7773c5135381 Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 00:32:02 +0200 Subject: [PATCH 04/12] feat(Verification): response data handling added --- sinch/domains/verification/__init__.py | 2 - .../endpoints/start_verification.py | 29 ++++++++-- sinch/domains/verification/models/__init__.py | 1 - sinch/domains/verification/models/requests.py | 34 ++++++++++-- .../domains/verification/models/responses.py | 31 ++++++++--- .../verification/test_start_verification.py | 54 +++++++++++++++---- 6 files changed, 124 insertions(+), 27 deletions(-) diff --git a/sinch/domains/verification/__init__.py b/sinch/domains/verification/__init__.py index c18ac200..e66f07b4 100644 --- a/sinch/domains/verification/__init__.py +++ b/sinch/domains/verification/__init__.py @@ -33,8 +33,6 @@ GetVerificationStatusByIdentityRequest, GetVerificationStatusByReferenceRequest ) - -from sinch.domains.verification.enums import VerificationMethod from sinch.domains.verification.models import VerificationIdentity diff --git a/sinch/domains/verification/endpoints/start_verification.py b/sinch/domains/verification/endpoints/start_verification.py index 1d380de4..9d8568a2 100644 --- a/sinch/domains/verification/endpoints/start_verification.py +++ b/sinch/domains/verification/endpoints/start_verification.py @@ -4,6 +4,9 @@ from sinch.domains.verification.enums import VerificationMethod from sinch.domains.verification.models.requests import StartVerificationRequest from sinch.domains.verification.models.responses import ( + FlashCallResponse, + SMSResponse, + DataResponse, StartVerificationResponse, StartSMSInitiateVerificationResponse, StartDataInitiateVerificationResponse, @@ -32,20 +35,38 @@ def handle_response(self, response: HTTPResponse) -> StartVerificationResponse: super().handle_response(response) if self.request_data.method == VerificationMethod.SMS.value: return StartSMSInitiateVerificationResponse( - **response.body + id=response.body.get("id"), + method=response.body.get("method"), + _links=response.body.get("_links"), + sms=SMSResponse( + interception_timeout=response.body["sms"].get("interceptionTimeout"), + template=response.body["sms"].get("template") + ) ) elif self.request_data.method == VerificationMethod.FLASHCALL.value: return StartFlashCallInitiateVerificationResponse( id=response.body.get("id"), method=response.body.get("method"), _links=response.body.get("_links"), - flashcall=response.body.get("flashCall") + flashcall=FlashCallResponse( + cli_filter=response.body["flashCall"].get("cliFilter"), + interception_timeout=response.body["flashCall"].get("interceptionTimeout"), + report_timeout=response.body["flashCall"].get("reportTimeout"), + deny_call_after=response.body["flashCall"].get("denyCallAfter") + ) ) elif self.request_data.method == VerificationMethod.CALLOUT.value: return StartCalloutInitiateVerificationResponse( - **response.body + id=response.body.get("id"), + method=response.body.get("method"), + _links=response.body.get("_links") ) elif self.request_data.method == VerificationMethod.SEAMLESS.value: return StartDataInitiateVerificationResponse( - **response.body + id=response.body.get("id"), + method=response.body.get("method"), + _links=response.body.get("_links"), + seamless=DataResponse( + target_uri=response.body["seamless"].get("targetUri") + ) ) diff --git a/sinch/domains/verification/models/__init__.py b/sinch/domains/verification/models/__init__.py index f685a0c3..f225ac43 100644 --- a/sinch/domains/verification/models/__init__.py +++ b/sinch/domains/verification/models/__init__.py @@ -4,4 +4,3 @@ class VerificationIdentity(TypedDict): type: str endpoint: str - diff --git a/sinch/domains/verification/models/requests.py b/sinch/domains/verification/models/requests.py index f7a28e64..eabe8cb4 100644 --- a/sinch/domains/verification/models/requests.py +++ b/sinch/domains/verification/models/requests.py @@ -13,10 +13,28 @@ class StartVerificationRequest(SinchRequestBaseModel): @dataclass class StartSMSVerificationRequest(StartVerificationRequest): + expiry: str + code_type: str + template: str method: str = VerificationMethod.SMS.value - expiry: str = None - code_type: str = None - template: str = None + + def as_dict(self): + payload = super().as_dict() + payload["smsOptions"] = {} + + if payload.get("code_type"): + payload["smsOptions"].update({ + "codeType": payload.pop("code_type") + }) + elif payload.get("expiry"): + payload["smsOptions"].update({ + "expiry": payload.pop("expiry") + }) + elif payload.get("template"): + payload["smsOptions"].update({ + "template": payload.pop("template") + }) + return payload @dataclass @@ -38,6 +56,16 @@ class StartCalloutVerificationRequest(StartVerificationRequest): speech_locale: str method: str = VerificationMethod.CALLOUT.value + def as_dict(self): + payload = super().as_dict() + if payload.get("speech_locale"): + payload["calloutOptions"] = { + "speech": { + "locale": payload.pop("speech_locale") + } + } + return payload + @dataclass class StartSeamlessVerificationRequest(StartVerificationRequest): diff --git a/sinch/domains/verification/models/responses.py b/sinch/domains/verification/models/responses.py index 911c1195..a21b1350 100644 --- a/sinch/domains/verification/models/responses.py +++ b/sinch/domains/verification/models/responses.py @@ -3,6 +3,25 @@ from sinch.domains.verification.enums import VerificationMethod, VerificationStatus +@dataclass +class FlashCallResponse: + cli_filter: str + interception_timeout: int + report_timeout: int + deny_call_after: int + + +@dataclass +class SMSResponse: + template: str + interception_timeout: str + + +@dataclass +class DataResponse: + target_uri: str + + @dataclass class StartVerificationResponse(SinchBaseModel): id: str @@ -12,22 +31,22 @@ class StartVerificationResponse(SinchBaseModel): @dataclass class StartSMSInitiateVerificationResponse(StartVerificationResponse): - sms: dict + sms: SMSResponse @dataclass class StartFlashCallInitiateVerificationResponse(StartVerificationResponse): - flashcall: dict + flashcall: FlashCallResponse @dataclass -class StartCalloutInitiateVerificationResponse(StartVerificationResponse): - callout: dict +class StartDataInitiateVerificationResponse(StartVerificationResponse): + seamless: DataResponse @dataclass -class StartDataInitiateVerificationResponse(StartVerificationResponse): - seamless: dict +class StartCalloutInitiateVerificationResponse(StartVerificationResponse): + pass @dataclass diff --git a/tests/e2e/verification/test_start_verification.py b/tests/e2e/verification/test_start_verification.py index 894fab5d..67a5ce7f 100644 --- a/tests/e2e/verification/test_start_verification.py +++ b/tests/e2e/verification/test_start_verification.py @@ -1,9 +1,10 @@ import pytest from sinch.domains.verification.models.responses import ( StartSMSInitiateVerificationResponse, - StartFlashCallInitiateVerificationResponse + StartFlashCallInitiateVerificationResponse, + StartCalloutInitiateVerificationResponse, + StartDataInitiateVerificationResponse ) -from sinch.domains.verification.enums import VerificationMethod from sinch.domains.verification.exceptions import VerificationException @@ -11,13 +12,13 @@ def test_start_verification_sms( sinch_client_sync, phone_number ): - verification_response = sinch_client_sync.verification.verifications.start( - method="sms", + verification_response = sinch_client_sync.verification.verifications.start_sms( identity={ "type": "number", "endpoint": phone_number }, - reference="random" + reference="random", + expiry="23:21:21" ) assert isinstance(verification_response, StartSMSInitiateVerificationResponse) @@ -28,8 +29,7 @@ def test_start_verification_sms_malformed_phone_number( phone_number ): with pytest.raises(VerificationException) as err: - sinch_client_sync.verification.verifications.start( - method="sms", + sinch_client_sync.verification.verifications.start_sms( identity={ "type": "number", "endpoint": "abcd" + phone_number + "abcd" @@ -55,17 +55,49 @@ def test_start_verification_flash_call( assert isinstance(verification_response, StartFlashCallInitiateVerificationResponse) -async def test_start_verification_async( +def test_start_verification_callout( + sinch_client_sync, + phone_number +): + verification_response = sinch_client_sync.verification.verifications.start_callout( + identity={ + "type": "number", + "endpoint": phone_number + }, + reference="random32", + speech_locale="en-US" + ) + + assert isinstance(verification_response, StartCalloutInitiateVerificationResponse) + + +@pytest.mark.skip(reason="Data verification. Mobile carrier support required.") +def test_start_verification_seamless( + sinch_client_sync, + phone_number +): + verification_response = sinch_client_sync.verification.verifications.start_seamless( + identity={ + "type": "number", + "endpoint": phone_number + }, + reference="random99" + ) + + assert isinstance(verification_response, StartDataInitiateVerificationResponse) + + +async def test_start_verification_sms_async( sinch_client_async, phone_number ): - verification_response = await sinch_client_async.verification.verifications.start( - method="sms", + verification_response = await sinch_client_async.verification.verifications.start_sms( identity={ "type": "number", "endpoint": phone_number }, - reference="random" + reference="random", + expiry="23:21:21" ) assert isinstance(verification_response, StartSMSInitiateVerificationResponse) From 01bbbfd219cb3459e9feeb90f77e5ccf48df3f0f Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:23:36 +0200 Subject: [PATCH 05/12] fix(CI): mitigate GH Actions permission issiue --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 0d4b61e4..73604d95 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -62,7 +62,7 @@ jobs: - uses: actions/setup-node@v3 - name: Install wait-port run: | - npm install -g wait-port + npm install wait-port - name: Test E2E with Pytest and Wiremock run: | From e4df8ee1a1090a6a1832272a3c3848eb5594ac71 Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:26:38 +0200 Subject: [PATCH 06/12] Revert "fix(CI): mitigate GH Actions permission issiue" This reverts commit 01bbbfd219cb3459e9feeb90f77e5ccf48df3f0f. --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 73604d95..0d4b61e4 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -62,7 +62,7 @@ jobs: - uses: actions/setup-node@v3 - name: Install wait-port run: | - npm install wait-port + npm install -g wait-port - name: Test E2E with Pytest and Wiremock run: | From c3cd296ffb23d5e45fb5bbd8c6d064c35f05e2bb Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:41:21 +0200 Subject: [PATCH 07/12] fix(CI): fix path for npm install --- .github/workflows/run-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 0d4b61e4..efbe5d4b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -62,6 +62,9 @@ jobs: - uses: actions/setup-node@v3 - name: Install wait-port run: | + mkdir ~/.npm-global + npm config set prefix '~/.npm-global' + export PATH=~/.npm-global/bin:$PATH npm install -g wait-port - name: Test E2E with Pytest and Wiremock From 2ccee4b645040d84a7be62cb08885727a7f6a8f1 Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:45:47 +0200 Subject: [PATCH 08/12] Revert "fix(CI): fix path for npm install" This reverts commit c3cd296ffb23d5e45fb5bbd8c6d064c35f05e2bb. --- .github/workflows/run-tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index efbe5d4b..0d4b61e4 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -62,9 +62,6 @@ jobs: - uses: actions/setup-node@v3 - name: Install wait-port run: | - mkdir ~/.npm-global - npm config set prefix '~/.npm-global' - export PATH=~/.npm-global/bin:$PATH npm install -g wait-port - name: Test E2E with Pytest and Wiremock From 947869025cddc34ef5ea0b567c0b67768d28cf38 Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:48:30 +0200 Subject: [PATCH 09/12] fix(CI): bump version of the GH action --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 0d4b61e4..bccb759d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -59,7 +59,7 @@ jobs: ref: numbers_fixtures path: sinch-sdk-internal-specs - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 - name: Install wait-port run: | npm install -g wait-port From 1d3b4b62034e2c9562e68e8dbe97a4515efc38b0 Mon Sep 17 00:00:00 2001 From: 650elx Date: Tue, 23 Apr 2024 12:52:57 +0200 Subject: [PATCH 10/12] fix(CI): unsifficient permissions for wait-port --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index bccb759d..2f8289b7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -59,10 +59,10 @@ jobs: ref: numbers_fixtures path: sinch-sdk-internal-specs - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v3 - name: Install wait-port run: | - npm install -g wait-port + sudo npm install -g wait-port - name: Test E2E with Pytest and Wiremock run: | From 221d711590e786970cfcac1ec26d23b82d534c48 Mon Sep 17 00:00:00 2001 From: 650elx Date: Fri, 26 Apr 2024 19:49:57 +0200 Subject: [PATCH 11/12] feat(Verification): only "number" is supported for Identity for now --- sinch/domains/verification/models/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sinch/domains/verification/models/__init__.py b/sinch/domains/verification/models/__init__.py index f225ac43..a8786da8 100644 --- a/sinch/domains/verification/models/__init__.py +++ b/sinch/domains/verification/models/__init__.py @@ -1,6 +1,6 @@ -from typing import TypedDict +from typing import TypedDict, Literal class VerificationIdentity(TypedDict): - type: str + type: Literal["number"] endpoint: str From 46cca82529f9148320fdb9938dd02211c2790aed Mon Sep 17 00:00:00 2001 From: 650elx Date: Mon, 29 Apr 2024 16:48:36 +0200 Subject: [PATCH 12/12] feat(Verification): more robust response handling --- .../verification/endpoints/start_verification.py | 13 ++++++++----- sinch/domains/verification/enums.py | 2 +- sinch/domains/verification/models/requests.py | 2 +- sinch/domains/verification/models/responses.py | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sinch/domains/verification/endpoints/start_verification.py b/sinch/domains/verification/endpoints/start_verification.py index 9d8568a2..3eb9956e 100644 --- a/sinch/domains/verification/endpoints/start_verification.py +++ b/sinch/domains/verification/endpoints/start_verification.py @@ -34,6 +34,7 @@ def request_body(self): def handle_response(self, response: HTTPResponse) -> StartVerificationResponse: super().handle_response(response) if self.request_data.method == VerificationMethod.SMS.value: + sms_response = response.body.get("sms") return StartSMSInitiateVerificationResponse( id=response.body.get("id"), method=response.body.get("method"), @@ -41,19 +42,20 @@ def handle_response(self, response: HTTPResponse) -> StartVerificationResponse: sms=SMSResponse( interception_timeout=response.body["sms"].get("interceptionTimeout"), template=response.body["sms"].get("template") - ) + ) if sms_response else None ) - elif self.request_data.method == VerificationMethod.FLASHCALL.value: + elif self.request_data.method == VerificationMethod.FLASH_CALL.value: + flash_call_response = response.body.get("flashCall") return StartFlashCallInitiateVerificationResponse( id=response.body.get("id"), method=response.body.get("method"), _links=response.body.get("_links"), - flashcall=FlashCallResponse( + flash_call=FlashCallResponse( cli_filter=response.body["flashCall"].get("cliFilter"), interception_timeout=response.body["flashCall"].get("interceptionTimeout"), report_timeout=response.body["flashCall"].get("reportTimeout"), deny_call_after=response.body["flashCall"].get("denyCallAfter") - ) + ) if flash_call_response else None ) elif self.request_data.method == VerificationMethod.CALLOUT.value: return StartCalloutInitiateVerificationResponse( @@ -62,11 +64,12 @@ def handle_response(self, response: HTTPResponse) -> StartVerificationResponse: _links=response.body.get("_links") ) elif self.request_data.method == VerificationMethod.SEAMLESS.value: + seamless_response = response.body.get("seamless") return StartDataInitiateVerificationResponse( id=response.body.get("id"), method=response.body.get("method"), _links=response.body.get("_links"), seamless=DataResponse( target_uri=response.body["seamless"].get("targetUri") - ) + ) if seamless_response else None ) diff --git a/sinch/domains/verification/enums.py b/sinch/domains/verification/enums.py index 82f6c80d..26e0212c 100644 --- a/sinch/domains/verification/enums.py +++ b/sinch/domains/verification/enums.py @@ -3,7 +3,7 @@ class VerificationMethod(Enum): SMS = "sms" - FLASHCALL = "flashcall" + FLASH_CALL = "flashCall" CALLOUT = "callout" SEAMLESS = "seamless" diff --git a/sinch/domains/verification/models/requests.py b/sinch/domains/verification/models/requests.py index eabe8cb4..1cd784a8 100644 --- a/sinch/domains/verification/models/requests.py +++ b/sinch/domains/verification/models/requests.py @@ -40,7 +40,7 @@ def as_dict(self): @dataclass class StartFlashCallVerificationRequest(StartVerificationRequest): dial_timeout: int - method: str = VerificationMethod.FLASHCALL.value + method: str = VerificationMethod.FLASH_CALL.value def as_dict(self): payload = super().as_dict() diff --git a/sinch/domains/verification/models/responses.py b/sinch/domains/verification/models/responses.py index a21b1350..b0c5ad27 100644 --- a/sinch/domains/verification/models/responses.py +++ b/sinch/domains/verification/models/responses.py @@ -36,7 +36,7 @@ class StartSMSInitiateVerificationResponse(StartVerificationResponse): @dataclass class StartFlashCallInitiateVerificationResponse(StartVerificationResponse): - flashcall: FlashCallResponse + flash_call: FlashCallResponse @dataclass