Skip to content

Commit

Permalink
creating more application models and refactoring common components
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed May 1, 2024
1 parent 47ce0f8 commit 10113f0
Show file tree
Hide file tree
Showing 13 changed files with 307 additions and 289 deletions.
92 changes: 48 additions & 44 deletions application/src/vonage_application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from pydantic import validate_call
from vonage_http_client.http_client import HttpClient

from .common import User
from .requests import ApplicationOptions, ListApplicationsFilter
from .responses import ApplicationInfo
from .responses import ApplicationData


class Application:
Expand All @@ -27,7 +26,7 @@ def http_client(self) -> HttpClient:
@validate_call
def list_applications(
self, filter: ListApplicationsFilter = ListApplicationsFilter()
) -> Tuple[List[ApplicationInfo], Optional[str]]:
) -> Tuple[List[ApplicationData], Optional[str]]:
""""""
response = self._http_client.get(
self._http_client.api_host,
Expand All @@ -49,61 +48,66 @@ def list_applications(
def create_application(
self, params: Optional[ApplicationOptions] = None
) -> ApplicationData:
""".
.
"""
response = self._http_client.post(
self._http_client.api_host,
'/v2/applications',
params.model_dump(exclude_none=True) if params is not None else None,
self._auth_type,
)
return User(**response)

@validate_call
def get_user(self, id: str) -> User:
"""Get a user by ID.
"""Create a new application.
Args:
id (str): The ID of the user to retrieve.
params (Optional[ApplicationOptions]): The application options.
Returns:
User: The user object.
ApplicationData: The created application object.
"""
response = self._http_client.get(
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
)
return User(**response)

@validate_call
def update_user(self, id: str, params: User) -> User:
"""Update a user.
Args:
id (str): The ID of the user to update.
params (User): The updated user object.
Returns:
User: The updated user object.
"""
response = self._http_client.patch(
response = self._http_client.post(
self._http_client.api_host,
f'/v1/users/{id}',
params.model_dump(exclude_none=True),
'/v2/applications',
params.model_dump(exclude_none=True) if params is not None else None,
self._auth_type,
)
return User(**response)
return ApplicationData(**response)

@validate_call
def delete_user(self, id: str) -> None:
"""Delete a user.
def get_application(self, id: str) -> ApplicationData:
"""Get application info by ID.
Args:
id (str): The ID of the user to delete.
id (str): The ID of the application to retrieve.
Returns:
None
ApplicationData: The created application object.
"""
self._http_client.delete(
response = self._http_client.get(
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
)
return ApplicationData(**response)

# @validate_call
# def update_application(self, id: str, params: User) -> User:
# """Update a user.

# Args:
# id (str): The ID of the user to update.
# params (User): The updated user object.

# Returns:
# User: The updated user object.
# """
# response = self._http_client.patch(
# self._http_client.api_host,
# f'/v1/users/{id}',
# params.model_dump(exclude_none=True),
# self._auth_type,
# )
# return User(**response)

# @validate_call
# def delete_application(self, id: str) -> None:
# """Delete an application.

# Args:
# id (str): The ID of the application to delete.

# Returns:
# None
# """
# self._http_client.delete(
# self._http_client.api_host, f'/v2/applications/{id}', None, self._auth_type
# )
107 changes: 51 additions & 56 deletions application/src/vonage_application/common.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,79 @@
from typing import List, Optional
from typing import Literal, Optional, Union

from pydantic import BaseModel, Field, model_validator
from vonage_utils.models import Link
from vonage_utils.types import PhoneNumber
from pydantic import BaseModel, Field, field_validator

from .enums import Region
from .errors import ApplicationError

class ResourceLink(BaseModel):
self: Link

class Url(BaseModel):
address: str
http_method: Optional[Literal['GET', 'POST']] = None

class PstnChannel(BaseModel):
number: int

class VoiceUrl(Url):
connection_timeout: Optional[int] = Field(None, ge=300, le=1000)
socket_timeout: Optional[int] = Field(None, ge=1000, le=5000)

class SipChannel(BaseModel):
uri: str = Field(..., pattern=r'^(sip|sips):\+?([\w|:.\-@;,=%&]+)')
username: str = None
password: str = None

class VoiceWebhooks(BaseModel):
answer_url: Optional[Url] = None
fallback_answer_url: Optional[Url] = None
event_url: Optional[Url] = None

class VbcChannel(BaseModel):
extension: str

class Voice(BaseModel):
webhooks: Optional[VoiceWebhooks] = None
signed_callbacks: Optional[bool] = None
conversations_ttl: Optional[int] = Field(None, ge=1, le=9000)
leg_persistence_time: Optional[int] = Field(None, ge=1, le=31)
region: Optional[Region] = None

class WebsocketChannel(BaseModel):
uri: str = Field(pattern=r'^(ws|wss):\/\/[a-zA-Z0-9~#%@&-_?\/.,:;)(\]\[]*$')
content_type: Optional[str] = Field(
None, alias='content-type', pattern='^audio/l16;rate=(8000|16000)$'
)
headers: Optional[dict] = None

class RtcWebhooks(BaseModel):
event_url: Optional[Url] = None

class SmsChannel(BaseModel):
number: PhoneNumber

class Rtc(BaseModel):
webhooks: Optional[RtcWebhooks] = None
signed_callbacks: Optional[bool] = None

class MmsChannel(BaseModel):
number: PhoneNumber

class MessagesWebhooks(BaseModel):
inbound_url: Optional[Url] = None
status_url: Optional[Url] = None

class WhatsappChannel(BaseModel):
number: PhoneNumber

class Messages(BaseModel):
version: Optional[str] = None
webhooks: Optional[MessagesWebhooks] = None

class ViberChannel(BaseModel):
number: PhoneNumber

class Vbc(BaseModel):
pass

class MessengerChannel(BaseModel):
id: str

class VerifyWebhooks(BaseModel):
status_url: Optional[Url] = None

class Channels(BaseModel):
sms: Optional[List[SmsChannel]] = None
mms: Optional[List[MmsChannel]] = None
whatsapp: Optional[List[WhatsappChannel]] = None
viber: Optional[List[ViberChannel]] = None
messenger: Optional[List[MessengerChannel]] = None
pstn: Optional[List[PstnChannel]] = None
sip: Optional[List[SipChannel]] = None
websocket: Optional[List[WebsocketChannel]] = None
vbc: Optional[List[VbcChannel]] = None
@field_validator('status_url')
@classmethod
def check_http_method(cls, v: Url):
if v.http_method is not None and v.http_method != 'POST':
raise ApplicationError('HTTP method must be POST')
return v


class Properties(BaseModel):
custom_data: Optional[dict] = None
class Verify(BaseModel):
webhooks: Optional[VerifyWebhooks] = None
version: Optional[str] = None


class User(BaseModel):
name: Optional[str] = None
display_name: Optional[str] = None
image_url: Optional[str] = None
channels: Optional[Channels] = None
properties: Optional[Properties] = None
links: Optional[ResourceLink] = Field(None, validation_alias='_links', exclude=True)
link: Optional[str] = None
id: Optional[str] = None
class Privacy(BaseModel):
improve_ai: Optional[bool] = None

@model_validator(mode='after')
def get_link(self):
if self.links is not None:
self.link = self.links.self.href
return self

class ApplicationBase(BaseModel):
name: str
capabilities: Optional[Union[Voice, Rtc, Messages, Vbc, Verify]] = None
privacy: Optional[Privacy] = None
10 changes: 10 additions & 0 deletions application/src/vonage_application/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from enum import Enum


class Region(str, Enum):
NA_EAST = 'na-east'
NA_WEST = 'na-west'
EU_EAST = 'eu-east'
EU_WEST = 'eu-west'
APAC_SNG = 'apac-sng'
APAC_AUSTRALIA = 'apac-australia'
5 changes: 5 additions & 0 deletions application/src/vonage_application/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from vonage_utils.errors import VonageError


class ApplicationError(VonageError):
"""Indicates an error with the Application package."""
54 changes: 5 additions & 49 deletions application/src/vonage_application/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from pydantic import BaseModel

from .common import ApplicationBase


class ListApplicationsFilter(BaseModel):
"""Request object for listing users."""
Expand All @@ -10,55 +12,9 @@ class ListApplicationsFilter(BaseModel):
page: int = None


class Webhook(BaseModel):
address: str
http_method: str
connection_timeout: Optional[int] = None
socket_timeout: Optional[int] = None


class Voice(BaseModel):
webhooks: Webhook
fallback_answer_url: Optional[Webhook] = None
event_url: Optional[Webhook] = None
signed_callbacks: bool
conversations_ttl: int
leg_persistence_time: int
region: str


class Messages(BaseModel):
version: str
webhooks: Webhook


class RTC(BaseModel):
webhooks: Webhook
signed_callbacks: bool


class Meetings(BaseModel):
webhooks: Webhook


class Verify(BaseModel):
webhooks: Webhook


class Privacy(BaseModel):
improve_ai: bool


class ApplicationBase(BaseModel):
name: str
capabilities: Optional[dict] = None
voice: Optional[Voice] = None
messages: Optional[Messages] = None
rtc: Optional[RTC] = None
meetings: Optional[Meetings] = None
verify: Optional[Verify] = None
privacy: Optional[Privacy] = None
class KeysRequest(BaseModel):
public_key: str


class ApplicationOptions(ApplicationBase):
keys: Optional[dict] = None
keys: Optional[KeysRequest] = None
Loading

0 comments on commit 10113f0

Please sign in to comment.