diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a89018..0738e37f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [4.23.1](https://github.com/plivo/plivo-python/tree/v4.23.1) (2022-04-11) +**Feature - List all recordings and The MultiPartyCall element** +- `from_number` and `to_number` added to filtering param [List all recordings](https://www.plivo.com/docs/voice/api/recording#list-all-recordings) +- `record_min_member_count` param added to [Add a participant to a multiparty call using API](https://www.plivo.com/docs/voice/api/multiparty-call/participants#add-a-participant) + ## [4.23.0](https://github.com/plivo/plivo-python/tree/v4.23.0) (2022-03-18) **Feature - DialElement** - `confirmTimeout` parameter added to [The Dial element](https://www.plivo.com/docs/voice/xml/dial/) diff --git a/makeCall.py b/makeCall.py new file mode 100644 index 00000000..bf34ee64 --- /dev/null +++ b/makeCall.py @@ -0,0 +1,9 @@ +import plivo + +client = plivo.RestClient('MAYJI2ZJDIMTVIODIWYJ','OTI2NWFmNGI4MmZjZjZkOTQ0YjNkYTQwMzY2ZDJl') +response = client.calls.create( + from_='+919999323467', + to_='sip:ajaydjv902035012689385@phone-qa.voice.plivodev.com', + answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml', + answer_method='GET', ) +print(response) \ No newline at end of file diff --git a/plivo/resources/multipartycall.py b/plivo/resources/multipartycall.py index 4bf93634..fe46d3b8 100644 --- a/plivo/resources/multipartycall.py +++ b/plivo/resources/multipartycall.py @@ -29,6 +29,7 @@ def add_participant(self, delay_dial=0, max_duration=14400, max_participants=10, + record_min_member_count=1, wait_music_url=None, wait_music_method='GET', agent_hold_music_url=None, @@ -250,6 +251,10 @@ def get(self, uuid=None, friendly_name=None): of_type_exact(int), check(lambda max_participants: 2 <= max_participants <= 10, '2 < max_participants <= 10') )], + record_min_member_count=[optional( + of_type_exact(int), + check(lambda record_min_member_count: 1 <= record_min_member_count <= 2, '1 < record_min_member_count <= 2') + )], wait_music_url=[optional(of_type_exact(str), is_url())], wait_music_method=[optional(of_type_exact(str), is_in(('GET', 'POST'), case_sensitive=False))], agent_hold_music_url=[optional(of_type_exact(str), is_url())], @@ -313,6 +318,7 @@ def add_participant(self, delay_dial=0, max_duration=14400, max_participants=10, + record_min_member_count=1, wait_music_url=None, wait_music_method='GET', agent_hold_music_url=None, diff --git a/plivo/resources/recordings.py b/plivo/resources/recordings.py index 48e43edf..622314b9 100644 --- a/plivo/resources/recordings.py +++ b/plivo/resources/recordings.py @@ -22,6 +22,8 @@ class Recordings(PlivoResourceInterface): _resource_type = Recording @validate_args( + from_number=[optional(of_type(six.text_type))], + to_number=[optional(of_type(six.text_type))], subaccount=[optional(is_subaccount())], call_uuid=[optional(of_type(six.text_type))], limit=[ @@ -35,7 +37,8 @@ class Recordings(PlivoResourceInterface): all_of( of_type(*six.integer_types), check(lambda offset: 0 <= offset, '0 <= offset'))) - ]) + ], + ) def list(self, subaccount=None, call_uuid=None, @@ -45,7 +48,9 @@ def list(self, add_time__lte=None, add_time=None, limit=20, - offset=0): + offset=0, + from_number=None, + to_number=None): if subaccount: if isinstance(subaccount, Subaccount): diff --git a/plivo/rest/client.py b/plivo/rest/client.py index bbdfa5da..ac562198 100644 --- a/plivo/rest/client.py +++ b/plivo/rest/client.py @@ -26,14 +26,14 @@ AuthenticationCredentials = namedtuple('AuthenticationCredentials', 'auth_id auth_token') -PLIVO_API = 'https://api.plivo.com' +PLIVO_API = 'https://api-qa.voice.plivodev.com' PLIVO_API_BASE_URI = '/'.join([PLIVO_API, 'v1/Account']) # Will change these urls before putting this change in production -API_VOICE = 'https://api.plivo.com' +API_VOICE = 'https://api-qa.voice.plivodev.com' API_VOICE_BASE_URI = '/'.join([API_VOICE, 'v1/Account']) -API_VOICE_FALLBACK_1 = 'https://api.plivo.com' -API_VOICE_FALLBACK_2 = 'https://api.plivo.com' +API_VOICE_FALLBACK_1 = 'https://api-qa.voice.plivodev.com' +API_VOICE_FALLBACK_2 = 'https://api-qa.voice.plivodev.com' API_VOICE_BASE_URI_FALLBACK_1 = '/'.join([API_VOICE_FALLBACK_1, 'v1/Account']) API_VOICE_BASE_URI_FALLBACK_2 = '/'.join([API_VOICE_FALLBACK_2, 'v1/Account']) diff --git a/plivo/version.py b/plivo/version.py index 63381b81..042040fd 100644 --- a/plivo/version.py +++ b/plivo/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -__version__ = '4.23.0' +__version__ = '4.23.1' diff --git a/plivo/xml/MultiPartyCallElement.py b/plivo/xml/MultiPartyCallElement.py index c445ea25..395e311b 100644 --- a/plivo/xml/MultiPartyCallElement.py +++ b/plivo/xml/MultiPartyCallElement.py @@ -45,6 +45,26 @@ def set_max_participants(self, max_participants): self.max_participants = max_participants return self + @property + def record_min_member_count(self): + return self.__record_min_member_count + + @record_min_member_count.setter + @validate_args( + record_min_member_count=[ + optional( + of_type_exact(int), + check(lambda record_min_member_count: 1 <= record_min_member_count <= 2, '1 <= record_min_member_count <= 2') + ) + ], + ) + def record_min_member_count(self, record_min_member_count): + self.__record_min_member_count = record_min_member_count + + def set_record_min_member_count(self, record_min_member_count): + self.record_min_member_count = record_min_member_count + return self + @property def wait_music_url(self): return self.__wait_music_url @@ -507,6 +527,7 @@ def __init__( role, max_duration=14400, max_participants=10, + record_min_member_count=1, wait_music_url=None, wait_music_method='GET', agent_hold_music_url=None, @@ -547,6 +568,7 @@ def __init__( self.role = role self.max_duration = max_duration self.max_participants = max_participants + self.record_min_member_count = record_min_member_count self.wait_music_url = wait_music_url self.wait_music_method = wait_music_method self.agent_hold_music_url = agent_hold_music_url @@ -579,6 +601,7 @@ def to_dict(self): 'role': self.role, 'maxDuration': self.max_duration, 'maxParticipants': self.max_participants, + 'recordMinMemberCount': self.record_min_member_count, 'waitMusicUrl': self.wait_music_url, 'waitMusicMethod': self.wait_music_method, 'agentHoldMusicUrl': self.agent_hold_music_url, diff --git a/requirements.txt b/requirements.txt index 14483e52..21581763 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ decorator==4.1.2 lxml==4.2.3 requests==2.20.0 -six==1.10.0 +six==1.16.0 PyJWT==2.1.0 diff --git a/tests/resources/fixtures/recordingGetAddedFilterResponse.json b/tests/resources/fixtures/recordingGetAddedFilterResponse.json new file mode 100644 index 00000000..cb9e4926 --- /dev/null +++ b/tests/resources/fixtures/recordingGetAddedFilterResponse.json @@ -0,0 +1,15 @@ +{ + "add_time":"2022-04-12 16:08:53.523657+05:30", + "call_uuid":"f72eea2a-446b-4412-a17f-3b17083bd25a", + "conference_name":"", + "from_number":"+919768368717", + "recording_duration_ms":"7560.00000", + "recording_end_ms":"1649759930398.00000", + "recording_format":"mp3", + "recording_id":"d405c4eb-d562-4399-af32-6ff3c57fa55x", + "recording_start_ms":"1649759922838.00000", + "recording_type":"call", + "recording_url":"https://media.plivo.com/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/d405c4eb-d562-4399-af32-6ff3c57fa559.mp3", + "resource_uri":"/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/d405c4eb-d562-4399-af32-6ff3c57fa559/", + "to_number":"sip:ajay6121801985815245533110@phone.plivo.com" +} \ No newline at end of file diff --git a/tests/resources/fixtures/recordingListFromFilterResponse.json b/tests/resources/fixtures/recordingListFromFilterResponse.json new file mode 100644 index 00000000..0eba469d --- /dev/null +++ b/tests/resources/fixtures/recordingListFromFilterResponse.json @@ -0,0 +1,57 @@ +{ + "api_id": "041a2d92-bf96-11ec-8d3a-0242ac110002", + "meta": { + "limit": 20, + "next": null, + "offset": 0, + "previous": null, + "total_count": 2 + }, + "objects": [ + { + "add_time": "2022-04-12 16:08:53.523657+05:30", + "call_uuid": "f72eea2a-446b-4412-a17f-3b17083bd25a", + "conference_name": "", + "from_number": "+919768368717", + "recording_duration_ms": "7560.00000", + "recording_end_ms": "1649759930398.00000", + "recording_format": "mp3", + "recording_id": "d405c4eb-d562-4399-af32-6ff3c57fa559", + "recording_start_ms": "1649759922838.00000", + "recording_type": "call", + "recording_url": "https://media.plivo.com/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/d405c4eb-d562-4399-af32-6ff3c57fa559.mp3", + "resource_uri": "/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/d405c4eb-d562-4399-af32-6ff3c57fa559/", + "to_number": "sip:ajay6121801985815245533110@phone.plivo.com" + }, + { + "add_time": "2022-04-12 13:49:19.579419+05:30", + "call_uuid": "b5e575b4-721c-425d-8da5-6c5cf6494487", + "conference_name": "", + "from_number": "+919768368712", + "recording_duration_ms": "25020.00000", + "recording_end_ms": "1649751556401.00000", + "recording_format": "mp3", + "recording_id": "7ed2395e-e08a-4448-86b1-9770331d94f3", + "recording_start_ms": "1649751531381.00000", + "recording_type": "call", + "recording_url": "https://media.plivo.com/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/7ed2395e-e08a-4448-86b1-9770331d94f3.mp3", + "resource_uri": "/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/7ed2395e-e08a-4448-86b1-9770331d94f3/", + "to_number": "sip:ajay6121801985815245533110@phone.plivo.com" + }, + { + "add_time": "2022-04-12 13:49:19.579419+05:30", + "call_uuid": "b5e575b4-721c-425d-8da5-6c5cf6494487", + "conference_name": "", + "from_number": "+919768368711", + "recording_duration_ms": "25020.00000", + "recording_end_ms": "1649751556401.00000", + "recording_format": "mp3", + "recording_id": "7ed2395e-e08a-4448-86b1-9770331d94f3", + "recording_start_ms": "1649751531381.00000", + "recording_type": "call", + "recording_url": "https://media.plivo.com/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/7ed2395e-e08a-4448-86b1-9770331d94f3.mp3", + "resource_uri": "/v1/Account/MAZTCXYJFKZJK3N2Q3YT/Recording/7ed2395e-e08a-4448-86b1-9770331d94f3/", + "to_number": "sip:ajay6121801985815245533110@phone.plivo.com" + } + ] +} \ No newline at end of file diff --git a/tests/resources/test_recordings.py b/tests/resources/test_recordings.py index ec4711f7..617501d6 100644 --- a/tests/resources/test_recordings.py +++ b/tests/resources/test_recordings.py @@ -148,3 +148,45 @@ def test_delete(self): # Verifying the method used self.assertEqual('DELETE', self.client.current_request.method) + + @with_response(200) + def test_get_added_filter(self): + recording = self.client.recordings.get( + 'd405c4eb-d562-4399-af32-6ff3c57fa55x') + + self.assertResponseMatches(recording) + + # Verifying the endpoint hit + self.assertEqual( + 'https://api.plivo.com/v1/Account/MAXXXXXXXXXXXXXXXXXX/Recording/d405c4eb-d562-4399-af32-6ff3c57fa55x/', + self.client.current_request.url) + + # Verifying the method used + self.assertEqual('GET', self.client.current_request.method) + + # Verifying the object type returned + self.assertEqual(plivo.resources.recordings.Recording, + recording.__class__) + # verify to and from no param + self.assertEqual('+919768368717', recording.from_number) + + self.assertEqual('sip:ajay6121801985815245533110@phone.plivo.com', recording.to_number) + + @with_response(200) + def test_list_from_filter(self): + recordings = self.client.recordings.list( + call_uuid="f72eea2a-446b-4412-a17f-3b17083bd25a", + from_number="919768368717" + ) + + # Verifying the endpoint hit + self.assertUrlEqual( + 'https://api.plivo.com/v1/Account/MAXXXXXXXXXXXXXXXXXX/Recording/?call_uuid=f72eea2a-446b-4412-a17f-3b17083bd25a&from_number=919768368717&limit=20&offset=0', + self.client.current_request.url) + + # Verifying if the Account specific changes and parsing happened + self.assertEqual('7ed2395e-e08a-4448-86b1-9770331d94f3', + recordings.objects[1].id) + + self.assertEqual('+919768368717', + recordings.objects[0].from_number) \ No newline at end of file