From f51c2697adcf94a1096b00b71aca63aa72905878 Mon Sep 17 00:00:00 2001 From: lokiNK Date: Wed, 1 May 2019 15:33:09 +0530 Subject: [PATCH 1/4] Verified validation --- .DS_Store | Bin 0 -> 6148 bytes plivo/resources/addresses.py | 4 + plivo/resources/applications.py | 31 ++- plivo/resources/calls.py | 396 +++++++++++++++++++++++++------- plivo/resources/conferences.py | 174 ++++++++++---- plivo/resources/identities.py | 7 +- plivo/resources/numbers.py | 8 +- plivo/utils/validators.py | 1 + programs/Address.py | 65 ++++++ programs/Identity.py | 0 programs/account.py | 67 ++++++ programs/application.py | 40 ++++ programs/calltest.py | 126 ++++++++++ programs/conference.py | 13 ++ programs/number.py | 35 +++ 15 files changed, 813 insertions(+), 154 deletions(-) create mode 100644 .DS_Store create mode 100644 programs/Address.py create mode 100644 programs/Identity.py create mode 100644 programs/account.py create mode 100644 programs/application.py create mode 100644 programs/calltest.py create mode 100644 programs/conference.py create mode 100644 programs/number.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c4745eb8f8d3f1beed4303679895c4958531a85d GIT binary patch literal 6148 zcmeHKOG?C05Ukc27?{m0UA`-LgD{LImN+dW<pfD7bQ*vi-!8Yn0l<##hz}1-^XKjhyQ++%#Tmn8eC!{Fpn<&b<=4(Fh3a7-NGaq!Keg<3@nH2bK1-<|YNE%!K literal 0 HcmV?d00001 diff --git a/plivo/resources/addresses.py b/plivo/resources/addresses.py index 899c8f8e..0e6f9c17 100644 --- a/plivo/resources/addresses.py +++ b/plivo/resources/addresses.py @@ -68,6 +68,8 @@ def create(self, region, postal_code, address_proof_type, + phone_number_country, + number_type, alias=None, file_to_upload=None, auto_correct_address=None, @@ -116,6 +118,8 @@ def create(self, salutation=[all_of(of_type(six.text_type), is_in(('Mr', 'Ms')))], first_name=[of_type(six.text_type)], last_name=[of_type(six.text_type)], + phone_number_country=[of_type(six.text_type)], + number_type=[of_type(six.text_type)], country_iso=[optional(of_type(six.text_type))], address_line1=[optional(of_type(six.text_type))], address_line2=[optional(of_type(six.text_type))], diff --git a/plivo/resources/applications.py b/plivo/resources/applications.py index 5b2462b1..055f0d9e 100755 --- a/plivo/resources/applications.py +++ b/plivo/resources/applications.py @@ -2,9 +2,10 @@ """ Application class - along with its list class """ - -from plivo.base import (ListResponseObject, PlivoResource, - PlivoResourceInterface) +from plivo.base import (ListResponseObject, + PlivoResource, + PlivoResourceInterface + ) from plivo.resources.accounts import Subaccount from plivo.utils import to_param_dict from plivo.utils.validators import * @@ -56,7 +57,8 @@ class Applications(PlivoResourceInterface): default_number_app=[optional(of_type_exact(bool))], default_endpoint_app=[optional(of_type_exact(bool))], subaccount=[optional(is_subaccount())], - log_incoming_messages = [optional(of_type_exact(bool))]) + log_incoming_messages = [optional(of_type_exact(bool))] + ) def create(self, answer_url, app_name, @@ -76,13 +78,15 @@ def create(self, if isinstance(subaccount, Subaccount): subaccount = subaccount.id - return self.client.request('POST', ('Application', ), - to_param_dict(self.create, locals())) + return self.client.request( + 'POST', ('Application', ), to_param_dict(self.create, locals()) + ) @validate_args(app_id=[of_type(six.text_type)]) def get(self, app_id): return self.client.request( - 'GET', ('Application', app_id), response_type=Application) + 'GET', ('Application', app_id), response_type=Application + ) @validate_args( subaccount=[optional(is_subaccount())], @@ -121,7 +125,8 @@ def list(self, subaccount=None, limit=20, offset=0): default_number_app=[optional(of_type_exact(bool))], default_endpoint_app=[optional(of_type_exact(bool))], subaccount=[optional(is_subaccount())], - log_incoming_messages=[optional(of_type_exact(bool))]) + log_incoming_messages=[optional(of_type_exact(bool))] + ) def update(self, app_id, answer_url, @@ -139,10 +144,12 @@ def update(self, if subaccount: if isinstance(subaccount, Subaccount): subaccount = subaccount.id - return self.client.request('POST', ('Application', app_id), - to_param_dict(self.update, locals())) + return self.client.request( + 'POST', ('Application', app_id), to_param_dict(self.update, locals()) + ) @validate_args(app_id=[of_type(six.text_type)]) def delete(self, app_id): - return self.client.request('DELETE', ('Application', app_id), - to_param_dict(self.update, locals())) + return self.client.request( + 'DELETE', ('Application', app_id), to_param_dict(self.update, locals()) + ) diff --git a/plivo/resources/calls.py b/plivo/resources/calls.py index 2884291e..45da3193 100755 --- a/plivo/resources/calls.py +++ b/plivo/resources/calls.py @@ -3,8 +3,10 @@ Call class - along with its list class """ -from plivo.base import (ListResponseObject, PlivoResource, - PlivoResourceInterface) +from plivo.base import (ListResponseObject, + PlivoResource, + PlivoResourceInterface + ) from plivo.utils import to_param_dict from plivo.utils.validators import * @@ -20,8 +22,9 @@ def update(self, aleg_method=None, bleg_url=None, bleg_method=None): - return self.client.calls.update(call_uuid, - **to_param_dict(self.update, locals())) + return self.client.calls.update( + call_uuid, **to_param_dict(self.update, locals()) + ) def get(self): return self.client.calls.get(self.id) @@ -33,9 +36,10 @@ def record(self, transcription_url=None, transcription_method=None, callback_url=None, - callback_mathod=None): - return self.client.calls.record(self.id, - **to_param_dict(self.record, locals())) + callback_method=None): + return self.client.calls.record( + self.id, **to_param_dict(self.record, locals()) + ) def start_recording(self, time_limit=None, @@ -44,24 +48,28 @@ def start_recording(self, transcription_url=None, transcription_method=None, callback_url=None, - callback_mathod=None): - return self.client.calls.start_recording(self.id, - **to_param_dict( - self.start_recording, - locals())) + callback_method=None): + return self.client.calls.start_recording( + self.id, **to_param_dict( self.start_recording, locals()) + ) def stop_recording(self): return self.client.calls.stop_recording(self.id) def play(self, urls, length=None, legs=None, loop=None, mix=None): - return self.client.calls.play(self.id, - **to_param_dict(self.start_playing, - locals())) + return self.client.calls.play( + self.id, **to_param_dict(self.start_playing, locals()) + ) - def start_playing(self, urls, length=None, legs=None, loop=None, mix=None): - return self.client.calls.play(self.id, - **to_param_dict(self.start_playing, - locals())) + def start_playing(self, + urls, + length=None, + legs=None, + loop=None, + mix=None): + return self.client.calls.play( + self.id, **to_param_dict(self.start_playing, locals()) + ) def stop_playing(self): return self.client.calls.stop_playing(self.id) @@ -74,9 +82,9 @@ def speak(self, legs=None, loop=None, mix=None): - return self.client.calls.speak(self.id, - **to_param_dict(self.start_playing, - locals())) + return self.client.calls.speak( + self.id, **to_param_dict(self.start_playing, locals()) + ) def start_speaking(self, text, @@ -85,18 +93,17 @@ def start_speaking(self, legs=None, loop=None, mix=None): - return self.client.calls.start_speaking(self.id, - **to_param_dict( - self.start_playing, - locals())) + return self.client.calls.start_speaking( + self.id, **to_param_dict(self.start_playing, locals()) + ) def stop_speaking(self): return self.client.calls.stop_speaking(self.id) def send_digits(self, digits, leg): - return self.client.calls.send_digits(self.id, - **to_param_dict( - self.start_playing, locals())) + return self.client.calls.send_digits( + self.id, **to_param_dict(self.start_playing, locals()) + ) def delete(self): return self.client.calls.delete(self.id) @@ -122,14 +129,47 @@ class Calls(PlivoResourceInterface): machine_detection_url=[optional(is_url())], machine_detection_method=[optional(of_type(six.text_type))], caller_name=[optional(of_type(six.text_type))], + send_digits=[optional(of_type(six.text_type))], + send_on_preanswer=[optional(of_type_exact(bool))], + time_limit=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda time_limit: 0 < time_limit, message='0 < time_limit') + ) + ) + ], + hangup_on_ring=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda hangup_on_ring: 0 < hangup_on_ring, + message='0 < hangup_on_ring') + ) + ) + ], + machine_detection=[optional(of_type_exact(bool))], + machine_detection_time=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda machine_detection_time: 2000 <= machine_detection_time <= 10000, + message='2000 <= machine_detection_time <= 10000') + ) + ) + ], + sip_headers=[optional(of_type(six.text_type))], error_if_parent_not_found=[optional(of_type_exact(bool))], parent_call_uuid=[optional(of_type(six.text_type))], ring_timeout=[ - optional(of_type(*six.integer_types)), - check( - lambda ring_timeout: 0 <= ring_timeout, - message='0 <= ring_timeout') - ], + optional( + all_of( + of_type(*six.integer_types), + check(lambda ring_timeout: 0 < ring_timeout, #I have changed the value of ring_timeout to be greater than 0 since having it equal to zero won't make sense. + message='0 < ring_timeout') + ) + ) + ] ) def create(self, from_, @@ -147,7 +187,7 @@ def create(self, send_on_preanswer=False, time_limit=None, hangup_on_ring=None, - machine_detection=None, + machine_detection=False, machine_detection_time=5000, machine_detection_url=None, machine_detection_method='POST', @@ -158,8 +198,9 @@ def create(self, if from_ in to_.split('<'): raise ValidationError('src and destination cannot overlap') - return self.client.request('POST', ('Call', ), - to_param_dict(self.create, locals())) + return self.client.request( + 'POST', ('Call', ), to_param_dict(self.create, locals()) + ) @validate_args( subaccount=[optional(is_subaccount())], @@ -213,10 +254,7 @@ def list(self, hangup_cause_code=None, hangup_source=None): return self.client.request( - 'GET', - ('Call', ), - to_param_dict(self.list, locals()), - response_type=ListResponseObject, + 'GET', ('Call', ), to_param_dict(self.list, locals()), response_type=ListResponseObject ) @validate_args(call_uuid=[of_type(six.text_type)]) @@ -232,6 +270,7 @@ def get(self, call_uuid): bleg_method=[optional(of_type(six.text_type))], bleg_url=[optional(is_url())], ) + def update(self, call_uuid, legs=None, @@ -239,8 +278,19 @@ def update(self, aleg_method=None, bleg_url=None, bleg_method=None): - return self.client.request('POST', ('Call', call_uuid), - to_param_dict(self.update, locals())) + return self.client.request( + 'POST', ('Call', call_uuid), to_param_dict(self.update, locals()) + ) + + @validate_args( + call_uuid=[of_type(six.text_type)], + legs=[of_type(six.text_type), + is_in(('aleg', 'bleg', 'both'))], + aleg_url=[optional(is_url())], + aleg_method=[optional(of_type(six.text_type))], + bleg_method=[optional(of_type(six.text_type))], + bleg_url=[optional(is_url())], + ) def transfer(self, call_uuid, @@ -257,7 +307,25 @@ def transfer(self, bleg_url=bleg_url, bleg_method=bleg_method) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)], + time_limit=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda time_limit: 0 < time_limit, message='0 < time_limit') + ) + ) + ], + file_format=[optional(of_type(six.text_type))], + transcription_type=[ + optional(of_type(six.text_type), is_in(('auto', 'hybrid'))) + ], + transcription_url=[optional(is_url())], + transcription_method=[optional(of_type(six.text_type))], + callback_url=[optional(is_url())], + callback_method=[optional(of_type(six.text_type))] + ) def record(self, call_uuid, time_limit=None, @@ -266,11 +334,30 @@ def record(self, transcription_url=None, transcription_method=None, callback_url=None, - callback_mathod=None): - return self.start_recording(**to_param_dict(self.start_recording, - locals())) + callback_method=None): + return self.start_recording( + **to_param_dict(self.start_recording, locals()) + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)], + time_limit=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda time_limit: 0 < time_limit, message='0 < time_limit') + ) + ) + ], + file_format=[optional(of_type(six.text_type))], + transcription_type=[ + optional(of_type(six.text_type), is_in(('auto', 'hybrid'))) + ], + transcription_url=[optional(is_url())], #will validate entered value. + transcription_method=[optional(of_type(six.text_type))], + callback_url=[optional(is_url())], #will validate entered value. + callback_method=[optional(of_type(six.text_type))] + ) def start_recording(self, call_uuid, time_limit=None, @@ -279,102 +366,239 @@ def start_recording(self, transcription_url=None, transcription_method=None, callback_url=None, - callback_mathod=None): - return self.client.request('POST', ('Call', call_uuid, 'Record'), - to_param_dict(self.start_recording, - locals())) + callback_method=None): + return self.client.request( + 'POST', ( + 'Call', call_uuid, 'Record'), to_param_dict( + self.start_recording, locals() + ) + ) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def record_stop(self, call_uuid): return self.client.calls.stop_recording(call_uuid) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def stop_recording(self, call_uuid): - return self.client.request('DELETE', ('Call', call_uuid, 'Record')) + return self.client.request( + 'DELETE', ('Call', call_uuid, 'Record') + ) + + @validate_args( + call_uuid=[of_type(six.text_type)], + urls=[is_url()], + length=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda length: 0 < length, + message='0 < length') + ) + ) + ], + legs=[ + optional(of_type(six.text_type), + is_in(('aleg', 'bleg', 'both'))) + ], + loop=[optional(of_type_exact(bool))], + mix=[optional(of_type_exact(bool))] + ) - @validate_args(call_uuid=[of_type(six.text_type)]) def play(self, call_uuid, urls, length=None, legs=None, - loop=None, - mix=None): - return self.start_playing(**to_param_dict(self.play, locals())) + loop=False, + mix=True): + return self.start_playing( + **to_param_dict(self.play, locals()) + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)], + urls=[is_url()], + length=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda length: 0 < length, + message='0 < length') + ) + ) + ], + legs=[ + optional(of_type(six.text_type), + is_in(('aleg', 'bleg', 'both'))) + ], + loop=[optional(of_type_exact(bool))], + mix=[optional(of_type_exact(bool))] + ) def start_playing(self, call_uuid, urls, length=None, legs=None, - loop=None, - mix=None): - return self.client.request('POST', ('Call', call_uuid, 'Play'), - to_param_dict(self.play, locals())) + loop=False, + mix=True): + return self.client.request( + 'POST', ('Call', call_uuid, 'Play'), to_param_dict(self.play, locals()) + ) + @validate_args( + call_uuid=[of_type(six.text_type)], + ) def play_stop(self, call_uuid): return self.client.calls.stop_playing(call_uuid) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def stop_playing(self, call_uuid): - return self.client.request('DELETE', ('Call', call_uuid, 'Play')) + return self.client.request( + 'DELETE', ('Call', call_uuid, 'Play') + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)], + text=[of_type(six.text_type)], + voice=[optional(of_type(six.text_type))], + language=[optional(of_type(six.text_type))], + legs=[ + optional(of_type(six.text_type), + is_in(('aleg', 'bleg', 'both'))) + ], + loop=[optional(of_type_exact(bool))], + mix=[optional(of_type_exact(bool))] + ) def speak(self, call_uuid, text, - voice=None, + voice='WOMAN', language=None, legs=None, - loop=None, - mix=None): - return self.start_speaking(call_uuid, text, voice, language, legs, - loop, mix) + loop=False, + mix=True): + return self.start_speaking( + call_uuid, text, voice, language, legs, loop, mix + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)], + text=[of_type(six.text_type)], + voice=[optional(of_type(six.text_type))], + language=[optional(of_type(six.text_type))], + legs=[ + optional(of_type(six.text_type), + is_in(('aleg', 'bleg', 'both'))) + ], + loop=[optional(of_type_exact(bool))], + mix=[optional(of_type_exact(bool))] + ) def start_speaking(self, call_uuid, text, - voice=None, + voice='WOMAN', language=None, legs=None, - loop=None, - mix=None): - return self.client.request('POST', ('Call', call_uuid, 'Speak'), - to_param_dict(self.start_speaking, - locals())) + loop=False, + mix=True): + return self.client.request( + 'POST', ('Call', call_uuid, 'Speak'), to_param_dict(self.start_speaking, locals()) + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def stop_speaking(self, call_uuid): return self.client.request('DELETE', ('Call', call_uuid, 'Speak')) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def speak_stop(self, call_uuid): return self.client.calls.stop_speaking(call_uuid) - @validate_args(call_uuid=[of_type(six.text_type)]) - def send_digits(self, call_uuid, digits, leg=None): - return self.client.request('POST', ('Call', call_uuid, 'DTMF'), - to_param_dict(self.send_digits, locals())) + @validate_args( + call_uuid=[of_type(six.text_type)], + digits=[of_type(six.text_type)], + leg=[ + optional(of_type(six.text_type), + is_in(('aleg', 'bleg'))) + ], + ) + def send_digits(self, call_uuid, digits, leg='aleg'): + return self.client.request( + 'POST', ('Call', call_uuid, 'DTMF'), to_param_dict(self.send_digits, locals()) + ) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def delete(self, call_uuid): return self.client.request('DELETE', ('Call', call_uuid)) - @validate_args(call_uuid=[of_type(six.text_type)]) + @validate_args( + call_uuid=[of_type(six.text_type)] + ) def hangup(self, call_uuid): return self.client.calls.delete(call_uuid) + @validate_args( + request_uuid=[of_type(six.text_type)] + ) def cancel(self, request_uuid): - return self.client.request('DELETE', ('Request', request_uuid)) + return self.client.request( + 'DELETE', ('Request', request_uuid) + ) + @validate_args( + request_uuid=[of_type(six.text_type)], + limit=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda limit: 0 < limit <= 20, '0 < limit <= 20'))) + ], + offset=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda offset: 0 <= offset, '0 <= offset'))) + ] + ) def live_call_list_ids(self, limit=None, offset=None): return self.client.live_calls.list_ids(limit, offset) + @validate_args( + _id=[of_type(six.text_type)] + ) def live_call_get(self, _id): return self.client.live_calls.get(_id) + @validate_args( + limit=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda limit: 0 < limit <= 20, '0 < limit <= 20'))) + ], + offset=[ + optional( + all_of( + of_type(*six.integer_types), + check(lambda offset: 0 <= offset, '0 <= offset'))) + ] + ) def queued_call_list_ids(self, limit=None, offset=None): return self.client.queued_calls.list_ids(limit, offset) + @validate_args( + _id=[of_type(six.text_type)] + ) def queued_call_get(self, _id): return self.client.queued_calls.get(_id) diff --git a/plivo/resources/conferences.py b/plivo/resources/conferences.py index c65144e1..a3756501 100755 --- a/plivo/resources/conferences.py +++ b/plivo/resources/conferences.py @@ -2,10 +2,9 @@ """ Conference class - along with its list class """ - from plivo.base import PlivoResource, PlivoResourceInterface -from plivo.exceptions import InvalidRequestError from plivo.utils import to_param_dict +from plivo.utils.validators import * class ConferenceMember(PlivoResource): @@ -50,18 +49,22 @@ def member_play(self, member_id, url): def member_play_stop(self, member_id): return self.client.conferences.member_play_stop( - self.conference_name, member_id) + self.conference_name, member_id + ) - def member_speak(self, member_id, text, voice=None, language=None): - return self.client.conferences.member_speak(self.conference_name, - member_id, text, - **to_param_dict( - self.member_speak, - locals())) + def member_speak(self, + member_id, + text, + voice="WOMAN", #Changed the value to "WOMAN" since the default value is WOMAN + language=None): + return self.client.conferences.member_speak( + self.conference_name, member_id, text, **to_param_dict( self.member_speak, locals()) + ) def member_speak_stop(self, member_id): return self.client.conferences.member_speak_stop( - self.conference_name, member_id) + self.conference_name, member_id + ) def record(self, file_format=None, @@ -70,9 +73,9 @@ def record(self, transcription_method=None, callback_url=None, callback_method=None): - return self.client.conferences.record(self.conference_name, - **to_param_dict( - self.member_speak, locals())) + return self.client.conferences.record( + self.conference_name, **to_param_dict(self.member_speak, locals()) + ) def record_stop(self): return self.client.conferences.record_stop(self.conference_name) @@ -85,88 +88,163 @@ class Conferences(PlivoResourceInterface): def list(self): return self.client.request('GET', ('Conference', )) + @validate_args( + conference_name=[of_type(six.text_type)] + ) def get(self, conference_name): - return self.client.request('GET', ('Conference', conference_name)) + return self.client.request( + 'GET', ('Conference', conference_name) + ) + @validate_args( + conference_name=[of_type(six.text_type)] + ) def delete(self, conference_name): - return self.client.request('DELETE', ('Conference', conference_name)) + return self.client.request( + 'DELETE', ('Conference', conference_name) + ) def delete_all(self): - return self.client.request('DELETE', ('Conference', )) + return self.client.request( + 'DELETE', ('Conference', ) + ) def hangup_all(self): return self.delete_all() + @validate_args( + conference_name=[of_type(six.text_type)] + ) def hangup(self, conference_name): return self.delete(conference_name) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + text=[of_type(six.text_type)], + voice=[optional(of_type(six.text_type))], + language=[optional(of_type(six.text_type))], + ) def member_speak(self, conference_name, member_id, text, - voice=None, - language=None): + voice="WOMAN", #Changed the value to "WOMAN" since the default value is WOMAN + language=None + ): return self.client.request( - 'POST', - ('Conference', conference_name, 'Member', member_id, 'Speak'), - to_param_dict(self.member_speak, locals())) - + 'POST', ('Conference', conference_name, 'Member', member_id, 'Speak'), + to_param_dict(self.member_speak, locals()) + ) + + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + url=[is_url()], + ) def member_play(self, conference_name, member_id, url): return self.client.request( - 'POST', - ('Conference', conference_name, 'Member', member_id, 'Play'), - to_param_dict(self.member_play, locals())) - + 'POST', ('Conference', conference_name, 'Member', member_id, 'Play'), + to_param_dict(self.member_play, locals()) + ) + + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_deaf(self, conference_name, member_id): return self.client.request( - 'POST', - ('Conference', conference_name, 'Member', member_id, 'Deaf')) + 'POST', ('Conference', conference_name, 'Member', member_id, 'Deaf') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_mute(self, conference_name, member_id): return self.client.request( - 'POST', - ('Conference', conference_name, 'Member', member_id, 'Mute')) + 'POST', ('Conference', conference_name, 'Member', member_id, 'Mute') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_speak_stop(self, conference_name, member_id): return self.client.request( - 'DELETE', - ('Conference', conference_name, 'Member', member_id, 'Speak')) + 'DELETE', ('Conference', conference_name, 'Member', member_id, 'Speak') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_play_stop(self, conference_name, member_id): return self.client.request( - 'DELETE', - ('Conference', conference_name, 'Member', member_id, 'Play')) + 'DELETE', ('Conference', conference_name, 'Member', member_id, 'Play') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_deaf_stop(self, conference_name, member_id): return self.client.request( - 'DELETE', - ('Conference', conference_name, 'Member', member_id, 'Deaf')) + 'DELETE', ('Conference', conference_name, 'Member', member_id, 'Deaf') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_mute_stop(self, conference_name, member_id): return self.client.request( - 'DELETE', - ('Conference', conference_name, 'Member', member_id, 'Mute')) + 'DELETE', ('Conference', conference_name, 'Member', member_id, 'Mute') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_kick(self, conference_name, member_id): return self.client.request( - 'POST', - ('Conference', conference_name, 'Member', member_id, 'Kick')) + 'POST', ('Conference', conference_name, 'Member', member_id, 'Kick') + ) + @validate_args( + conference_name=[of_type(six.text_type)], + member_id=[of_type(six.text_type)], + ) def member_hangup(self, conference_name, member_id): return self.client.request( - 'DELETE', ('Conference', conference_name, 'Member', member_id)) - + 'DELETE', ('Conference', conference_name, 'Member', member_id) + ) + + @validate_args( + conference_name=[of_type(six.text_type)], + file_format=[optional(of_type(six.text_type))], + transcription_type=[ + optional(of_type(six.text_type), is_in(('auto', 'hybrid'))) + ], + transcription_url=[optional(is_url())], #Changed the validation to 'is_url' + transcription_method=[optional(of_type(six.text_type))], + callback_url=[optional(is_url())], #Changed the validation to 'is_url' + callback_method=[optional(of_type(six.text_type))] + ) def record(self, conference_name, file_format=None, transcription_type=None, transcription_url=None, - transcription_method=None, + transcription_method="POST", #Changed the value to "POST" since the default value is POST callback_url=None, - callback_method=None): - return self.client.request('POST', - ('Conference', conference_name, 'Record')) + callback_method="POST" #Changed the value to "POST" since the default value is POST + ): + return self.client.request( + 'POST', ('Conference', conference_name, 'Record') + ) def record_stop(self, conference_name): - return self.client.request('DELETE', - ('Conference', conference_name, 'Record')) + return self.client.request( + 'DELETE', ('Conference', conference_name, 'Record') + ) diff --git a/plivo/resources/identities.py b/plivo/resources/identities.py index b4bb4c0e..4eff5791 100644 --- a/plivo/resources/identities.py +++ b/plivo/resources/identities.py @@ -34,7 +34,8 @@ def update(self, subaccount=None, file_to_upload=None, auto_correct_address=None, - callback_url=None): + callback_url=None, + url=None,): #One of param which was missing. return self.client.identities.update( self.id, country_iso, salutation, first_name, last_name, birth_place, birth_date, nationality, id_nationality, @@ -157,9 +158,9 @@ def update(self, street_code=None, municipal_code=None, subaccount=None, - file_to_upload=None, + file_to_upload=None, # Value in doc 'file' auto_correct_address=None, - callback_url=None): + callback_url=None,): if file_to_upload: file_extension = file_to_upload.strip().split('.')[-1].lower() if file_extension not in ['jpg', 'jpeg', 'png', 'pdf']: diff --git a/plivo/resources/numbers.py b/plivo/resources/numbers.py index 522dd43b..79b4cea6 100755 --- a/plivo/resources/numbers.py +++ b/plivo/resources/numbers.py @@ -50,9 +50,10 @@ def search(self, offset=None, eligible=None): return self.client.request('GET', ('PhoneNumber', ), - to_param_dict(self.search, locals())) + to_param_dict(self.list, locals()), response_type=ListResponseObject) @validate_args( + country_iso=[is_countryiso()], services=[ optional( is_iterable( @@ -79,10 +80,7 @@ def list(self, services=None, limit=20, offset=0): - return self.client.request( - 'GET', - ('Number', ), - to_param_dict(self.list, locals()), + return self.client.request('GET',('Number', ),to_param_dict(self.list, locals()), objects_type=Number, response_type=ListResponseObject, ) diff --git a/plivo/utils/validators.py b/plivo/utils/validators.py index a78abd6a..bf927534 100755 --- a/plivo/utils/validators.py +++ b/plivo/utils/validators.py @@ -175,6 +175,7 @@ def wrapper(self, *args, **kwargs): is_valid_date = functools.partial(of_type, six.text_type) +is_countryiso = functools.partial(regex(r'[A-Z]{2}$')) is_phonenumber = functools.partial(of_type, six.text_type) is_subaccount_id = functools.partial(all_of, of_type(six.text_type), regex(r'^SA[A-Z0-9]{18}$')) diff --git a/programs/Address.py b/programs/Address.py new file mode 100644 index 00000000..cf6cf854 --- /dev/null +++ b/programs/Address.py @@ -0,0 +1,65 @@ +import plivo + +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') +#Create address: +""" +response = client.addresses.create( + country_iso='DK', + salutation='Mr', + first_name='Kiran', + last_name='Wayne', + address_line1='854', + address_line2='RUE DU COMMANDANT GUILBAUD', + city='PARIS', + region='PARIS', + postal_code='75016', + address_proof_type='others', + phone_number_country='UK', + number_type='Local') +print(response) + +Observation : In docs we have mentioned "auto_correct_address" in doc in SDK we set the value to 'None' +and "callback_url" is not mentioned in the list of parameters. Also, the mandatory parameter "phone_number_country","number_type" is not +a part of allowed args in SDK. + return self.client.addresses.update( + self.id, + salutation + first_name, + last_name, + country_iso, + address_line1, + address_line2, + city, + region, + postal_code, + alias, + file_to_upload, + auto_correct_address, + callback_url + ) +Also, when "phone_number_country" is not used a validation error is returned. +---------------- +Logs: https://www.scalyr.com/events?filter=%27phone_number_country%27&teamToken=G6OgJJW2i5fjksxFW6bwDg--&startTime=1556108383775&endTime=1556110278512 +Response: +plivo.exceptions.ValidationError: {u'error': u'phone_number_country field is mandatory.', + u'message': u'Could not complete address verification.', + u'status': u'error'} +This response is retunred by our servers. +---------------- + +Test1: +When contry code is "ES" the validation works and Validation error is +returned "plivo.exceptions.ValidationError: The parameter fiscal_identification_code is required for Spain numbers" +Test2: +When country code is 'DK' the validation fails. +Response: +TypeError: all() takes exactly one argument (2 given) +Test3: +Any different contry code: +The Request is accepted. But the address does not show up. +Response: +{u'api_id': u'd5fc05a6-6699-11e9-8d11-0242ac110003', + u'message': u'Your request has been accepted.'} + +I have changed the code in addresses.py. There are no errors now. +""" diff --git a/programs/Identity.py b/programs/Identity.py new file mode 100644 index 00000000..e69de29b diff --git a/programs/account.py b/programs/account.py new file mode 100644 index 00000000..70441b48 --- /dev/null +++ b/programs/account.py @@ -0,0 +1,67 @@ +import plivo; + +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') +""" +Create subaccount: +response = client.subaccounts.create( + name='Wayne Enterprises Subaccount', + enabled=True, ) +print(response) +-------------- +Response: +{'_name': 'Subaccount', + u'api_id': u'f1fe3490-6685-11e9-8d11-0242ac110003', + u'auth_id': u'SAMJCXY2QZNZHHZTLHZW', + u'auth_token': u'MTUzNGYzOTYwYjZmNzZkMDExMzhjZWZiYjA5ZWE1', + 'client': , + u'message': u'created'} + +obvervation: Subaccount was created. +""" + +""" +Update Subaccount: +response = client.subaccounts.update( + auth_id='SAMJCXY2QZNZHHZTLHZW', + name='Updated Subaccount Name', ) +print(response) + +--------------- +Response: +{u'api_id': u'a88d0892-6688-11e9-b12a-0242ac110005', u'message': u'changed'} +obvervation: Details were updated. +""" + +""" +Delete Subaccount: +response = client.subaccounts.delete( + auth_id='SAMJCXY2QZNZHHZTLHZW', + cascade=True ) +print(response) +---------------- +Response: +None +obvervation: We should check why the response was empty.But the subaccount and the Phone number associated with the subaccount was deleted. +""" +""" +Update account details: +response = client.account.update( + name='Lucius Fox', + city='New York', + address='Times Square', ) +print(response) +---------------- +Response: +{u'api_id': u'9b5ab36c-6689-11e9-8d11-0242ac110003', u'message': u'changed'} +obvervation: There was a delay in reflecting changes on console. +""" + +""" +Validation test successful +response = client.account.update( + ) +print(response) +------- +Response: +plivo.exceptions.ValidationError: One parameter of name, city and address is required +""" diff --git a/programs/application.py b/programs/application.py new file mode 100644 index 00000000..3337ec24 --- /dev/null +++ b/programs/application.py @@ -0,0 +1,40 @@ +import plivo + +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') + +""" +response = client.applications.create( + app_name='Test Application' ,) + +------------- +Response: +{u'api_id': u'd25eb2d0-669a-11e9-b12a-0242ac110005', + u'app_id': u'28049981997530414', + u'message': u'created'} + +Test1: +If the answer_url or app_name is missing +Below error is returned: +Traceback (most recent call last): + File "application.py", line 7, in + app_name='Test Application' ,) +TypeError: create() takes at least 3 arguments (2 given) +""" +""" +response = client.applications.delete( + app_id='31485478729817310', ) +print(response) +Observation: No issues +""" +""" +response = client.applications.update( + app_id='28949038654699014', + answer_url='http://updated.answer.url', ) +print(response) +-------------------- +Test1: If the app is notfound error is retunred. +Response: plivo.exceptions.ResourceNotFoundError: not found +Test2: Updating app works. +Response: +{u'api_id': u'4ce95cf0-669e-11e9-8d11-0242ac110003', u'message': u'changed'} +""" diff --git a/programs/calltest.py b/programs/calltest.py new file mode 100644 index 00000000..527ca39b --- /dev/null +++ b/programs/calltest.py @@ -0,0 +1,126 @@ +import plivo +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') + +""" +response = client.calls.create( + from_='918548854984', + to_='919538183813<918548854984', + answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', + answer_method='GET', ) +print(response) +--------------- +Response: +Traceback (most recent call last): + File "calltest.py", line 7, in + answer_method='GET', ) + File "", line 2, in create + File "build/bdist.macosx-10.14-intel/egg/plivo/utils/validators.py", line 170, in wrapper + File "build/bdist.macosx-10.14-intel/egg/plivo/resources/calls.py", line 199, in create +plivo.exceptions.ValidationError: src and destination cannot overlap + +""" +""" +All the agrguments are correct , +""" +""" +Get CDR of a call: +response = client.calls.get( + call_uuid='bdfe1272-6690-11e9-9b65-77979dc81b25', ) +print(response) + +Response: + +{u'answer_time': u'2019-04-24 12:59:24+00:00', + u'api_id': u'0f92aeb2-66ba-11e9-b6d9-0242ac110005', + u'bill_duration': 3, + u'billed_duration': 60, + u'call_direction': u'inbound', + u'call_duration': 3, + u'call_state': u'ANSWER', + u'call_uuid': u'bdfe1272-6690-11e9-9b65-77979dc81b25', + u'end_time': u'2019-04-24 12:59:27+00:00', + u'from_number': u'sip:Demo123180918183311@phone.plivo.com', + u'hangup_cause_code': 4010, + u'hangup_cause_name': u'End Of XML Instructions', + u'hangup_source': u'Plivo', + u'initiation_time': u'2019-04-24 12:59:06+00:00', + u'parent_call_uuid': None, + u'resource_uri': u'/v1/Account/MAYMI3MZA5MZAWNJUXMD/Call/bdfe1272-6690-11e9-9b65-77979dc81b25/', + u'to_number': u'493022957150', + u'total_amount': u'0.00300', + u'total_rate': u'0.00300'} +""" +""" +response = client.calls.create( + from_='918548854988', + to_='918548854984', + answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', + answer_method='GET',) +print(response) +------------- +Response: +{u'api_id': u'bef91198-66ba-11e9-a08c-0242ac110005', + u'message': u'call fired', + u'request_uuid': u'a585a2f3-0de1-4261-af53-aaa933d894f7'} + +""" +""" +response = client.calls.record( + call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', ) +print(response) +""" + +""" +response = client.calls.create( + from_='918548854988', + to_='918548854984', + answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', + answer_method='GET',) +print(response) + +------------- +Response: +plivo.exceptions.ValidationError: ['0 < hangup_on_ring (actual value: 0)'] +""" +""" +As per doc: +"Valid values are aleg, bleg or both. aleg will +transfer call_uuid. bleg will transfer the bridged leg of call_uuid. +both will transfer both aleg and bleg." +""" +""" +response = client.calls.transfer( + legs='aleg', + aleg_url='//aleg.', + call_uuid='84fa44f0-4d90-4518-9df1-d4e50b01fb71', ) +print(response) +-------------- +Response: +plivo.exceptions.ValidationError: ['aleg_url should match format +(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: //aleg.)'] +""" +""" +response = client.calls.play( + call_uuid='bc480f62-6d99-469e-b80e-090e620de824',) +print(response) +-------------- +Response: +TypeError: play() takes at least 3 arguments (2 given) +""" +""" +response = client.calls.record( + call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', + callback_url='uerigrf' ) +print(response) + + +Test1: transcription_url is not a url +Response: +plivo.exceptions.ValidationError: ['transcription_url should match format +(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: uerigrf)'] + +Test2: callback_url is not a url +Response: +plivo.exceptions.ValidationError: ['callback_url should match format +(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: uerigrf)'] +""" diff --git a/programs/conference.py b/programs/conference.py new file mode 100644 index 00000000..5b2fdf3d --- /dev/null +++ b/programs/conference.py @@ -0,0 +1,13 @@ +import plivo +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') + +""" +response = client.conferences.record( + conference_name='testing', + transcription_url='qigryfbeuor') +print(response) +----------- +Response: +plivo.exceptions.ValidationError: ['transcription_url should match format +(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: qigryfbeuor)'] +""" diff --git a/programs/number.py b/programs/number.py new file mode 100644 index 00000000..23c7e66e --- /dev/null +++ b/programs/number.py @@ -0,0 +1,35 @@ +import plivo + +client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') + +""" +response = client.numbers.search(country_iso='GB', +limit='2',offset='3') +print(response) + + +api_id: "9b5d1346-6747-11e9-b12a-0242ac110005" +api_id: "d23cf340-6747-11e9-8d11-0242ac110003" + +""" +""" +response = client.numbers.search(country_iso='GB', +limit='0',offset='0') +print(response) + +Test1: limit='0' +plivo.exceptions.ValidationError: ['0 < limit <= 20 (actual value: 0)'] +Test2: offset='0' + +""" +response = client.numbers.list( + limit=5, + offset=0, + type='fixed', ) +print(response) + +""" +-------------- +Response: +plivo.exceptions.ValidationError: ['0 <= offset (actual value: -1)'] +""" From d4d0e1b15c5b479ea7b53b432a2f12c5d85f40a9 Mon Sep 17 00:00:00 2001 From: lokiNK Date: Sun, 5 May 2019 12:30:27 +0530 Subject: [PATCH 2/4] Fixing validation --- plivo/resources/messages.py | 7 ++++++- plivo/resources/numbers.py | 4 ++-- plivo/rest/client.py | 3 +-- plivo/utils/validators.py | 1 - programs/calltest.py | 7 ++++++- programs/number.py | 16 +++++++++------- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/plivo/resources/messages.py b/plivo/resources/messages.py index 750e9c78..d75f740b 100755 --- a/plivo/resources/messages.py +++ b/plivo/resources/messages.py @@ -33,6 +33,7 @@ class Messages(PlivoResourceInterface): log=[optional(of_type_exact(bool))], trackable=[optional(of_type_exact(bool))], powerpack_uuid=[optional(of_type(six.text_type))]) + def create(self, dst, text, @@ -86,7 +87,11 @@ def get(self, message_uuid): all_of( of_type(*six.integer_types), check(lambda offset: 0 <= offset, '0 <= offset'))) - ]) + ], + error_code=[optional(is_in(('10','20','30','40','50','60','70','80','90', + '100','110','201','1000')))] + ) #validating error codes. + def list(self, subaccount=None, message_direction=None, diff --git a/plivo/resources/numbers.py b/plivo/resources/numbers.py index 79b4cea6..7bd25592 100755 --- a/plivo/resources/numbers.py +++ b/plivo/resources/numbers.py @@ -50,10 +50,10 @@ def search(self, offset=None, eligible=None): return self.client.request('GET', ('PhoneNumber', ), - to_param_dict(self.list, locals()), response_type=ListResponseObject) + to_param_dict(self.search, locals())) @validate_args( - country_iso=[is_countryiso()], + country_iso=[(is_countryiso())], services=[ optional( is_iterable( diff --git a/plivo/rest/client.py b/plivo/rest/client.py index 6f8670b2..b3ebe874 100644 --- a/plivo/rest/client.py +++ b/plivo/rest/client.py @@ -13,7 +13,7 @@ ResourceNotFoundError, ValidationError) from plivo.resources import (Accounts, Addresses, Applications, Calls, Conferences, Endpoints, Identities, Messages, - Numbers, Pricings, Recordings, Subaccounts) + Numbers, Pricings, Recordings, Subaccounts,OTP) from plivo.resources.live_calls import LiveCalls from plivo.resources.queued_calls import QueuedCalls from plivo.utils import is_valid_mainaccount, is_valid_subaccount @@ -53,7 +53,6 @@ class Client(object): def __init__(self, auth_id=None, auth_token=None, proxies=None, timeout=5): """ The Plivo API client. - Deals with all the API requests to be made. """ diff --git a/plivo/utils/validators.py b/plivo/utils/validators.py index bf927534..a78abd6a 100755 --- a/plivo/utils/validators.py +++ b/plivo/utils/validators.py @@ -175,7 +175,6 @@ def wrapper(self, *args, **kwargs): is_valid_date = functools.partial(of_type, six.text_type) -is_countryiso = functools.partial(regex(r'[A-Z]{2}$')) is_phonenumber = functools.partial(of_type, six.text_type) is_subaccount_id = functools.partial(all_of, of_type(six.text_type), regex(r'^SA[A-Z0-9]{18}$')) diff --git a/programs/calltest.py b/programs/calltest.py index 527ca39b..7fb0efe4 100644 --- a/programs/calltest.py +++ b/programs/calltest.py @@ -20,7 +20,7 @@ """ """ -All the agrguments are correct , +All the agrguments are correct , """ """ Get CDR of a call: @@ -124,3 +124,8 @@ plivo.exceptions.ValidationError: ['callback_url should match format (http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: uerigrf)'] """ + +response = client.calls.list( + limit=5, + offset=0, ) +print(response) diff --git a/programs/number.py b/programs/number.py index 23c7e66e..902b9bd0 100644 --- a/programs/number.py +++ b/programs/number.py @@ -1,13 +1,10 @@ import plivo - client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') - -""" -response = client.numbers.search(country_iso='GB', -limit='2',offset='3') +response = client.numbers.search( + country_iso='US') print(response) - +""" api_id: "9b5d1346-6747-11e9-b12a-0242ac110005" api_id: "d23cf340-6747-11e9-8d11-0242ac110003" @@ -21,6 +18,7 @@ plivo.exceptions.ValidationError: ['0 < limit <= 20 (actual value: 0)'] Test2: offset='0' +""" """ response = client.numbers.list( limit=5, @@ -28,8 +26,12 @@ type='fixed', ) print(response) -""" + -------------- Response: plivo.exceptions.ValidationError: ['0 <= offset (actual value: -1)'] + +response = client.numbers.delete( + number='14156886775') +print(response) """ From 583d37bd4ad5abf97db183030ff6a4b1c66714fc Mon Sep 17 00:00:00 2001 From: lokiNK Date: Sun, 5 May 2019 13:05:44 +0530 Subject: [PATCH 3/4] Fix validation --- programs/Address.py | 65 -------------------- programs/Identity.py | 0 programs/account.py | 67 -------------------- programs/application.py | 40 ------------ programs/calltest.py | 131 ---------------------------------------- programs/conference.py | 13 ---- programs/number.py | 37 ------------ 7 files changed, 353 deletions(-) delete mode 100644 programs/Address.py delete mode 100644 programs/Identity.py delete mode 100644 programs/account.py delete mode 100644 programs/application.py delete mode 100644 programs/calltest.py delete mode 100644 programs/conference.py delete mode 100644 programs/number.py diff --git a/programs/Address.py b/programs/Address.py deleted file mode 100644 index cf6cf854..00000000 --- a/programs/Address.py +++ /dev/null @@ -1,65 +0,0 @@ -import plivo - -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') -#Create address: -""" -response = client.addresses.create( - country_iso='DK', - salutation='Mr', - first_name='Kiran', - last_name='Wayne', - address_line1='854', - address_line2='RUE DU COMMANDANT GUILBAUD', - city='PARIS', - region='PARIS', - postal_code='75016', - address_proof_type='others', - phone_number_country='UK', - number_type='Local') -print(response) - -Observation : In docs we have mentioned "auto_correct_address" in doc in SDK we set the value to 'None' -and "callback_url" is not mentioned in the list of parameters. Also, the mandatory parameter "phone_number_country","number_type" is not -a part of allowed args in SDK. - return self.client.addresses.update( - self.id, - salutation - first_name, - last_name, - country_iso, - address_line1, - address_line2, - city, - region, - postal_code, - alias, - file_to_upload, - auto_correct_address, - callback_url - ) -Also, when "phone_number_country" is not used a validation error is returned. ----------------- -Logs: https://www.scalyr.com/events?filter=%27phone_number_country%27&teamToken=G6OgJJW2i5fjksxFW6bwDg--&startTime=1556108383775&endTime=1556110278512 -Response: -plivo.exceptions.ValidationError: {u'error': u'phone_number_country field is mandatory.', - u'message': u'Could not complete address verification.', - u'status': u'error'} -This response is retunred by our servers. ----------------- - -Test1: -When contry code is "ES" the validation works and Validation error is -returned "plivo.exceptions.ValidationError: The parameter fiscal_identification_code is required for Spain numbers" -Test2: -When country code is 'DK' the validation fails. -Response: -TypeError: all() takes exactly one argument (2 given) -Test3: -Any different contry code: -The Request is accepted. But the address does not show up. -Response: -{u'api_id': u'd5fc05a6-6699-11e9-8d11-0242ac110003', - u'message': u'Your request has been accepted.'} - -I have changed the code in addresses.py. There are no errors now. -""" diff --git a/programs/Identity.py b/programs/Identity.py deleted file mode 100644 index e69de29b..00000000 diff --git a/programs/account.py b/programs/account.py deleted file mode 100644 index 70441b48..00000000 --- a/programs/account.py +++ /dev/null @@ -1,67 +0,0 @@ -import plivo; - -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') -""" -Create subaccount: -response = client.subaccounts.create( - name='Wayne Enterprises Subaccount', - enabled=True, ) -print(response) --------------- -Response: -{'_name': 'Subaccount', - u'api_id': u'f1fe3490-6685-11e9-8d11-0242ac110003', - u'auth_id': u'SAMJCXY2QZNZHHZTLHZW', - u'auth_token': u'MTUzNGYzOTYwYjZmNzZkMDExMzhjZWZiYjA5ZWE1', - 'client': , - u'message': u'created'} - -obvervation: Subaccount was created. -""" - -""" -Update Subaccount: -response = client.subaccounts.update( - auth_id='SAMJCXY2QZNZHHZTLHZW', - name='Updated Subaccount Name', ) -print(response) - ---------------- -Response: -{u'api_id': u'a88d0892-6688-11e9-b12a-0242ac110005', u'message': u'changed'} -obvervation: Details were updated. -""" - -""" -Delete Subaccount: -response = client.subaccounts.delete( - auth_id='SAMJCXY2QZNZHHZTLHZW', - cascade=True ) -print(response) ----------------- -Response: -None -obvervation: We should check why the response was empty.But the subaccount and the Phone number associated with the subaccount was deleted. -""" -""" -Update account details: -response = client.account.update( - name='Lucius Fox', - city='New York', - address='Times Square', ) -print(response) ----------------- -Response: -{u'api_id': u'9b5ab36c-6689-11e9-8d11-0242ac110003', u'message': u'changed'} -obvervation: There was a delay in reflecting changes on console. -""" - -""" -Validation test successful -response = client.account.update( - ) -print(response) -------- -Response: -plivo.exceptions.ValidationError: One parameter of name, city and address is required -""" diff --git a/programs/application.py b/programs/application.py deleted file mode 100644 index 3337ec24..00000000 --- a/programs/application.py +++ /dev/null @@ -1,40 +0,0 @@ -import plivo - -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') - -""" -response = client.applications.create( - app_name='Test Application' ,) - -------------- -Response: -{u'api_id': u'd25eb2d0-669a-11e9-b12a-0242ac110005', - u'app_id': u'28049981997530414', - u'message': u'created'} - -Test1: -If the answer_url or app_name is missing -Below error is returned: -Traceback (most recent call last): - File "application.py", line 7, in - app_name='Test Application' ,) -TypeError: create() takes at least 3 arguments (2 given) -""" -""" -response = client.applications.delete( - app_id='31485478729817310', ) -print(response) -Observation: No issues -""" -""" -response = client.applications.update( - app_id='28949038654699014', - answer_url='http://updated.answer.url', ) -print(response) --------------------- -Test1: If the app is notfound error is retunred. -Response: plivo.exceptions.ResourceNotFoundError: not found -Test2: Updating app works. -Response: -{u'api_id': u'4ce95cf0-669e-11e9-8d11-0242ac110003', u'message': u'changed'} -""" diff --git a/programs/calltest.py b/programs/calltest.py deleted file mode 100644 index 7fb0efe4..00000000 --- a/programs/calltest.py +++ /dev/null @@ -1,131 +0,0 @@ -import plivo -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') - -""" -response = client.calls.create( - from_='918548854984', - to_='919538183813<918548854984', - answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', - answer_method='GET', ) -print(response) ---------------- -Response: -Traceback (most recent call last): - File "calltest.py", line 7, in - answer_method='GET', ) - File "", line 2, in create - File "build/bdist.macosx-10.14-intel/egg/plivo/utils/validators.py", line 170, in wrapper - File "build/bdist.macosx-10.14-intel/egg/plivo/resources/calls.py", line 199, in create -plivo.exceptions.ValidationError: src and destination cannot overlap - -""" -""" -All the agrguments are correct , -""" -""" -Get CDR of a call: -response = client.calls.get( - call_uuid='bdfe1272-6690-11e9-9b65-77979dc81b25', ) -print(response) - -Response: - -{u'answer_time': u'2019-04-24 12:59:24+00:00', - u'api_id': u'0f92aeb2-66ba-11e9-b6d9-0242ac110005', - u'bill_duration': 3, - u'billed_duration': 60, - u'call_direction': u'inbound', - u'call_duration': 3, - u'call_state': u'ANSWER', - u'call_uuid': u'bdfe1272-6690-11e9-9b65-77979dc81b25', - u'end_time': u'2019-04-24 12:59:27+00:00', - u'from_number': u'sip:Demo123180918183311@phone.plivo.com', - u'hangup_cause_code': 4010, - u'hangup_cause_name': u'End Of XML Instructions', - u'hangup_source': u'Plivo', - u'initiation_time': u'2019-04-24 12:59:06+00:00', - u'parent_call_uuid': None, - u'resource_uri': u'/v1/Account/MAYMI3MZA5MZAWNJUXMD/Call/bdfe1272-6690-11e9-9b65-77979dc81b25/', - u'to_number': u'493022957150', - u'total_amount': u'0.00300', - u'total_rate': u'0.00300'} -""" -""" -response = client.calls.create( - from_='918548854988', - to_='918548854984', - answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', - answer_method='GET',) -print(response) -------------- -Response: -{u'api_id': u'bef91198-66ba-11e9-a08c-0242ac110005', - u'message': u'call fired', - u'request_uuid': u'a585a2f3-0de1-4261-af53-aaa933d894f7'} - -""" -""" -response = client.calls.record( - call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', ) -print(response) -""" - -""" -response = client.calls.create( - from_='918548854988', - to_='918548854984', - answer_url='http://s3.amazonaws.com/static.plivo.com/answer.xml', - answer_method='GET',) -print(response) - -------------- -Response: -plivo.exceptions.ValidationError: ['0 < hangup_on_ring (actual value: 0)'] -""" -""" -As per doc: -"Valid values are aleg, bleg or both. aleg will -transfer call_uuid. bleg will transfer the bridged leg of call_uuid. -both will transfer both aleg and bleg." -""" -""" -response = client.calls.transfer( - legs='aleg', - aleg_url='//aleg.', - call_uuid='84fa44f0-4d90-4518-9df1-d4e50b01fb71', ) -print(response) --------------- -Response: -plivo.exceptions.ValidationError: ['aleg_url should match format -(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: //aleg.)'] -""" -""" -response = client.calls.play( - call_uuid='bc480f62-6d99-469e-b80e-090e620de824',) -print(response) --------------- -Response: -TypeError: play() takes at least 3 arguments (2 given) -""" -""" -response = client.calls.record( - call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', - callback_url='uerigrf' ) -print(response) - - -Test1: transcription_url is not a url -Response: -plivo.exceptions.ValidationError: ['transcription_url should match format -(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: uerigrf)'] - -Test2: callback_url is not a url -Response: -plivo.exceptions.ValidationError: ['callback_url should match format -(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: uerigrf)'] -""" - -response = client.calls.list( - limit=5, - offset=0, ) -print(response) diff --git a/programs/conference.py b/programs/conference.py deleted file mode 100644 index 5b2fdf3d..00000000 --- a/programs/conference.py +++ /dev/null @@ -1,13 +0,0 @@ -import plivo -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') - -""" -response = client.conferences.record( - conference_name='testing', - transcription_url='qigryfbeuor') -print(response) ------------ -Response: -plivo.exceptions.ValidationError: ['transcription_url should match format -(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None) (actual value: qigryfbeuor)'] -""" diff --git a/programs/number.py b/programs/number.py deleted file mode 100644 index 902b9bd0..00000000 --- a/programs/number.py +++ /dev/null @@ -1,37 +0,0 @@ -import plivo -client = plivo.RestClient('MAYMI3MZA5MZAWNJUXMD','YWU1MzJiMjBiZjBiMDQ4OTcyZDQ4YzBlZWEyZjgx') -response = client.numbers.search( - country_iso='US') -print(response) - -""" -api_id: "9b5d1346-6747-11e9-b12a-0242ac110005" -api_id: "d23cf340-6747-11e9-8d11-0242ac110003" - -""" -""" -response = client.numbers.search(country_iso='GB', -limit='0',offset='0') -print(response) - -Test1: limit='0' -plivo.exceptions.ValidationError: ['0 < limit <= 20 (actual value: 0)'] -Test2: offset='0' - -""" -""" -response = client.numbers.list( - limit=5, - offset=0, - type='fixed', ) -print(response) - - --------------- -Response: -plivo.exceptions.ValidationError: ['0 <= offset (actual value: -1)'] - -response = client.numbers.delete( - number='14156886775') -print(response) -""" From 67cccf718a538d97d7e0f1380d0bd5c5434bd6c4 Mon Sep 17 00:00:00 2001 From: KIRAN NK Date: Wed, 8 May 2019 08:43:25 +0530 Subject: [PATCH 4/4] Update client.py --- plivo/rest/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plivo/rest/client.py b/plivo/rest/client.py index b3ebe874..64667738 100644 --- a/plivo/rest/client.py +++ b/plivo/rest/client.py @@ -13,7 +13,7 @@ ResourceNotFoundError, ValidationError) from plivo.resources import (Accounts, Addresses, Applications, Calls, Conferences, Endpoints, Identities, Messages, - Numbers, Pricings, Recordings, Subaccounts,OTP) + Numbers, Pricings, Recordings, Subaccounts) from plivo.resources.live_calls import LiveCalls from plivo.resources.queued_calls import QueuedCalls from plivo.utils import is_valid_mainaccount, is_valid_subaccount