Skip to content

Commit

Permalink
get list_calls working
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed Apr 19, 2024
1 parent 5819ed3 commit 016e34c
Show file tree
Hide file tree
Showing 17 changed files with 270 additions and 78 deletions.
4 changes: 2 additions & 2 deletions users/src/vonage_users/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from .common import User
from .requests import ListUsersRequest
from .requests import ListUsersFilter
from .responses import UserSummary
from .users import Users

__all__ = [
'Users',
'User',
'ListUsersRequest',
'ListUsersFilter',
'UserSummary',
]
5 changes: 1 addition & 4 deletions users/src/vonage_users/common.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from typing import List, Optional

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


class Link(BaseModel):
href: str


class ResourceLink(BaseModel):
self: Link

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 @@ -3,7 +3,7 @@
from pydantic import BaseModel, Field


class ListUsersRequest(BaseModel):
class ListUsersFilter(BaseModel):
"""Request object for listing users."""

page_size: Optional[int] = Field(100, ge=1, le=100)
Expand Down
1 change: 0 additions & 1 deletion users/src/vonage_users/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class UserSummary(BaseModel):
link: Optional[str] = None

@model_validator(mode='after')
@classmethod
def get_link(self):
if self.links is not None:
self.link = self.links.self.href
Expand Down
18 changes: 11 additions & 7 deletions users/src/vonage_users/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from vonage_http_client.http_client import HttpClient

from .common import User
from .requests import ListUsersRequest
from .requests import ListUsersFilter
from .responses import ListUsersResponse, UserSummary


Expand All @@ -22,23 +22,27 @@ def __init__(self, http_client: HttpClient) -> None:

@validate_call
def list_users(
self, params: ListUsersRequest = ListUsersRequest()
) -> Tuple[List[UserSummary], str]:
self, filter: ListUsersFilter = ListUsersFilter()
) -> Tuple[List[UserSummary], Optional[str]]:
"""List all users.
Retrieves a list of all users. Gets 100 users by default.
If you want to see more information about a specific user, you can use the `Users.get_user` method.
If you want to see more information about a specific user, you can use the
`Users.get_user` method.
Args:
params (ListUsersRequest, optional): An instance of the ListUsersRequest class that allows you to specify additional parameters for the user listing.
params (ListUsersFilter, optional): An instance of the `ListUsersFilter`
class that allows you to specify additional parameters for the user listing.
Returns:
Tuple[List[UserSummary], str]: A tuple containing a list of UserSummary objects representing the users and a string representing the next cursor for pagination.
Tuple[List[UserSummary], Optional[str]]: A tuple containing a list of `UserSummary`
objects representing the users and a string representing the next cursor for
pagination, if there are more results than the specified `page_size`.
"""
response = self._http_client.get(
self._http_client.api_host,
'/v1/users',
params.model_dump(exclude_none=True),
filter.model_dump(exclude_none=True),
self._auth_type,
)

Expand Down
6 changes: 3 additions & 3 deletions users/tests/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from vonage_http_client.http_client import HttpClient
from vonage_users import Users
from vonage_users.common import *
from vonage_users.requests import ListUsersRequest
from vonage_users.requests import ListUsersFilter

from testutils import build_response, get_mock_jwt_auth

Expand All @@ -21,7 +21,7 @@ def test_create_list_users_request():
'cursor': '7EjDNQrAcipmOnc0HCzpQRkhBULzY44ljGUX4lXKyUIVfiZay5pv9wg=',
'name': 'my_user',
}
list_users_request = ListUsersRequest(**params)
list_users_request = ListUsersFilter(**params)

assert list_users_request.model_dump() == params

Expand Down Expand Up @@ -52,7 +52,7 @@ def test_list_users_options():
path, 'GET', 'https://api.nexmo.com/v1/users', 'list_users_options.json'
)

params = ListUsersRequest(
params = ListUsersFilter(
page_size=2,
order='asc',
cursor='zAmuSchIBsUF1QaaohGdaf32NgHOkP130XeQrZkoOPEuGPnIxFb0Xj3iqCfOzxSSq9Es/S/2h+HYumKt3HS0V9ewjis+j74oMcsvYBLN1PwFEupI6ENEWHYC7lk=',
Expand Down
30 changes: 30 additions & 0 deletions voice/src/vonage_voice/models/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
from typing import Literal, Optional

from pydantic import BaseModel, Field
from vonage_utils.types import Dtmf, PhoneNumber, SipUri
from vonage_voice.models.enums import Channel


class Phone(BaseModel):
number: PhoneNumber
type: Channel = Channel.PHONE


class ToPhone(Phone):
dtmf_answer: Optional[Dtmf] = Field(None, serialization_alias='dtmfAnswer')


class Sip(BaseModel):
uri: SipUri
type: Channel = Channel.SIP


class Websocket(BaseModel):
uri: str = Field(..., min_length=1, max_length=50)
content_type: Literal['audio/l16;rate=8000', 'audio/l16;rate=16000'] = Field(
'audio/l16;rate=16000', serialization_alias='content-type'
)
type: Channel = Channel.WEBSOCKET
headers: Optional[dict] = None


class Vbc(BaseModel):
extension: str
type: Channel = Channel.VBC


class AdvancedMachineDetection(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion voice/src/vonage_voice/models/ncco.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Annotated, List, Optional, Union
from typing import List, Optional, Union

from pydantic import BaseModel, Field, model_validator
from typing_extensions import Literal
Expand Down
37 changes: 4 additions & 33 deletions voice/src/vonage_voice/models/requests.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,11 @@
from typing import List, Literal, Optional, Union

from pydantic import BaseModel, Field, model_validator
from vonage_utils.types import Dtmf, PhoneNumber, SipUri

from ..errors import VoiceError
from .common import AdvancedMachineDetection
from .enums import CallStatus, Channel
from .ncco import Record, Conversation, Connect, Input, Talk, Stream, Notify


class Phone(BaseModel):
number: PhoneNumber
type: Channel = Channel.PHONE


class ToPhone(Phone):
dtmf_answer: Optional[Dtmf] = Field(None, serialization_alias='dtmfAnswer')


class Sip(BaseModel):
uri: SipUri
type: Channel = Channel.SIP


class Websocket(BaseModel):
uri: str = Field(..., min_length=1, max_length=50)
content_type: Literal['audio/l16;rate=8000', 'audio/l16;rate=16000'] = Field(
'audio/l16;rate=16000', serialization_alias='content-type'
)
type: Channel = Channel.WEBSOCKET
headers: Optional[dict] = None


class Vbc(BaseModel):
extension: str
type: Channel = Channel.VBC
from .common import AdvancedMachineDetection, Phone, Sip, ToPhone, Vbc, Websocket
from .enums import CallStatus
from .ncco import Connect, Conversation, Input, Notify, Record, Stream, Talk


class CreateCallRequest(BaseModel):
Expand Down Expand Up @@ -73,7 +44,7 @@ class ListCallsFilter(BaseModel):
status: Optional[CallStatus] = None
date_start: Optional[str] = None
date_end: Optional[str] = None
page_size: Optional[int] = Field(None, ge=1, le=100)
page_size: Optional[int] = Field(100, ge=1, le=100)
record_index: Optional[int] = None
order: Optional[Literal['asc', 'desc']] = None
conversation_uuid: Optional[str] = None
23 changes: 9 additions & 14 deletions voice/src/vonage_voice/models/responses.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from typing import List, Optional
from typing import List, Optional, Union

from pydantic import BaseModel, Field, model_validator
from vonage_utils.models import Link

from .common import Phone, Sip, ToPhone, Vbc, Websocket


class CreateCallResponse(BaseModel):
Expand All @@ -14,27 +18,19 @@ class CallStatus(BaseModel):
uuid: str


class Link(BaseModel):
href: str


class Links(BaseModel):
self: Link
first: Optional[Link] = None
next: Optional[Link] = None
last: Optional[Link] = None
prev: Optional[Link] = None


class Endpoint(BaseModel):
type: str
number: str
next: Optional[Link] = None


class CallInfo(BaseModel):
uuid: str
conversation_uuid: str
to: Endpoint
from_: Endpoint = Field(..., alias='from')
to: ToPhone
from_: Union[Phone, Sip, Websocket, Vbc] = Field(..., validation_alias='from')
status: str
direction: str
rate: Optional[str] = None
Expand All @@ -47,7 +43,6 @@ class CallInfo(BaseModel):
link: Optional[str] = None

@model_validator(mode='after')
@classmethod
def get_link(self):
self.link = self.links.self.href
return self
Expand Down
20 changes: 15 additions & 5 deletions voice/src/vonage_voice/voice.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List, Optional, Tuple

from pydantic import validate_call
from vonage_http_client.http_client import HttpClient

Expand Down Expand Up @@ -30,22 +32,30 @@ def create_call(self, params: CreateCallRequest) -> CreateCallResponse:
return CreateCallResponse(**response)

@validate_call
def list_calls(self, params: ListCallsFilter = None) -> CallList:
def list_calls(
self, filter: ListCallsFilter = ListCallsFilter()
) -> Tuple[List[CallInfo], Optional[int]]:
"""Lists calls made with the Vonage Voice API.
Args:
params (ListCallsFilter): The parameters to filter the list of calls.
filter (ListCallsFilter): The parameters to filter the list of calls.
Returns:
CallList: The response object containing information about the calls.
Tuple[List[CallInfo], Optional[int]] A tuple containing a list of `CallInfo` objects and the
value of the `record_index` attribute to get the next page of results, if there
are more results than the specified `page_size`.
"""
response = self._http_client.get(
self._http_client.api_host,
'/v1/calls',
params.model_dump(by_alias=True, exclude_none=True) if params else None,
filter.model_dump(by_alias=True, exclude_none=True),
)

return CallList(**response)
list_response = CallList(**response)
if list_response.links.next is None:
return list_response.embedded.calls, None
next_page_index = list_response.record_index + 1
return list_response.embedded.calls, next_page_index

@validate_call
def get_call(self, call_id: str) -> CallInfo:
Expand Down
Loading

0 comments on commit 016e34c

Please sign in to comment.