Skip to content

Commit c8e2f69

Browse files
committed
add more voice methods
1 parent 016e34c commit c8e2f69

File tree

10 files changed

+279
-24
lines changed

10 files changed

+279
-24
lines changed

http_client/src/vonage_http_client/http_client.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ def patch(
161161
'PATCH', host, request_path, params, auth_type, sent_data_type
162162
)
163163

164+
def put(
165+
self,
166+
host: str,
167+
request_path: str = '',
168+
params: dict = None,
169+
auth_type: Literal['jwt', 'basic', 'body', 'signature'] = 'jwt',
170+
sent_data_type: Literal['json', 'form', 'query_params'] = 'json',
171+
) -> Union[dict, None]:
172+
return self.make_request(
173+
'PUT', host, request_path, params, auth_type, sent_data_type
174+
)
175+
164176
def delete(
165177
self,
166178
host: str,
@@ -176,7 +188,7 @@ def delete(
176188
@validate_call
177189
def make_request(
178190
self,
179-
request_type: Literal['GET', 'POST', 'PATCH', 'DELETE'],
191+
request_type: Literal['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],
180192
host: str,
181193
request_path: str = '',
182194
params: Optional[dict] = None,

testutils/testutils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def _filter_none_values(data: dict) -> dict:
1717
@validate_call
1818
def build_response(
1919
file_path: str,
20-
method: Literal['GET', 'POST', 'PATCH', 'DELETE'],
20+
method: Literal['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],
2121
url: str,
2222
mock_path: str = None,
2323
status_code: int = 200,

voice/src/vonage_voice/models/common.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Literal, Optional
22

33
from pydantic import BaseModel, Field
4-
from vonage_utils.types import Dtmf, PhoneNumber, SipUri
4+
from vonage_utils.types import PhoneNumber, SipUri
55
from vonage_voice.models.enums import Channel
66

77

@@ -10,10 +10,6 @@ class Phone(BaseModel):
1010
type: Channel = Channel.PHONE
1111

1212

13-
class ToPhone(Phone):
14-
dtmf_answer: Optional[Dtmf] = Field(None, serialization_alias='dtmfAnswer')
15-
16-
1713
class Sip(BaseModel):
1814
uri: SipUri
1915
type: Channel = Channel.SIP

voice/src/vonage_voice/models/enums.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ConnectEndpointType(str, Enum):
2626
VBC = 'vbc'
2727

2828

29-
class CallStatus(str, Enum):
29+
class CallState(str, Enum):
3030
STARTED = 'started'
3131
RINGING = 'ringing'
3232
ANSWERED = 'answered'

voice/src/vonage_voice/models/requests.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
from pydantic import BaseModel, Field, model_validator
44

5+
from vonage_utils.types import Dtmf
6+
57
from ..errors import VoiceError
6-
from .common import AdvancedMachineDetection, Phone, Sip, ToPhone, Vbc, Websocket
7-
from .enums import CallStatus
8+
from .common import AdvancedMachineDetection, Phone, Sip, Vbc, Websocket
9+
from .enums import CallState
810
from .ncco import Connect, Conversation, Input, Notify, Record, Stream, Talk
911

1012

13+
class ToPhone(Phone):
14+
dtmf_answer: Optional[Dtmf] = Field(None, serialization_alias='dtmfAnswer')
15+
16+
1117
class CreateCallRequest(BaseModel):
1218
ncco: List[Union[Record, Conversation, Connect, Input, Talk, Stream, Notify]] = None
1319
answer_url: List[str] = None
@@ -41,7 +47,7 @@ def validate_from_and_random_from_number(self):
4147

4248

4349
class ListCallsFilter(BaseModel):
44-
status: Optional[CallStatus] = None
50+
status: Optional[CallState] = None
4551
date_start: Optional[str] = None
4652
date_end: Optional[str] = None
4753
page_size: Optional[int] = Field(100, ge=1, le=100)

voice/src/vonage_voice/models/responses.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pydantic import BaseModel, Field, model_validator
44
from vonage_utils.models import Link
55

6-
from .common import Phone, Sip, ToPhone, Vbc, Websocket
6+
from .common import Phone, Sip, Vbc, Websocket
77

88

99
class CreateCallResponse(BaseModel):
@@ -13,7 +13,7 @@ class CreateCallResponse(BaseModel):
1313
conversation_uuid: str
1414

1515

16-
class CallStatus(BaseModel):
16+
class CallMessage(BaseModel):
1717
message: str
1818
uuid: str
1919

@@ -29,7 +29,7 @@ class Links(BaseModel):
2929
class CallInfo(BaseModel):
3030
uuid: str
3131
conversation_uuid: str
32-
to: ToPhone
32+
to: Phone
3333
from_: Union[Phone, Sip, Websocket, Vbc] = Field(..., validation_alias='from')
3434
status: str
3535
direction: str

voice/src/vonage_voice/voice.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
from pydantic import validate_call
44
from vonage_http_client.http_client import HttpClient
5+
from vonage_voice.models.ncco import NccoAction
56

67
from .models.requests import CreateCallRequest, ListCallsFilter
7-
from .models.responses import CallInfo, CallList, CreateCallResponse
8+
from .models.responses import CallInfo, CallList, CallMessage, CreateCallResponse
89

910

1011
class Voice:
@@ -72,3 +73,87 @@ def get_call(self, call_id: str) -> CallInfo:
7273
)
7374

7475
return CallInfo(**response)
76+
77+
@validate_call
78+
def transfer_call_ncco(self, uuid: str, ncco: List[NccoAction]) -> None:
79+
"""Transfers a call to a new NCCO.
80+
81+
Args:
82+
uuid (str): The UUID of the call to transfer.
83+
ncco (List[NccoAction]): The new NCCO to transfer the call to.
84+
"""
85+
serializable_ncco = [
86+
action.model_dump(by_alias=True, exclude_none=True) for action in ncco
87+
]
88+
self._http_client.put(
89+
self._http_client.api_host,
90+
f'/v1/calls/{uuid}',
91+
{
92+
'action': 'transfer',
93+
'destination': {'type': 'ncco', 'ncco': serializable_ncco},
94+
},
95+
)
96+
97+
@validate_call
98+
def transfer_call_answer_url(self, uuid: str, answer_url: str) -> None:
99+
"""Transfers a call to a new answer URL.
100+
101+
Args:
102+
uuid (str): The UUID of the call to transfer.
103+
answer_url (str): The new answer URL to transfer the call to.
104+
"""
105+
self._http_client.put(
106+
self._http_client.api_host,
107+
f'/v1/calls/{uuid}',
108+
{'action': 'transfer', 'destination': {'type': 'ncco', 'url': [answer_url]}},
109+
)
110+
111+
def hangup(self, uuid: str) -> None:
112+
"""Ends the call for the specified UUID, removing them from it.
113+
114+
Args:
115+
uuid (str): The UUID to end the call for.
116+
"""
117+
self._http_client.put(
118+
self._http_client.api_host, f'/v1/calls/{uuid}', {'action': 'hangup'}
119+
)
120+
121+
def mute(self, uuid: str) -> None:
122+
"""Mutes a call for the specified UUID.
123+
124+
Args:
125+
uuid (str): The UUID to mute the call for.
126+
"""
127+
self._http_client.put(
128+
self._http_client.api_host, f'/v1/calls/{uuid}', {'action': 'mute'}
129+
)
130+
131+
def unmute(self, uuid: str) -> None:
132+
"""Unmutes a call for the specified UUID.
133+
134+
Args:
135+
uuid (str): The UUID to unmute the call for.
136+
"""
137+
self._http_client.put(
138+
self._http_client.api_host, f'/v1/calls/{uuid}', {'action': 'unmute'}
139+
)
140+
141+
def earmuff(self, uuid: str) -> None:
142+
"""Earmuffs a call for the specified UUID (prevents them from hearing audio).
143+
144+
Args:
145+
uuid (str): The UUID you want to prevent from hearing audio.
146+
"""
147+
self._http_client.put(
148+
self._http_client.api_host, f'/v1/calls/{uuid}', {'action': 'earmuff'}
149+
)
150+
151+
def unearmuff(self, uuid: str) -> None:
152+
"""Allows the specified UUID to hear audio.
153+
154+
Args:
155+
uuid (str): The UUID you want to to allow to hear audio.
156+
"""
157+
self._http_client.put(
158+
self._http_client.api_host, f'/v1/calls/{uuid}', {'action': 'unearmuff'}
159+
)

voice/tests/data/get_call.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"_links": {
3+
"self": {
4+
"href": "/v1/calls/e154eb57-2962-41e7-baf4-90f63e25e439"
5+
}
6+
},
7+
"conversation_uuid": "CON-d4e1389a-b2c8-4621-97eb-c6f3a2b51c72",
8+
"direction": "outbound",
9+
"duration": "2",
10+
"end_time": "2024-04-19T01:34:20.000Z",
11+
"from": {
12+
"number": "9876543210",
13+
"type": "phone"
14+
},
15+
"network": "23420",
16+
"price": "0.00333333",
17+
"rate": "0.10000000",
18+
"start_time": "2024-04-19T01:34:18.000Z",
19+
"status": "completed",
20+
"to": {
21+
"number": "1234567890",
22+
"type": "phone"
23+
},
24+
"uuid": "e154eb57-2962-41e7-baf4-90f63e25e439"
25+
}

0 commit comments

Comments
 (0)