Skip to content

Commit

Permalink
start working on verify api
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed Mar 29, 2024
1 parent 2173273 commit b176787
Show file tree
Hide file tree
Showing 24 changed files with 452 additions and 10 deletions.
13 changes: 8 additions & 5 deletions http_client/src/vonage_http_client/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def post(
host: str,
request_path: str = '',
params: dict = None,
auth_type: Literal['jwt', 'basic', 'signature'] = 'jwt',
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
sent_data_type: Literal['json', 'data'] = 'json',
) -> Union[dict, None]:
return self.make_request(
Expand All @@ -118,7 +118,7 @@ def get(
host: str,
request_path: str = '',
params: dict = None,
auth_type: Literal['jwt', 'basic', 'signature'] = 'jwt',
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
sent_data_type: Literal['json', 'form', 'query_params'] = 'json',
) -> Union[dict, None]:
return self.make_request(
Expand All @@ -130,7 +130,7 @@ def patch(
host: str,
request_path: str = '',
params: dict = None,
auth_type: Literal['jwt', 'basic', 'signature'] = 'jwt',
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
sent_data_type: Literal['json', 'form', 'query_params'] = 'json',
) -> Union[dict, None]:
return self.make_request(
Expand All @@ -142,7 +142,7 @@ def delete(
host: str,
request_path: str = '',
params: dict = None,
auth_type: Literal['jwt', 'basic', 'signature'] = 'jwt',
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
sent_data_type: Literal['json', 'form', 'query_params'] = 'json',
) -> Union[dict, None]:
return self.make_request(
Expand All @@ -156,7 +156,7 @@ def make_request(
host: str,
request_path: str = '',
params: Optional[dict] = None,
auth_type: Literal['jwt', 'basic', 'signature'] = 'jwt',
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
sent_data_type: Literal['json', 'form', 'query_params'] = 'json',
):
url = f'https://{host}{request_path}'
Expand All @@ -167,6 +167,9 @@ def make_request(
self._headers['Authorization'] = self._auth.create_jwt_auth_string()
elif auth_type == 'basic':
self._headers['Authorization'] = self._auth.create_basic_auth_string()
elif auth_type == 'body':
params['api_key'] = self._auth.api_key
params['api_secret'] = self._auth.api_secret
elif auth_type == 'signature':
params['api_key'] = self._auth.api_key
params['sig'] = self._auth.sign_params(params)
Expand Down
1 change: 1 addition & 0 deletions pants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ filter = [
'users/src',
'utils/src',
'testutils',
'verify/src',
]

[black]
Expand Down
4 changes: 1 addition & 3 deletions users/src/vonage_users/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from typing import List, Optional

from pydantic import BaseModel, Field, model_validator
from typing_extensions import Annotated

PhoneNumber = Annotated[str, Field(pattern=r'^[1-9]\d{6,14}$')]
from vonage_utils.types.phone_number import PhoneNumber


class Link(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion users/src/vonage_users/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class ListUsersRequest(BaseModel):
"""Request object for listing users."""

page_size: Optional[int] = Field(2, ge=1, le=100)
page_size: Optional[int] = Field(100, ge=1, le=100)
order: Optional[Literal['asc', 'desc', 'ASC', 'DESC']] = None
cursor: Optional[str] = Field(
None,
Expand Down
16 changes: 16 additions & 0 deletions verify/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource(name='pyproject', source='pyproject.toml')
file(name='readme', source='README.md')

files(sources=['tests/data/*'])

python_distribution(
name='vonage-verify',
dependencies=[
':pyproject',
':readme',
'verify/src/vonage_verify',
],
provides=python_artifact(),
generate_setup=False,
repositories=['@pypi'],
)
2 changes: 2 additions & 0 deletions verify/CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 1.0.0
- Initial upload
27 changes: 27 additions & 0 deletions verify/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Vonage Verify Package

This package contains the code to use Vonage's Verify API in Python. There is a more current package to user Vonage's Verify v2 API which is recommended to use for most use cases. The v2 API lets you send messages via multiple channels, including Email, SMS, MMS, WhatsApp, Messenger and others. You can also make Silent Authentication requests with Verify v2 to give an end user a more seamless experience.

This package includes methods for sending 2-factor authentication (2FA) messages and returns...


asdf
asdf


## Usage

It is recommended to use this as part of the main `vonage` package. The examples below assume you've created an instance of the `vonage.Vonage` class called `vonage_client`.

### Make a Verify Request

<!-- Create an `SmsMessage` object, then pass into the `Sms.send` method.
```python
from vonage_sms import SmsMessage, SmsResponse
message = SmsMessage(to='1234567890', from_='Acme Inc.', text='Hello, World!')
response: SmsResponse = vonage_client.sms.send(message)
print(response.model_dump(exclude_unset=True))
``` -->
29 changes: 29 additions & 0 deletions verify/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[project]
name = 'vonage-verify'
version = '1.0.0'
description = 'Vonage verify package'
readme = "README.md"
authors = [{ name = "Vonage", email = "devrel@vonage.com" }]
requires-python = ">=3.8"
dependencies = [
"vonage-http-client>=1.1.1",
"vonage-utils>=1.0.0",
"pydantic>=2.6.1",
]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: Apache Software License",
]

[project.urls]
homepage = "https://github.com/Vonage/vonage-python-sdk"

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
1 change: 1 addition & 0 deletions verify/src/vonage_verify/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python_sources()
11 changes: 11 additions & 0 deletions verify/src/vonage_verify/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# from .errors import PartialFailureError, SmsError
from .requests import Psd2Request, VerifyRequest

# from .responses import MessageResponse, SmsResponse
from .verify import Verify

__all__ = [
'Verify',
'VerifyRequest',
'Psd2Request',
]
16 changes: 16 additions & 0 deletions verify/src/vonage_verify/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from vonage_utils.errors import VonageError


class VerifyError(VonageError):
"""Indicates an error with the Vonage Verify Package."""


# class PartialFailureError(SmsError):
# """Indicates that a request was partially successful."""

# def __init__(self, response: Response):
# self.message = (
# 'Sms.send_message method partially failed. Not all of the message(s) sent successfully.',
# )
# super().__init__(self.message)
# self.response = response
67 changes: 67 additions & 0 deletions verify/src/vonage_verify/language_codes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from enum import Enum


class LanguageCode(str, Enum):
ar_xa = 'ar-xa'
cs_cz = 'cs-cz'
cy_cy = 'cy-cy'
cy_gb = 'cy-gb'
da_dk = 'da-dk'
de_de = 'de-de'
el_gr = 'el-gr'
en_au = 'en-au'
en_gb = 'en-gb'
en_in = 'en-in'
en_us = 'en-us'
es_es = 'es-es'
es_mx = 'es-mx'
es_us = 'es-us'
fi_fi = 'fi-fi'
fil_ph = 'fil-ph'
fr_ca = 'fr-ca'
fr_fr = 'fr-fr'
hi_in = 'hi-in'
hu_hu = 'hu-hu'
id_id = 'id-id'
is_is = 'is-is'
it_it = 'it-it'
ja_jp = 'ja-jp'
ko_kr = 'ko-kr'
nb_no = 'nb-no'
nl_nl = 'nl-nl'
pl_pl = 'pl-pl'
pt_br = 'pt-br'
pt_pt = 'pt-pt'
ro_ro = 'ro-ro'
ru_ru = 'ru-ru'
sv_se = 'sv-se'
th_th = 'th-th'
tr_tr = 'tr-tr'
vi_vn = 'vi-vn'
yue_cn = 'yue-cn'
zh_cn = 'zh-cn'
zh_tw = 'zh-tw'


class Psd2LanguageCode(Enum):
en_gb = 'en-gb'
bg_bg = 'bg-bg'
cs_cz = 'cs-cz'
da_dk = 'da-dk'
de_de = 'de-de'
ee_et = 'ee-et'
el_gr = 'el-gr'
es_es = 'es-es'
fi_fi = 'fi-fi'
fr_fr = 'fr-fr'
ga_ie = 'ga-ie'
hu_hu = 'hu-hu'
it_it = 'it-it'
lv_lv = 'lv-lv'
lt_lt = 'lt-lt'
mt_mt = 'mt-mt'
nl_nl = 'nl-nl'
pl_pl = 'pl-pl'
sk_sk = 'sk-sk'
sl_si = 'sl-si'
sv_se = 'sv-se'
56 changes: 56 additions & 0 deletions verify/src/vonage_verify/requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from logging import getLogger
from typing import Literal, Optional

from pydantic import BaseModel, Field, model_validator
from vonage_utils.types.phone_number import PhoneNumber

from .language_codes import LanguageCode, Psd2LanguageCode

logger = getLogger('vonage_verify')


class BaseVerifyRequest(BaseModel):
"""Base request object containing the data and options for a verification request."""

number: PhoneNumber
country: Optional[str] = Field(None, max_length=2)
code_length: Optional[Literal[4, 6]] = 4
pin_expiry: Optional[int] = Field(None, ge=60, le=3600)
next_event_wait: Optional[int] = Field(None, ge=60, le=900)
workflow_id: Optional[Literal[1, 2, 3, 4, 5, 6, 7]] = None

@model_validator(mode='after')
def check_expiry_and_next_event_timing(self):
if self.pin_expiry is None or self.next_event_wait is None:
return self
if self.pin_expiry % self.next_event_wait != 0:
logger.debug(
f'The pin_expiry should be a multiple of next_event_wait.'
f'The current values are: pin_expiry={self.pin_expiry}, next_event_wait={self.next_event_wait}.'
f'The value of pin_expiry will be set to next_event_wait.'
)
self.pin_expiry = self.next_event_wait
return self


class VerifyRequest(BaseVerifyRequest):
"""Request object for a verification request.
You must set the `number` and `brand` fields.
"""

brand: str = Field(..., max_length=18)
sender_id: Optional[str] = Field('VERIFY', max_length=11)
lg: Optional[LanguageCode] = None
pin_code: Optional[str] = Field(None, min_length=4, max_length=10)


class Psd2Request(BaseVerifyRequest):
"""Request object for a PSD2 verification request.
You must set the `number`, `payee` and `amount` fields.
"""

payee: str = Field(..., max_length=18)
amount: float
lg: Optional[Psd2LanguageCode] = None
22 changes: 22 additions & 0 deletions verify/src/vonage_verify/responses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from pydantic import BaseModel


class VerifyResponse(BaseModel):
request_id: str
status: str


# class MessageResponse(BaseModel):
# to: str
# message_id: str = Field(..., validation_alias='message-id')
# status: str
# remaining_balance: str = Field(..., validation_alias='remaining-balance')
# message_price: str = Field(..., validation_alias='message-price')
# network: str
# client_ref: Optional[str] = Field(None, validation_alias='client-ref')
# account_ref: Optional[str] = Field(None, validation_alias='account-ref')


# class SmsResponse(BaseModel):
# message_count: str = Field(..., validation_alias='message-count')
# messages: List[MessageResponse]
Loading

0 comments on commit b176787

Please sign in to comment.