Skip to content

Commit 10113f0

Browse files
committed
creating more application models and refactoring common components
1 parent 47ce0f8 commit 10113f0

File tree

13 files changed

+307
-289
lines changed

13 files changed

+307
-289
lines changed

application/src/vonage_application/application.py

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
from pydantic import validate_call
44
from vonage_http_client.http_client import HttpClient
55

6-
from .common import User
76
from .requests import ApplicationOptions, ListApplicationsFilter
8-
from .responses import ApplicationInfo
7+
from .responses import ApplicationData
98

109

1110
class Application:
@@ -27,7 +26,7 @@ def http_client(self) -> HttpClient:
2726
@validate_call
2827
def list_applications(
2928
self, filter: ListApplicationsFilter = ListApplicationsFilter()
30-
) -> Tuple[List[ApplicationInfo], Optional[str]]:
29+
) -> Tuple[List[ApplicationData], Optional[str]]:
3130
""""""
3231
response = self._http_client.get(
3332
self._http_client.api_host,
@@ -49,61 +48,66 @@ def list_applications(
4948
def create_application(
5049
self, params: Optional[ApplicationOptions] = None
5150
) -> ApplicationData:
52-
""".
53-
.
54-
"""
55-
response = self._http_client.post(
56-
self._http_client.api_host,
57-
'/v2/applications',
58-
params.model_dump(exclude_none=True) if params is not None else None,
59-
self._auth_type,
60-
)
61-
return User(**response)
62-
63-
@validate_call
64-
def get_user(self, id: str) -> User:
65-
"""Get a user by ID.
51+
"""Create a new application.
6652
6753
Args:
68-
id (str): The ID of the user to retrieve.
54+
params (Optional[ApplicationOptions]): The application options.
6955
7056
Returns:
71-
User: The user object.
57+
ApplicationData: The created application object.
7258
"""
73-
response = self._http_client.get(
74-
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
75-
)
76-
return User(**response)
77-
78-
@validate_call
79-
def update_user(self, id: str, params: User) -> User:
80-
"""Update a user.
81-
82-
Args:
83-
id (str): The ID of the user to update.
84-
params (User): The updated user object.
85-
86-
Returns:
87-
User: The updated user object.
88-
"""
89-
response = self._http_client.patch(
59+
response = self._http_client.post(
9060
self._http_client.api_host,
91-
f'/v1/users/{id}',
92-
params.model_dump(exclude_none=True),
61+
'/v2/applications',
62+
params.model_dump(exclude_none=True) if params is not None else None,
9363
self._auth_type,
9464
)
95-
return User(**response)
65+
return ApplicationData(**response)
9666

9767
@validate_call
98-
def delete_user(self, id: str) -> None:
99-
"""Delete a user.
68+
def get_application(self, id: str) -> ApplicationData:
69+
"""Get application info by ID.
10070
10171
Args:
102-
id (str): The ID of the user to delete.
72+
id (str): The ID of the application to retrieve.
10373
10474
Returns:
105-
None
75+
ApplicationData: The created application object.
10676
"""
107-
self._http_client.delete(
77+
response = self._http_client.get(
10878
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
10979
)
80+
return ApplicationData(**response)
81+
82+
# @validate_call
83+
# def update_application(self, id: str, params: User) -> User:
84+
# """Update a user.
85+
86+
# Args:
87+
# id (str): The ID of the user to update.
88+
# params (User): The updated user object.
89+
90+
# Returns:
91+
# User: The updated user object.
92+
# """
93+
# response = self._http_client.patch(
94+
# self._http_client.api_host,
95+
# f'/v1/users/{id}',
96+
# params.model_dump(exclude_none=True),
97+
# self._auth_type,
98+
# )
99+
# return User(**response)
100+
101+
# @validate_call
102+
# def delete_application(self, id: str) -> None:
103+
# """Delete an application.
104+
105+
# Args:
106+
# id (str): The ID of the application to delete.
107+
108+
# Returns:
109+
# None
110+
# """
111+
# self._http_client.delete(
112+
# self._http_client.api_host, f'/v2/applications/{id}', None, self._auth_type
113+
# )
Lines changed: 51 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,79 @@
1-
from typing import List, Optional
1+
from typing import Literal, Optional, Union
22

3-
from pydantic import BaseModel, Field, model_validator
4-
from vonage_utils.models import Link
5-
from vonage_utils.types import PhoneNumber
3+
from pydantic import BaseModel, Field, field_validator
64

5+
from .enums import Region
6+
from .errors import ApplicationError
77

8-
class ResourceLink(BaseModel):
9-
self: Link
108

9+
class Url(BaseModel):
10+
address: str
11+
http_method: Optional[Literal['GET', 'POST']] = None
1112

12-
class PstnChannel(BaseModel):
13-
number: int
1413

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

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

19+
class VoiceWebhooks(BaseModel):
20+
answer_url: Optional[Url] = None
21+
fallback_answer_url: Optional[Url] = None
22+
event_url: Optional[Url] = None
2123

22-
class VbcChannel(BaseModel):
23-
extension: str
2424

25+
class Voice(BaseModel):
26+
webhooks: Optional[VoiceWebhooks] = None
27+
signed_callbacks: Optional[bool] = None
28+
conversations_ttl: Optional[int] = Field(None, ge=1, le=9000)
29+
leg_persistence_time: Optional[int] = Field(None, ge=1, le=31)
30+
region: Optional[Region] = None
2531

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

33+
class RtcWebhooks(BaseModel):
34+
event_url: Optional[Url] = None
3335

34-
class SmsChannel(BaseModel):
35-
number: PhoneNumber
3636

37+
class Rtc(BaseModel):
38+
webhooks: Optional[RtcWebhooks] = None
39+
signed_callbacks: Optional[bool] = None
3740

38-
class MmsChannel(BaseModel):
39-
number: PhoneNumber
4041

42+
class MessagesWebhooks(BaseModel):
43+
inbound_url: Optional[Url] = None
44+
status_url: Optional[Url] = None
4145

42-
class WhatsappChannel(BaseModel):
43-
number: PhoneNumber
4446

47+
class Messages(BaseModel):
48+
version: Optional[str] = None
49+
webhooks: Optional[MessagesWebhooks] = None
4550

46-
class ViberChannel(BaseModel):
47-
number: PhoneNumber
4851

52+
class Vbc(BaseModel):
53+
pass
4954

50-
class MessengerChannel(BaseModel):
51-
id: str
5255

56+
class VerifyWebhooks(BaseModel):
57+
status_url: Optional[Url] = None
5358

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

6566

66-
class Properties(BaseModel):
67-
custom_data: Optional[dict] = None
67+
class Verify(BaseModel):
68+
webhooks: Optional[VerifyWebhooks] = None
69+
version: Optional[str] = None
6870

6971

70-
class User(BaseModel):
71-
name: Optional[str] = None
72-
display_name: Optional[str] = None
73-
image_url: Optional[str] = None
74-
channels: Optional[Channels] = None
75-
properties: Optional[Properties] = None
76-
links: Optional[ResourceLink] = Field(None, validation_alias='_links', exclude=True)
77-
link: Optional[str] = None
78-
id: Optional[str] = None
72+
class Privacy(BaseModel):
73+
improve_ai: Optional[bool] = None
7974

80-
@model_validator(mode='after')
81-
def get_link(self):
82-
if self.links is not None:
83-
self.link = self.links.self.href
84-
return self
75+
76+
class ApplicationBase(BaseModel):
77+
name: str
78+
capabilities: Optional[Union[Voice, Rtc, Messages, Vbc, Verify]] = None
79+
privacy: Optional[Privacy] = None
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from enum import Enum
2+
3+
4+
class Region(str, Enum):
5+
NA_EAST = 'na-east'
6+
NA_WEST = 'na-west'
7+
EU_EAST = 'eu-east'
8+
EU_WEST = 'eu-west'
9+
APAC_SNG = 'apac-sng'
10+
APAC_AUSTRALIA = 'apac-australia'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from vonage_utils.errors import VonageError
2+
3+
4+
class ApplicationError(VonageError):
5+
"""Indicates an error with the Application package."""

application/src/vonage_application/requests.py

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from pydantic import BaseModel
44

5+
from .common import ApplicationBase
6+
57

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

1214

13-
class Webhook(BaseModel):
14-
address: str
15-
http_method: str
16-
connection_timeout: Optional[int] = None
17-
socket_timeout: Optional[int] = None
18-
19-
20-
class Voice(BaseModel):
21-
webhooks: Webhook
22-
fallback_answer_url: Optional[Webhook] = None
23-
event_url: Optional[Webhook] = None
24-
signed_callbacks: bool
25-
conversations_ttl: int
26-
leg_persistence_time: int
27-
region: str
28-
29-
30-
class Messages(BaseModel):
31-
version: str
32-
webhooks: Webhook
33-
34-
35-
class RTC(BaseModel):
36-
webhooks: Webhook
37-
signed_callbacks: bool
38-
39-
40-
class Meetings(BaseModel):
41-
webhooks: Webhook
42-
43-
44-
class Verify(BaseModel):
45-
webhooks: Webhook
46-
47-
48-
class Privacy(BaseModel):
49-
improve_ai: bool
50-
51-
52-
class ApplicationBase(BaseModel):
53-
name: str
54-
capabilities: Optional[dict] = None
55-
voice: Optional[Voice] = None
56-
messages: Optional[Messages] = None
57-
rtc: Optional[RTC] = None
58-
meetings: Optional[Meetings] = None
59-
verify: Optional[Verify] = None
60-
privacy: Optional[Privacy] = None
15+
class KeysRequest(BaseModel):
16+
public_key: str
6117

6218

6319
class ApplicationOptions(ApplicationBase):
64-
keys: Optional[dict] = None
20+
keys: Optional[KeysRequest] = None

0 commit comments

Comments
 (0)