From b802c80256a72edb83053896f98ae4fb6201cfeb Mon Sep 17 00:00:00 2001 From: jmulford-bandwidth Date: Tue, 8 Dec 2020 15:41:53 -0500 Subject: [PATCH 1/2] removed unneeded files --- bandwidth_sdk.egg-info/PKG-INFO | 11 - bandwidth_sdk.egg-info/SOURCES.txt | 139 -- bandwidth_sdk.egg-info/dependency_links.txt | 1 - bandwidth_sdk.egg-info/requires.txt | 6 - bandwidth_sdk.egg-info/top_level.txt | 1 - build/lib/bandwidth/__init__.py | 10 - build/lib/bandwidth/api_helper.py | 414 ----- build/lib/bandwidth/bandwidth_client.py | 62 - build/lib/bandwidth/configuration.py | 222 --- build/lib/bandwidth/controllers/__init__.py | 3 - .../bandwidth/controllers/base_controller.py | 94 -- build/lib/bandwidth/decorators.py | 23 - build/lib/bandwidth/exceptions/__init__.py | 3 - .../lib/bandwidth/exceptions/api_exception.py | 33 - build/lib/bandwidth/http/__init__.py | 9 - build/lib/bandwidth/http/api_response.py | 49 - build/lib/bandwidth/http/auth/__init__.py | 6 - .../http/auth/messaging_basic_auth.py | 30 - .../http/auth/two_factor_auth_basic_auth.py | 30 - .../bandwidth/http/auth/voice_basic_auth.py | 30 - .../bandwidth/http/auth/web_rtc_basic_auth.py | 30 - build/lib/bandwidth/http/http_call_back.py | 37 - build/lib/bandwidth/http/http_client.py | 209 --- build/lib/bandwidth/http/http_method_enum.py | 49 - build/lib/bandwidth/http/http_request.py | 87 - build/lib/bandwidth/http/http_response.py | 46 - build/lib/bandwidth/http/requests_client.py | 124 -- build/lib/bandwidth/messaging/__init__.py | 6 - .../messaging/controllers/__init__.py | 4 - .../messaging/controllers/api_controller.py | 345 ---- .../messaging/controllers/base_controller.py | 94 -- .../messaging/exceptions/__init__.py | 3 - .../exceptions/messaging_exception.py | 38 - .../bandwidth/messaging/messaging_client.py | 47 - .../bandwidth/messaging/models/__init__.py | 8 - .../models/bandwidth_callback_message.py | 85 - .../messaging/models/bandwidth_message.py | 114 -- .../messaging/models/deferred_result.py | 60 - build/lib/bandwidth/messaging/models/media.py | 111 -- .../messaging/models/message_request.py | 84 - build/lib/bandwidth/messaging/models/tag.py | 60 - build/lib/bandwidth/models/__init__.py | 0 build/lib/bandwidth/twofactorauth/__init__.py | 6 - .../twofactorauth/controllers/__init__.py | 4 - .../controllers/api_controller.py | 186 --- .../controllers/base_controller.py | 94 -- .../twofactorauth/exceptions/__init__.py | 3 - .../exceptions/invalid_request_exception.py | 37 - .../twofactorauth/models/__init__.py | 7 - .../models/two_factor_code_request_schema.py | 95 -- .../models/two_factor_messaging_response.py | 54 - .../models/two_factor_verify_code_response.py | 54 - .../two_factor_verify_request_schema.py | 98 -- .../models/two_factor_voice_response.py | 54 - .../twofactorauth/two_factor_auth_client.py | 47 - build/lib/bandwidth/utilities/__init__.py | 3 - build/lib/bandwidth/utilities/file_wrapper.py | 24 - build/lib/bandwidth/voice/__init__.py | 7 - build/lib/bandwidth/voice/bxml/__init__.py | 2 - build/lib/bandwidth/voice/bxml/response.py | 41 - .../bandwidth/voice/bxml/verbs/__init__.py | 20 - .../bandwidth/voice/bxml/verbs/base_verb.py | 21 - .../lib/bandwidth/voice/bxml/verbs/bridge.py | 87 - .../bandwidth/voice/bxml/verbs/conference.py | 90 - .../lib/bandwidth/voice/bxml/verbs/forward.py | 46 - .../lib/bandwidth/voice/bxml/verbs/gather.py | 100 -- .../lib/bandwidth/voice/bxml/verbs/hangup.py | 15 - build/lib/bandwidth/voice/bxml/verbs/pause.py | 30 - .../voice/bxml/verbs/pause_recording.py | 15 - .../voice/bxml/verbs/phone_number.py | 85 - .../bandwidth/voice/bxml/verbs/play_audio.py | 46 - .../lib/bandwidth/voice/bxml/verbs/record.py | 104 -- .../bandwidth/voice/bxml/verbs/redirect.py | 64 - .../voice/bxml/verbs/resume_recording.py | 15 - build/lib/bandwidth/voice/bxml/verbs/ring.py | 30 - .../bandwidth/voice/bxml/verbs/send_dtmf.py | 38 - .../voice/bxml/verbs/speak_sentence.py | 52 - .../voice/bxml/verbs/start_gather.py | 47 - .../voice/bxml/verbs/start_recording.py | 71 - .../bandwidth/voice/bxml/verbs/stop_gather.py | 15 - .../voice/bxml/verbs/stop_recording.py | 15 - .../bandwidth/voice/bxml/verbs/transfer.py | 87 - .../bandwidth/voice/controllers/__init__.py | 4 - .../voice/controllers/api_controller.py | 1445 ----------------- .../voice/controllers/base_controller.py | 94 -- .../bandwidth/voice/exceptions/__init__.py | 3 - .../api_error_response_exception.py | 39 - build/lib/bandwidth/voice/models/__init__.py | 32 - .../models/answer_fallback_method_enum.py | 24 - .../voice/models/answer_method_enum.py | 24 - .../voice/models/api_call_response.py | 171 -- .../voice/models/api_call_state_response.py | 139 -- .../voice/models/api_create_call_request.py | 158 -- .../voice/models/api_modify_call_request.py | 109 -- .../api_transcribe_recording_request.py | 84 - .../call_engine_modify_conference_request.py | 103 -- .../voice/models/callback_method_enum.py | 42 - .../voice/models/conference_detail.py | 102 -- .../models/conference_event_method_enum.py | 42 - .../voice/models/conference_member_detail.py | 84 - .../conference_recording_metadata_response.py | 115 -- .../bandwidth/voice/models/direction_enum.py | 24 - .../voice/models/disconnect_cause_enum.py | 54 - .../voice/models/disconnect_method_enum.py | 24 - .../voice/models/file_format_enum.py | 24 - .../models/modify_call_recording_state.py | 54 - .../models/recording_metadata_response.py | 158 -- .../models/redirect_fallback_method_enum.py | 24 - .../voice/models/redirect_method_enum.py | 24 - .../bandwidth/voice/models/state_1_enum.py | 24 - .../bandwidth/voice/models/state_2_enum.py | 27 - .../lib/bandwidth/voice/models/state_enum.py | 27 - .../bandwidth/voice/models/status_1_enum.py | 36 - .../bandwidth/voice/models/status_3_enum.py | 39 - .../lib/bandwidth/voice/models/status_enum.py | 24 - .../lib/bandwidth/voice/models/transcript.py | 60 - .../bandwidth/voice/models/transcription.py | 72 - .../voice/models/transcription_response.py | 57 - build/lib/bandwidth/voice/voice_client.py | 47 - build/lib/bandwidth/webrtc/__init__.py | 6 - .../bandwidth/webrtc/controllers/__init__.py | 4 - .../webrtc/controllers/api_controller.py | 680 -------- .../webrtc/controllers/base_controller.py | 94 -- .../bandwidth/webrtc/exceptions/__init__.py | 3 - .../webrtc/exceptions/error_exception.py | 38 - build/lib/bandwidth/webrtc/models/__init__.py | 8 - .../models/accounts_participants_response.py | 63 - .../bandwidth/webrtc/models/participant.py | 88 - .../webrtc/models/participant_subscription.py | 55 - .../webrtc/models/publish_permission_enum.py | 24 - build/lib/bandwidth/webrtc/models/session.py | 60 - .../bandwidth/webrtc/models/subscriptions.py | 67 - build/lib/bandwidth/webrtc/utils/__init__.py | 1 - .../bandwidth/webrtc/utils/transfer_util.py | 18 - build/lib/bandwidth/webrtc/web_rtc_client.py | 47 - dist/bandwidth-sdk-6.13.2.tar.gz | Bin 49066 -> 0 bytes dist/bandwidth_sdk-6.13.2-py3-none-any.whl | Bin 107169 -> 0 bytes 137 files changed, 9595 deletions(-) delete mode 100644 bandwidth_sdk.egg-info/PKG-INFO delete mode 100644 bandwidth_sdk.egg-info/SOURCES.txt delete mode 100644 bandwidth_sdk.egg-info/dependency_links.txt delete mode 100644 bandwidth_sdk.egg-info/requires.txt delete mode 100644 bandwidth_sdk.egg-info/top_level.txt delete mode 100644 build/lib/bandwidth/__init__.py delete mode 100644 build/lib/bandwidth/api_helper.py delete mode 100644 build/lib/bandwidth/bandwidth_client.py delete mode 100644 build/lib/bandwidth/configuration.py delete mode 100644 build/lib/bandwidth/controllers/__init__.py delete mode 100644 build/lib/bandwidth/controllers/base_controller.py delete mode 100644 build/lib/bandwidth/decorators.py delete mode 100644 build/lib/bandwidth/exceptions/__init__.py delete mode 100644 build/lib/bandwidth/exceptions/api_exception.py delete mode 100644 build/lib/bandwidth/http/__init__.py delete mode 100644 build/lib/bandwidth/http/api_response.py delete mode 100644 build/lib/bandwidth/http/auth/__init__.py delete mode 100644 build/lib/bandwidth/http/auth/messaging_basic_auth.py delete mode 100644 build/lib/bandwidth/http/auth/two_factor_auth_basic_auth.py delete mode 100644 build/lib/bandwidth/http/auth/voice_basic_auth.py delete mode 100644 build/lib/bandwidth/http/auth/web_rtc_basic_auth.py delete mode 100644 build/lib/bandwidth/http/http_call_back.py delete mode 100644 build/lib/bandwidth/http/http_client.py delete mode 100644 build/lib/bandwidth/http/http_method_enum.py delete mode 100644 build/lib/bandwidth/http/http_request.py delete mode 100644 build/lib/bandwidth/http/http_response.py delete mode 100644 build/lib/bandwidth/http/requests_client.py delete mode 100644 build/lib/bandwidth/messaging/__init__.py delete mode 100644 build/lib/bandwidth/messaging/controllers/__init__.py delete mode 100644 build/lib/bandwidth/messaging/controllers/api_controller.py delete mode 100644 build/lib/bandwidth/messaging/controllers/base_controller.py delete mode 100644 build/lib/bandwidth/messaging/exceptions/__init__.py delete mode 100644 build/lib/bandwidth/messaging/exceptions/messaging_exception.py delete mode 100644 build/lib/bandwidth/messaging/messaging_client.py delete mode 100644 build/lib/bandwidth/messaging/models/__init__.py delete mode 100644 build/lib/bandwidth/messaging/models/bandwidth_callback_message.py delete mode 100644 build/lib/bandwidth/messaging/models/bandwidth_message.py delete mode 100644 build/lib/bandwidth/messaging/models/deferred_result.py delete mode 100644 build/lib/bandwidth/messaging/models/media.py delete mode 100644 build/lib/bandwidth/messaging/models/message_request.py delete mode 100644 build/lib/bandwidth/messaging/models/tag.py delete mode 100644 build/lib/bandwidth/models/__init__.py delete mode 100644 build/lib/bandwidth/twofactorauth/__init__.py delete mode 100644 build/lib/bandwidth/twofactorauth/controllers/__init__.py delete mode 100644 build/lib/bandwidth/twofactorauth/controllers/api_controller.py delete mode 100644 build/lib/bandwidth/twofactorauth/controllers/base_controller.py delete mode 100644 build/lib/bandwidth/twofactorauth/exceptions/__init__.py delete mode 100644 build/lib/bandwidth/twofactorauth/exceptions/invalid_request_exception.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/__init__.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/two_factor_code_request_schema.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/two_factor_messaging_response.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/two_factor_verify_code_response.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/two_factor_verify_request_schema.py delete mode 100644 build/lib/bandwidth/twofactorauth/models/two_factor_voice_response.py delete mode 100644 build/lib/bandwidth/twofactorauth/two_factor_auth_client.py delete mode 100644 build/lib/bandwidth/utilities/__init__.py delete mode 100644 build/lib/bandwidth/utilities/file_wrapper.py delete mode 100644 build/lib/bandwidth/voice/__init__.py delete mode 100644 build/lib/bandwidth/voice/bxml/__init__.py delete mode 100644 build/lib/bandwidth/voice/bxml/response.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/__init__.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/base_verb.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/bridge.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/conference.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/forward.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/gather.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/hangup.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/pause.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/pause_recording.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/phone_number.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/play_audio.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/record.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/redirect.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/resume_recording.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/ring.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/send_dtmf.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/speak_sentence.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/start_gather.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/start_recording.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/stop_gather.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/stop_recording.py delete mode 100644 build/lib/bandwidth/voice/bxml/verbs/transfer.py delete mode 100644 build/lib/bandwidth/voice/controllers/__init__.py delete mode 100644 build/lib/bandwidth/voice/controllers/api_controller.py delete mode 100644 build/lib/bandwidth/voice/controllers/base_controller.py delete mode 100644 build/lib/bandwidth/voice/exceptions/__init__.py delete mode 100644 build/lib/bandwidth/voice/exceptions/api_error_response_exception.py delete mode 100644 build/lib/bandwidth/voice/models/__init__.py delete mode 100644 build/lib/bandwidth/voice/models/answer_fallback_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/answer_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/api_call_response.py delete mode 100644 build/lib/bandwidth/voice/models/api_call_state_response.py delete mode 100644 build/lib/bandwidth/voice/models/api_create_call_request.py delete mode 100644 build/lib/bandwidth/voice/models/api_modify_call_request.py delete mode 100644 build/lib/bandwidth/voice/models/api_transcribe_recording_request.py delete mode 100644 build/lib/bandwidth/voice/models/call_engine_modify_conference_request.py delete mode 100644 build/lib/bandwidth/voice/models/callback_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/conference_detail.py delete mode 100644 build/lib/bandwidth/voice/models/conference_event_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/conference_member_detail.py delete mode 100644 build/lib/bandwidth/voice/models/conference_recording_metadata_response.py delete mode 100644 build/lib/bandwidth/voice/models/direction_enum.py delete mode 100644 build/lib/bandwidth/voice/models/disconnect_cause_enum.py delete mode 100644 build/lib/bandwidth/voice/models/disconnect_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/file_format_enum.py delete mode 100644 build/lib/bandwidth/voice/models/modify_call_recording_state.py delete mode 100644 build/lib/bandwidth/voice/models/recording_metadata_response.py delete mode 100644 build/lib/bandwidth/voice/models/redirect_fallback_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/redirect_method_enum.py delete mode 100644 build/lib/bandwidth/voice/models/state_1_enum.py delete mode 100644 build/lib/bandwidth/voice/models/state_2_enum.py delete mode 100644 build/lib/bandwidth/voice/models/state_enum.py delete mode 100644 build/lib/bandwidth/voice/models/status_1_enum.py delete mode 100644 build/lib/bandwidth/voice/models/status_3_enum.py delete mode 100644 build/lib/bandwidth/voice/models/status_enum.py delete mode 100644 build/lib/bandwidth/voice/models/transcript.py delete mode 100644 build/lib/bandwidth/voice/models/transcription.py delete mode 100644 build/lib/bandwidth/voice/models/transcription_response.py delete mode 100644 build/lib/bandwidth/voice/voice_client.py delete mode 100644 build/lib/bandwidth/webrtc/__init__.py delete mode 100644 build/lib/bandwidth/webrtc/controllers/__init__.py delete mode 100644 build/lib/bandwidth/webrtc/controllers/api_controller.py delete mode 100644 build/lib/bandwidth/webrtc/controllers/base_controller.py delete mode 100644 build/lib/bandwidth/webrtc/exceptions/__init__.py delete mode 100644 build/lib/bandwidth/webrtc/exceptions/error_exception.py delete mode 100644 build/lib/bandwidth/webrtc/models/__init__.py delete mode 100644 build/lib/bandwidth/webrtc/models/accounts_participants_response.py delete mode 100644 build/lib/bandwidth/webrtc/models/participant.py delete mode 100644 build/lib/bandwidth/webrtc/models/participant_subscription.py delete mode 100644 build/lib/bandwidth/webrtc/models/publish_permission_enum.py delete mode 100644 build/lib/bandwidth/webrtc/models/session.py delete mode 100644 build/lib/bandwidth/webrtc/models/subscriptions.py delete mode 100644 build/lib/bandwidth/webrtc/utils/__init__.py delete mode 100644 build/lib/bandwidth/webrtc/utils/transfer_util.py delete mode 100644 build/lib/bandwidth/webrtc/web_rtc_client.py delete mode 100644 dist/bandwidth-sdk-6.13.2.tar.gz delete mode 100644 dist/bandwidth_sdk-6.13.2-py3-none-any.whl diff --git a/bandwidth_sdk.egg-info/PKG-INFO b/bandwidth_sdk.egg-info/PKG-INFO deleted file mode 100644 index 483f7257..00000000 --- a/bandwidth_sdk.egg-info/PKG-INFO +++ /dev/null @@ -1,11 +0,0 @@ -Metadata-Version: 2.1 -Name: bandwidth-sdk -Version: 6.13.2 -Summary: Bandwidth's set of APIs -Home-page: https://apimatic.io -Author: APIMatic SDK Generator -Author-email: support@apimatic.io -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN -Description-Content-Type: text/markdown diff --git a/bandwidth_sdk.egg-info/SOURCES.txt b/bandwidth_sdk.egg-info/SOURCES.txt deleted file mode 100644 index ea2a8feb..00000000 --- a/bandwidth_sdk.egg-info/SOURCES.txt +++ /dev/null @@ -1,139 +0,0 @@ -LICENSE -MANIFEST.in -README.md -setup.py -bandwidth/__init__.py -bandwidth/api_helper.py -bandwidth/bandwidth_client.py -bandwidth/configuration.py -bandwidth/decorators.py -bandwidth/controllers/__init__.py -bandwidth/controllers/base_controller.py -bandwidth/exceptions/__init__.py -bandwidth/exceptions/api_exception.py -bandwidth/http/__init__.py -bandwidth/http/api_response.py -bandwidth/http/http_call_back.py -bandwidth/http/http_client.py -bandwidth/http/http_method_enum.py -bandwidth/http/http_request.py -bandwidth/http/http_response.py -bandwidth/http/requests_client.py -bandwidth/http/auth/__init__.py -bandwidth/http/auth/messaging_basic_auth.py -bandwidth/http/auth/two_factor_auth_basic_auth.py -bandwidth/http/auth/voice_basic_auth.py -bandwidth/http/auth/web_rtc_basic_auth.py -bandwidth/messaging/__init__.py -bandwidth/messaging/messaging_client.py -bandwidth/messaging/controllers/__init__.py -bandwidth/messaging/controllers/api_controller.py -bandwidth/messaging/controllers/base_controller.py -bandwidth/messaging/exceptions/__init__.py -bandwidth/messaging/exceptions/messaging_exception.py -bandwidth/messaging/models/__init__.py -bandwidth/messaging/models/bandwidth_callback_message.py -bandwidth/messaging/models/bandwidth_message.py -bandwidth/messaging/models/deferred_result.py -bandwidth/messaging/models/media.py -bandwidth/messaging/models/message_request.py -bandwidth/messaging/models/tag.py -bandwidth/models/__init__.py -bandwidth/twofactorauth/__init__.py -bandwidth/twofactorauth/two_factor_auth_client.py -bandwidth/twofactorauth/controllers/__init__.py -bandwidth/twofactorauth/controllers/api_controller.py -bandwidth/twofactorauth/controllers/base_controller.py -bandwidth/twofactorauth/exceptions/__init__.py -bandwidth/twofactorauth/exceptions/invalid_request_exception.py -bandwidth/twofactorauth/models/__init__.py -bandwidth/twofactorauth/models/two_factor_code_request_schema.py -bandwidth/twofactorauth/models/two_factor_messaging_response.py -bandwidth/twofactorauth/models/two_factor_verify_code_response.py -bandwidth/twofactorauth/models/two_factor_verify_request_schema.py -bandwidth/twofactorauth/models/two_factor_voice_response.py -bandwidth/utilities/__init__.py -bandwidth/utilities/file_wrapper.py -bandwidth/voice/__init__.py -bandwidth/voice/voice_client.py -bandwidth/voice/bxml/__init__.py -bandwidth/voice/bxml/response.py -bandwidth/voice/bxml/verbs/__init__.py -bandwidth/voice/bxml/verbs/base_verb.py -bandwidth/voice/bxml/verbs/bridge.py -bandwidth/voice/bxml/verbs/conference.py -bandwidth/voice/bxml/verbs/forward.py -bandwidth/voice/bxml/verbs/gather.py -bandwidth/voice/bxml/verbs/hangup.py -bandwidth/voice/bxml/verbs/pause.py -bandwidth/voice/bxml/verbs/pause_recording.py -bandwidth/voice/bxml/verbs/phone_number.py -bandwidth/voice/bxml/verbs/play_audio.py -bandwidth/voice/bxml/verbs/record.py -bandwidth/voice/bxml/verbs/redirect.py -bandwidth/voice/bxml/verbs/resume_recording.py -bandwidth/voice/bxml/verbs/ring.py -bandwidth/voice/bxml/verbs/send_dtmf.py -bandwidth/voice/bxml/verbs/speak_sentence.py -bandwidth/voice/bxml/verbs/start_gather.py -bandwidth/voice/bxml/verbs/start_recording.py -bandwidth/voice/bxml/verbs/stop_gather.py -bandwidth/voice/bxml/verbs/stop_recording.py -bandwidth/voice/bxml/verbs/transfer.py -bandwidth/voice/controllers/__init__.py -bandwidth/voice/controllers/api_controller.py -bandwidth/voice/controllers/base_controller.py -bandwidth/voice/exceptions/__init__.py -bandwidth/voice/exceptions/api_error_response_exception.py -bandwidth/voice/models/__init__.py -bandwidth/voice/models/answer_fallback_method_enum.py -bandwidth/voice/models/answer_method_enum.py -bandwidth/voice/models/api_call_response.py -bandwidth/voice/models/api_call_state_response.py -bandwidth/voice/models/api_create_call_request.py -bandwidth/voice/models/api_modify_call_request.py -bandwidth/voice/models/api_transcribe_recording_request.py -bandwidth/voice/models/call_engine_modify_conference_request.py -bandwidth/voice/models/callback_method_enum.py -bandwidth/voice/models/conference_detail.py -bandwidth/voice/models/conference_event_method_enum.py -bandwidth/voice/models/conference_member_detail.py -bandwidth/voice/models/conference_recording_metadata_response.py -bandwidth/voice/models/direction_enum.py -bandwidth/voice/models/disconnect_cause_enum.py -bandwidth/voice/models/disconnect_method_enum.py -bandwidth/voice/models/file_format_enum.py -bandwidth/voice/models/modify_call_recording_state.py -bandwidth/voice/models/recording_metadata_response.py -bandwidth/voice/models/redirect_fallback_method_enum.py -bandwidth/voice/models/redirect_method_enum.py -bandwidth/voice/models/state_1_enum.py -bandwidth/voice/models/state_2_enum.py -bandwidth/voice/models/state_enum.py -bandwidth/voice/models/status_1_enum.py -bandwidth/voice/models/status_3_enum.py -bandwidth/voice/models/status_enum.py -bandwidth/voice/models/transcript.py -bandwidth/voice/models/transcription.py -bandwidth/voice/models/transcription_response.py -bandwidth/webrtc/__init__.py -bandwidth/webrtc/web_rtc_client.py -bandwidth/webrtc/controllers/__init__.py -bandwidth/webrtc/controllers/api_controller.py -bandwidth/webrtc/controllers/base_controller.py -bandwidth/webrtc/exceptions/__init__.py -bandwidth/webrtc/exceptions/error_exception.py -bandwidth/webrtc/models/__init__.py -bandwidth/webrtc/models/accounts_participants_response.py -bandwidth/webrtc/models/participant.py -bandwidth/webrtc/models/participant_subscription.py -bandwidth/webrtc/models/publish_permission_enum.py -bandwidth/webrtc/models/session.py -bandwidth/webrtc/models/subscriptions.py -bandwidth/webrtc/utils/__init__.py -bandwidth/webrtc/utils/transfer_util.py -bandwidth_sdk.egg-info/PKG-INFO -bandwidth_sdk.egg-info/SOURCES.txt -bandwidth_sdk.egg-info/dependency_links.txt -bandwidth_sdk.egg-info/requires.txt -bandwidth_sdk.egg-info/top_level.txt \ No newline at end of file diff --git a/bandwidth_sdk.egg-info/dependency_links.txt b/bandwidth_sdk.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/bandwidth_sdk.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/bandwidth_sdk.egg-info/requires.txt b/bandwidth_sdk.egg-info/requires.txt deleted file mode 100644 index b53c4d89..00000000 --- a/bandwidth_sdk.egg-info/requires.txt +++ /dev/null @@ -1,6 +0,0 @@ -requests<3.0,>=2.9.1 -jsonpickle<1.0,>=0.7.1 -cachecontrol<1.0,>=0.11.7 -python-dateutil<3.0,>=2.5.3 -enum34>=1.1.6 -lxml>=4.3.4 diff --git a/bandwidth_sdk.egg-info/top_level.txt b/bandwidth_sdk.egg-info/top_level.txt deleted file mode 100644 index 985310a9..00000000 --- a/bandwidth_sdk.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -bandwidth diff --git a/build/lib/bandwidth/__init__.py b/build/lib/bandwidth/__init__.py deleted file mode 100644 index cdb0db88..00000000 --- a/build/lib/bandwidth/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -__all__ = [ - 'api_helper', - 'bandwidth_client', - 'configuration', - 'controllers', - 'decorators', - 'exceptions', - 'http', - 'models', -] diff --git a/build/lib/bandwidth/api_helper.py b/build/lib/bandwidth/api_helper.py deleted file mode 100644 index 023805ca..00000000 --- a/build/lib/bandwidth/api_helper.py +++ /dev/null @@ -1,414 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -import re -import sys -import datetime -import calendar -import email.utils as eut -from time import mktime - -import jsonpickle -import dateutil.parser -from requests.utils import quote - - -class APIHelper(object): - - """A Helper Class for various functions associated with API Calls. - - This class contains static methods for operations that need to be - performed during API requests. All of the methods inside this class are - static methods, there is no need to ever initialise an instance of this - class. - - """ - - @staticmethod - def merge_dicts(dict1, dict2): - """Merges two dictionaries into one as a shallow copy. - - Args: - dict1 (dict): The first dictionary. - dict2 (dict): The second dictionary. - - Returns: - dict: A dictionary containing key value pairs - from both the argument dictionaries. In the case - of a key conflict, values from dict2 are used - and those from dict1 are lost. - - """ - temp = dict1.copy() - temp.update(dict2) - return temp - - @staticmethod - def json_serialize(obj): - """JSON Serialization of a given object. - - Args: - obj (object): The object to serialize. - - Returns: - str: The JSON serialized string of the object. - - """ - if obj is None: - return None - - # Resolve any Names if it's one of our objects that needs to have this called on - if isinstance(obj, list): - value = list() - for item in obj: - if hasattr(item, "_names"): - value.append(APIHelper.to_dictionary(item)) - else: - value.append(item) - obj = value - else: - if hasattr(obj, "_names"): - obj = APIHelper.to_dictionary(obj) - - return jsonpickle.encode(obj, False) - - @staticmethod - def json_deserialize(json, unboxing_function=None): - """JSON Deserialization of a given string. - - Args: - json (str): The JSON serialized string to deserialize. - - Returns: - dict: A dictionary representing the data contained in the - JSON serialized string. - - """ - if json is None: - return None - - try: - decoded = jsonpickle.decode(json) - except ValueError: - return json - - if unboxing_function is None: - return decoded - elif isinstance(decoded, list): - return [unboxing_function(element) for element in decoded] - else: - return unboxing_function(decoded) - - @staticmethod - def serialize_array(key, array, formatting="indexed"): - """Converts an array parameter to a list of key value tuples. - - Args: - key (str): The name of the parameter. - array (list): The value of the parameter. - formatting (str): The type of key formatting expected. - - Returns: - list: A list with key value tuples for the array elements. - - """ - tuples = [] - - if sys.version_info[0] < 3: - serializable_types = (str, int, long, float, bool, datetime.date, APIHelper.CustomDate) - else: - serializable_types = (str, int, float, bool, datetime.date, APIHelper.CustomDate) - - if isinstance(array[0], serializable_types): - if formatting == "unindexed": - tuples += [("{0}[]".format(key), element) for element in array] - elif formatting == "indexed": - tuples += [("{0}[{1}]".format(key, index), element) for index, element in enumerate(array)] - elif formatting == "plain": - tuples += [(key, element) for element in array] - else: - raise ValueError("Invalid format provided.") - else: - tuples += [("{0}[{1}]".format(key, index), element) for index, element in enumerate(array)] - - return tuples - - @staticmethod - def append_url_with_template_parameters(url, parameters): - """Replaces template parameters in the given url. - - Args: - url (str): The query url string to replace the template parameters. - parameters (dict): The parameters to replace in the url. - - Returns: - str: URL with replaced parameters. - - """ - # Parameter validation - if url is None: - raise ValueError("URL is None.") - if parameters is None: - return url - - # Iterate and replace parameters - for key in parameters: - value = parameters[key]['value'] - encode = parameters[key]['encode'] - replace_value = '' - - # Load parameter value - if value is None: - replace_value = '' - elif isinstance(value, list): - replace_value = "/".join((quote(str(x), safe='') if encode else str(x)) for x in value) - else: - replace_value = quote(str(value), safe='') if encode else str(value) - - url = url.replace('{{{0}}}'.format(key), str(replace_value)) - - return url - - @staticmethod - def append_url_with_query_parameters(url, - parameters, - array_serialization="indexed"): - """Adds query parameters to a URL. - - Args: - url (str): The URL string. - parameters (dict): The query parameters to add to the URL. - array_serialization (str): The format of array parameter serialization. - - Returns: - str: URL with added query parameters. - - """ - # Parameter validation - if url is None: - raise ValueError("URL is None.") - if parameters is None: - return url - - for key, value in parameters.items(): - seperator = '&' if '?' in url else '?' - if value is not None: - if isinstance(value, list): - value = [element for element in value if element] - if array_serialization == "csv": - url += "{0}{1}={2}".format( - seperator, - key, - ",".join(quote(str(x), safe='') for x in value) - ) - elif array_serialization == "psv": - url += "{0}{1}={2}".format( - seperator, - key, - "|".join(quote(str(x), safe='') for x in value) - ) - elif array_serialization == "tsv": - url += "{0}{1}={2}".format( - seperator, - key, - "\t".join(quote(str(x), safe='') for x in value) - ) - else: - url += "{0}{1}".format( - seperator, - "&".join(("{0}={1}".format(k, quote(str(v), safe=''))) - for k, v in APIHelper.serialize_array(key, value, array_serialization)) - ) - else: - url += "{0}{1}={2}".format(seperator, key, quote(str(value), safe='')) - - return url - - @staticmethod - def clean_url(url): - """Validates and processes the given query Url to clean empty slashes. - - Args: - url (str): The given query Url to process. - - Returns: - str: Clean Url as string. - - """ - # Ensure that the urls are absolute - regex = "^https?://[^/]+" - match = re.match(regex, url) - if match is None: - raise ValueError('Invalid Url format.') - - protocol = match.group(0) - index = url.find('?') - query_url = url[len(protocol): index if index != -1 else None] - query_url = re.sub("//+", "/", query_url) - parameters = url[index:] if index != -1 else "" - - return protocol + query_url + parameters - - @staticmethod - def form_encode_parameters(form_parameters, - array_serialization="indexed"): - """Form encodes a dictionary of form parameters - - Args: - form_parameters (dictionary): The given dictionary which has - atleast one model to form encode. - array_serialization (str): The format of array parameter serialization. - - Returns: - dict: A dictionary of form encoded properties of the model. - - """ - encoded = [] - - for key, value in form_parameters.items(): - encoded += APIHelper.form_encode(value, key, array_serialization) - - return encoded - - @staticmethod - def form_encode(obj, - instance_name, - array_serialization="indexed"): - """Encodes a model in a form-encoded manner such as person[Name] - - Args: - obj (object): The given Object to form encode. - instance_name (string): The base name to appear before each entry - for this object. - array_serialization (string): The format of array parameter serialization. - - Returns: - dict: A dictionary of form encoded properties of the model. - - """ - retval = [] - # If we received an object, resolve it's field names. - if hasattr(obj, "_names"): - obj = APIHelper.to_dictionary(obj) - - if obj is None: - return [] - elif isinstance(obj, list): - for element in APIHelper.serialize_array(instance_name, obj, array_serialization): - retval += APIHelper.form_encode(element[1], element[0], array_serialization) - elif isinstance(obj, dict): - for item in obj: - retval += APIHelper.form_encode(obj[item], instance_name + "[" + item + "]", array_serialization) - else: - retval.append((instance_name, obj)) - - return retval - - @staticmethod - def to_dictionary(obj): - """Creates a dictionary representation of a class instance. The - keys are taken from the API description and may differ from language - specific variable names of properties. - - Args: - obj: The object to be converted into a dictionary. - - Returns: - dictionary: A dictionary form of the model with properties in - their API formats. - - """ - dictionary = dict() - - # Loop through all properties in this model - for name in {k: v for k, v in obj.__dict__.items() if v is not None}: - value = getattr(obj, name) - if isinstance(value, list): - # Loop through each item - dictionary[obj._names[name]] = list() - for item in value: - dictionary[obj._names[name]].append(APIHelper.to_dictionary(item) if hasattr(item, "_names") else item) - elif isinstance(value, dict): - # Loop through each item - dictionary[obj._names[name]] = dict() - for key in value: - dictionary[obj._names[name]][key] = APIHelper.to_dictionary(value[key]) if hasattr(value[key], "_names") else value[key] - else: - dictionary[obj._names[name]] = APIHelper.to_dictionary(value) if hasattr(value, "_names") else value - - # Return the result - return dictionary - - @staticmethod - def when_defined(func, value): - return func(value) if value else None - - class CustomDate(object): - - """ A base class for wrapper classes of datetime. - - This class contains methods which help in - appropriate serialization of datetime objects. - - """ - - def __init__(self, dtime, value=None): - self.datetime = dtime - if not value: - self.value = self.from_datetime(dtime) - else: - self.value = value - - def __repr__(self): - return str(self.value) - - def __getstate__(self): - return self.value - - def __setstate__(self, state): - pass - - class HttpDateTime(CustomDate): - - """ A wrapper class for datetime to support HTTP date format.""" - - @classmethod - def from_datetime(cls, date_time): - return eut.formatdate(timeval=mktime(date_time.timetuple()), - localtime=False, usegmt=True) - - @classmethod - def from_value(cls, value): - dtime = datetime.datetime.fromtimestamp(eut.mktime_tz(eut.parsedate_tz(value))) - return cls(dtime, value) - - class UnixDateTime(CustomDate): - - """ A wrapper class for datetime to support Unix date format.""" - - @classmethod - def from_datetime(cls, date_time): - return calendar.timegm(date_time.utctimetuple()) - - @classmethod - def from_value(cls, value): - dtime = datetime.datetime.utcfromtimestamp(float(value)) - return cls(dtime, float(value)) - - class RFC3339DateTime(CustomDate): - - """ A wrapper class for datetime to support Rfc 3339 format.""" - - @classmethod - def from_datetime(cls, date_time): - return date_time.isoformat() - - @classmethod - def from_value(cls, value): - dtime = dateutil.parser.parse(value) - return cls(dtime, value) diff --git a/build/lib/bandwidth/bandwidth_client.py b/build/lib/bandwidth/bandwidth_client.py deleted file mode 100644 index ab40fdca..00000000 --- a/build/lib/bandwidth/bandwidth_client.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.decorators import lazy_property -from bandwidth.configuration import Configuration -from bandwidth.configuration import Environment -from bandwidth.messaging.messaging_client import MessagingClient -from bandwidth.twofactorauth.two_factor_auth_client import TwoFactorAuthClient -from bandwidth.voice.voice_client import VoiceClient -from bandwidth.webrtc.web_rtc_client import WebRtcClient - - -class BandwidthClient(object): - - @lazy_property - def messaging_client(self): - return MessagingClient(config=self.config) - - @lazy_property - def two_factor_auth_client(self): - return TwoFactorAuthClient(config=self.config) - - @lazy_property - def voice_client(self): - return VoiceClient(config=self.config) - - @lazy_property - def web_rtc_client(self): - return WebRtcClient(config=self.config) - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace', config=None): - if config is None: - self.config = Configuration(timeout=timeout, - max_retries=max_retries, - backoff_factor=backoff_factor, - environment=environment, - base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password) - else: - self.config = config diff --git a/build/lib/bandwidth/configuration.py b/build/lib/bandwidth/configuration.py deleted file mode 100644 index 4c6253c1..00000000 --- a/build/lib/bandwidth/configuration.py +++ /dev/null @@ -1,222 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from enum import Enum -from bandwidth.api_helper import APIHelper -from bandwidth.http.requests_client import RequestsClient - - -class Environment(Enum): - """An enum for SDK environments""" - PRODUCTION = 0 - CUSTOM = 1 - - -class Server(Enum): - """An enum for API servers""" - DEFAULT = 0 - MESSAGINGDEFAULT = 1 - TWOFACTORAUTHDEFAULT = 2 - VOICEDEFAULT = 3 - WEBRTCDEFAULT = 4 - - -class Configuration(object): - """A class used for configuring the SDK by a user. - """ - - @property - def http_client(self): - return self._http_client - - @property - def timeout(self): - return self._timeout - - @property - def max_retries(self): - return self._max_retries - - @property - def backoff_factor(self): - return self._backoff_factor - - @property - def environment(self): - return self._environment - - @property - def base_url(self): - return self._base_url - - @property - def messaging_basic_auth_user_name(self): - return self._messaging_basic_auth_user_name - - @property - def messaging_basic_auth_password(self): - return self._messaging_basic_auth_password - - @property - def two_factor_auth_basic_auth_user_name(self): - return self._two_factor_auth_basic_auth_user_name - - @property - def two_factor_auth_basic_auth_password(self): - return self._two_factor_auth_basic_auth_password - - @property - def voice_basic_auth_user_name(self): - return self._voice_basic_auth_user_name - - @property - def voice_basic_auth_password(self): - return self._voice_basic_auth_password - - @property - def web_rtc_basic_auth_user_name(self): - return self._web_rtc_basic_auth_user_name - - @property - def web_rtc_basic_auth_password(self): - return self._web_rtc_basic_auth_password - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace'): - # The value to use for connection timeout - self._timeout = timeout - - # The number of times to retry an endpoint call if it fails - self._max_retries = max_retries - - # A backoff factor to apply between attempts after the second try. - # urllib3 will sleep for: - # `{backoff factor} * (2 ** ({number of total retries} - 1))` - self._backoff_factor = backoff_factor - - # Current API environment - self._environment = environment - - # base_url value - self._base_url = base_url - - # The username to use with basic authentication - self._messaging_basic_auth_user_name = messaging_basic_auth_user_name - - # The password to use with basic authentication - self._messaging_basic_auth_password = messaging_basic_auth_password - - # The username to use with basic authentication - self._two_factor_auth_basic_auth_user_name = two_factor_auth_basic_auth_user_name - - # The password to use with basic authentication - self._two_factor_auth_basic_auth_password = two_factor_auth_basic_auth_password - - # The username to use with basic authentication - self._voice_basic_auth_user_name = voice_basic_auth_user_name - - # The password to use with basic authentication - self._voice_basic_auth_password = voice_basic_auth_password - - # The username to use with basic authentication - self._web_rtc_basic_auth_user_name = web_rtc_basic_auth_user_name - - # The password to use with basic authentication - self._web_rtc_basic_auth_password = web_rtc_basic_auth_password - - # The Http Client to use for making requests. - self._http_client = self.create_http_client() - - def clone_with(self, timeout=None, max_retries=None, backoff_factor=None, - environment=None, base_url=None, - messaging_basic_auth_user_name=None, - messaging_basic_auth_password=None, - two_factor_auth_basic_auth_user_name=None, - two_factor_auth_basic_auth_password=None, - voice_basic_auth_user_name=None, - voice_basic_auth_password=None, - web_rtc_basic_auth_user_name=None, - web_rtc_basic_auth_password=None): - timeout = timeout or self.timeout - max_retries = max_retries or self.max_retries - backoff_factor = backoff_factor or self.backoff_factor - environment = environment or self.environment - base_url = base_url or self.base_url - messaging_basic_auth_user_name = messaging_basic_auth_user_name or self.messaging_basic_auth_user_name - messaging_basic_auth_password = messaging_basic_auth_password or self.messaging_basic_auth_password - two_factor_auth_basic_auth_user_name = two_factor_auth_basic_auth_user_name or self.two_factor_auth_basic_auth_user_name - two_factor_auth_basic_auth_password = two_factor_auth_basic_auth_password or self.two_factor_auth_basic_auth_password - voice_basic_auth_user_name = voice_basic_auth_user_name or self.voice_basic_auth_user_name - voice_basic_auth_password = voice_basic_auth_password or self.voice_basic_auth_password - web_rtc_basic_auth_user_name = web_rtc_basic_auth_user_name or self.web_rtc_basic_auth_user_name - web_rtc_basic_auth_password = web_rtc_basic_auth_password or self.web_rtc_basic_auth_password - - return Configuration( - timeout=timeout, max_retries=max_retries, - backoff_factor=backoff_factor, environment=environment, base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password - ) - - def create_http_client(self): - return RequestsClient(timeout=self.timeout, - max_retries=self.max_retries, - backoff_factor=self.backoff_factor) - - # All the environments the SDK can run in - environments = { - Environment.PRODUCTION: { - Server.DEFAULT: 'api.bandwidth.com', - Server.MESSAGINGDEFAULT: 'https://messaging.bandwidth.com/api/v2', - Server.TWOFACTORAUTHDEFAULT: 'https://mfa.bandwidth.com/api/v1/', - Server.VOICEDEFAULT: 'https://voice.bandwidth.com', - Server.WEBRTCDEFAULT: 'https://api.webrtc.bandwidth.com/v1' - }, - Environment.CUSTOM: { - Server.DEFAULT: '{base_url}', - Server.MESSAGINGDEFAULT: '{base_url}', - Server.TWOFACTORAUTHDEFAULT: '{base_url}', - Server.VOICEDEFAULT: '{base_url}', - Server.WEBRTCDEFAULT: '{base_url}' - } - } - - def get_base_uri(self, server=Server.DEFAULT): - """Generates the appropriate base URI for the environment and the - server. - - Args: - server (Configuration.Server): The server enum for which the base - URI is required. - - Returns: - String: The base URI. - - """ - parameters = { - "base_url": {'value': self.base_url, 'encode': False}, - } - - return APIHelper.append_url_with_template_parameters( - self.environments[self.environment][server], parameters - ) diff --git a/build/lib/bandwidth/controllers/__init__.py b/build/lib/bandwidth/controllers/__init__.py deleted file mode 100644 index 3d169dc3..00000000 --- a/build/lib/bandwidth/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'base_controller', -] diff --git a/build/lib/bandwidth/controllers/base_controller.py b/build/lib/bandwidth/controllers/base_controller.py deleted file mode 100644 index 3f7583fb..00000000 --- a/build/lib/bandwidth/controllers/base_controller.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.exceptions.api_exception import APIException - - -class BaseController(object): - - """All controllers inherit from this base class. - - Attributes: - config (Configuration): The HttpClient which a specific controller - instance will use. By default all the controller objects share - the same HttpClient. A user can use his own custom HttpClient - as well. - http_call_back (HttpCallBack): An object which holds call back - methods to be called before and after the execution of an HttpRequest. - global_headers (dict): The global headers of the API which are sent with - every request. - - """ - - def global_headers(self): - return { - 'user-agent': 'python-sdk-refs/tags/python6.13.2' - } - - def __init__(self, config, call_back=None): - self._config = config - self._http_call_back = call_back - - @property - def config(self): - return self._config - - @property - def http_call_back(self): - return self._http_call_back - - def validate_parameters(self, **kwargs): - """Validates required parameters of an endpoint. - - Args: - kwargs (dict): A dictionary of the required parameters. - - """ - for name, value in kwargs.items(): - if value is None: - raise ValueError("Required parameter {} cannot be None.".format(name)) - - def execute_request(self, request, binary=False): - """Executes an HttpRequest. - - Args: - request (HttpRequest): The HttpRequest to execute. - binary (bool): A flag which should be set to True if - a binary response is expected. - - Returns: - HttpResponse: The HttpResponse received. - - """ - # Invoke the on before request HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_before_request(request) - - # Add global headers to request - request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers) - - # Invoke the API call to fetch the response. - func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string - response = func(request) - - # Invoke the on after response HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_after_response(response) - - return response - - def validate_response(self, response): - """Validates an HTTP response by checking for global errors. - - Args: - response (HttpResponse): The HttpResponse of the API call. - - """ - if (response.status_code < 200) or (response.status_code > 208): # [200,208] = HTTP OK - raise APIException('HTTP response not OK.', response) diff --git a/build/lib/bandwidth/decorators.py b/build/lib/bandwidth/decorators.py deleted file mode 100644 index a112ab65..00000000 --- a/build/lib/bandwidth/decorators.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class lazy_property(object): - - """A decorator class for lazy instantiation.""" - - def __init__(self, fget): - self.fget = fget - self.func_name = fget.__name__ - - def __get__(self, obj, cls): - if obj is None: - return None - value = self.fget(obj) - setattr(obj, self.func_name, value) - return value diff --git a/build/lib/bandwidth/exceptions/__init__.py b/build/lib/bandwidth/exceptions/__init__.py deleted file mode 100644 index 1f4885eb..00000000 --- a/build/lib/bandwidth/exceptions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'api_exception', -] diff --git a/build/lib/bandwidth/exceptions/api_exception.py b/build/lib/bandwidth/exceptions/api_exception.py deleted file mode 100644 index c778fbae..00000000 --- a/build/lib/bandwidth/exceptions/api_exception.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class APIException(Exception): - - """Class that handles HTTP Exceptions when fetching API Endpoints. - - Attributes: - response_code (int): The status code of the response. - response (HttpResponse): The HttpResponse of the API call. - - """ - - def __init__(self, - reason, - response): - """Constructor for the APIException class - - Args: - reason (string): The reason (or error message) for the Exception - to be raised. - response (HttpResponse): The HttpResponse of the API call. - - """ - super(APIException, self).__init__(reason) - self.response = response - self.response_code = response.status_code diff --git a/build/lib/bandwidth/http/__init__.py b/build/lib/bandwidth/http/__init__.py deleted file mode 100644 index 4348222a..00000000 --- a/build/lib/bandwidth/http/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -__all__ = [ - 'auth', - 'http_method_enum', - 'http_request', - 'http_response', - 'http_client', - 'requests_client', - 'http_call_back', -] diff --git a/build/lib/bandwidth/http/api_response.py b/build/lib/bandwidth/http/api_response.py deleted file mode 100644 index 77edf3a7..00000000 --- a/build/lib/bandwidth/http/api_response.py +++ /dev/null @@ -1,49 +0,0 @@ -import json - - -class ApiResponse: - - """Http response received. - - Attributes: - status_code (int): The status code response from the server that - corresponds to this response. - reason_phrase (string): The reason phrase returned by the server. - headers (dict): A dictionary of headers (key : value) that were - returned with the response - text (string): The Raw body of the HTTP Response as a string - request (HttpRequest): The request that resulted in this response. - body (Object): The data field specified for the response - errors (Array): Any errors returned by the server - - """ - - def __init__(self, http_response, - body=None, - errors=None): - - """The Constructor - - Args: - http_response (HttpResponse): The original, raw response from the api - data (Object): The data field specified for the response - errors (Array): Any errors returned by the server - - """ - - self.status_code = http_response.status_code - self.reason_phrase = http_response.reason_phrase - self.headers = http_response.headers - self.text = http_response.text - self.request = http_response.request - self.body = body - self.errors = errors - - def is_success(self): - return 200 <= self.status_code < 300 - - def is_error(self): - return 400 <= self.status_code < 600 - - def __repr__(self): - return '' % (self.text) diff --git a/build/lib/bandwidth/http/auth/__init__.py b/build/lib/bandwidth/http/auth/__init__.py deleted file mode 100644 index 8ce8edd6..00000000 --- a/build/lib/bandwidth/http/auth/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -__all__ = [ - 'messaging_basic_auth', - 'two_factor_auth_basic_auth', - 'voice_basic_auth', - 'web_rtc_basic_auth', -] diff --git a/build/lib/bandwidth/http/auth/messaging_basic_auth.py b/build/lib/bandwidth/http/auth/messaging_basic_auth.py deleted file mode 100644 index 5bd4c174..00000000 --- a/build/lib/bandwidth/http/auth/messaging_basic_auth.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -import base64 - - -class MessagingBasicAuth: - - @staticmethod - def apply(config, http_request): - """ Add basic authentication to the request. - - Args: - config (Configuration): The Configuration object which holds the - authentication information. - http_request (HttpRequest): The HttpRequest object to which - authentication will be added. - - """ - username = config.messaging_basic_auth_user_name - password = config.messaging_basic_auth_password - joined = "{}:{}".format(username, password) - encoded = base64.b64encode(str.encode(joined)).decode('iso-8859-1') - header_value = "Basic {}".format(encoded) - http_request.headers["Authorization"] = header_value diff --git a/build/lib/bandwidth/http/auth/two_factor_auth_basic_auth.py b/build/lib/bandwidth/http/auth/two_factor_auth_basic_auth.py deleted file mode 100644 index c370f3ff..00000000 --- a/build/lib/bandwidth/http/auth/two_factor_auth_basic_auth.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -import base64 - - -class TwoFactorAuthBasicAuth: - - @staticmethod - def apply(config, http_request): - """ Add basic authentication to the request. - - Args: - config (Configuration): The Configuration object which holds the - authentication information. - http_request (HttpRequest): The HttpRequest object to which - authentication will be added. - - """ - username = config.two_factor_auth_basic_auth_user_name - password = config.two_factor_auth_basic_auth_password - joined = "{}:{}".format(username, password) - encoded = base64.b64encode(str.encode(joined)).decode('iso-8859-1') - header_value = "Basic {}".format(encoded) - http_request.headers["Authorization"] = header_value diff --git a/build/lib/bandwidth/http/auth/voice_basic_auth.py b/build/lib/bandwidth/http/auth/voice_basic_auth.py deleted file mode 100644 index 514a94b0..00000000 --- a/build/lib/bandwidth/http/auth/voice_basic_auth.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -import base64 - - -class VoiceBasicAuth: - - @staticmethod - def apply(config, http_request): - """ Add basic authentication to the request. - - Args: - config (Configuration): The Configuration object which holds the - authentication information. - http_request (HttpRequest): The HttpRequest object to which - authentication will be added. - - """ - username = config.voice_basic_auth_user_name - password = config.voice_basic_auth_password - joined = "{}:{}".format(username, password) - encoded = base64.b64encode(str.encode(joined)).decode('iso-8859-1') - header_value = "Basic {}".format(encoded) - http_request.headers["Authorization"] = header_value diff --git a/build/lib/bandwidth/http/auth/web_rtc_basic_auth.py b/build/lib/bandwidth/http/auth/web_rtc_basic_auth.py deleted file mode 100644 index 0dffdbb8..00000000 --- a/build/lib/bandwidth/http/auth/web_rtc_basic_auth.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -import base64 - - -class WebRtcBasicAuth: - - @staticmethod - def apply(config, http_request): - """ Add basic authentication to the request. - - Args: - config (Configuration): The Configuration object which holds the - authentication information. - http_request (HttpRequest): The HttpRequest object to which - authentication will be added. - - """ - username = config.web_rtc_basic_auth_user_name - password = config.web_rtc_basic_auth_password - joined = "{}:{}".format(username, password) - encoded = base64.b64encode(str.encode(joined)).decode('iso-8859-1') - header_value = "Basic {}".format(encoded) - http_request.headers["Authorization"] = header_value diff --git a/build/lib/bandwidth/http/http_call_back.py b/build/lib/bandwidth/http/http_call_back.py deleted file mode 100644 index 694fd393..00000000 --- a/build/lib/bandwidth/http/http_call_back.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class HttpCallBack(object): - - """An interface for the callback to be called before and after the - HTTP call for an endpoint is made. - - This class should not be instantiated but should be used as a base class - for HttpCallBack classes. - - """ - - def on_before_request(self, - request): - """The controller will call this method before making the HttpRequest. - - Args: - request (HttpRequest): The request object which will be sent - to the HttpClient to be executed. - """ - raise NotImplementedError("This method has not been implemented.") - - def on_after_response(self, - http_response): - """The controller will call this method after making the HttpRequest. - - Args: - http_response (HttpResponse): The HttpResponse of the API call. - """ - raise NotImplementedError("This method has not been implemented.") diff --git a/build/lib/bandwidth/http/http_client.py b/build/lib/bandwidth/http/http_client.py deleted file mode 100644 index 5bec9e4f..00000000 --- a/build/lib/bandwidth/http/http_client.py +++ /dev/null @@ -1,209 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.http.http_method_enum import HttpMethodEnum -from bandwidth.http.http_request import HttpRequest - - -class HttpClient(object): - - """An interface for the methods that an HTTP Client must implement - - This class should not be instantiated but should be used as a base class - for HTTP Client classes. - - """ - - def execute_as_string(self, request): - """Execute a given HttpRequest to get a string response back - - Args: - request (HttpRequest): The given HttpRequest to execute. - - Returns: - HttpResponse: The response of the HttpRequest. - - """ - raise NotImplementedError("Please Implement this method") - - def execute_as_binary(self, request): - """Execute a given HttpRequest to get a binary response back - - Args: - request (HttpRequest): The given HttpRequest to execute. - - Returns: - HttpResponse: The response of the HttpRequest. - - """ - raise NotImplementedError("Please Implement this method") - - def convert_response(self, response, binary): - """Converts the Response object of the HttpClient into an - HttpResponse object. - - Args: - response (dynamic): The original response object. - - Returns: - HttpResponse: The converted HttpResponse object. - - """ - raise NotImplementedError("Please Implement this method") - - def get(self, query_url, - headers={}, - query_parameters={}): - """Create a simple GET HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.GET, - query_url, - headers, - query_parameters, - None, - None) - - def head(self, query_url, - headers={}, - query_parameters={}): - """Create a simple HEAD HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.HEAD, - query_url, - headers, - query_parameters, - None, - None) - - def post(self, query_url, - headers={}, - query_parameters={}, - parameters={}, - files={}): - """Create a simple POST HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - parameters (dict, optional): Form or body parameters to be included - in the body. - files (dict, optional): Files to be sent with the request. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.POST, - query_url, - headers, - query_parameters, - parameters, - files) - - def put(self, query_url, - headers={}, - query_parameters={}, - parameters={}, - files={}): - """Create a simple PUT HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - parameters (dict, optional): Form or body parameters to be included - in the body. - files (dict, optional): Files to be sent with the request. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.PUT, - query_url, - headers, - query_parameters, - parameters, - files) - - def patch(self, query_url, - headers={}, - query_parameters={}, - parameters={}, - files={}): - """Create a simple PATCH HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - parameters (dict, optional): Form or body parameters to be included - in the body. - files (dict, optional): Files to be sent with the request. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.PATCH, - query_url, - headers, - query_parameters, - parameters, - files) - - def delete(self, query_url, - headers={}, - query_parameters={}, - parameters={}, - files={}): - """Create a simple DELETE HttpRequest object for the given parameters - - Args: - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - parameters (dict, optional): Form or body parameters to be - included in the body. - files (dict, optional): Files to be sent with the request. - - Returns: - HttpRequest: The generated HttpRequest for the given paremeters. - - """ - return HttpRequest(HttpMethodEnum.DELETE, - query_url, - headers, - query_parameters, - parameters, - files) diff --git a/build/lib/bandwidth/http/http_method_enum.py b/build/lib/bandwidth/http/http_method_enum.py deleted file mode 100644 index 83cfbd59..00000000 --- a/build/lib/bandwidth/http/http_method_enum.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class HttpMethodEnum(object): - - """Enumeration of an HTTP Method - - Attributes: - GET: A GET Request - POST: A POST Request - PUT: A PUT Request - PATCH: A PATCH Request - DELETE: A DELETE Request - - """ - - GET = "GET" - - POST = "POST" - - PUT = "PUT" - - PATCH = "PATCH" - - DELETE = "DELETE" - - HEAD = "HEAD" - - @classmethod - def to_string(cls, val): - """Returns the string equivalent for the Enum. - - """ - for k, v in list(vars(cls).items()): - if v == val: - return k - - @classmethod - def from_string(cls, str): - """Creates an instance of the Enum from a given string. - - """ - return getattr(cls, str.upper(), None) diff --git a/build/lib/bandwidth/http/http_request.py b/build/lib/bandwidth/http/http_request.py deleted file mode 100644 index ac1e0e5a..00000000 --- a/build/lib/bandwidth/http/http_request.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper - - -class HttpRequest(object): - - """Information about an HTTP Request including its method, headers, - parameters, URL, and Basic Auth details - - Attributes: - http_method (HttpMethodEnum): The HTTP Method that this request should - perform when called. - headers (dict): A dictionary of headers (key : value) that should be - sent along with the request. - query_url (string): The URL that the request should be sent to. - parameters (dict): A dictionary of parameters that are to be sent along - with the request in the form body of the request - - """ - - def __init__(self, - http_method, - query_url, - headers=None, - query_parameters=None, - parameters=None, - files=None): - """Constructor for the HttpRequest class - - Args: - http_method (HttpMethodEnum): The HTTP Method. - query_url (string): The URL to send the request to. - headers (dict, optional): The headers for the HTTP Request. - query_parameters (dict, optional): Query parameters to add in the - URL. - parameters (dict, optional): Form or body parameters to be included - in the body. - files (dict, optional): Files to be sent with the request. - - """ - self.http_method = http_method - self.query_url = query_url - self.headers = headers - self.query_parameters = query_parameters - self.parameters = parameters - self.files = files - - def add_header(self, name, value): - """ Add a header to the HttpRequest. - - Args: - name (string): The name of the header. - value (string): The value of the header. - - """ - self.headers[name] = value - - def add_parameter(self, name, value): - """ Add a parameter to the HttpRequest. - - Args: - name (string): The name of the parameter. - value (string): The value of the parameter. - - """ - self.parameters[name] = value - - def add_query_parameter(self, name, value): - """ Add a query parameter to the HttpRequest. - - Args: - name (string): The name of the query parameter. - value (string): The value of the query parameter. - - """ - self.query_url = APIHelper.append_url_with_query_parameters( - self.query_url, - {name: value} - ) - self.query_url = APIHelper.clean_url(self.query_url) diff --git a/build/lib/bandwidth/http/http_response.py b/build/lib/bandwidth/http/http_response.py deleted file mode 100644 index 98c25bf0..00000000 --- a/build/lib/bandwidth/http/http_response.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class HttpResponse(object): - - """Information about an HTTP Response including its status code, returned - headers, and raw body - - Attributes: - status_code (int): The status code response from the server that - corresponds to this response. - reason_phrase (string): The reason phrase returned by the server. - headers (dict): A dictionary of headers (key : value) that were - returned with the response - text (string): The Raw body of the HTTP Response as a string - request (HttpRequest): The request that resulted in this response. - - """ - - def __init__(self, - status_code, - reason_phrase, - headers, - text, - request): - """Constructor for the HttpResponse class - - Args: - status_code (int): The response status code. - reason_phrase (string): The response reason phrase. - headers (dict): The response headers. - text (string): The raw body from the server. - request (HttpRequest): The request that resulted in this response. - - """ - self.status_code = status_code - self.reason_phrase = reason_phrase - self.headers = headers - self.text = text - self.request = request diff --git a/build/lib/bandwidth/http/requests_client.py b/build/lib/bandwidth/http/requests_client.py deleted file mode 100644 index 1983ecdd..00000000 --- a/build/lib/bandwidth/http/requests_client.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from cachecontrol import CacheControl -from requests import session -from requests.adapters import HTTPAdapter -from urllib3.util.retry import Retry - -from bandwidth.http.http_client import HttpClient -from bandwidth.http.http_method_enum import HttpMethodEnum -from bandwidth.http.http_response import HttpResponse - - -class RequestsClient(HttpClient): - - """An implementation of HttpClient that uses Requests as its HTTP Client - - Attributes: - timeout (int): The default timeout for all API requests. - - """ - - def __init__(self, - timeout=60, - cache=False, - max_retries=None, - backoff_factor=None, - verify=True): - """The constructor. - - Args: - timeout (float): The default global timeout(seconds). - - """ - self.timeout = timeout - self.session = session() - - retries = Retry(total=max_retries, backoff_factor=backoff_factor) - self.session.mount('http://', HTTPAdapter(max_retries=retries)) - self.session.mount('https://', HTTPAdapter(max_retries=retries)) - - if cache: - self.session = CacheControl(self.session) - - self.session.verify = verify - - def execute_as_string(self, request): - """Execute a given HttpRequest to get a string response back - - Args: - request (HttpRequest): The given HttpRequest to execute. - - Returns: - HttpResponse: The response of the HttpRequest. - - """ - response = self.session.request( - HttpMethodEnum.to_string(request.http_method), - request.query_url, - headers=request.headers, - params=request.query_parameters, - data=request.parameters, - files=request.files, - timeout=self.timeout - ) - - return self.convert_response(response, False, request) - - def execute_as_binary(self, request): - """Execute a given HttpRequest to get a binary response back - - Args: - request (HttpRequest): The given HttpRequest to execute. - - Returns: - HttpResponse: The response of the HttpRequest. - - """ - - response = self.session.request( - HttpMethodEnum.to_string(request.http_method), - request.query_url, - headers=request.headers, - params=request.query_parameters, - data=request.parameters, - files=request.files, - timeout=self.timeout - ) - - return self.convert_response(response, True, request) - - def convert_response(self, response, binary, http_request): - """Converts the Response object of the HttpClient into an - HttpResponse object. - - Args: - response (dynamic): The original response object. - http_request (HttpRequest): The original HttpRequest object. - - Returns: - HttpResponse: The converted HttpResponse object. - - """ - if binary: - return HttpResponse( - response.status_code, - response.reason, - response.headers, - response.content, - http_request - ) - else: - return HttpResponse( - response.status_code, - response.reason, - response.headers, - response.text, - http_request - ) diff --git a/build/lib/bandwidth/messaging/__init__.py b/build/lib/bandwidth/messaging/__init__.py deleted file mode 100644 index 1216246e..00000000 --- a/build/lib/bandwidth/messaging/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -__all__ = [ - 'controllers', - 'exceptions', - 'messaging_client', - 'models', -] diff --git a/build/lib/bandwidth/messaging/controllers/__init__.py b/build/lib/bandwidth/messaging/controllers/__init__.py deleted file mode 100644 index c1660224..00000000 --- a/build/lib/bandwidth/messaging/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'base_controller', - 'api_controller', -] diff --git a/build/lib/bandwidth/messaging/controllers/api_controller.py b/build/lib/bandwidth/messaging/controllers/api_controller.py deleted file mode 100644 index 28ec5dee..00000000 --- a/build/lib/bandwidth/messaging/controllers/api_controller.py +++ /dev/null @@ -1,345 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.configuration import Server -from bandwidth.http.api_response import ApiResponse -from bandwidth.utilities.file_wrapper import FileWrapper -from bandwidth.messaging.controllers.base_controller import BaseController -from bandwidth.http.auth.messaging_basic_auth import MessagingBasicAuth -from bandwidth.messaging.models.media import Media -from bandwidth.messaging.models.bandwidth_message import BandwidthMessage -from bandwidth.messaging.exceptions.messaging_exception import MessagingException - - -class APIController(BaseController): - - """A Controller to access Endpoints in the bandwidth API.""" - - def __init__(self, config, call_back=None): - super(APIController, self).__init__(config, call_back) - - def list_media(self, - user_id, - continuation_token=None): - """Does a GET request to /users/{userId}/media. - - listMedia - - Args: - user_id (string): TODO: type description here. - continuation_token (string, optional): TODO: type description - here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/users/{userId}/media' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'userId': {'value': user_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'Continuation-Token': continuation_token - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - MessagingBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise MessagingException('400 Request is malformed or invalid', _response) - elif _response.status_code == 401: - raise MessagingException('401 The specified user does not have access to the account', _response) - elif _response.status_code == 403: - raise MessagingException('403 The user does not have access to this API', _response) - elif _response.status_code == 404: - raise MessagingException('404 Path not found', _response) - elif _response.status_code == 415: - raise MessagingException('415 The content-type of the request is incorrect', _response) - elif _response.status_code == 429: - raise MessagingException('429 The rate limit has been reached', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Media.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_media(self, - user_id, - media_id): - """Does a GET request to /users/{userId}/media/{mediaId}. - - getMedia - - Args: - user_id (string): TODO: type description here. - media_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/users/{userId}/media/{mediaId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'userId': {'value': user_id, 'encode': True}, - 'mediaId': {'value': media_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.get(_query_url) - MessagingBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request, binary=True) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise MessagingException('400 Request is malformed or invalid', _response) - elif _response.status_code == 401: - raise MessagingException('401 The specified user does not have access to the account', _response) - elif _response.status_code == 403: - raise MessagingException('403 The user does not have access to this API', _response) - elif _response.status_code == 404: - raise MessagingException('404 Path not found', _response) - elif _response.status_code == 415: - raise MessagingException('415 The content-type of the request is incorrect', _response) - elif _response.status_code == 429: - raise MessagingException('429 The rate limit has been reached', _response) - self.validate_response(_response) - - decoded = _response.text - _result = ApiResponse(_response, body=decoded) - return _result - - def upload_media(self, - user_id, - media_id, - content_length, - body, - content_type='application/octet-stream', - cache_control=None): - """Does a PUT request to /users/{userId}/media/{mediaId}. - - uploadMedia - - Args: - user_id (string): TODO: type description here. - media_id (string): TODO: type description here. - content_length (long|int): TODO: type description here. - body (typing.BinaryIO): TODO: type description here. - content_type (string, optional): TODO: type description here. - Example: application/octet-stream - cache_control (string, optional): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/users/{userId}/media/{mediaId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'userId': {'value': user_id, 'encode': True}, - 'mediaId': {'value': media_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - if isinstance(body, FileWrapper): - body_wrapper = body.file_stream - body_content_type = body.content_type - else: - body_wrapper = body - body_content_type = content_type - - # Prepare headers - _headers = { - 'content-type': body_content_type, - 'Content-Length': content_length, - 'Cache-Control': cache_control - } - - # Prepare and execute request - _request = self.config.http_client.put(_query_url, headers=_headers, parameters=body_wrapper) - MessagingBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise MessagingException('400 Request is malformed or invalid', _response) - elif _response.status_code == 401: - raise MessagingException('401 The specified user does not have access to the account', _response) - elif _response.status_code == 403: - raise MessagingException('403 The user does not have access to this API', _response) - elif _response.status_code == 404: - raise MessagingException('404 Path not found', _response) - elif _response.status_code == 415: - raise MessagingException('415 The content-type of the request is incorrect', _response) - elif _response.status_code == 429: - raise MessagingException('429 The rate limit has been reached', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def delete_media(self, - user_id, - media_id): - """Does a DELETE request to /users/{userId}/media/{mediaId}. - - deleteMedia - - Args: - user_id (string): TODO: type description here. - media_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/users/{userId}/media/{mediaId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'userId': {'value': user_id, 'encode': True}, - 'mediaId': {'value': media_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - MessagingBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise MessagingException('400 Request is malformed or invalid', _response) - elif _response.status_code == 401: - raise MessagingException('401 The specified user does not have access to the account', _response) - elif _response.status_code == 403: - raise MessagingException('403 The user does not have access to this API', _response) - elif _response.status_code == 404: - raise MessagingException('404 Path not found', _response) - elif _response.status_code == 415: - raise MessagingException('415 The content-type of the request is incorrect', _response) - elif _response.status_code == 429: - raise MessagingException('429 The rate limit has been reached', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def create_message(self, - user_id, - body=None): - """Does a POST request to /users/{userId}/messages. - - createMessage - - Args: - user_id (string): TODO: type description here. - body (MessageRequest, optional): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/users/{userId}/messages' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'userId': {'value': user_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - MessagingBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise MessagingException('400 Request is malformed or invalid', _response) - elif _response.status_code == 401: - raise MessagingException('401 The specified user does not have access to the account', _response) - elif _response.status_code == 403: - raise MessagingException('403 The user does not have access to this API', _response) - elif _response.status_code == 404: - raise MessagingException('404 Path not found', _response) - elif _response.status_code == 415: - raise MessagingException('415 The content-type of the request is incorrect', _response) - elif _response.status_code == 429: - raise MessagingException('429 The rate limit has been reached', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, BandwidthMessage.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result diff --git a/build/lib/bandwidth/messaging/controllers/base_controller.py b/build/lib/bandwidth/messaging/controllers/base_controller.py deleted file mode 100644 index 3f7583fb..00000000 --- a/build/lib/bandwidth/messaging/controllers/base_controller.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.exceptions.api_exception import APIException - - -class BaseController(object): - - """All controllers inherit from this base class. - - Attributes: - config (Configuration): The HttpClient which a specific controller - instance will use. By default all the controller objects share - the same HttpClient. A user can use his own custom HttpClient - as well. - http_call_back (HttpCallBack): An object which holds call back - methods to be called before and after the execution of an HttpRequest. - global_headers (dict): The global headers of the API which are sent with - every request. - - """ - - def global_headers(self): - return { - 'user-agent': 'python-sdk-refs/tags/python6.13.2' - } - - def __init__(self, config, call_back=None): - self._config = config - self._http_call_back = call_back - - @property - def config(self): - return self._config - - @property - def http_call_back(self): - return self._http_call_back - - def validate_parameters(self, **kwargs): - """Validates required parameters of an endpoint. - - Args: - kwargs (dict): A dictionary of the required parameters. - - """ - for name, value in kwargs.items(): - if value is None: - raise ValueError("Required parameter {} cannot be None.".format(name)) - - def execute_request(self, request, binary=False): - """Executes an HttpRequest. - - Args: - request (HttpRequest): The HttpRequest to execute. - binary (bool): A flag which should be set to True if - a binary response is expected. - - Returns: - HttpResponse: The HttpResponse received. - - """ - # Invoke the on before request HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_before_request(request) - - # Add global headers to request - request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers) - - # Invoke the API call to fetch the response. - func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string - response = func(request) - - # Invoke the on after response HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_after_response(response) - - return response - - def validate_response(self, response): - """Validates an HTTP response by checking for global errors. - - Args: - response (HttpResponse): The HttpResponse of the API call. - - """ - if (response.status_code < 200) or (response.status_code > 208): # [200,208] = HTTP OK - raise APIException('HTTP response not OK.', response) diff --git a/build/lib/bandwidth/messaging/exceptions/__init__.py b/build/lib/bandwidth/messaging/exceptions/__init__.py deleted file mode 100644 index 8d2920ac..00000000 --- a/build/lib/bandwidth/messaging/exceptions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'messaging_exception', -] diff --git a/build/lib/bandwidth/messaging/exceptions/messaging_exception.py b/build/lib/bandwidth/messaging/exceptions/messaging_exception.py deleted file mode 100644 index 283ebde2..00000000 --- a/build/lib/bandwidth/messaging/exceptions/messaging_exception.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -import bandwidth.exceptions.api_exception - - -class MessagingException(bandwidth.exceptions.api_exception.APIException): - def __init__(self, reason, response): - """Constructor for the MessagingException class - - Args: - reason (string): The reason (or error message) for the Exception - to be raised. - response (HttpResponse): The HttpResponse of the API call. - - """ - super(MessagingException, self).__init__(reason, response) - dictionary = APIHelper.json_deserialize(self.response.text) - if isinstance(dictionary, dict): - self.unbox(dictionary) - - def unbox(self, dictionary): - """Populates the properties of this object by extracting them from a dictionary. - - Args: - dictionary (dictionary): A dictionary representation of the object as - obtained from the deserialization of the server's response. The keys - MUST match property names in the API description. - - """ - self.mtype = dictionary.get('type') - self.description = dictionary.get('description') diff --git a/build/lib/bandwidth/messaging/messaging_client.py b/build/lib/bandwidth/messaging/messaging_client.py deleted file mode 100644 index 86b29def..00000000 --- a/build/lib/bandwidth/messaging/messaging_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.decorators import lazy_property -from bandwidth.configuration import Configuration -from bandwidth.configuration import Environment -from bandwidth.messaging.controllers.api_controller import APIController - - -class MessagingClient(object): - - @lazy_property - def client(self): - return APIController(self.config) - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace', config=None): - if config is None: - self.config = Configuration(timeout=timeout, - max_retries=max_retries, - backoff_factor=backoff_factor, - environment=environment, - base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password) - else: - self.config = config diff --git a/build/lib/bandwidth/messaging/models/__init__.py b/build/lib/bandwidth/messaging/models/__init__.py deleted file mode 100644 index 46d2bfc0..00000000 --- a/build/lib/bandwidth/messaging/models/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -__all__ = [ - 'media', - 'tag', - 'deferred_result', - 'bandwidth_callback_message', - 'bandwidth_message', - 'message_request', -] diff --git a/build/lib/bandwidth/messaging/models/bandwidth_callback_message.py b/build/lib/bandwidth/messaging/models/bandwidth_callback_message.py deleted file mode 100644 index 6ce2d18d..00000000 --- a/build/lib/bandwidth/messaging/models/bandwidth_callback_message.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.messaging.models.bandwidth_message import BandwidthMessage - - -class BandwidthCallbackMessage(object): - - """Implementation of the 'BandwidthCallbackMessage' model. - - TODO: type model description here. - - Attributes: - time (string): TODO: type description here. - mtype (string): TODO: type description here. - to (string): TODO: type description here. - error_code (string): TODO: type description here. - description (string): TODO: type description here. - message (BandwidthMessage): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "time": 'time', - "mtype": 'type', - "to": 'to', - "error_code": 'errorCode', - "description": 'description', - "message": 'message' - } - - def __init__(self, - time=None, - mtype=None, - to=None, - error_code=None, - description=None, - message=None): - """Constructor for the BandwidthCallbackMessage class""" - - # Initialize members of the class - self.time = time - self.mtype = mtype - self.to = to - self.error_code = error_code - self.description = description - self.message = message - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - time = dictionary.get('time') - mtype = dictionary.get('type') - to = dictionary.get('to') - error_code = dictionary.get('errorCode') - description = dictionary.get('description') - message = BandwidthMessage.from_dictionary(dictionary.get('message')) if dictionary.get('message') else None - - # Return an object of this model - return cls(time, - mtype, - to, - error_code, - description, - message) diff --git a/build/lib/bandwidth/messaging/models/bandwidth_message.py b/build/lib/bandwidth/messaging/models/bandwidth_message.py deleted file mode 100644 index 58098c98..00000000 --- a/build/lib/bandwidth/messaging/models/bandwidth_message.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class BandwidthMessage(object): - - """Implementation of the 'BandwidthMessage' model. - - TODO: type model description here. - - Attributes: - id (string): TODO: type description here. - owner (string): TODO: type description here. - application_id (string): TODO: type description here. - time (string): TODO: type description here. - segment_count (int): TODO: type description here. - direction (string): TODO: type description here. - to (list of string): TODO: type description here. - mfrom (string): TODO: type description here. - media (list of string): TODO: type description here. - text (string): TODO: type description here. - tag (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "id": 'id', - "owner": 'owner', - "application_id": 'applicationId', - "time": 'time', - "segment_count": 'segmentCount', - "direction": 'direction', - "to": 'to', - "mfrom": 'from', - "media": 'media', - "text": 'text', - "tag": 'tag' - } - - def __init__(self, - id=None, - owner=None, - application_id=None, - time=None, - segment_count=None, - direction=None, - to=None, - mfrom=None, - media=None, - text=None, - tag=None): - """Constructor for the BandwidthMessage class""" - - # Initialize members of the class - self.id = id - self.owner = owner - self.application_id = application_id - self.time = time - self.segment_count = segment_count - self.direction = direction - self.to = to - self.mfrom = mfrom - self.media = media - self.text = text - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - id = dictionary.get('id') - owner = dictionary.get('owner') - application_id = dictionary.get('applicationId') - time = dictionary.get('time') - segment_count = dictionary.get('segmentCount') - direction = dictionary.get('direction') - to = dictionary.get('to') - mfrom = dictionary.get('from') - media = dictionary.get('media') - text = dictionary.get('text') - tag = dictionary.get('tag') - - # Return an object of this model - return cls(id, - owner, - application_id, - time, - segment_count, - direction, - to, - mfrom, - media, - text, - tag) diff --git a/build/lib/bandwidth/messaging/models/deferred_result.py b/build/lib/bandwidth/messaging/models/deferred_result.py deleted file mode 100644 index da85ac48..00000000 --- a/build/lib/bandwidth/messaging/models/deferred_result.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class DeferredResult(object): - - """Implementation of the 'DeferredResult' model. - - TODO: type model description here. - - Attributes: - result (object): TODO: type description here. - set_or_expired (bool): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "result": 'result', - "set_or_expired": 'setOrExpired' - } - - def __init__(self, - result=None, - set_or_expired=None): - """Constructor for the DeferredResult class""" - - # Initialize members of the class - self.result = result - self.set_or_expired = set_or_expired - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - result = dictionary.get('result') - set_or_expired = dictionary.get('setOrExpired') - - # Return an object of this model - return cls(result, - set_or_expired) diff --git a/build/lib/bandwidth/messaging/models/media.py b/build/lib/bandwidth/messaging/models/media.py deleted file mode 100644 index 33f6f6c9..00000000 --- a/build/lib/bandwidth/messaging/models/media.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.messaging.models.tag import Tag - - -class Media(object): - - """Implementation of the 'Media' model. - - TODO: type model description here. - - Attributes: - input_stream (object): TODO: type description here. - content (string): TODO: type description here. - url (string): TODO: type description here. - content_length (string): TODO: type description here. - content_type (string): TODO: type description here. - tags (list of Tag): TODO: type description here. - user_id (string): TODO: type description here. - media_name (string): TODO: type description here. - media_id (string): TODO: type description here. - cache_control (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "input_stream": 'inputStream', - "content": 'content', - "url": 'url', - "content_length": 'contentLength', - "content_type": 'contentType', - "tags": 'tags', - "user_id": 'userId', - "media_name": 'mediaName', - "media_id": 'mediaId', - "cache_control": 'cacheControl' - } - - def __init__(self, - input_stream=None, - content=None, - url=None, - content_length=None, - content_type=None, - tags=None, - user_id=None, - media_name=None, - media_id=None, - cache_control=None): - """Constructor for the Media class""" - - # Initialize members of the class - self.input_stream = input_stream - self.content = content - self.url = url - self.content_length = content_length - self.content_type = content_type - self.tags = tags - self.user_id = user_id - self.media_name = media_name - self.media_id = media_id - self.cache_control = cache_control - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - input_stream = dictionary.get('inputStream') - content = dictionary.get('content') - url = dictionary.get('url') - content_length = dictionary.get('contentLength') - content_type = dictionary.get('contentType') - tags = None - if dictionary.get('tags') is not None: - tags = [Tag.from_dictionary(x) for x in dictionary.get('tags')] - user_id = dictionary.get('userId') - media_name = dictionary.get('mediaName') - media_id = dictionary.get('mediaId') - cache_control = dictionary.get('cacheControl') - - # Return an object of this model - return cls(input_stream, - content, - url, - content_length, - content_type, - tags, - user_id, - media_name, - media_id, - cache_control) diff --git a/build/lib/bandwidth/messaging/models/message_request.py b/build/lib/bandwidth/messaging/models/message_request.py deleted file mode 100644 index 2af96789..00000000 --- a/build/lib/bandwidth/messaging/models/message_request.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class MessageRequest(object): - - """Implementation of the 'MessageRequest' model. - - TODO: type model description here. - - Attributes: - application_id (string): TODO: type description here. - to (list of string): TODO: type description here. - mfrom (string): TODO: type description here. - text (string): TODO: type description here. - media (list of string): TODO: type description here. - tag (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "application_id": 'applicationId', - "to": 'to', - "mfrom": 'from', - "text": 'text', - "media": 'media', - "tag": 'tag' - } - - def __init__(self, - application_id=None, - to=None, - mfrom=None, - text=None, - media=None, - tag=None): - """Constructor for the MessageRequest class""" - - # Initialize members of the class - self.application_id = application_id - self.to = to - self.mfrom = mfrom - self.text = text - self.media = media - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - application_id = dictionary.get('applicationId') - to = dictionary.get('to') - mfrom = dictionary.get('from') - text = dictionary.get('text') - media = dictionary.get('media') - tag = dictionary.get('tag') - - # Return an object of this model - return cls(application_id, - to, - mfrom, - text, - media, - tag) diff --git a/build/lib/bandwidth/messaging/models/tag.py b/build/lib/bandwidth/messaging/models/tag.py deleted file mode 100644 index 43236b04..00000000 --- a/build/lib/bandwidth/messaging/models/tag.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Tag(object): - - """Implementation of the 'Tag' model. - - TODO: type model description here. - - Attributes: - key (string): TODO: type description here. - value (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "key": 'key', - "value": 'value' - } - - def __init__(self, - key=None, - value=None): - """Constructor for the Tag class""" - - # Initialize members of the class - self.key = key - self.value = value - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - key = dictionary.get('key') - value = dictionary.get('value') - - # Return an object of this model - return cls(key, - value) diff --git a/build/lib/bandwidth/models/__init__.py b/build/lib/bandwidth/models/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/build/lib/bandwidth/twofactorauth/__init__.py b/build/lib/bandwidth/twofactorauth/__init__.py deleted file mode 100644 index dbf8f2d9..00000000 --- a/build/lib/bandwidth/twofactorauth/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -__all__ = [ - 'controllers', - 'exceptions', - 'models', - 'two_factor_auth_client', -] diff --git a/build/lib/bandwidth/twofactorauth/controllers/__init__.py b/build/lib/bandwidth/twofactorauth/controllers/__init__.py deleted file mode 100644 index c1660224..00000000 --- a/build/lib/bandwidth/twofactorauth/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'base_controller', - 'api_controller', -] diff --git a/build/lib/bandwidth/twofactorauth/controllers/api_controller.py b/build/lib/bandwidth/twofactorauth/controllers/api_controller.py deleted file mode 100644 index 436d2458..00000000 --- a/build/lib/bandwidth/twofactorauth/controllers/api_controller.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.configuration import Server -from bandwidth.http.api_response import ApiResponse -from bandwidth.twofactorauth.controllers.base_controller import BaseController -from bandwidth.http.auth.two_factor_auth_basic_auth import TwoFactorAuthBasicAuth -from bandwidth.twofactorauth.models.two_factor_voice_response import TwoFactorVoiceResponse -from bandwidth.twofactorauth.models.two_factor_messaging_response import TwoFactorMessagingResponse -from bandwidth.twofactorauth.models.two_factor_verify_code_response import TwoFactorVerifyCodeResponse -from bandwidth.twofactorauth.exceptions.invalid_request_exception import InvalidRequestException - - -class APIController(BaseController): - - """A Controller to access Endpoints in the bandwidth API.""" - - def __init__(self, config, call_back=None): - super(APIController, self).__init__(config, call_back) - - def create_voice_two_factor(self, - account_id, - body): - """Does a POST request to /accounts/{accountId}/code/voice. - - Two-Factor authentication with Bandwidth Voice services - - Args: - account_id (string): Bandwidth Account ID with Voice service - enabled - body (TwoFactorCodeRequestSchema): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/code/voice' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.TWOFACTORAUTHDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - TwoFactorAuthBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise InvalidRequestException('client request error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, TwoFactorVoiceResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def create_messaging_two_factor(self, - account_id, - body): - """Does a POST request to /accounts/{accountId}/code/messaging. - - Two-Factor authentication with Bandwidth messaging services - - Args: - account_id (string): Bandwidth Account ID with Messaging service - enabled - body (TwoFactorCodeRequestSchema): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/code/messaging' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.TWOFACTORAUTHDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - TwoFactorAuthBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise InvalidRequestException('client request error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, TwoFactorMessagingResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def create_verify_two_factor(self, - account_id, - body): - """Does a POST request to /accounts/{accountId}/code/verify. - - Verify a previously sent two-factor authentication code - - Args: - account_id (string): Bandwidth Account ID with Two-Factor enabled - body (TwoFactorVerifyRequestSchema): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/code/verify' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.TWOFACTORAUTHDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - TwoFactorAuthBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise InvalidRequestException('client request error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, TwoFactorVerifyCodeResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result diff --git a/build/lib/bandwidth/twofactorauth/controllers/base_controller.py b/build/lib/bandwidth/twofactorauth/controllers/base_controller.py deleted file mode 100644 index 3f7583fb..00000000 --- a/build/lib/bandwidth/twofactorauth/controllers/base_controller.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.exceptions.api_exception import APIException - - -class BaseController(object): - - """All controllers inherit from this base class. - - Attributes: - config (Configuration): The HttpClient which a specific controller - instance will use. By default all the controller objects share - the same HttpClient. A user can use his own custom HttpClient - as well. - http_call_back (HttpCallBack): An object which holds call back - methods to be called before and after the execution of an HttpRequest. - global_headers (dict): The global headers of the API which are sent with - every request. - - """ - - def global_headers(self): - return { - 'user-agent': 'python-sdk-refs/tags/python6.13.2' - } - - def __init__(self, config, call_back=None): - self._config = config - self._http_call_back = call_back - - @property - def config(self): - return self._config - - @property - def http_call_back(self): - return self._http_call_back - - def validate_parameters(self, **kwargs): - """Validates required parameters of an endpoint. - - Args: - kwargs (dict): A dictionary of the required parameters. - - """ - for name, value in kwargs.items(): - if value is None: - raise ValueError("Required parameter {} cannot be None.".format(name)) - - def execute_request(self, request, binary=False): - """Executes an HttpRequest. - - Args: - request (HttpRequest): The HttpRequest to execute. - binary (bool): A flag which should be set to True if - a binary response is expected. - - Returns: - HttpResponse: The HttpResponse received. - - """ - # Invoke the on before request HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_before_request(request) - - # Add global headers to request - request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers) - - # Invoke the API call to fetch the response. - func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string - response = func(request) - - # Invoke the on after response HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_after_response(response) - - return response - - def validate_response(self, response): - """Validates an HTTP response by checking for global errors. - - Args: - response (HttpResponse): The HttpResponse of the API call. - - """ - if (response.status_code < 200) or (response.status_code > 208): # [200,208] = HTTP OK - raise APIException('HTTP response not OK.', response) diff --git a/build/lib/bandwidth/twofactorauth/exceptions/__init__.py b/build/lib/bandwidth/twofactorauth/exceptions/__init__.py deleted file mode 100644 index 62a035cd..00000000 --- a/build/lib/bandwidth/twofactorauth/exceptions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'invalid_request_exception', -] diff --git a/build/lib/bandwidth/twofactorauth/exceptions/invalid_request_exception.py b/build/lib/bandwidth/twofactorauth/exceptions/invalid_request_exception.py deleted file mode 100644 index 9c91cb66..00000000 --- a/build/lib/bandwidth/twofactorauth/exceptions/invalid_request_exception.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -import bandwidth.exceptions.api_exception - - -class InvalidRequestException(bandwidth.exceptions.api_exception.APIException): - def __init__(self, reason, response): - """Constructor for the InvalidRequestException class - - Args: - reason (string): The reason (or error message) for the Exception - to be raised. - response (HttpResponse): The HttpResponse of the API call. - - """ - super(InvalidRequestException, self).__init__(reason, response) - dictionary = APIHelper.json_deserialize(self.response.text) - if isinstance(dictionary, dict): - self.unbox(dictionary) - - def unbox(self, dictionary): - """Populates the properties of this object by extracting them from a dictionary. - - Args: - dictionary (dictionary): A dictionary representation of the object as - obtained from the deserialization of the server's response. The keys - MUST match property names in the API description. - - """ - self.result = dictionary.get('result') diff --git a/build/lib/bandwidth/twofactorauth/models/__init__.py b/build/lib/bandwidth/twofactorauth/models/__init__.py deleted file mode 100644 index a22a5a11..00000000 --- a/build/lib/bandwidth/twofactorauth/models/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -__all__ = [ - 'two_factor_code_request_schema', - 'two_factor_voice_response', - 'two_factor_messaging_response', - 'two_factor_verify_request_schema', - 'two_factor_verify_code_response', -] diff --git a/build/lib/bandwidth/twofactorauth/models/two_factor_code_request_schema.py b/build/lib/bandwidth/twofactorauth/models/two_factor_code_request_schema.py deleted file mode 100644 index ba0b3a28..00000000 --- a/build/lib/bandwidth/twofactorauth/models/two_factor_code_request_schema.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class TwoFactorCodeRequestSchema(object): - - """Implementation of the 'TwoFactorCodeRequestSchema' model. - - TODO: type model description here. - - Attributes: - to (string): The phone number to send the 2fa code to. - mfrom (string): The application phone number, the sender of the 2fa - code. - application_id (string): The application unique ID, obtained from - Bandwidth. - scope (string): An optional field to denote what scope or action the - 2fa code is addressing. If not supplied, defaults to "2FA". - message (string): The message format of the 2fa code. There are three - values that the system will replace "{CODE}", "{NAME}", "{SCOPE}". - The "{SCOPE}" and "{NAME} value template are optional, while - "{CODE}" must be supplied. As the name would suggest, code will - be replace with the actual 2fa code. Name is replaced with the - application name, configured during provisioning of 2fa. The - scope value is the same value sent during the call and partitioned - by the server. - digits (float): The number of digits for your 2fa code. The valid - number ranges from 2 to 8, inclusively. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "to": 'to', - "mfrom": 'from', - "application_id": 'applicationId', - "message": 'message', - "digits": 'digits', - "scope": 'scope' - } - - def __init__(self, - to=None, - mfrom=None, - application_id=None, - message=None, - digits=None, - scope=None): - """Constructor for the TwoFactorCodeRequestSchema class""" - - # Initialize members of the class - self.to = to - self.mfrom = mfrom - self.application_id = application_id - self.scope = scope - self.message = message - self.digits = digits - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - to = dictionary.get('to') - mfrom = dictionary.get('from') - application_id = dictionary.get('applicationId') - message = dictionary.get('message') - digits = dictionary.get('digits') - scope = dictionary.get('scope') - - # Return an object of this model - return cls(to, - mfrom, - application_id, - message, - digits, - scope) diff --git a/build/lib/bandwidth/twofactorauth/models/two_factor_messaging_response.py b/build/lib/bandwidth/twofactorauth/models/two_factor_messaging_response.py deleted file mode 100644 index 6bd78ee4..00000000 --- a/build/lib/bandwidth/twofactorauth/models/two_factor_messaging_response.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class TwoFactorMessagingResponse(object): - - """Implementation of the 'TwoFactorMessagingResponse' model. - - TODO: type model description here. - - Attributes: - message_id (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "message_id": 'messageId' - } - - def __init__(self, - message_id=None): - """Constructor for the TwoFactorMessagingResponse class""" - - # Initialize members of the class - self.message_id = message_id - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - message_id = dictionary.get('messageId') - - # Return an object of this model - return cls(message_id) diff --git a/build/lib/bandwidth/twofactorauth/models/two_factor_verify_code_response.py b/build/lib/bandwidth/twofactorauth/models/two_factor_verify_code_response.py deleted file mode 100644 index 5ee46a6d..00000000 --- a/build/lib/bandwidth/twofactorauth/models/two_factor_verify_code_response.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class TwoFactorVerifyCodeResponse(object): - - """Implementation of the 'TwoFactorVerifyCodeResponse' model. - - TODO: type model description here. - - Attributes: - valid (bool): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "valid": 'valid' - } - - def __init__(self, - valid=None): - """Constructor for the TwoFactorVerifyCodeResponse class""" - - # Initialize members of the class - self.valid = valid - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - valid = dictionary.get('valid') - - # Return an object of this model - return cls(valid) diff --git a/build/lib/bandwidth/twofactorauth/models/two_factor_verify_request_schema.py b/build/lib/bandwidth/twofactorauth/models/two_factor_verify_request_schema.py deleted file mode 100644 index eb147906..00000000 --- a/build/lib/bandwidth/twofactorauth/models/two_factor_verify_request_schema.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class TwoFactorVerifyRequestSchema(object): - - """Implementation of the 'TwoFactorVerifyRequestSchema' model. - - TODO: type model description here. - - Attributes: - to (string): The phone number to send the 2fa code to. - mfrom (string): The application phone number, the sender of the 2fa - code. - application_id (string): The application unique ID, obtained from - Bandwidth. - scope (string): An optional field to denote what scope or action the - 2fa code is addressing. If not supplied, defaults to "2FA". - digits (float): The number of digits for your 2fa code. The valid - number ranges from 2 to 8, inclusively. - expiration_time_in_minutes (float): The time period, in minutes, to - validate the 2fa code. By setting this to 3 minutes, it will mean - any code generated within the last 3 minutes are still valid. The - valid range for expiration time is between 0 and 15 minutes, - exclusively and inclusively, respectively. - code (string): The generated 2fa code to check if valid - - """ - - # Create a mapping from Model property names to API property names - _names = { - "to": 'to', - "mfrom": 'from', - "application_id": 'applicationId', - "digits": 'digits', - "expiration_time_in_minutes": 'expirationTimeInMinutes', - "code": 'code', - "scope": 'scope' - } - - def __init__(self, - to=None, - mfrom=None, - application_id=None, - digits=None, - expiration_time_in_minutes=None, - code=None, - scope=None): - """Constructor for the TwoFactorVerifyRequestSchema class""" - - # Initialize members of the class - self.to = to - self.mfrom = mfrom - self.application_id = application_id - self.scope = scope - self.digits = digits - self.expiration_time_in_minutes = expiration_time_in_minutes - self.code = code - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - to = dictionary.get('to') - mfrom = dictionary.get('from') - application_id = dictionary.get('applicationId') - digits = dictionary.get('digits') - expiration_time_in_minutes = dictionary.get('expirationTimeInMinutes') - code = dictionary.get('code') - scope = dictionary.get('scope') - - # Return an object of this model - return cls(to, - mfrom, - application_id, - digits, - expiration_time_in_minutes, - code, - scope) diff --git a/build/lib/bandwidth/twofactorauth/models/two_factor_voice_response.py b/build/lib/bandwidth/twofactorauth/models/two_factor_voice_response.py deleted file mode 100644 index 0734c4b7..00000000 --- a/build/lib/bandwidth/twofactorauth/models/two_factor_voice_response.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class TwoFactorVoiceResponse(object): - - """Implementation of the 'TwoFactorVoiceResponse' model. - - TODO: type model description here. - - Attributes: - call_id (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "call_id": 'callId' - } - - def __init__(self, - call_id=None): - """Constructor for the TwoFactorVoiceResponse class""" - - # Initialize members of the class - self.call_id = call_id - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - call_id = dictionary.get('callId') - - # Return an object of this model - return cls(call_id) diff --git a/build/lib/bandwidth/twofactorauth/two_factor_auth_client.py b/build/lib/bandwidth/twofactorauth/two_factor_auth_client.py deleted file mode 100644 index 8da2ce1d..00000000 --- a/build/lib/bandwidth/twofactorauth/two_factor_auth_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.decorators import lazy_property -from bandwidth.configuration import Configuration -from bandwidth.configuration import Environment -from bandwidth.twofactorauth.controllers.api_controller import APIController - - -class TwoFactorAuthClient(object): - - @lazy_property - def client(self): - return APIController(self.config) - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace', config=None): - if config is None: - self.config = Configuration(timeout=timeout, - max_retries=max_retries, - backoff_factor=backoff_factor, - environment=environment, - base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password) - else: - self.config = config diff --git a/build/lib/bandwidth/utilities/__init__.py b/build/lib/bandwidth/utilities/__init__.py deleted file mode 100644 index 6ade54ba..00000000 --- a/build/lib/bandwidth/utilities/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'file_wrapper.py', -] diff --git a/build/lib/bandwidth/utilities/file_wrapper.py b/build/lib/bandwidth/utilities/file_wrapper.py deleted file mode 100644 index 274b196e..00000000 --- a/build/lib/bandwidth/utilities/file_wrapper.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class FileWrapper(): - - """A wrapper to allow passing in content type for file uploads.""" - - def __init__(self, file, content_type='application/octet-stream'): - self._file_stream = file - self._content_type = content_type - - @property - def file_stream(self): - return self._file_stream - - @property - def content_type(self): - return self._content_type diff --git a/build/lib/bandwidth/voice/__init__.py b/build/lib/bandwidth/voice/__init__.py deleted file mode 100644 index 358ad66e..00000000 --- a/build/lib/bandwidth/voice/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -__all__ = [ - 'bxml', - 'controllers', - 'exceptions', - 'models', - 'voice_client', -] diff --git a/build/lib/bandwidth/voice/bxml/__init__.py b/build/lib/bandwidth/voice/bxml/__init__.py deleted file mode 100644 index 27199698..00000000 --- a/build/lib/bandwidth/voice/bxml/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import response -from . import verbs diff --git a/build/lib/bandwidth/voice/bxml/response.py b/build/lib/bandwidth/voice/bxml/response.py deleted file mode 100644 index b3280225..00000000 --- a/build/lib/bandwidth/voice/bxml/response.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -response.py - -Class that allows user to generate BXML programatically in python - -@copyright Bandwidth INC -""" - -RESPONSE_TAG = "Response" -XML_HEADER = '' - - -class Response: - - def __init__(self): - """ - Creates the Response class - """ - self.verbs = [] - - def add_verb(self, verb): - """ - Adds the Verb to the already existing verbs - - :param Verb verb: The Verb to add - """ - self.verbs.append(verb) - - def to_bxml(self): - """ - Converts the Response class to its XML representation - - :rtype str: The XML representation of the Response class - """ - xml_string = XML_HEADER - xml_string += '<' + RESPONSE_TAG + '>' - for verb in self.verbs: - xml_string += verb.to_bxml() - xml_string += '' - - return xml_string diff --git a/build/lib/bandwidth/voice/bxml/verbs/__init__.py b/build/lib/bandwidth/voice/bxml/verbs/__init__.py deleted file mode 100644 index 05b5c3e2..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -from .hangup import Hangup -from .send_dtmf import SendDtmf -from .gather import Gather -from .pause import Pause -from .phone_number import PhoneNumber -from .redirect import Redirect -from .speak_sentence import SpeakSentence -from .transfer import Transfer -from .play_audio import PlayAudio -from .forward import Forward -from .record import Record -from .pause_recording import PauseRecording -from .resume_recording import ResumeRecording -from .stop_recording import StopRecording -from .start_recording import StartRecording -from .conference import Conference -from .bridge import Bridge -from .ring import Ring -from .stop_gather import StopGather -from .start_gather import StartGather diff --git a/build/lib/bandwidth/voice/bxml/verbs/base_verb.py b/build/lib/bandwidth/voice/bxml/verbs/base_verb.py deleted file mode 100644 index 37879636..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/base_verb.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -base_verb.py - -Defines the abstract class for all BXML verbs - -@copyright Bandwidth INC -""" - -from abc import ABC, abstractmethod - - -class AbstractBxmlVerb(ABC): - - @abstractmethod - def to_bxml(self): - """ - Converts the class into its xml representation - - :return str: The string xml representation - """ - pass diff --git a/build/lib/bandwidth/voice/bxml/verbs/bridge.py b/build/lib/bandwidth/voice/bxml/verbs/bridge.py deleted file mode 100644 index c65bbbbb..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/bridge.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -bridge.py - -Representation of Bandwidth's speak sentence BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -import re - -BRIDGE_TAG = "Bridge" - -class Bridge(AbstractBxmlVerb): - - def __init__(self, call_id, bridge_complete_url=None, bridge_complete_method=None, - bridge_target_complete_url=None, bridge_target_complete_method=None, - username=None, password=None, tag=None, bridge_complete_fallback_url=None, - bridge_complete_fallback_method=None, bridge_target_complete_fallback_url=None, - bridge_target_complete_fallback_method=None, fallback_username=None, - fallback_password=None): - """ - Initializes the Bridge class with the following parameters - - :param str call_id: The call to bridge - :param str bridge_complete_url: URL to send the bridge complete event to - :param str bridge_complete_method: HTTP method to send the bridge complete event - :param str bridge_target_complete_url: URL to send the bridge target complete event to - :param str bridge_target_complete_method: HTTP method to send the bridge target complete event - :param str username: HTTP basic auth username for events - :param str password: HTTP basic auth password for events - :param str tag: Custom tag to include in callbacks - :param str bridge_complete_fallback_url: Fallback url for bridge complete events - :param str bridge_complete_fallback_method: HTTP method for bridge complete fallback - :param str bridge_target_complete_fallback_url: Fallback url for bridge target complete events - :param str bridge_target_complete_fallback_method: HTTP method for bridge target complete fallback - :param str fallback_username: Basic auth username for fallback events - :param str fallback_password: Basic auth password for fallback events - """ - self.call_id = call_id - self.bridge_complete_url = bridge_complete_url - self.bridge_complete_method = bridge_complete_method - self.bridge_target_complete_url = bridge_target_complete_url - self.bridge_target_complete_method = bridge_target_complete_method - self.username = username - self.password = password - self.tag = tag - self.bridge_complete_fallback_url = bridge_complete_fallback_url - self.bridge_complete_fallback_method = bridge_complete_fallback_method - self.bridge_target_complete_fallback_url = bridge_target_complete_fallback_url - self.bridge_target_complete_fallback_method = bridge_target_complete_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(BRIDGE_TAG) - root.text = self.call_id - if self.bridge_complete_url is not None: - root.set("bridgeCompleteUrl", self.bridge_complete_url) - if self.bridge_complete_method is not None: - root.set("bridgeCompleteMethod", self.bridge_complete_method) - if self.bridge_target_complete_url is not None: - root.set("bridgeTargetCompleteUrl", self.bridge_target_complete_url) - if self.bridge_target_complete_method is not None: - root.set("bridgeTargetCompleteMethod", self.bridge_target_complete_method) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.tag is not None: - root.set("tag", self.tag) - if self.bridge_complete_fallback_url is not None: - root.set("bridgeCompleteFallbackUrl", self.bridge_complete_fallback_url) - if self.bridge_complete_fallback_method is not None: - root.set("bridgeCompleteFallbackMethod", self.bridge_complete_fallback_method) - if self.bridge_target_complete_fallback_url is not None: - root.set("bridgeTargetCompleteFallbackUrl", self.bridge_target_complete_fallback_url) - if self.bridge_target_complete_fallback_method is not None: - root.set("bridgeTargetCompleteFallbackMethod", self.bridge_target_complete_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/conference.py b/build/lib/bandwidth/voice/bxml/verbs/conference.py deleted file mode 100644 index 7a36c9eb..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/conference.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -conference.py - -Representation of Bandwidth's conference BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -CONFERENCE_TAG = "Conference" - - -class Conference(AbstractBxmlVerb): - - def __init__(self, conference_name, mute=None, hold=None, call_ids_to_coach=None, - conference_event_url=None, conference_event_method=None, - username=None, password=None, tag=None, conference_event_fallback_url=None, - conference_event_fallback_method=None, fallback_username=None, - fallback_password=None): - """ - Init for Conference - - :param str conference_name: The name of the conference - :param boolean mute: Determines if conference members should be on mute - :param boolean hold: Determines if conference members should be on hold - :param string|list call_ids_to_coach: A string of comma separated call IDs to coach, or an array of call IDs to coach - :param string conference_event_url: The url to receive conference events - :param string conference_event_method: The HTTP method to send conference events - :param string username: Basic auth username for events - :param string password: Basic auth password for events - :param string tag: Custom tag to be included in events - :param string conference_event_fallback_url: Fallback URL for conference events - :param string conference_event_fallback_method: HTTP method for fallback URL requests - :param string fallback_username: Basic auth username for fallback requests - :param string fallback_password: Basic auth password for fallback requests - """ - self.conference_name = conference_name - self.mute = mute - self.hold = hold - self.call_ids_to_coach = call_ids_to_coach - self.conference_event_url = conference_event_url - self.conference_event_method = conference_event_method - self.username = username - self.password = password - self.tag = tag - self.conference_event_fallback_url = conference_event_fallback_url - self.conference_event_fallback_method = conference_event_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(CONFERENCE_TAG) - root.text = self.conference_name - - if self.mute is not None: - strn = "true" if self.mute else "false" - root.set("mute", strn) - if self.hold is not None: - strn = "true" if self.hold else "false" - root.set("hold", strn) - if self.call_ids_to_coach is not None: - strn = None - if isinstance(self.call_ids_to_coach, str): - strn = self.call_ids_to_coach - else: - strn = ",".join(self.call_ids_to_coach) - root.set("callIdsToCoach", strn) - if self.conference_event_url is not None: - root.set("conferenceEventUrl", self.conference_event_url) - if self.conference_event_method is not None: - root.set("conferenceEventMethod", self.conference_event_method) - if self.tag is not None: - root.set("tag", self.tag) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.conference_event_fallback_url is not None: - root.set("conferenceEventFallbackUrl", self.conference_event_fallback_url) - if self.conference_event_fallback_method is not None: - root.set("conferenceEventFallbackMethod", self.conference_event_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/forward.py b/build/lib/bandwidth/voice/bxml/verbs/forward.py deleted file mode 100644 index 1ea510c6..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/forward.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -forward.py - -Representation of Bandwidth's forward BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -FORWARD_TAG = "Forward" - - -class Forward(AbstractBxmlVerb): - - def __init__(self, to=None, from_=None, call_timeout=None, diversion_treatment=None, diversion_reason=None): - """ - Initializes the Forward class with the following parameters - - :param str to: The phone number destination of the call - :param str from_: The phone number that the recipient will receive the call from - :param int call_timeout: The number of seconds to wait before timing out the call - :param str diversion_treatment: The diversion treatment for the call - :param str diversion_reason: The diversion reason for the call - """ - self.to = to - self.from_ = from_ - self.call_timeout = call_timeout - self.diversion_treatment = diversion_treatment - self.diversion_reason = diversion_reason - - def to_bxml(self): - root = etree.Element(FORWARD_TAG) - if self.to is not None: - root.set("to", self.to) - if self.call_timeout is not None: - root.set("callTimeout", str(self.call_timeout)) - if self.from_ is not None: - root.set("from", self.from_) - if self.diversion_treatment is not None: - root.set("diversionTreatment", self.diversion_treatment) - if self.diversion_reason is not None: - root.set("diversionReason", self.diversion_reason) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/gather.py b/build/lib/bandwidth/voice/bxml/verbs/gather.py deleted file mode 100644 index b6aecde8..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/gather.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -gather.py - -Representation of Bandwidth's gather BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -GATHER_TAG = "Gather" - - -class Gather(AbstractBxmlVerb): - - def __init__(self, gather_url=None, gather_method=None, terminating_digits=None, tag=None, max_digits=None, - inter_digit_timeout=None, username=None, password=None, first_digit_timeout=None, - play_audio=None, speak_sentence=None, repeat_count=None, nested_verbs=None, - gather_fallback_url=None, gather_fallback_method=None, fallback_username=None, - fallback_password=None): - """ - Initializes the Gather class with the following parameters - - :param str gather_url: The url to receive the gather callback - :param str gather_method: The HTTP method used to send the gather callback - :param str terminating_digits: The digits used to terminate the gather - :param str tag: Custom string included in callbacks - :param int max_digits: Max digits to press in the gather - :param int inter_digit_timeout: Seconds allowed between digit presses before terminating the gather - :param str username: The username for callback http authentication - :param str password: The password for callback http authentication - :param int first_digit_timeout: Seconds allowed before the first digit press before terminating the gather - :param PlayAudio play_audio: The PlayAudio tag to include in the gather - :param SpeakSentence speak_sentence: The SpeakSentence tag to include in the gather - :param int repeat_count: The number of times to repeat the audio prompt - :param list nested_verbs: The list of verbs to nest in the gather - :param str gather_fallback_url: Fallback url for gather events - :param str gather_fallback_method: HTTP method for fallback requests - :param str fallback_username: Basic auth username for fallback requests - :param str fallback_password: Basic auth password for fallback requests - """ - - self.gather_url = gather_url - self.gather_method = gather_method - self.terminating_digits = terminating_digits - self.tag = tag - self.max_digits = max_digits - self.inter_digit_timeout = inter_digit_timeout - self.username = username - self.password = password - self.first_digit_timeout = first_digit_timeout - self.play_audio = play_audio - self.speak_sentence = speak_sentence - self.repeat_count = repeat_count - self.nested_verbs = nested_verbs - self.gather_fallback_url = gather_fallback_url - self.gather_fallback_method = gather_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(GATHER_TAG) - if self.gather_url is not None: - root.set("gatherUrl", self.gather_url) - if self.gather_method is not None: - root.set("gatherMethod", self.gather_method) - if self.terminating_digits is not None: - root.set("terminatingDigits", self.terminating_digits) - if self.tag is not None: - root.set("tag", self.tag) - if self.max_digits is not None: - root.set("maxDigits", str(self.max_digits)) - if self.inter_digit_timeout is not None: - root.set("interDigitTimeout", str(self.inter_digit_timeout)) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.first_digit_timeout is not None: - root.set("firstDigitTimeout", str(self.first_digit_timeout)) - if self.repeat_count is not None: - root.set("repeatCount", str(self.repeat_count)) - if self.gather_fallback_url is not None: - root.set("gatherFallbackUrl", self.gather_fallback_url) - if self.gather_fallback_method is not None: - root.set("gatherFallbackMethod", self.gather_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - if self.play_audio is not None: - root.append(self.play_audio.to_etree_element()) - if self.speak_sentence is not None: - root.append(self.speak_sentence.to_etree_element()) - if self.nested_verbs is not None: - for verb in self.nested_verbs: - root.append(verb.to_etree_element()) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/hangup.py b/build/lib/bandwidth/voice/bxml/verbs/hangup.py deleted file mode 100644 index 99e2e203..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/hangup.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -hangup.py - -Representation of Bandwidth's hangup BXML verb - -@copyright Bandwidth INC -""" - -from .base_verb import AbstractBxmlVerb - - -class Hangup(AbstractBxmlVerb): - - def to_bxml(self): - return "" diff --git a/build/lib/bandwidth/voice/bxml/verbs/pause.py b/build/lib/bandwidth/voice/bxml/verbs/pause.py deleted file mode 100644 index 827358e2..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/pause.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -pause.py - -Representation of Bandwidth's pause BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -PAUSE_TAG = "Pause" - - -class Pause(AbstractBxmlVerb): - - def __init__(self, duration): - """ - Initializes the Pause class with the duration parameter - - :param float duration: The time in seconds to pause - """ - self.duration = duration - - def to_bxml(self): - root = etree.Element(PAUSE_TAG) - if self.duration is not None: - root.set("duration", str(self.duration)) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/pause_recording.py b/build/lib/bandwidth/voice/bxml/verbs/pause_recording.py deleted file mode 100644 index 8aacf4a2..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/pause_recording.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -pause_recording.py - -Representation of Bandwidth's PauseRecording BXML verb - -@copyright Bandwidth INC -""" - -from .base_verb import AbstractBxmlVerb - - -class PauseRecording(AbstractBxmlVerb): - - def to_bxml(self): - return "" diff --git a/build/lib/bandwidth/voice/bxml/verbs/phone_number.py b/build/lib/bandwidth/voice/bxml/verbs/phone_number.py deleted file mode 100644 index a1b0937f..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/phone_number.py +++ /dev/null @@ -1,85 +0,0 @@ -""" -phone_number.py - -Representation of Bandwidth's phone number BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -PHONE_NUMBER_TAG = "PhoneNumber" - - -class PhoneNumber(AbstractBxmlVerb): - - def __init__(self, number=None, transfer_answer_url=None, transfer_answer_method=None, - username=None, password=None, tag=None, transfer_disconnect_url=None, transfer_disconnect_method=None, - transfer_answer_fallback_url=None, transfer_answer_fallback_method=None, - fallback_username=None, fallback_password=None): - """ - Initializes the PhoneNumber class with the following parameters - - :param str number: The phone number - :param str transfer_answer_url: The url to send the transfer event to - :param str transfer_answer_method: The http method of the transfer event request - :param str transfer_disconnect_url: The url to send the transfer disconnect event to - :param str transfer_disconnect_method: The http method of the transfer disconnect event request - :param str username: The username to authenticate on the transfer event url - :param str password: The password to authenticate on the transfer event url - :param str tag: Custom string sent in the callback - :param str transfer_answer_fallback_url: URL for fallback events - :param str transfer_answer_fallback_method: HTTP method for fallback events - :param str fallback_username: Basic auth username for fallback events - :param str fallback_password: Basic auth password for fallback events - """ - self.number = number - self.transfer_answer_url = transfer_answer_url - self.transfer_answer_method = transfer_answer_method - self.username = username - self.password = password - self.tag = tag - self.transfer_disconnect_method = transfer_disconnect_method - self.transfer_disconnect_url = transfer_disconnect_url - self.transfer_answer_fallback_url = transfer_answer_fallback_url - self.transfer_answer_fallback_method = transfer_answer_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_etree_element(self): - """ - Converts the class into an etree element. Used for other verb classes to build xml - - :return etree.Element: The etree Element representing this class - """ - root = etree.Element(PHONE_NUMBER_TAG) - if self.number is not None: - root.text = self.number - if self.transfer_answer_url is not None: - root.set("transferAnswerUrl", self.transfer_answer_url) - if self.transfer_answer_method is not None: - root.set("transferAnswerMethod", self.transfer_answer_method) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.tag is not None: - root.set("tag", self.tag) - if self.transfer_disconnect_method is not None: - root.set("transferDisconnectMethod", self.transfer_disconnect_method) - if self.transfer_disconnect_url is not None: - root.set("transferDisconnectUrl", self.transfer_disconnect_url) - if self.transfer_answer_fallback_url is not None: - root.set("transferAnswerFallbackUrl", self.transfer_answer_fallback_url) - if self.transfer_answer_fallback_method is not None: - root.set("transferAnswerFallbackMethod", self.transfer_answer_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - return root - - def to_bxml(self): - return etree.tostring(self.to_etree_element()).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/play_audio.py b/build/lib/bandwidth/voice/bxml/verbs/play_audio.py deleted file mode 100644 index b5d19227..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/play_audio.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -play_audio.py - -Representation of Bandwidth's play audio BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -PLAY_AUDIO_TAG = "PlayAudio" - - -class PlayAudio(AbstractBxmlVerb): - - def __init__(self, url=None, username=None, password=None): - """ - Initializes the PlayAudio class with the following parameters - - :param str url: The url of the audio to play - :param str username: The username to authenticate on the url - :param str password: The password to authenticate on the url - """ - self.url = url - self.username = username - self.password = password - - def to_etree_element(self): - """ - Converts the class into an etree element. Used for other verb classes to build xml - - :return etree.Element: The etree Element representing this class - """ - root = etree.Element(PLAY_AUDIO_TAG) - if self.url is not None: - root.text = self.url - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - return root - - def to_bxml(self): - return etree.tostring(self.to_etree_element()).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/record.py b/build/lib/bandwidth/voice/bxml/verbs/record.py deleted file mode 100644 index d38b3a67..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/record.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -record.py - -Representation of Bandwidth's redirect BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -RECORD_TAG = "Record" - - -class Record(AbstractBxmlVerb): - - def __init__(self, tag=None, username=None, password=None, record_complete_url=None, record_complete_method=None, - recording_available_url=None, recording_available_method=None, terminating_digits=None, max_duration=None, - file_format=None, transcribe=None, transcription_available_url=None, transcription_available_method=None, - silence_timeout=None, record_complete_fallback_url=None, record_complete_fallback_method=None, - fallback_username=None, fallback_password=None): - """ - Initializes the Record class with the following parameters - - :param str tag: Optional tag to include in the callback - :param str username: Username for http authentication on the redirect url - :param str password: Password for http authentication on the redirect url - :param str record_complete_url: URL for record complete callback - :param str record_complete_method: HTTP method for record complete callback - :param str recording_available_url: URL for record available callback - :param str recording_available_method: HTTP method for record available callback - :param str terminating_digits: Digits to terminate the recording - :param int max_duration: Max duration to record in seconds - :param str file_format: The file format to save the recording in - :param bool transcribe: True to transcribe the recording on completion, False otherwise - :param str transcription_available_url: URL to send the transcriptionAvailable event to. - :param str transcription_available_method: The HTTP method to use for the request to transcriptionAvailableUrl. GET or POST - :param int silence_timeout: Number of seconds of silence that ends the recording - :param str record_complete_fallback_url: URL for fallback events - :param str record_complete_fallback_method: HTTP method for fallback events - :param str fallback_username: Basic auth username for fallback events - :param str fallback_password: Basic auth password for fallback events - """ - self.tag = tag - self.username = username - self.password = password - self.record_complete_url = record_complete_url - self.record_complete_method = record_complete_method - self.recording_available_url = recording_available_url - self.recording_available_method = recording_available_method - self.terminating_digits = terminating_digits - self.max_duration = max_duration - self.file_format = file_format - self.transcribe = transcribe - self.transcription_available_url = transcription_available_url - self.transcription_available_method = transcription_available_method - self.silence_timeout = silence_timeout - self.record_complete_fallback_url = record_complete_fallback_url - self.record_complete_fallback_method = record_complete_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(RECORD_TAG) - if self.tag is not None: - root.set("tag", self.tag) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.record_complete_url is not None: - root.set("recordCompleteUrl", self.record_complete_url) - if self.record_complete_method is not None: - root.set("recordCompleteMethod", self.record_complete_method) - if self.recording_available_url is not None: - root.set("recordingAvailableUrl", self.recording_available_url) - if self.recording_available_method is not None: - root.set("recordingAvailableMethod", self.recording_available_method) - if self.terminating_digits is not None: - root.set("terminatingDigits", self.terminating_digits) - if self.max_duration is not None: - root.set("maxDuration", str(self.max_duration)) - if self.file_format is not None: - root.set("fileFormat", self.file_format) - if self.transcribe is not None: - #Convert True to "true", or False to "false" - strn = "true" if self.transcribe else "false" - root.set("transcribe", strn) - if self.transcription_available_url is not None: - root.set("transcriptionAvailableUrl", self.transcription_available_url) - if self.transcription_available_method is not None: - root.set("transcriptionAvailableMethod", self.transcription_available_method) - if self.silence_timeout is not None: - root.set("silenceTimeout", str(self.silence_timeout)) - if self.record_complete_fallback_url is not None: - root.set("recordCompleteFallbackUrl", self.record_complete_fallback_url) - if self.record_complete_fallback_method is not None: - root.set("recordCompleteFallbackMethod", self.record_complete_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/redirect.py b/build/lib/bandwidth/voice/bxml/verbs/redirect.py deleted file mode 100644 index 51047009..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/redirect.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -redirect.py - -Representation of Bandwidth's redirect BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -REDIRECT_TAG = "Redirect" - - -class Redirect(AbstractBxmlVerb): - - def __init__(self, redirect_url=None, redirect_method=None, tag=None, username=None, password=None, - redirect_fallback_url=None, redirect_fallback_method=None, - fallback_username=None, fallback_password=None): - """ - Initializes the Redirect class with the following parameters - - :param str redirect_url: The url to retrieve the next BXML - :param str redirect_method: The HTTP method used to retrieve the next url - :param str tag: Optional tag to include in the callback - :param str username: Username for http authentication on the redirect url - :param str password: Password for http authentication on the redirect url - :param str redirect_fallback_url: URL for fallback events - :param str redirect_fallback_method: HTTP method for fallback events - :param str fallback_username: Basic auth username for fallback events - :param str fallback_password: Basic auth password for fallback events - """ - self.redirect_url = redirect_url - self.redirect_method = redirect_method - self.tag = tag - self.username = username - self.password = password - self.redirect_fallback_url = redirect_fallback_url - self.redirect_fallback_method = redirect_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(REDIRECT_TAG) - if self.redirect_url is not None: - root.set("redirectUrl", self.redirect_url) - if self.redirect_method is not None: - root.set("redirectMethod", self.redirect_method) - if self.tag is not None: - root.set("tag", self.tag) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.redirect_fallback_url is not None: - root.set("redirectFallbackUrl", self.redirect_fallback_url) - if self.redirect_fallback_method is not None: - root.set("redirectFallbackMethod", self.redirect_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/resume_recording.py b/build/lib/bandwidth/voice/bxml/verbs/resume_recording.py deleted file mode 100644 index c445648b..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/resume_recording.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -resume_recording.py - -Representation of Bandwidth's ResumeRecording BXML verb - -@copyright Bandwidth INC -""" - -from .base_verb import AbstractBxmlVerb - - -class ResumeRecording(AbstractBxmlVerb): - - def to_bxml(self): - return "" diff --git a/build/lib/bandwidth/voice/bxml/verbs/ring.py b/build/lib/bandwidth/voice/bxml/verbs/ring.py deleted file mode 100644 index a83e2e59..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/ring.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -ring.py - -Representation of Bandwidth's ring BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -RING_TAG = "Ring" - - -class Ring(AbstractBxmlVerb): - - def __init__(self, duration): - """ - Initializes the Ring class with the duration parameter - - :param float duration: The time in seconds to ring - """ - self.duration = duration - - def to_bxml(self): - root = etree.Element(RING_TAG) - if self.duration is not None: - root.set("duration", str(self.duration)) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/send_dtmf.py b/build/lib/bandwidth/voice/bxml/verbs/send_dtmf.py deleted file mode 100644 index fafa197d..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/send_dtmf.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -send_dtmf.py - -Representation of Bandwidth's send dtmf BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -SEND_DTMF_TAG = "SendDtmf" - - -class SendDtmf(AbstractBxmlVerb): - - def __init__(self, dtmf, tone_duration=None, tone_interval=None): - """ - Initializes the SendDtmf class with the dtmf parameter - - :param str dtmf: The dtmf to build the SendDtmf verb - :param double tone_duration: The length in milliseconds of each DTMF tone - :param double tone_interval: The duration of silence in milliseconds following each DTMF tone - """ - self.dtmf = dtmf - self.tone_duration = tone_duration - self.tone_interval = tone_interval - - def to_bxml(self): - root = etree.Element(SEND_DTMF_TAG) - root.text = self.dtmf - if self.tone_duration is not None: - root.set("toneDuration", str(self.tone_duration)) - if self.tone_interval is not None: - root.set("toneInterval", str(self.tone_interval)) - - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/speak_sentence.py b/build/lib/bandwidth/voice/bxml/verbs/speak_sentence.py deleted file mode 100644 index 36d3a7f0..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/speak_sentence.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -speak_sentence.py - -Representation of Bandwidth's speak sentence BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -import re - -SPEAK_SENTENCE_TAG = "SpeakSentence" -SSML_REGEX = r"<([a-zA-Z//].*?)>" - -class SpeakSentence(AbstractBxmlVerb): - - def __init__(self, sentence=None, voice=None, locale=None, gender=None): - """ - Initializes the SpeakSentence class with the following parameters - - :param str sentence: The sentence to speak - :param str voice: The voice to speak the sentence - :param str locale: The locale of the voice - :param str gender: The gender of the voice - """ - self.sentence = sentence - self.voice = voice - self.locale = locale - self.gender = gender - - def to_etree_element(self): - """ - Converts the class into an etree element. Used for other verb classes to build xml - - :return etree.Element: The etree Element representing this class - """ - root = etree.Element(SPEAK_SENTENCE_TAG) - if self.sentence is not None: - root.text = self.sentence - if self.voice is not None: - root.set("voice", self.voice) - if self.locale is not None: - root.set("locale", self.locale) - if self.gender is not None: - root.set("gender", self.gender) - return root - - def to_bxml(self): - return re.sub(SSML_REGEX, r"<\1>", etree.tostring(self.to_etree_element()).decode()) diff --git a/build/lib/bandwidth/voice/bxml/verbs/start_gather.py b/build/lib/bandwidth/voice/bxml/verbs/start_gather.py deleted file mode 100644 index 68efa542..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/start_gather.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -startGather.py - -Representation of Bandwidth's startGather BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -START_GATHER_TAG = "StartGather" - - -class StartGather(AbstractBxmlVerb): - - def __init__(self, dtmfUrl=None, dtmfMethod=None, username=None, password=None, tag=None): - """ - Initializes the Gather class with the following parameters - - :param str dtmfUrl: The url to receive the dtmf event - :param str dtmfMethod: The HTTP method used to send the gather dtmfUrl event - :param str username: The username for callback http authentication - :param str password: The password for callback http authentication - :param str tag: - """ - - self.dtmfUrl = dtmfUrl - self.dtmfMethod = dtmfMethod - self.username = username - self.password = password - self.tag = tag - - def to_bxml(self): - root = etree.Element(START_GATHER_TAG) - if self.dtmfUrl is not None: - root.set("dtmfUrl", self.dtmfUrl) - if self.dtmfMethod is not None: - root.set("dtmfMethod", self.dtmfMethod) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.tag is not None: - root.set("tag", self.tag) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/start_recording.py b/build/lib/bandwidth/voice/bxml/verbs/start_recording.py deleted file mode 100644 index 887eef99..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/start_recording.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -start_recording.py - -Representation of Bandwidth's StartRecording BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -START_RECORDING_TAG = "StartRecording" - - -class StartRecording(AbstractBxmlVerb): - - def __init__(self, tag=None, username=None, password=None, recording_available_url=None, recording_available_method=None, - file_format=None, multi_channel=None, transcribe=None, transcription_available_url=None, transcription_available_method=None): - """ - Initializes the Record class with the following parameters - - :param str tag: Optional tag to include in the callback - :param str username: Username for http authentication on the redirect url - :param str password: Password for http authentication on the redirect url - :param str recording_available_url: URL for record available callback - :param str recording_available_method: HTTP method for record available callback - :param str file_format: The file format to save the recording in - :param bool multi_channel: Whether or not to record the channels separately (default is false, 1 recording) - :param bool transcribe: True to transcribe the recording on completion, False otherwise - :param str transcription_available_url: URL to send the transcriptionAvailable event to. - :param str transcription_available_method: The HTTP method to use for the request to transcriptionAvailableUrl. GET or POST - """ - self.tag = tag - self.username = username - self.password = password - self.recording_available_url = recording_available_url - self.recording_available_method = recording_available_method - self.file_format = file_format - self.multi_channel = multi_channel - self.transcribe = transcribe - self.transcription_available_url = transcription_available_url - self.transcription_available_method = transcription_available_method - - def to_bxml(self): - root = etree.Element(START_RECORDING_TAG) - if self.tag is not None: - root.set("tag", self.tag) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.recording_available_url is not None: - root.set("recordingAvailableUrl", self.recording_available_url) - if self.recording_available_method is not None: - root.set("recordingAvailableMethod", self.recording_available_method) - if self.file_format is not None: - root.set("fileFormat", self.file_format) - if self.multi_channel is not None: - #Convert True to "true", or False to "false" - strn = "true" if self.multi_channel else "false" - root.set("multiChannel", strn) - if self.transcribe is not None: - #Convert True to "true", or False to "false" - strn = "true" if self.transcribe else "false" - root.set("transcribe", strn) - if self.transcription_available_url is not None: - root.set("transcriptionAvailableUrl", self.transcription_available_url) - if self.transcription_available_method is not None: - root.set("transcriptionAvailableMethod", self.transcription_available_method) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/bxml/verbs/stop_gather.py b/build/lib/bandwidth/voice/bxml/verbs/stop_gather.py deleted file mode 100644 index 6ad39862..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/stop_gather.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -stopGather.py - -Representation of Bandwidth's stopGather BXML verb - -@copyright Bandwidth INC -""" - -from .base_verb import AbstractBxmlVerb - - -class StopGather(AbstractBxmlVerb): - - def to_bxml(self): - return "" diff --git a/build/lib/bandwidth/voice/bxml/verbs/stop_recording.py b/build/lib/bandwidth/voice/bxml/verbs/stop_recording.py deleted file mode 100644 index 0231eae1..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/stop_recording.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -stop_recording.py - -Representation of Bandwidth's StopRecording BXML verb - -@copyright Bandwidth INC -""" - -from .base_verb import AbstractBxmlVerb - - -class StopRecording(AbstractBxmlVerb): - - def to_bxml(self): - return "" diff --git a/build/lib/bandwidth/voice/bxml/verbs/transfer.py b/build/lib/bandwidth/voice/bxml/verbs/transfer.py deleted file mode 100644 index be71c450..00000000 --- a/build/lib/bandwidth/voice/bxml/verbs/transfer.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -transfer.py - -Representation of Bandwidth's transfer BXML verb - -@copyright Bandwidth INC -""" - -from lxml import etree - -from .base_verb import AbstractBxmlVerb - -TRANSFER_TAG = "Transfer" - - -class Transfer(AbstractBxmlVerb): - - def __init__(self, transfer_caller_id=None, call_timeout=None, tag=None, transfer_complete_url=None, - transfer_complete_method=None, username=None, password=None, diversion_treatment=None, - diversion_reason=None, phone_numbers=None, - transfer_complete_fallback_url=None, transfer_complete_fallback_method=None, - fallback_username=None, fallback_password=None): - """ - Initializes the Transfer class with the following parameters - - :param str transfer_caller_id: The phone number to make the transfer - :param int call_timeout: The number of seconds to wait before timing out the transfer - :param str tag: Custom tag to be included in callbacks - :param str transfer_complete_url: The url to receive the transfer complete callback - :param str transfer_complete_method: The HTTP method used to send the transfer complete callback - :param str username: The username to authenticate on the transfer complete url - :param str password: The password to authenticate on the transfer complete url - :param str diversion_treatment: The diversion treatment for the call - :param str diversion_reason: The diversion reason for the call - :param list phone_numbers: The numbers to receive the transferred call - :param str transfer_complete_fallback_url: URL for fallback events - :param str transfer_complete_fallback_method: HTTP method for fallback events - :param str fallback_username: Basic auth username for fallback events - :param str fallback_password: Basic auth password for fallback events - """ - self.transfer_caller_id = transfer_caller_id - self.call_timeout = call_timeout - self.tag = tag - self.transfer_complete_url = transfer_complete_url - self.transfer_complete_method = transfer_complete_method - self.username = username - self.password = password - self.diversion_treatment = diversion_treatment - self.diversion_reason = diversion_reason - self.phone_numbers = phone_numbers - self.transfer_complete_fallback_url = transfer_complete_fallback_url - self.transfer_complete_fallback_method = transfer_complete_fallback_method - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - def to_bxml(self): - root = etree.Element(TRANSFER_TAG) - if self.transfer_caller_id is not None: - root.set("transferCallerId", self.transfer_caller_id) - if self.call_timeout is not None: - root.set("callTimeout", str(self.call_timeout)) - if self.tag is not None: - root.set("tag", self.tag) - if self.transfer_complete_url is not None: - root.set("transferCompleteUrl", self.transfer_complete_url) - if self.transfer_complete_method is not None: - root.set("transferCompleteMethod", self.transfer_complete_method) - if self.username is not None: - root.set("username", self.username) - if self.password is not None: - root.set("password", self.password) - if self.diversion_treatment is not None: - root.set("diversionTreatment", self.diversion_treatment) - if self.diversion_reason is not None: - root.set("diversionReason", self.diversion_reason) - if self.transfer_complete_fallback_url is not None: - root.set("transferCompleteFallbackUrl", self.transfer_complete_fallback_url) - if self.transfer_complete_fallback_method is not None: - root.set("transferCompleteFallbackMethod", self.transfer_complete_fallback_method) - if self.fallback_username is not None: - root.set("fallbackUsername", self.fallback_username) - if self.fallback_password is not None: - root.set("fallbackPassword", self.fallback_password) - if self.phone_numbers is not None: - for phone_number in self.phone_numbers: - root.append(phone_number.to_etree_element()) - return etree.tostring(root).decode() diff --git a/build/lib/bandwidth/voice/controllers/__init__.py b/build/lib/bandwidth/voice/controllers/__init__.py deleted file mode 100644 index c1660224..00000000 --- a/build/lib/bandwidth/voice/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'base_controller', - 'api_controller', -] diff --git a/build/lib/bandwidth/voice/controllers/api_controller.py b/build/lib/bandwidth/voice/controllers/api_controller.py deleted file mode 100644 index 472cb35f..00000000 --- a/build/lib/bandwidth/voice/controllers/api_controller.py +++ /dev/null @@ -1,1445 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.configuration import Server -from bandwidth.http.api_response import ApiResponse -from bandwidth.voice.controllers.base_controller import BaseController -from bandwidth.http.auth.voice_basic_auth import VoiceBasicAuth -from bandwidth.voice.models.api_call_response import ApiCallResponse -from bandwidth.voice.models.api_call_state_response import ApiCallStateResponse -from bandwidth.voice.models.recording_metadata_response import RecordingMetadataResponse -from bandwidth.voice.models.transcription_response import TranscriptionResponse -from bandwidth.voice.models.conference_detail import ConferenceDetail -from bandwidth.voice.models.conference_member_detail import ConferenceMemberDetail -from bandwidth.voice.models.conference_recording_metadata_response import ConferenceRecordingMetadataResponse -from bandwidth.voice.exceptions.api_error_response_exception import ApiErrorResponseException -from bandwidth.exceptions.api_exception import APIException - - -class APIController(BaseController): - - """A Controller to access Endpoints in the bandwidth API.""" - - def __init__(self, config, call_back=None): - super(APIController, self).__init__(config, call_back) - - def create_call(self, - account_id, - body=None): - """Does a POST request to /api/v2/accounts/{accountId}/calls. - - Creates an outbound call - - Args: - account_id (string): TODO: type description here. - body (ApiCreateCallRequest, optional): TODO: type description - here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ApiCallResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_call_state(self, - account_id, - call_id): - """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}. - - Returns near-realtime metadata about the specified call - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ApiCallStateResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def modify_call(self, - account_id, - call_id, - body=None): - """Does a POST request to /api/v2/accounts/{accountId}/calls/{callId}. - - Interrupts and replaces an active call's BXML document - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - body (ApiModifyCallRequest, optional): TODO: type description - here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def modify_call_recording_state(self, - account_id, - call_id, - body=None): - """Does a PUT request to /api/v2/accounts/{accountId}/calls/{callId}/recording. - - Pauses or resumes a recording - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - body (ModifyCallRecordingState, optional): TODO: type description - here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recording' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.put(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_query_metadata_for_account_and_call(self, - account_id, - call_id): - """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}/recordings. - - Returns a (potentially empty) list of metadata for the recordings that - took place during the specified call - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, RecordingMetadataResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_metadata_for_recording(self, - account_id, - call_id, - recording_id): - """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}. - - Returns metadata for the specified recording - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, RecordingMetadataResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def delete_recording(self, - account_id, - call_id, - recording_id): - """Does a DELETE request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}. - - Deletes the specified recording - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_stream_recording_media(self, - account_id, - call_id, - recording_id): - """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media. - - Downloads the specified recording - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.get(_query_url) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request, binary=True) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = _response.text - _result = ApiResponse(_response, body=decoded) - return _result - - def delete_recording_media(self, - account_id, - call_id, - recording_id): - """Does a DELETE request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media. - - Deletes the specified recording's media - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_recording_transcription(self, - account_id, - call_id, - recording_id): - """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription. - - Downloads the specified transcription - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, TranscriptionResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def create_transcribe_recording(self, - account_id, - call_id, - recording_id, - body=None): - """Does a POST request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription. - - Requests that the specified recording be transcribed - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - body (ApiTranscribeRecordingRequest, optional): TODO: type - description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 410: - raise ApiErrorResponseException('The media for this recording has been deleted, so we can\'t transcribe it', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def delete_recording_transcription(self, - account_id, - call_id, - recording_id): - """Does a DELETE request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription. - - Deletes the specified recording's transcription - - Args: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_conferences_by_account(self, - account_id, - page_size=1000, - page_token=None, - name=None, - min_created_time=None, - max_created_time=None): - """Does a GET request to /api/v2/accounts/{accountId}/conferences. - - Returns information about the conferences in the account - - Args: - account_id (string): TODO: type description here. - page_size (int, optional): TODO: type description here. Example: - 1000 - page_token (string, optional): TODO: type description here. - name (string, optional): TODO: type description here. - min_created_time (string, optional): TODO: type description here. - max_created_time (string, optional): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_parameters = { - 'pageSize': page_size, - 'pageToken': page_token, - 'name': name, - 'minCreatedTime': min_created_time, - 'maxCreatedTime': max_created_time - } - _query_builder = APIHelper.append_url_with_query_parameters( - _query_builder, - _query_parameters - ) - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ConferenceDetail.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_conference_by_id(self, - account_id, - conference_id): - """Does a GET request to /api/v2/accounts/{accountId}/conferences/{conferenceId}. - - Returns information about the specified conference - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ConferenceDetail.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def modify_conference(self, - account_id, - conference_id, - body=None): - """Does a POST request to /api/v2/accounts/{accountId}/conferences/{conferenceId}. - - Modify the conference state - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - body (CallEngineModifyConferenceRequest, optional): TODO: type - description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def modify_conference_member(self, - account_id, - conference_id, - call_id, - body=None): - """Does a PUT request to /api/v2/accounts/{accountId}/conferences/{conferenceId}/members/{callId}. - - Updates settings for a particular conference member - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - call_id (string): TODO: type description here. - body (ConferenceMemberDetail, optional): TODO: type description - here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}/members/{callId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True}, - 'callId': {'value': call_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.put(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_conference_member(self, - account_id, - conference_id, - member_id): - """Does a GET request to /api/v2/accounts/{accountId}/conferences/{conferenceId}/members/{memberId}. - - Returns information about the specified conference member - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - member_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}/members/{memberId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True}, - 'memberId': {'value': member_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ConferenceMemberDetail.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_query_metadata_for_account_and_conference(self, - account_id, - conference_id): - """Does a GET request to /api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings. - - Returns a (potentially empty) list of metadata for the recordings that - took place during the specified conference - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, ConferenceRecordingMetadataResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_metadata_for_conference_recording(self, - account_id, - conference_id, - recording_id): - """Does a GET request to /api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings/{recordingId}. - - Returns metadata for the specified recording - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings/{recordingId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, RecordingMetadataResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_stream_conference_recording_media(self, - account_id, - conference_id, - recording_id): - """Does a GET request to /api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings/{recordingId}/media. - - Downloads the specified recording - - Args: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/conferences/{conferenceId}/recordings/{recordingId}/media' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'conferenceId': {'value': conference_id, 'encode': True}, - 'recordingId': {'value': recording_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.get(_query_url) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request, binary=True) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = _response.text - _result = ApiResponse(_response, body=decoded) - return _result - - def get_query_metadata_for_account(self, - account_id, - mfrom=None, - to=None, - min_start_time=None, - max_start_time=None): - """Does a GET request to /api/v2/accounts/{accountId}/recordings. - - Returns a list of metadata for the recordings associated with the - specified account. The list can be filtered by the optional from, to, - minStartTime, and maxStartTime arguments. The list is capped at 1000 - entries and may be empty if no recordings match the specified - criteria. - - Args: - account_id (string): TODO: type description here. - mfrom (string, optional): TODO: type description here. - to (string, optional): TODO: type description here. - min_start_time (string, optional): TODO: type description here. - max_start_time (string, optional): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. - successful operation - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/api/v2/accounts/{accountId}/recordings' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT) - _query_builder += _url_path - _query_parameters = { - 'from': mfrom, - 'to': to, - 'minStartTime': min_start_time, - 'maxStartTime': max_start_time - } - _query_builder = APIHelper.append_url_with_query_parameters( - _query_builder, - _query_parameters - ) - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - VoiceBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise ApiErrorResponseException('Something\'s not quite right... Your request is invalid. Please fix it before trying again.', _response) - elif _response.status_code == 401: - raise APIException('Your credentials are invalid. Please use your Bandwidth dashboard credentials to authenticate to the API.', _response) - elif _response.status_code == 403: - raise ApiErrorResponseException('User unauthorized to perform this action.', _response) - elif _response.status_code == 404: - raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response) - elif _response.status_code == 415: - raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response) - elif _response.status_code == 429: - raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response) - elif _response.status_code == 500: - raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, RecordingMetadataResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result diff --git a/build/lib/bandwidth/voice/controllers/base_controller.py b/build/lib/bandwidth/voice/controllers/base_controller.py deleted file mode 100644 index 3f7583fb..00000000 --- a/build/lib/bandwidth/voice/controllers/base_controller.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.exceptions.api_exception import APIException - - -class BaseController(object): - - """All controllers inherit from this base class. - - Attributes: - config (Configuration): The HttpClient which a specific controller - instance will use. By default all the controller objects share - the same HttpClient. A user can use his own custom HttpClient - as well. - http_call_back (HttpCallBack): An object which holds call back - methods to be called before and after the execution of an HttpRequest. - global_headers (dict): The global headers of the API which are sent with - every request. - - """ - - def global_headers(self): - return { - 'user-agent': 'python-sdk-refs/tags/python6.13.2' - } - - def __init__(self, config, call_back=None): - self._config = config - self._http_call_back = call_back - - @property - def config(self): - return self._config - - @property - def http_call_back(self): - return self._http_call_back - - def validate_parameters(self, **kwargs): - """Validates required parameters of an endpoint. - - Args: - kwargs (dict): A dictionary of the required parameters. - - """ - for name, value in kwargs.items(): - if value is None: - raise ValueError("Required parameter {} cannot be None.".format(name)) - - def execute_request(self, request, binary=False): - """Executes an HttpRequest. - - Args: - request (HttpRequest): The HttpRequest to execute. - binary (bool): A flag which should be set to True if - a binary response is expected. - - Returns: - HttpResponse: The HttpResponse received. - - """ - # Invoke the on before request HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_before_request(request) - - # Add global headers to request - request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers) - - # Invoke the API call to fetch the response. - func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string - response = func(request) - - # Invoke the on after response HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_after_response(response) - - return response - - def validate_response(self, response): - """Validates an HTTP response by checking for global errors. - - Args: - response (HttpResponse): The HttpResponse of the API call. - - """ - if (response.status_code < 200) or (response.status_code > 208): # [200,208] = HTTP OK - raise APIException('HTTP response not OK.', response) diff --git a/build/lib/bandwidth/voice/exceptions/__init__.py b/build/lib/bandwidth/voice/exceptions/__init__.py deleted file mode 100644 index ab7800b4..00000000 --- a/build/lib/bandwidth/voice/exceptions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'api_error_response_exception', -] diff --git a/build/lib/bandwidth/voice/exceptions/api_error_response_exception.py b/build/lib/bandwidth/voice/exceptions/api_error_response_exception.py deleted file mode 100644 index 470d35f9..00000000 --- a/build/lib/bandwidth/voice/exceptions/api_error_response_exception.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -import bandwidth.exceptions.api_exception - - -class ApiErrorResponseException(bandwidth.exceptions.api_exception.APIException): - def __init__(self, reason, response): - """Constructor for the ApiErrorResponseException class - - Args: - reason (string): The reason (or error message) for the Exception - to be raised. - response (HttpResponse): The HttpResponse of the API call. - - """ - super(ApiErrorResponseException, self).__init__(reason, response) - dictionary = APIHelper.json_deserialize(self.response.text) - if isinstance(dictionary, dict): - self.unbox(dictionary) - - def unbox(self, dictionary): - """Populates the properties of this object by extracting them from a dictionary. - - Args: - dictionary (dictionary): A dictionary representation of the object as - obtained from the deserialization of the server's response. The keys - MUST match property names in the API description. - - """ - self.mtype = dictionary.get('type') - self.description = dictionary.get('description') - self.id = dictionary.get('id') diff --git a/build/lib/bandwidth/voice/models/__init__.py b/build/lib/bandwidth/voice/models/__init__.py deleted file mode 100644 index 1b9d7f05..00000000 --- a/build/lib/bandwidth/voice/models/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -__all__ = [ - 'api_call_response', - 'api_call_state_response', - 'api_create_call_request', - 'api_modify_call_request', - 'call_engine_modify_conference_request', - 'api_transcribe_recording_request', - 'conference_detail', - 'conference_member_detail', - 'conference_recording_metadata_response', - 'modify_call_recording_state', - 'recording_metadata_response', - 'transcript', - 'transcription', - 'transcription_response', - 'answer_fallback_method_enum', - 'answer_method_enum', - 'callback_method_enum', - 'conference_event_method_enum', - 'direction_enum', - 'disconnect_cause_enum', - 'disconnect_method_enum', - 'file_format_enum', - 'redirect_fallback_method_enum', - 'redirect_method_enum', - 'state_enum', - 'state_1_enum', - 'state_2_enum', - 'status_enum', - 'status_1_enum', - 'status_3_enum', -] diff --git a/build/lib/bandwidth/voice/models/answer_fallback_method_enum.py b/build/lib/bandwidth/voice/models/answer_fallback_method_enum.py deleted file mode 100644 index 733c621d..00000000 --- a/build/lib/bandwidth/voice/models/answer_fallback_method_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class AnswerFallbackMethodEnum(object): - - """Implementation of the 'AnswerFallbackMethod' enum. - - TODO: type enum description here. - - Attributes: - POST: TODO: type description here. - GET: TODO: type description here. - - """ - - POST = 'POST' - - GET = 'GET' diff --git a/build/lib/bandwidth/voice/models/answer_method_enum.py b/build/lib/bandwidth/voice/models/answer_method_enum.py deleted file mode 100644 index 8d174748..00000000 --- a/build/lib/bandwidth/voice/models/answer_method_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class AnswerMethodEnum(object): - - """Implementation of the 'AnswerMethod' enum. - - TODO: type enum description here. - - Attributes: - POST: TODO: type description here. - GET: TODO: type description here. - - """ - - POST = 'POST' - - GET = 'GET' diff --git a/build/lib/bandwidth/voice/models/api_call_response.py b/build/lib/bandwidth/voice/models/api_call_response.py deleted file mode 100644 index 39467f60..00000000 --- a/build/lib/bandwidth/voice/models/api_call_response.py +++ /dev/null @@ -1,171 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.api_helper import APIHelper - - -class ApiCallResponse(object): - - """Implementation of the 'ApiCallResponse' model. - - TODO: type model description here. - - Attributes: - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - application_id (string): TODO: type description here. - to (string): TODO: type description here. - mfrom (string): TODO: type description here. - start_time (datetime): TODO: type description here. - call_url (string): TODO: type description here. - call_timeout (float): TODO: type description here. - callback_timeout (float): TODO: type description here. - answer_url (string): TODO: type description here. - answer_method (AnswerMethodEnum): TODO: type description here. - answer_fallback_url (string): TODO: type description here. - answer_fallback_method (AnswerFallbackMethodEnum): TODO: type - description here. - disconnect_url (string): TODO: type description here. - disconnect_method (DisconnectMethodEnum): TODO: type description - here. - username (string): TODO: type description here. - password (string): TODO: type description here. - fallback_username (string): TODO: type description here. - fallback_password (string): TODO: type description here. - tag (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "account_id": 'accountId', - "call_id": 'callId', - "application_id": 'applicationId', - "to": 'to', - "mfrom": 'from', - "call_url": 'callUrl', - "answer_url": 'answerUrl', - "answer_method": 'answerMethod', - "disconnect_method": 'disconnectMethod', - "start_time": 'startTime', - "call_timeout": 'callTimeout', - "callback_timeout": 'callbackTimeout', - "answer_fallback_url": 'answerFallbackUrl', - "answer_fallback_method": 'answerFallbackMethod', - "disconnect_url": 'disconnectUrl', - "username": 'username', - "password": 'password', - "fallback_username": 'fallbackUsername', - "fallback_password": 'fallbackPassword', - "tag": 'tag' - } - - def __init__(self, - account_id=None, - call_id=None, - application_id=None, - to=None, - mfrom=None, - call_url=None, - answer_url=None, - answer_method=None, - disconnect_method=None, - start_time=None, - call_timeout=None, - callback_timeout=None, - answer_fallback_url=None, - answer_fallback_method=None, - disconnect_url=None, - username=None, - password=None, - fallback_username=None, - fallback_password=None, - tag=None): - """Constructor for the ApiCallResponse class""" - - # Initialize members of the class - self.account_id = account_id - self.call_id = call_id - self.application_id = application_id - self.to = to - self.mfrom = mfrom - self.start_time = APIHelper.RFC3339DateTime(start_time) if start_time else None - self.call_url = call_url - self.call_timeout = call_timeout - self.callback_timeout = callback_timeout - self.answer_url = answer_url - self.answer_method = answer_method - self.answer_fallback_url = answer_fallback_url - self.answer_fallback_method = answer_fallback_method - self.disconnect_url = disconnect_url - self.disconnect_method = disconnect_method - self.username = username - self.password = password - self.fallback_username = fallback_username - self.fallback_password = fallback_password - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - account_id = dictionary.get('accountId') - call_id = dictionary.get('callId') - application_id = dictionary.get('applicationId') - to = dictionary.get('to') - mfrom = dictionary.get('from') - call_url = dictionary.get('callUrl') - answer_url = dictionary.get('answerUrl') - answer_method = dictionary.get('answerMethod') - disconnect_method = dictionary.get('disconnectMethod') - start_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("startTime")).datetime if dictionary.get("startTime") else None - call_timeout = dictionary.get('callTimeout') - callback_timeout = dictionary.get('callbackTimeout') - answer_fallback_url = dictionary.get('answerFallbackUrl') - answer_fallback_method = dictionary.get('answerFallbackMethod') - disconnect_url = dictionary.get('disconnectUrl') - username = dictionary.get('username') - password = dictionary.get('password') - fallback_username = dictionary.get('fallbackUsername') - fallback_password = dictionary.get('fallbackPassword') - tag = dictionary.get('tag') - - # Return an object of this model - return cls(account_id, - call_id, - application_id, - to, - mfrom, - call_url, - answer_url, - answer_method, - disconnect_method, - start_time, - call_timeout, - callback_timeout, - answer_fallback_url, - answer_fallback_method, - disconnect_url, - username, - password, - fallback_username, - fallback_password, - tag) diff --git a/build/lib/bandwidth/voice/models/api_call_state_response.py b/build/lib/bandwidth/voice/models/api_call_state_response.py deleted file mode 100644 index 44e740d7..00000000 --- a/build/lib/bandwidth/voice/models/api_call_state_response.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.api_helper import APIHelper - - -class ApiCallStateResponse(object): - - """Implementation of the 'ApiCallStateResponse' model. - - TODO: type model description here. - - Attributes: - call_id (string): TODO: type description here. - parent_call_id (string): TODO: type description here. - application_id (string): TODO: type description here. - account_id (string): TODO: type description here. - to (string): TODO: type description here. - mfrom (string): TODO: type description here. - direction (string): TODO: type description here. - state (StateEnum): TODO: type description here. - start_time (datetime): TODO: type description here. - answer_time (datetime): TODO: type description here. - end_time (datetime): TODO: type description here. - disconnect_cause (DisconnectCauseEnum): TODO: type description here. - error_message (string): TODO: type description here. - error_id (string): TODO: type description here. - last_update (datetime): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "call_id": 'callId', - "parent_call_id": 'parentCallId', - "application_id": 'applicationId', - "account_id": 'accountId', - "to": 'to', - "mfrom": 'from', - "direction": 'direction', - "state": 'state', - "start_time": 'startTime', - "answer_time": 'answerTime', - "end_time": 'endTime', - "disconnect_cause": 'disconnectCause', - "error_message": 'errorMessage', - "error_id": 'errorId', - "last_update": 'lastUpdate' - } - - def __init__(self, - call_id=None, - parent_call_id=None, - application_id=None, - account_id=None, - to=None, - mfrom=None, - direction=None, - state=None, - start_time=None, - answer_time=None, - end_time=None, - disconnect_cause=None, - error_message=None, - error_id=None, - last_update=None): - """Constructor for the ApiCallStateResponse class""" - - # Initialize members of the class - self.call_id = call_id - self.parent_call_id = parent_call_id - self.application_id = application_id - self.account_id = account_id - self.to = to - self.mfrom = mfrom - self.direction = direction - self.state = state - self.start_time = APIHelper.RFC3339DateTime(start_time) if start_time else None - self.answer_time = APIHelper.RFC3339DateTime(answer_time) if answer_time else None - self.end_time = APIHelper.RFC3339DateTime(end_time) if end_time else None - self.disconnect_cause = disconnect_cause - self.error_message = error_message - self.error_id = error_id - self.last_update = APIHelper.RFC3339DateTime(last_update) if last_update else None - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - call_id = dictionary.get('callId') - parent_call_id = dictionary.get('parentCallId') - application_id = dictionary.get('applicationId') - account_id = dictionary.get('accountId') - to = dictionary.get('to') - mfrom = dictionary.get('from') - direction = dictionary.get('direction') - state = dictionary.get('state') - start_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("startTime")).datetime if dictionary.get("startTime") else None - answer_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("answerTime")).datetime if dictionary.get("answerTime") else None - end_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("endTime")).datetime if dictionary.get("endTime") else None - disconnect_cause = dictionary.get('disconnectCause') - error_message = dictionary.get('errorMessage') - error_id = dictionary.get('errorId') - last_update = APIHelper.RFC3339DateTime.from_value(dictionary.get("lastUpdate")).datetime if dictionary.get("lastUpdate") else None - - # Return an object of this model - return cls(call_id, - parent_call_id, - application_id, - account_id, - to, - mfrom, - direction, - state, - start_time, - answer_time, - end_time, - disconnect_cause, - error_message, - error_id, - last_update) diff --git a/build/lib/bandwidth/voice/models/api_create_call_request.py b/build/lib/bandwidth/voice/models/api_create_call_request.py deleted file mode 100644 index 7351a3f8..00000000 --- a/build/lib/bandwidth/voice/models/api_create_call_request.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ApiCreateCallRequest(object): - - """Implementation of the 'ApiCreateCallRequest' model. - - TODO: type model description here. - - Attributes: - mfrom (string): Format is E164 - to (string): Format is E164 - call_timeout (float): TODO: type description here. - callback_timeout (float): TODO: type description here. - answer_url (string): TODO: type description here. - answer_fallback_url (string): TODO: type description here. - username (string): TODO: type description here. - password (string): TODO: type description here. - fallback_username (string): TODO: type description here. - fallback_password (string): TODO: type description here. - answer_method (AnswerMethodEnum): TODO: type description here. - answer_fallback_method (AnswerFallbackMethodEnum): TODO: type - description here. - disconnect_url (string): TODO: type description here. - disconnect_method (DisconnectMethodEnum): TODO: type description - here. - tag (string): TODO: type description here. - application_id (string): TODO: type description here. - obfuscated_to (string): TODO: type description here. - obfuscated_from (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "mfrom": 'from', - "to": 'to', - "answer_url": 'answerUrl', - "application_id": 'applicationId', - "call_timeout": 'callTimeout', - "callback_timeout": 'callbackTimeout', - "answer_fallback_url": 'answerFallbackUrl', - "username": 'username', - "password": 'password', - "fallback_username": 'fallbackUsername', - "fallback_password": 'fallbackPassword', - "answer_method": 'answerMethod', - "answer_fallback_method": 'answerFallbackMethod', - "disconnect_url": 'disconnectUrl', - "disconnect_method": 'disconnectMethod', - "tag": 'tag', - "obfuscated_to": 'obfuscatedTo', - "obfuscated_from": 'obfuscatedFrom' - } - - def __init__(self, - mfrom=None, - to=None, - answer_url=None, - application_id=None, - call_timeout=None, - callback_timeout=None, - answer_fallback_url=None, - username=None, - password=None, - fallback_username=None, - fallback_password=None, - answer_method=None, - answer_fallback_method=None, - disconnect_url=None, - disconnect_method=None, - tag=None, - obfuscated_to=None, - obfuscated_from=None): - """Constructor for the ApiCreateCallRequest class""" - - # Initialize members of the class - self.mfrom = mfrom - self.to = to - self.call_timeout = call_timeout - self.callback_timeout = callback_timeout - self.answer_url = answer_url - self.answer_fallback_url = answer_fallback_url - self.username = username - self.password = password - self.fallback_username = fallback_username - self.fallback_password = fallback_password - self.answer_method = answer_method - self.answer_fallback_method = answer_fallback_method - self.disconnect_url = disconnect_url - self.disconnect_method = disconnect_method - self.tag = tag - self.application_id = application_id - self.obfuscated_to = obfuscated_to - self.obfuscated_from = obfuscated_from - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - mfrom = dictionary.get('from') - to = dictionary.get('to') - answer_url = dictionary.get('answerUrl') - application_id = dictionary.get('applicationId') - call_timeout = dictionary.get('callTimeout') - callback_timeout = dictionary.get('callbackTimeout') - answer_fallback_url = dictionary.get('answerFallbackUrl') - username = dictionary.get('username') - password = dictionary.get('password') - fallback_username = dictionary.get('fallbackUsername') - fallback_password = dictionary.get('fallbackPassword') - answer_method = dictionary.get('answerMethod') - answer_fallback_method = dictionary.get('answerFallbackMethod') - disconnect_url = dictionary.get('disconnectUrl') - disconnect_method = dictionary.get('disconnectMethod') - tag = dictionary.get('tag') - obfuscated_to = dictionary.get('obfuscatedTo') - obfuscated_from = dictionary.get('obfuscatedFrom') - - # Return an object of this model - return cls(mfrom, - to, - answer_url, - application_id, - call_timeout, - callback_timeout, - answer_fallback_url, - username, - password, - fallback_username, - fallback_password, - answer_method, - answer_fallback_method, - disconnect_url, - disconnect_method, - tag, - obfuscated_to, - obfuscated_from) diff --git a/build/lib/bandwidth/voice/models/api_modify_call_request.py b/build/lib/bandwidth/voice/models/api_modify_call_request.py deleted file mode 100644 index 0b6872a8..00000000 --- a/build/lib/bandwidth/voice/models/api_modify_call_request.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ApiModifyCallRequest(object): - - """Implementation of the 'ApiModifyCallRequest' model. - - TODO: type model description here. - - Attributes: - state (State1Enum): TODO: type description here. - redirect_url (string): TODO: type description here. - redirect_fallback_url (string): TODO: type description here. - redirect_method (RedirectMethodEnum): TODO: type description here. - redirect_fallback_method (RedirectFallbackMethodEnum): TODO: type - description here. - username (string): TODO: type description here. - password (string): TODO: type description here. - fallback_username (string): TODO: type description here. - fallback_password (string): TODO: type description here. - tag (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "redirect_url": 'redirectUrl', - "state": 'state', - "redirect_fallback_url": 'redirectFallbackUrl', - "redirect_method": 'redirectMethod', - "redirect_fallback_method": 'redirectFallbackMethod', - "username": 'username', - "password": 'password', - "fallback_username": 'fallbackUsername', - "fallback_password": 'fallbackPassword', - "tag": 'tag' - } - - def __init__(self, - redirect_url=None, - state=None, - redirect_fallback_url=None, - redirect_method=None, - redirect_fallback_method=None, - username=None, - password=None, - fallback_username=None, - fallback_password=None, - tag=None): - """Constructor for the ApiModifyCallRequest class""" - - # Initialize members of the class - self.state = state - self.redirect_url = redirect_url - self.redirect_fallback_url = redirect_fallback_url - self.redirect_method = redirect_method - self.redirect_fallback_method = redirect_fallback_method - self.username = username - self.password = password - self.fallback_username = fallback_username - self.fallback_password = fallback_password - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - redirect_url = dictionary.get('redirectUrl') - state = dictionary.get('state') - redirect_fallback_url = dictionary.get('redirectFallbackUrl') - redirect_method = dictionary.get('redirectMethod') - redirect_fallback_method = dictionary.get('redirectFallbackMethod') - username = dictionary.get('username') - password = dictionary.get('password') - fallback_username = dictionary.get('fallbackUsername') - fallback_password = dictionary.get('fallbackPassword') - tag = dictionary.get('tag') - - # Return an object of this model - return cls(redirect_url, - state, - redirect_fallback_url, - redirect_method, - redirect_fallback_method, - username, - password, - fallback_username, - fallback_password, - tag) diff --git a/build/lib/bandwidth/voice/models/api_transcribe_recording_request.py b/build/lib/bandwidth/voice/models/api_transcribe_recording_request.py deleted file mode 100644 index 935e8303..00000000 --- a/build/lib/bandwidth/voice/models/api_transcribe_recording_request.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ApiTranscribeRecordingRequest(object): - - """Implementation of the 'ApiTranscribeRecordingRequest' model. - - TODO: type model description here. - - Attributes: - callback_url (string): TODO: type description here. - callback_method (CallbackMethodEnum): TODO: type description here. - username (string): TODO: type description here. - password (string): TODO: type description here. - tag (string): TODO: type description here. - callback_timeout (float): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "callback_url": 'callbackUrl', - "callback_method": 'callbackMethod', - "username": 'username', - "password": 'password', - "tag": 'tag', - "callback_timeout": 'callbackTimeout' - } - - def __init__(self, - callback_url=None, - callback_method=None, - username=None, - password=None, - tag=None, - callback_timeout=None): - """Constructor for the ApiTranscribeRecordingRequest class""" - - # Initialize members of the class - self.callback_url = callback_url - self.callback_method = callback_method - self.username = username - self.password = password - self.tag = tag - self.callback_timeout = callback_timeout - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - callback_url = dictionary.get('callbackUrl') - callback_method = dictionary.get('callbackMethod') - username = dictionary.get('username') - password = dictionary.get('password') - tag = dictionary.get('tag') - callback_timeout = dictionary.get('callbackTimeout') - - # Return an object of this model - return cls(callback_url, - callback_method, - username, - password, - tag, - callback_timeout) diff --git a/build/lib/bandwidth/voice/models/call_engine_modify_conference_request.py b/build/lib/bandwidth/voice/models/call_engine_modify_conference_request.py deleted file mode 100644 index 8374370d..00000000 --- a/build/lib/bandwidth/voice/models/call_engine_modify_conference_request.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class CallEngineModifyConferenceRequest(object): - - """Implementation of the 'CallEngineModifyConferenceRequest' model. - - TODO: type model description here. - - Attributes: - status (StatusEnum): TODO: type description here. - redirect_url (string): TODO: type description here. - redirect_fallback_url (string): TODO: type description here. - redirect_method (RedirectMethodEnum): TODO: type description here. - redirect_fallback_method (RedirectFallbackMethodEnum): TODO: type - description here. - username (string): TODO: type description here. - password (string): TODO: type description here. - fallback_username (string): TODO: type description here. - fallback_password (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "redirect_url": 'redirectUrl', - "status": 'status', - "redirect_fallback_url": 'redirectFallbackUrl', - "redirect_method": 'redirectMethod', - "redirect_fallback_method": 'redirectFallbackMethod', - "username": 'username', - "password": 'password', - "fallback_username": 'fallbackUsername', - "fallback_password": 'fallbackPassword' - } - - def __init__(self, - redirect_url=None, - status=None, - redirect_fallback_url=None, - redirect_method=None, - redirect_fallback_method=None, - username=None, - password=None, - fallback_username=None, - fallback_password=None): - """Constructor for the CallEngineModifyConferenceRequest class""" - - # Initialize members of the class - self.status = status - self.redirect_url = redirect_url - self.redirect_fallback_url = redirect_fallback_url - self.redirect_method = redirect_method - self.redirect_fallback_method = redirect_fallback_method - self.username = username - self.password = password - self.fallback_username = fallback_username - self.fallback_password = fallback_password - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - redirect_url = dictionary.get('redirectUrl') - status = dictionary.get('status') - redirect_fallback_url = dictionary.get('redirectFallbackUrl') - redirect_method = dictionary.get('redirectMethod') - redirect_fallback_method = dictionary.get('redirectFallbackMethod') - username = dictionary.get('username') - password = dictionary.get('password') - fallback_username = dictionary.get('fallbackUsername') - fallback_password = dictionary.get('fallbackPassword') - - # Return an object of this model - return cls(redirect_url, - status, - redirect_fallback_url, - redirect_method, - redirect_fallback_method, - username, - password, - fallback_username, - fallback_password) diff --git a/build/lib/bandwidth/voice/models/callback_method_enum.py b/build/lib/bandwidth/voice/models/callback_method_enum.py deleted file mode 100644 index b796f530..00000000 --- a/build/lib/bandwidth/voice/models/callback_method_enum.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class CallbackMethodEnum(object): - - """Implementation of the 'CallbackMethod' enum. - - TODO: type enum description here. - - Attributes: - GET: TODO: type description here. - HEAD: TODO: type description here. - POST: TODO: type description here. - PUT: TODO: type description here. - PATCH: TODO: type description here. - DELETE: TODO: type description here. - OPTIONS: TODO: type description here. - TRACE: TODO: type description here. - - """ - - GET = 'GET' - - HEAD = 'HEAD' - - POST = 'POST' - - PUT = 'PUT' - - PATCH = 'PATCH' - - DELETE = 'DELETE' - - OPTIONS = 'OPTIONS' - - TRACE = 'TRACE' diff --git a/build/lib/bandwidth/voice/models/conference_detail.py b/build/lib/bandwidth/voice/models/conference_detail.py deleted file mode 100644 index ac5503db..00000000 --- a/build/lib/bandwidth/voice/models/conference_detail.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.api_helper import APIHelper -from bandwidth.voice.models.conference_member_detail import ConferenceMemberDetail - - -class ConferenceDetail(object): - - """Implementation of the 'ConferenceDetail' model. - - TODO: type model description here. - - Attributes: - id (string): TODO: type description here. - name (string): TODO: type description here. - created_time (datetime): TODO: type description here. - completed_time (datetime): TODO: type description here. - conference_event_url (string): TODO: type description here. - conference_event_method (ConferenceEventMethodEnum): TODO: type - description here. - tag (string): TODO: type description here. - active_members (list of ConferenceMemberDetail): TODO: type - description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "id": 'id', - "name": 'name', - "created_time": 'createdTime', - "completed_time": 'completedTime', - "conference_event_url": 'conferenceEventUrl', - "conference_event_method": 'conferenceEventMethod', - "tag": 'tag', - "active_members": 'activeMembers' - } - - def __init__(self, - id=None, - name=None, - created_time=None, - completed_time=None, - conference_event_url=None, - conference_event_method=None, - tag=None, - active_members=None): - """Constructor for the ConferenceDetail class""" - - # Initialize members of the class - self.id = id - self.name = name - self.created_time = APIHelper.RFC3339DateTime(created_time) if created_time else None - self.completed_time = APIHelper.RFC3339DateTime(completed_time) if completed_time else None - self.conference_event_url = conference_event_url - self.conference_event_method = conference_event_method - self.tag = tag - self.active_members = active_members - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - id = dictionary.get('id') - name = dictionary.get('name') - created_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("createdTime")).datetime if dictionary.get("createdTime") else None - completed_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("completedTime")).datetime if dictionary.get("completedTime") else None - conference_event_url = dictionary.get('conferenceEventUrl') - conference_event_method = dictionary.get('conferenceEventMethod') - tag = dictionary.get('tag') - active_members = None - if dictionary.get('activeMembers') is not None: - active_members = [ConferenceMemberDetail.from_dictionary(x) for x in dictionary.get('activeMembers')] - - # Return an object of this model - return cls(id, - name, - created_time, - completed_time, - conference_event_url, - conference_event_method, - tag, - active_members) diff --git a/build/lib/bandwidth/voice/models/conference_event_method_enum.py b/build/lib/bandwidth/voice/models/conference_event_method_enum.py deleted file mode 100644 index 9f471b85..00000000 --- a/build/lib/bandwidth/voice/models/conference_event_method_enum.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ConferenceEventMethodEnum(object): - - """Implementation of the 'ConferenceEventMethod' enum. - - TODO: type enum description here. - - Attributes: - GET: TODO: type description here. - HEAD: TODO: type description here. - POST: TODO: type description here. - PUT: TODO: type description here. - PATCH: TODO: type description here. - DELETE: TODO: type description here. - OPTIONS: TODO: type description here. - TRACE: TODO: type description here. - - """ - - GET = 'GET' - - HEAD = 'HEAD' - - POST = 'POST' - - PUT = 'PUT' - - PATCH = 'PATCH' - - DELETE = 'DELETE' - - OPTIONS = 'OPTIONS' - - TRACE = 'TRACE' diff --git a/build/lib/bandwidth/voice/models/conference_member_detail.py b/build/lib/bandwidth/voice/models/conference_member_detail.py deleted file mode 100644 index c4bc8060..00000000 --- a/build/lib/bandwidth/voice/models/conference_member_detail.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ConferenceMemberDetail(object): - - """Implementation of the 'ConferenceMemberDetail' model. - - TODO: type model description here. - - Attributes: - call_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - member_url (string): TODO: type description here. - mute (bool): TODO: type description here. - hold (bool): TODO: type description here. - call_ids_to_coach (list of string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "call_id": 'callId', - "conference_id": 'conferenceId', - "member_url": 'memberUrl', - "mute": 'mute', - "hold": 'hold', - "call_ids_to_coach": 'callIdsToCoach' - } - - def __init__(self, - call_id=None, - conference_id=None, - member_url=None, - mute=None, - hold=None, - call_ids_to_coach=None): - """Constructor for the ConferenceMemberDetail class""" - - # Initialize members of the class - self.call_id = call_id - self.conference_id = conference_id - self.member_url = member_url - self.mute = mute - self.hold = hold - self.call_ids_to_coach = call_ids_to_coach - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - call_id = dictionary.get('callId') - conference_id = dictionary.get('conferenceId') - member_url = dictionary.get('memberUrl') - mute = dictionary.get('mute') - hold = dictionary.get('hold') - call_ids_to_coach = dictionary.get('callIdsToCoach') - - # Return an object of this model - return cls(call_id, - conference_id, - member_url, - mute, - hold, - call_ids_to_coach) diff --git a/build/lib/bandwidth/voice/models/conference_recording_metadata_response.py b/build/lib/bandwidth/voice/models/conference_recording_metadata_response.py deleted file mode 100644 index 6a12091c..00000000 --- a/build/lib/bandwidth/voice/models/conference_recording_metadata_response.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.api_helper import APIHelper - - -class ConferenceRecordingMetadataResponse(object): - - """Implementation of the 'ConferenceRecordingMetadataResponse' model. - - TODO: type model description here. - - Attributes: - account_id (string): TODO: type description here. - conference_id (string): TODO: type description here. - name (string): TODO: type description here. - recording_id (string): TODO: type description here. - duration (string): Format is ISO-8601 - channels (int): TODO: type description here. - start_time (datetime): TODO: type description here. - end_time (datetime): TODO: type description here. - file_format (FileFormatEnum): TODO: type description here. - status (Status1Enum): TODO: type description here. - media_url (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "account_id": 'accountId', - "conference_id": 'conferenceId', - "name": 'name', - "recording_id": 'recordingId', - "duration": 'duration', - "channels": 'channels', - "start_time": 'startTime', - "end_time": 'endTime', - "file_format": 'fileFormat', - "status": 'status', - "media_url": 'mediaUrl' - } - - def __init__(self, - account_id=None, - conference_id=None, - name=None, - recording_id=None, - duration=None, - channels=None, - start_time=None, - end_time=None, - file_format=None, - status=None, - media_url=None): - """Constructor for the ConferenceRecordingMetadataResponse class""" - - # Initialize members of the class - self.account_id = account_id - self.conference_id = conference_id - self.name = name - self.recording_id = recording_id - self.duration = duration - self.channels = channels - self.start_time = APIHelper.RFC3339DateTime(start_time) if start_time else None - self.end_time = APIHelper.RFC3339DateTime(end_time) if end_time else None - self.file_format = file_format - self.status = status - self.media_url = media_url - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - account_id = dictionary.get('accountId') - conference_id = dictionary.get('conferenceId') - name = dictionary.get('name') - recording_id = dictionary.get('recordingId') - duration = dictionary.get('duration') - channels = dictionary.get('channels') - start_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("startTime")).datetime if dictionary.get("startTime") else None - end_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("endTime")).datetime if dictionary.get("endTime") else None - file_format = dictionary.get('fileFormat') - status = dictionary.get('status') - media_url = dictionary.get('mediaUrl') - - # Return an object of this model - return cls(account_id, - conference_id, - name, - recording_id, - duration, - channels, - start_time, - end_time, - file_format, - status, - media_url) diff --git a/build/lib/bandwidth/voice/models/direction_enum.py b/build/lib/bandwidth/voice/models/direction_enum.py deleted file mode 100644 index 9f9cee3d..00000000 --- a/build/lib/bandwidth/voice/models/direction_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class DirectionEnum(object): - - """Implementation of the 'Direction' enum. - - TODO: type enum description here. - - Attributes: - INBOUND: TODO: type description here. - OUTBOUND: TODO: type description here. - - """ - - INBOUND = 'inbound' - - OUTBOUND = 'outbound' diff --git a/build/lib/bandwidth/voice/models/disconnect_cause_enum.py b/build/lib/bandwidth/voice/models/disconnect_cause_enum.py deleted file mode 100644 index b66b0abc..00000000 --- a/build/lib/bandwidth/voice/models/disconnect_cause_enum.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class DisconnectCauseEnum(object): - - """Implementation of the 'DisconnectCause' enum. - - TODO: type enum description here. - - Attributes: - BUSY: TODO: type description here. - CALLBACKERROR: TODO: type description here. - CANCEL: TODO: type description here. - ERROR: TODO: type description here. - HANGUP: TODO: type description here. - INVALIDBXML: TODO: type description here. - REJECTED: TODO: type description here. - TIMEOUT: TODO: type description here. - ACCOUNTLIMIT: TODO: type description here. - NODECAPACITYEXCEEDED: TODO: type description here. - UNKNOWN: TODO: type description here. - APPLICATIONERROR: TODO: type description here. - - """ - - BUSY = 'busy' - - CALLBACKERROR = 'callback-error' - - CANCEL = 'cancel' - - ERROR = 'error' - - HANGUP = 'hangup' - - INVALIDBXML = 'invalid-bxml' - - REJECTED = 'rejected' - - TIMEOUT = 'timeout' - - ACCOUNTLIMIT = 'account-limit' - - NODECAPACITYEXCEEDED = 'node-capacity-exceeded' - - UNKNOWN = 'unknown' - - APPLICATIONERROR = 'application-error' diff --git a/build/lib/bandwidth/voice/models/disconnect_method_enum.py b/build/lib/bandwidth/voice/models/disconnect_method_enum.py deleted file mode 100644 index 03da0a49..00000000 --- a/build/lib/bandwidth/voice/models/disconnect_method_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class DisconnectMethodEnum(object): - - """Implementation of the 'DisconnectMethod' enum. - - TODO: type enum description here. - - Attributes: - POST: TODO: type description here. - GET: TODO: type description here. - - """ - - POST = 'POST' - - GET = 'GET' diff --git a/build/lib/bandwidth/voice/models/file_format_enum.py b/build/lib/bandwidth/voice/models/file_format_enum.py deleted file mode 100644 index 87a4204e..00000000 --- a/build/lib/bandwidth/voice/models/file_format_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class FileFormatEnum(object): - - """Implementation of the 'FileFormat' enum. - - TODO: type enum description here. - - Attributes: - MP3: TODO: type description here. - WAV: TODO: type description here. - - """ - - MP3 = 'mp3' - - WAV = 'wav' diff --git a/build/lib/bandwidth/voice/models/modify_call_recording_state.py b/build/lib/bandwidth/voice/models/modify_call_recording_state.py deleted file mode 100644 index c31fcafc..00000000 --- a/build/lib/bandwidth/voice/models/modify_call_recording_state.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ModifyCallRecordingState(object): - - """Implementation of the 'ModifyCallRecordingState' model. - - TODO: type model description here. - - Attributes: - state (State2Enum): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "state": 'state' - } - - def __init__(self, - state=None): - """Constructor for the ModifyCallRecordingState class""" - - # Initialize members of the class - self.state = state - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - state = dictionary.get('state') - - # Return an object of this model - return cls(state) diff --git a/build/lib/bandwidth/voice/models/recording_metadata_response.py b/build/lib/bandwidth/voice/models/recording_metadata_response.py deleted file mode 100644 index 915189a1..00000000 --- a/build/lib/bandwidth/voice/models/recording_metadata_response.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.api_helper import APIHelper -from bandwidth.voice.models.transcription import Transcription - - -class RecordingMetadataResponse(object): - - """Implementation of the 'RecordingMetadataResponse' model. - - TODO: type model description here. - - Attributes: - application_id (string): TODO: type description here. - account_id (string): TODO: type description here. - call_id (string): TODO: type description here. - parent_call_id (string): TODO: type description here. - recording_id (string): TODO: type description here. - to (string): TODO: type description here. - mfrom (string): TODO: type description here. - transfer_caller_id (string): TODO: type description here. - transfer_to (string): TODO: type description here. - duration (string): Format is ISO-8601 - direction (DirectionEnum): TODO: type description here. - channels (int): TODO: type description here. - start_time (datetime): TODO: type description here. - end_time (datetime): TODO: type description here. - file_format (FileFormatEnum): TODO: type description here. - status (Status1Enum): TODO: type description here. - media_url (string): TODO: type description here. - transcription (Transcription): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "application_id": 'applicationId', - "account_id": 'accountId', - "call_id": 'callId', - "parent_call_id": 'parentCallId', - "recording_id": 'recordingId', - "to": 'to', - "mfrom": 'from', - "transfer_caller_id": 'transferCallerId', - "transfer_to": 'transferTo', - "duration": 'duration', - "direction": 'direction', - "channels": 'channels', - "start_time": 'startTime', - "end_time": 'endTime', - "file_format": 'fileFormat', - "status": 'status', - "media_url": 'mediaUrl', - "transcription": 'transcription' - } - - def __init__(self, - application_id=None, - account_id=None, - call_id=None, - parent_call_id=None, - recording_id=None, - to=None, - mfrom=None, - transfer_caller_id=None, - transfer_to=None, - duration=None, - direction=None, - channels=None, - start_time=None, - end_time=None, - file_format=None, - status=None, - media_url=None, - transcription=None): - """Constructor for the RecordingMetadataResponse class""" - - # Initialize members of the class - self.application_id = application_id - self.account_id = account_id - self.call_id = call_id - self.parent_call_id = parent_call_id - self.recording_id = recording_id - self.to = to - self.mfrom = mfrom - self.transfer_caller_id = transfer_caller_id - self.transfer_to = transfer_to - self.duration = duration - self.direction = direction - self.channels = channels - self.start_time = APIHelper.RFC3339DateTime(start_time) if start_time else None - self.end_time = APIHelper.RFC3339DateTime(end_time) if end_time else None - self.file_format = file_format - self.status = status - self.media_url = media_url - self.transcription = transcription - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - application_id = dictionary.get('applicationId') - account_id = dictionary.get('accountId') - call_id = dictionary.get('callId') - parent_call_id = dictionary.get('parentCallId') - recording_id = dictionary.get('recordingId') - to = dictionary.get('to') - mfrom = dictionary.get('from') - transfer_caller_id = dictionary.get('transferCallerId') - transfer_to = dictionary.get('transferTo') - duration = dictionary.get('duration') - direction = dictionary.get('direction') - channels = dictionary.get('channels') - start_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("startTime")).datetime if dictionary.get("startTime") else None - end_time = APIHelper.RFC3339DateTime.from_value(dictionary.get("endTime")).datetime if dictionary.get("endTime") else None - file_format = dictionary.get('fileFormat') - status = dictionary.get('status') - media_url = dictionary.get('mediaUrl') - transcription = Transcription.from_dictionary(dictionary.get('transcription')) if dictionary.get('transcription') else None - - # Return an object of this model - return cls(application_id, - account_id, - call_id, - parent_call_id, - recording_id, - to, - mfrom, - transfer_caller_id, - transfer_to, - duration, - direction, - channels, - start_time, - end_time, - file_format, - status, - media_url, - transcription) diff --git a/build/lib/bandwidth/voice/models/redirect_fallback_method_enum.py b/build/lib/bandwidth/voice/models/redirect_fallback_method_enum.py deleted file mode 100644 index 5070dc40..00000000 --- a/build/lib/bandwidth/voice/models/redirect_fallback_method_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class RedirectFallbackMethodEnum(object): - - """Implementation of the 'RedirectFallbackMethod' enum. - - TODO: type enum description here. - - Attributes: - POST: TODO: type description here. - GET: TODO: type description here. - - """ - - POST = 'POST' - - GET = 'GET' diff --git a/build/lib/bandwidth/voice/models/redirect_method_enum.py b/build/lib/bandwidth/voice/models/redirect_method_enum.py deleted file mode 100644 index 856752bd..00000000 --- a/build/lib/bandwidth/voice/models/redirect_method_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class RedirectMethodEnum(object): - - """Implementation of the 'RedirectMethod' enum. - - TODO: type enum description here. - - Attributes: - POST: TODO: type description here. - GET: TODO: type description here. - - """ - - POST = 'POST' - - GET = 'GET' diff --git a/build/lib/bandwidth/voice/models/state_1_enum.py b/build/lib/bandwidth/voice/models/state_1_enum.py deleted file mode 100644 index 6e0e9060..00000000 --- a/build/lib/bandwidth/voice/models/state_1_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class State1Enum(object): - - """Implementation of the 'State1' enum. - - TODO: type enum description here. - - Attributes: - ACTIVE: TODO: type description here. - COMPLETED: TODO: type description here. - - """ - - ACTIVE = 'active' - - COMPLETED = 'completed' diff --git a/build/lib/bandwidth/voice/models/state_2_enum.py b/build/lib/bandwidth/voice/models/state_2_enum.py deleted file mode 100644 index 310c3719..00000000 --- a/build/lib/bandwidth/voice/models/state_2_enum.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class State2Enum(object): - - """Implementation of the 'State2' enum. - - TODO: type enum description here. - - Attributes: - NOT_RECORDING: TODO: type description here. - PAUSED: TODO: type description here. - RECORDING: TODO: type description here. - - """ - - NOT_RECORDING = 'NOT_RECORDING' - - PAUSED = 'PAUSED' - - RECORDING = 'RECORDING' diff --git a/build/lib/bandwidth/voice/models/state_enum.py b/build/lib/bandwidth/voice/models/state_enum.py deleted file mode 100644 index 5fb7ff43..00000000 --- a/build/lib/bandwidth/voice/models/state_enum.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class StateEnum(object): - - """Implementation of the 'State' enum. - - TODO: type enum description here. - - Attributes: - DISCONNECTED: TODO: type description here. - ANSWERED: TODO: type description here. - INITIATED: TODO: type description here. - - """ - - DISCONNECTED = 'disconnected' - - ANSWERED = 'answered' - - INITIATED = 'initiated' diff --git a/build/lib/bandwidth/voice/models/status_1_enum.py b/build/lib/bandwidth/voice/models/status_1_enum.py deleted file mode 100644 index 52ef0e04..00000000 --- a/build/lib/bandwidth/voice/models/status_1_enum.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Status1Enum(object): - - """Implementation of the 'Status1' enum. - - TODO: type enum description here. - - Attributes: - PROCESSING: TODO: type description here. - PARTIAL: TODO: type description here. - COMPLETE: TODO: type description here. - DELETED: TODO: type description here. - ERROR: TODO: type description here. - ALREADYINPROGRESS: TODO: type description here. - - """ - - PROCESSING = 'processing' - - PARTIAL = 'partial' - - COMPLETE = 'complete' - - DELETED = 'deleted' - - ERROR = 'error' - - ALREADYINPROGRESS = 'already-in-progress' diff --git a/build/lib/bandwidth/voice/models/status_3_enum.py b/build/lib/bandwidth/voice/models/status_3_enum.py deleted file mode 100644 index d7150517..00000000 --- a/build/lib/bandwidth/voice/models/status_3_enum.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Status3Enum(object): - - """Implementation of the 'Status3' enum. - - TODO: type enum description here. - - Attributes: - NONE: TODO: type description here. - PROCESSING: TODO: type description here. - AVAILABLE: TODO: type description here. - ERROR: TODO: type description here. - TIMEOUT: TODO: type description here. - FILESIZETOOBIG: TODO: type description here. - FILESIZETOOSMALL: TODO: type description here. - - """ - - NONE = 'none' - - PROCESSING = 'processing' - - AVAILABLE = 'available' - - ERROR = 'error' - - TIMEOUT = 'timeout' - - FILESIZETOOBIG = 'file-size-too-big' - - FILESIZETOOSMALL = 'file-size-too-small' diff --git a/build/lib/bandwidth/voice/models/status_enum.py b/build/lib/bandwidth/voice/models/status_enum.py deleted file mode 100644 index 2f14dae5..00000000 --- a/build/lib/bandwidth/voice/models/status_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class StatusEnum(object): - - """Implementation of the 'Status' enum. - - TODO: type enum description here. - - Attributes: - ACTIVE: TODO: type description here. - COMPLETED: TODO: type description here. - - """ - - ACTIVE = 'active' - - COMPLETED = 'completed' diff --git a/build/lib/bandwidth/voice/models/transcript.py b/build/lib/bandwidth/voice/models/transcript.py deleted file mode 100644 index dcf4803a..00000000 --- a/build/lib/bandwidth/voice/models/transcript.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Transcript(object): - - """Implementation of the 'Transcript' model. - - TODO: type model description here. - - Attributes: - text (string): TODO: type description here. - confidence (float): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "text": 'text', - "confidence": 'confidence' - } - - def __init__(self, - text=None, - confidence=None): - """Constructor for the Transcript class""" - - # Initialize members of the class - self.text = text - self.confidence = confidence - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - text = dictionary.get('text') - confidence = dictionary.get('confidence') - - # Return an object of this model - return cls(text, - confidence) diff --git a/build/lib/bandwidth/voice/models/transcription.py b/build/lib/bandwidth/voice/models/transcription.py deleted file mode 100644 index 5e67466e..00000000 --- a/build/lib/bandwidth/voice/models/transcription.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Transcription(object): - - """Implementation of the 'Transcription' model. - - TODO: type model description here. - - Attributes: - id (string): TODO: type description here. - status (Status3Enum): TODO: type description here. - completed_time (string): TODO: type description here. - url (string): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "id": 'id', - "status": 'status', - "completed_time": 'completedTime', - "url": 'url' - } - - def __init__(self, - id=None, - status=None, - completed_time=None, - url=None): - """Constructor for the Transcription class""" - - # Initialize members of the class - self.id = id - self.status = status - self.completed_time = completed_time - self.url = url - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - id = dictionary.get('id') - status = dictionary.get('status') - completed_time = dictionary.get('completedTime') - url = dictionary.get('url') - - # Return an object of this model - return cls(id, - status, - completed_time, - url) diff --git a/build/lib/bandwidth/voice/models/transcription_response.py b/build/lib/bandwidth/voice/models/transcription_response.py deleted file mode 100644 index 0236e11a..00000000 --- a/build/lib/bandwidth/voice/models/transcription_response.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.voice.models.transcript import Transcript - - -class TranscriptionResponse(object): - - """Implementation of the 'TranscriptionResponse' model. - - TODO: type model description here. - - Attributes: - transcripts (list of Transcript): TODO: type description here. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "transcripts": 'transcripts' - } - - def __init__(self, - transcripts=None): - """Constructor for the TranscriptionResponse class""" - - # Initialize members of the class - self.transcripts = transcripts - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - transcripts = None - if dictionary.get('transcripts') is not None: - transcripts = [Transcript.from_dictionary(x) for x in dictionary.get('transcripts')] - - # Return an object of this model - return cls(transcripts) diff --git a/build/lib/bandwidth/voice/voice_client.py b/build/lib/bandwidth/voice/voice_client.py deleted file mode 100644 index 58a049dd..00000000 --- a/build/lib/bandwidth/voice/voice_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.decorators import lazy_property -from bandwidth.configuration import Configuration -from bandwidth.configuration import Environment -from bandwidth.voice.controllers.api_controller import APIController - - -class VoiceClient(object): - - @lazy_property - def client(self): - return APIController(self.config) - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace', config=None): - if config is None: - self.config = Configuration(timeout=timeout, - max_retries=max_retries, - backoff_factor=backoff_factor, - environment=environment, - base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password) - else: - self.config = config diff --git a/build/lib/bandwidth/webrtc/__init__.py b/build/lib/bandwidth/webrtc/__init__.py deleted file mode 100644 index f601a659..00000000 --- a/build/lib/bandwidth/webrtc/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -__all__ = [ - 'controllers', - 'exceptions', - 'models', - 'web_rtc_client', -] diff --git a/build/lib/bandwidth/webrtc/controllers/__init__.py b/build/lib/bandwidth/webrtc/controllers/__init__.py deleted file mode 100644 index c1660224..00000000 --- a/build/lib/bandwidth/webrtc/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -__all__ = [ - 'base_controller', - 'api_controller', -] diff --git a/build/lib/bandwidth/webrtc/controllers/api_controller.py b/build/lib/bandwidth/webrtc/controllers/api_controller.py deleted file mode 100644 index cc324876..00000000 --- a/build/lib/bandwidth/webrtc/controllers/api_controller.py +++ /dev/null @@ -1,680 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.configuration import Server -from bandwidth.http.api_response import ApiResponse -from bandwidth.webrtc.controllers.base_controller import BaseController -from bandwidth.http.auth.web_rtc_basic_auth import WebRtcBasicAuth -from bandwidth.webrtc.models.accounts_participants_response import AccountsParticipantsResponse -from bandwidth.webrtc.models.participant import Participant -from bandwidth.webrtc.models.session import Session -from bandwidth.webrtc.models.subscriptions import Subscriptions -from bandwidth.exceptions.api_exception import APIException -from bandwidth.webrtc.exceptions.error_exception import ErrorException - - -class APIController(BaseController): - - """A Controller to access Endpoints in the bandwidth API.""" - - def __init__(self, config, call_back=None): - super(APIController, self).__init__(config, call_back) - - def create_participant(self, - account_id, - body=None): - """Does a POST request to /accounts/{accountId}/participants. - - Create a new participant under this account - Participants are idempotent, so relevant parameters must be set in - this function if desired - - Args: - account_id (string): Account ID - body (Participant, optional): Participant parameters - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/participants' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise APIException('Bad Request', _response) - elif _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, AccountsParticipantsResponse.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_participant(self, - account_id, - participant_id): - """Does a GET request to /accounts/{accountId}/participants/{participantId}. - - Get participant by ID - - Args: - account_id (string): Account ID - participant_id (string): Participant ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/participants/{participantId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Participant.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def delete_participant(self, - account_id, - participant_id): - """Does a DELETE request to /accounts/{accountId}/participants/{participantId}. - - Delete participant by ID - - Args: - account_id (string): Account ID - participant_id (string): TODO: type description here. - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. No - Content - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/participants/{participantId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def create_session(self, - account_id, - body=None): - """Does a POST request to /accounts/{accountId}/sessions. - - Create a new session - Sessions are idempotent, so relevant parameters must be set in this - function if desired - - Args: - account_id (string): Account ID - body (Session, optional): Session parameters - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json', - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise APIException('Bad Request', _response) - elif _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Session.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def get_session(self, - account_id, - session_id): - """Does a GET request to /accounts/{accountId}/sessions/{sessionId}. - - Get session by ID - - Args: - account_id (string): Account ID - session_id (string): Session ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Session.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def delete_session(self, - account_id, - session_id): - """Does a DELETE request to /accounts/{accountId}/sessions/{sessionId}. - - Delete session by ID - - Args: - account_id (string): Account ID - session_id (string): Session ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. No - Content - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def list_session_participants(self, - account_id, - session_id): - """Does a GET request to /accounts/{accountId}/sessions/{sessionId}/participants. - - List participants in a session - - Args: - account_id (string): Account ID - session_id (string): Session ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Participant.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def add_participant_to_session(self, - account_id, - session_id, - participant_id, - body=None): - """Does a PUT request to /accounts/{accountId}/sessions/{sessionId}/participants/{participantId}. - - Add a participant to a session - Subscriptions can optionally be provided as part of this call - - Args: - account_id (string): Account ID - session_id (string): Session ID - participant_id (string): Participant ID - body (Subscriptions, optional): Subscriptions the participant - should be created with - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. No - Content - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants/{participantId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.put(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def remove_participant_from_session(self, - account_id, - participant_id, - session_id): - """Does a DELETE request to /accounts/{accountId}/sessions/{sessionId}/participants/{participantId}. - - Remove a participant from a session - This will automatically remove any subscriptions the participant has - associated with this session - - Args: - account_id (string): Account ID - participant_id (string): Participant ID - session_id (string): Session ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. No - Content - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants/{participantId}' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare and execute request - _request = self.config.http_client.delete(_query_url) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) - - def get_participant_subscriptions(self, - account_id, - participant_id, - session_id): - """Does a GET request to /accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions. - - Get a participant's subscriptions - - Args: - account_id (string): Account ID - participant_id (string): Participant ID - session_id (string): Session ID - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. Success - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'accept': 'application/json' - } - - # Prepare and execute request - _request = self.config.http_client.get(_query_url, headers=_headers) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - decoded = APIHelper.json_deserialize(_response.text, Subscriptions.from_dictionary) - _result = ApiResponse(_response, body=decoded) - return _result - - def update_participant_subscriptions(self, - account_id, - participant_id, - session_id, - body=None): - """Does a PUT request to /accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions. - - Update a participant's subscriptions - This is a full update that will replace the participant's - subscriptions. First call `getParticipantSubscriptions` if you need - the current subscriptions. Call this function with no `Subscriptions` - object to remove all subscriptions - - Args: - account_id (string): Account ID - participant_id (string): Participant ID - session_id (string): Session ID - body (Subscriptions, optional): Initial state - - Returns: - ApiResponse: An object with the response value as well as other - useful information such as status codes and headers. No - Content - - Raises: - APIException: When an error occurs while fetching the data from - the remote API. This exception includes the HTTP Response - code, an error message, and the HTTP body that was received in - the request. - - """ - - # Prepare query URL - _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions' - _url_path = APIHelper.append_url_with_template_parameters(_url_path, { - 'accountId': {'value': account_id, 'encode': True}, - 'participantId': {'value': participant_id, 'encode': True}, - 'sessionId': {'value': session_id, 'encode': True} - }) - _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT) - _query_builder += _url_path - _query_url = APIHelper.clean_url(_query_builder) - - # Prepare headers - _headers = { - 'content-type': 'application/json; charset=utf-8' - } - - # Prepare and execute request - _request = self.config.http_client.put(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body)) - WebRtcBasicAuth.apply(self.config, _request) - _response = self.execute_request(_request) - - # Endpoint and global error handling using HTTP status codes. - if _response.status_code == 400: - raise APIException('Bad Request', _response) - elif _response.status_code == 401: - raise APIException('Unauthorized', _response) - elif _response.status_code == 403: - raise APIException('Access Denied', _response) - elif _response.status_code == 404: - raise APIException('Not Found', _response) - elif (_response.status_code < 200) or (_response.status_code > 208): - raise ErrorException('Unexpected Error', _response) - self.validate_response(_response) - - # Return appropriate type - return ApiResponse(_response) diff --git a/build/lib/bandwidth/webrtc/controllers/base_controller.py b/build/lib/bandwidth/webrtc/controllers/base_controller.py deleted file mode 100644 index 3f7583fb..00000000 --- a/build/lib/bandwidth/webrtc/controllers/base_controller.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -from bandwidth.exceptions.api_exception import APIException - - -class BaseController(object): - - """All controllers inherit from this base class. - - Attributes: - config (Configuration): The HttpClient which a specific controller - instance will use. By default all the controller objects share - the same HttpClient. A user can use his own custom HttpClient - as well. - http_call_back (HttpCallBack): An object which holds call back - methods to be called before and after the execution of an HttpRequest. - global_headers (dict): The global headers of the API which are sent with - every request. - - """ - - def global_headers(self): - return { - 'user-agent': 'python-sdk-refs/tags/python6.13.2' - } - - def __init__(self, config, call_back=None): - self._config = config - self._http_call_back = call_back - - @property - def config(self): - return self._config - - @property - def http_call_back(self): - return self._http_call_back - - def validate_parameters(self, **kwargs): - """Validates required parameters of an endpoint. - - Args: - kwargs (dict): A dictionary of the required parameters. - - """ - for name, value in kwargs.items(): - if value is None: - raise ValueError("Required parameter {} cannot be None.".format(name)) - - def execute_request(self, request, binary=False): - """Executes an HttpRequest. - - Args: - request (HttpRequest): The HttpRequest to execute. - binary (bool): A flag which should be set to True if - a binary response is expected. - - Returns: - HttpResponse: The HttpResponse received. - - """ - # Invoke the on before request HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_before_request(request) - - # Add global headers to request - request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers) - - # Invoke the API call to fetch the response. - func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string - response = func(request) - - # Invoke the on after response HttpCallBack if specified - if self.http_call_back is not None: - self.http_call_back.on_after_response(response) - - return response - - def validate_response(self, response): - """Validates an HTTP response by checking for global errors. - - Args: - response (HttpResponse): The HttpResponse of the API call. - - """ - if (response.status_code < 200) or (response.status_code > 208): # [200,208] = HTTP OK - raise APIException('HTTP response not OK.', response) diff --git a/build/lib/bandwidth/webrtc/exceptions/__init__.py b/build/lib/bandwidth/webrtc/exceptions/__init__.py deleted file mode 100644 index 4d4907bb..00000000 --- a/build/lib/bandwidth/webrtc/exceptions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -__all__ = [ - 'error_exception', -] diff --git a/build/lib/bandwidth/webrtc/exceptions/error_exception.py b/build/lib/bandwidth/webrtc/exceptions/error_exception.py deleted file mode 100644 index a3fe4b9d..00000000 --- a/build/lib/bandwidth/webrtc/exceptions/error_exception.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.api_helper import APIHelper -import bandwidth.exceptions.api_exception - - -class ErrorException(bandwidth.exceptions.api_exception.APIException): - def __init__(self, reason, response): - """Constructor for the ErrorException class - - Args: - reason (string): The reason (or error message) for the Exception - to be raised. - response (HttpResponse): The HttpResponse of the API call. - - """ - super(ErrorException, self).__init__(reason, response) - dictionary = APIHelper.json_deserialize(self.response.text) - if isinstance(dictionary, dict): - self.unbox(dictionary) - - def unbox(self, dictionary): - """Populates the properties of this object by extracting them from a dictionary. - - Args: - dictionary (dictionary): A dictionary representation of the object as - obtained from the deserialization of the server's response. The keys - MUST match property names in the API description. - - """ - self.code = dictionary.get('code') - self.message = dictionary.get('message') diff --git a/build/lib/bandwidth/webrtc/models/__init__.py b/build/lib/bandwidth/webrtc/models/__init__.py deleted file mode 100644 index 66181a67..00000000 --- a/build/lib/bandwidth/webrtc/models/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -__all__ = [ - 'session', - 'participant', - 'subscriptions', - 'participant_subscription', - 'accounts_participants_response', - 'publish_permission_enum', -] diff --git a/build/lib/bandwidth/webrtc/models/accounts_participants_response.py b/build/lib/bandwidth/webrtc/models/accounts_participants_response.py deleted file mode 100644 index 73a27d67..00000000 --- a/build/lib/bandwidth/webrtc/models/accounts_participants_response.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.webrtc.models.participant import Participant - - -class AccountsParticipantsResponse(object): - - """Implementation of the 'Accounts Participants Response' model. - - TODO: type model description here. - - Attributes: - participant (Participant): A participant object - token (string): Auth token for the returned participant This should - be passed to the participant so that they can connect to the - platform - - """ - - # Create a mapping from Model property names to API property names - _names = { - "participant": 'participant', - "token": 'token' - } - - def __init__(self, - participant=None, - token=None): - """Constructor for the AccountsParticipantsResponse class""" - - # Initialize members of the class - self.participant = participant - self.token = token - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - participant = Participant.from_dictionary(dictionary.get('participant')) if dictionary.get('participant') else None - token = dictionary.get('token') - - # Return an object of this model - return cls(participant, - token) diff --git a/build/lib/bandwidth/webrtc/models/participant.py b/build/lib/bandwidth/webrtc/models/participant.py deleted file mode 100644 index 1341c2ea..00000000 --- a/build/lib/bandwidth/webrtc/models/participant.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.webrtc.models.subscriptions import Subscriptions - - -class Participant(object): - - """Implementation of the 'Participant' model. - - A participant object - - Attributes: - id (string): Unique id of the participant - callback_url (string): Full callback url to use for notifications - about this participant - publish_permissions (list of PublishPermissionEnum): Defines if this - participant can publish audio or video - sessions (list of string): List of session ids this participant is - associated with Capped to one - subscriptions (Subscriptions): TODO: type description here. - tag (string): User defined tag to associate with the participant - - """ - - # Create a mapping from Model property names to API property names - _names = { - "id": 'id', - "callback_url": 'callbackUrl', - "publish_permissions": 'publishPermissions', - "sessions": 'sessions', - "subscriptions": 'subscriptions', - "tag": 'tag' - } - - def __init__(self, - id=None, - callback_url=None, - publish_permissions=None, - sessions=None, - subscriptions=None, - tag=None): - """Constructor for the Participant class""" - - # Initialize members of the class - self.id = id - self.callback_url = callback_url - self.publish_permissions = publish_permissions - self.sessions = sessions - self.subscriptions = subscriptions - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - id = dictionary.get('id') - callback_url = dictionary.get('callbackUrl') - publish_permissions = dictionary.get('publishPermissions') - sessions = dictionary.get('sessions') - subscriptions = Subscriptions.from_dictionary(dictionary.get('subscriptions')) if dictionary.get('subscriptions') else None - tag = dictionary.get('tag') - - # Return an object of this model - return cls(id, - callback_url, - publish_permissions, - sessions, - subscriptions, - tag) diff --git a/build/lib/bandwidth/webrtc/models/participant_subscription.py b/build/lib/bandwidth/webrtc/models/participant_subscription.py deleted file mode 100644 index 602220dc..00000000 --- a/build/lib/bandwidth/webrtc/models/participant_subscription.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class ParticipantSubscription(object): - - """Implementation of the 'ParticipantSubscription' model. - - TODO: type model description here. - - Attributes: - participant_id (string): Participant the subscriber should be - subscribed to - - """ - - # Create a mapping from Model property names to API property names - _names = { - "participant_id": 'participantId' - } - - def __init__(self, - participant_id=None): - """Constructor for the ParticipantSubscription class""" - - # Initialize members of the class - self.participant_id = participant_id - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - participant_id = dictionary.get('participantId') - - # Return an object of this model - return cls(participant_id) diff --git a/build/lib/bandwidth/webrtc/models/publish_permission_enum.py b/build/lib/bandwidth/webrtc/models/publish_permission_enum.py deleted file mode 100644 index b49328a9..00000000 --- a/build/lib/bandwidth/webrtc/models/publish_permission_enum.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class PublishPermissionEnum(object): - - """Implementation of the 'PublishPermission' enum. - - TODO: type enum description here. - - Attributes: - AUDIO: TODO: type description here. - VIDEO: TODO: type description here. - - """ - - AUDIO = 'AUDIO' - - VIDEO = 'VIDEO' diff --git a/build/lib/bandwidth/webrtc/models/session.py b/build/lib/bandwidth/webrtc/models/session.py deleted file mode 100644 index 4dde2445..00000000 --- a/build/lib/bandwidth/webrtc/models/session.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - - -class Session(object): - - """Implementation of the 'Session' model. - - A session object - - Attributes: - id (string): Unique id of the session - tag (string): User defined tag to associate with the session - - """ - - # Create a mapping from Model property names to API property names - _names = { - "id": 'id', - "tag": 'tag' - } - - def __init__(self, - id=None, - tag=None): - """Constructor for the Session class""" - - # Initialize members of the class - self.id = id - self.tag = tag - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - id = dictionary.get('id') - tag = dictionary.get('tag') - - # Return an object of this model - return cls(id, - tag) diff --git a/build/lib/bandwidth/webrtc/models/subscriptions.py b/build/lib/bandwidth/webrtc/models/subscriptions.py deleted file mode 100644 index bde709ff..00000000 --- a/build/lib/bandwidth/webrtc/models/subscriptions.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" -from bandwidth.webrtc.models.participant_subscription import ParticipantSubscription - - -class Subscriptions(object): - - """Implementation of the 'Subscriptions' model. - - TODO: type model description here. - - Attributes: - session_id (string): Session the subscriptions are associated with If - this is the only field, the subscriber will be subscribed to all - participants in the session (including any participants that are - later added to the session) - participants (list of ParticipantSubscription): Subset of participants - to subscribe to in the session. Optional. - - """ - - # Create a mapping from Model property names to API property names - _names = { - "session_id": 'sessionId', - "participants": 'participants' - } - - def __init__(self, - session_id=None, - participants=None): - """Constructor for the Subscriptions class""" - - # Initialize members of the class - self.session_id = session_id - self.participants = participants - - @classmethod - def from_dictionary(cls, - dictionary): - """Creates an instance of this model from a dictionary - - Args: - dictionary (dictionary): A dictionary representation of the object - as obtained from the deserialization of the server's response. The - keys MUST match property names in the API description. - - Returns: - object: An instance of this structure class. - - """ - if dictionary is None: - return None - - # Extract variables from the dictionary - session_id = dictionary.get('sessionId') - participants = None - if dictionary.get('participants') is not None: - participants = [ParticipantSubscription.from_dictionary(x) for x in dictionary.get('participants')] - - # Return an object of this model - return cls(session_id, - participants) diff --git a/build/lib/bandwidth/webrtc/utils/__init__.py b/build/lib/bandwidth/webrtc/utils/__init__.py deleted file mode 100644 index eb601abb..00000000 --- a/build/lib/bandwidth/webrtc/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .transfer_util import generate_transfer_bxml diff --git a/build/lib/bandwidth/webrtc/utils/transfer_util.py b/build/lib/bandwidth/webrtc/utils/transfer_util.py deleted file mode 100644 index de7e6075..00000000 --- a/build/lib/bandwidth/webrtc/utils/transfer_util.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -transfer_util.py - -Method to generate the transfer BXML to connect WebRTC <-> phones - -@copyright Bandwidth INC -""" - -def generate_transfer_bxml(deviceToken, sip_uri='sip:sipx.webrtc.bandwidth.com:5060'): - """ - Returns BXML string with WebRTC a device token to perform a SIP transfer - """ - return f''' - - - {sip_uri} - -''' diff --git a/build/lib/bandwidth/webrtc/web_rtc_client.py b/build/lib/bandwidth/webrtc/web_rtc_client.py deleted file mode 100644 index 0541581c..00000000 --- a/build/lib/bandwidth/webrtc/web_rtc_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -bandwidth - -This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). -""" - -from bandwidth.decorators import lazy_property -from bandwidth.configuration import Configuration -from bandwidth.configuration import Environment -from bandwidth.webrtc.controllers.api_controller import APIController - - -class WebRtcClient(object): - - @lazy_property - def client(self): - return APIController(self.config) - - def __init__(self, timeout=60, max_retries=3, backoff_factor=0, - environment=Environment.PRODUCTION, - base_url='https://www.example.com', - messaging_basic_auth_user_name='TODO: Replace', - messaging_basic_auth_password='TODO: Replace', - two_factor_auth_basic_auth_user_name='TODO: Replace', - two_factor_auth_basic_auth_password='TODO: Replace', - voice_basic_auth_user_name='TODO: Replace', - voice_basic_auth_password='TODO: Replace', - web_rtc_basic_auth_user_name='TODO: Replace', - web_rtc_basic_auth_password='TODO: Replace', config=None): - if config is None: - self.config = Configuration(timeout=timeout, - max_retries=max_retries, - backoff_factor=backoff_factor, - environment=environment, - base_url=base_url, - messaging_basic_auth_user_name=messaging_basic_auth_user_name, - messaging_basic_auth_password=messaging_basic_auth_password, - two_factor_auth_basic_auth_user_name=two_factor_auth_basic_auth_user_name, - two_factor_auth_basic_auth_password=two_factor_auth_basic_auth_password, - voice_basic_auth_user_name=voice_basic_auth_user_name, - voice_basic_auth_password=voice_basic_auth_password, - web_rtc_basic_auth_user_name=web_rtc_basic_auth_user_name, - web_rtc_basic_auth_password=web_rtc_basic_auth_password) - else: - self.config = config diff --git a/dist/bandwidth-sdk-6.13.2.tar.gz b/dist/bandwidth-sdk-6.13.2.tar.gz deleted file mode 100644 index 431b5c18a2a7f2d11e1303356d2ff3ea929fc6a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49066 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

(DvL0y1UCN4 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%0A+v^-}*rBW0cL? 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%0DGaArUx6=AQ80<Veb8z{Jq<7GR8IR zewtrGWK~wCZE~Q;TC8++rg{!mD42%+5$(^<@~iH<1_R)$C<2OUhX2!-u{Qo~O7K7L z!M`h_KY>8cU^@(PSRF0JS#!*rXoeKj{jG>ziXr|5G+#oN5Eh&CI3&8(b(WzyBs7uH z3l-DS^rq)h`LpsTAWOef9!Y;qJ7{6zd`X}ra|^y4L$1n4WuE0SRCW#kVIfN!z?wlS z@3e9~d2<1gy-2;l3s5*wsW?AZ8?6{jfL5b=Aso|Hp)b@UOa~@rK|imOkzda@X^Rkg z#%63+L&uvU_-VbSqGp&+o^Hm6oFf_Z<mAUbM=)r?{&<0Vj;oR*OYH(SByXJ1$f6|v zZn~>sIXs&$Qh&@c#_&YK6)F~A%}%9a(-kgf+Ih40KG@m-Ni3?~zMlNWj|?U6*)&x_ z>4{R?LqjP~H~}&x89`agTrtD9?V`D*cL8%ztl&E^7_+5j1W+(C^QqM@4RVd7=g+WZ z^8TnrX8~(8GBfxFkK8)0^Bb-W0nJY>;|I3dWtvox?6#kWs_DSy-#n6%V{@U@D7`(v zdTZ&w$$q@XjbDAYpk*;JUGM&YvD#DPOSlX<Aqq!U2}ZhTdv3Zio!%^18-F3N7<*y} zQfN10I@0M7_|_s!g9WM(88=f>7L$hh1?rjgI$MQzacSErS)H|t_&ZzKBkgIed@pkK zBcjDOEx7d9(3M~p*_CQpLqF#vEKaEqGQ#D>nXhW)EQX_7x765>1GGz6W{+k!<?^Wn zxR^tSl*8^OPQ$z8BNWWa`99HIRa`2Kw<1hkC2~<=hlhpW1sTmMLu28aDW=r$=Y4mv z0YluV^OfQTl=8tB0uO$VSBF4I<aeTiv?=Y8Kr?az=B+(9KgLOu9EG=(C8I+n7gG-h zU;IfyTL*1DF_hE4!51OfS`jhkW)3$xCB8>IlV#9doS!G{e@@H-j;Xm&r%kth+ybZ7 zN*J0YqhJ$T-l^zU9r=;1Q6trhL})P+k%0c>P|C^{rGQ>B3UX}rwKh^xb~`AP(+Qhb zRv>qlEkHX~MuxV^1dp>yM-zW6=Ab_ki#u1^)DveOI(x2iQ3O}p-`hEAsDpy2x0u&S zBL*jNHZHyn+GX2d*<hyA&Pwca;nQDkV2H#-)^D3ID}+y<`2J5f@Slo5zwuGuNZ(2S zPm3KYlE1h5IsjXJzYFI`k=B(@krhBd%r%&Ep-jTt+|YGQ4NDS9eDX^kzf0#5G;zri zBwZ@=4)?g5@g1nj4Q)Y%0<F_jxw5r8)3?3r?P~*;3~e2&G_lSbCG6YOaevjS9rPYo z6`(TZc*cID6l2lFe7<2o;mqB09DDa>QQHxGklhQ9(8XU;qtW3zDPhATpwmTQrG07? zFL*&pB<0mrE(FO%3tduIzcB`m-Mc58P+c0ZB5*2~Cw7ULC~*9EAzz(Dejlc+9tIU? z@Ip#rQ9Y-@$Lr8IF$&{|9MMDe8JSZKJm?91em@S4+(h5h>gIA!AM#kufY1-QOz3)M zkvpy$r&&Sb+Pb1jg9Z0CmRMXK8s!E#AY#{`Q*D_=wA{H=9QRbS4s`VDmqbl#a-*A+ z<<jbXj+?3&0Wd<=ye#}eHm~=i8TLh2P*-_?AGC8rq6B@3LI2$rnRRjYgo;Rfhq7|2 zV4GzO((1INW8KfZ30<Vt(xW!n{g0h8Cr2svNXxXWtdtJamO;v<WU&J<Fm_7G8lWPQ z3)l)tb-AOGe0&+u(y6;cZ|l=OSb_lGkV_MgNmI#hjkYIF?}@?o5Ec5p;P55fW`6Ik zpIP{ScgbO#wC28@FGUv`XG7+DyL<wfX6kFRZbFkDB#q8FKx!7ofL*$)yW&Q~)}X!J zg?MSRY<7PlsdWc=Y#g<U;0!aQX^Pm%>9I0ZKlBw0$=iVTH$))iPbAAq63@-b5tmDi zKjK@Ck^&Anl@e&#l>#n5ZQBiHU?4xQHAH|eyHH%4uF6%YKvEXNV>JQJqW9~9;VHAZ zyMUTc(w<;=58OxC*Gy7o{ROjr%#idkg~1u0><+&t^KEFnGnDy;h++7FXksc13(RfE zM?i=h^fjy{7vT=;5@G&RSV%IyS6gd)bMw<4^c|~qNcShrPa8{yfl>sAPVONuTbBt- za7I!07>Xokxrj?%oZN{xF!GYDvK)2qW_VhnF}l+Cj!K~f*y;Y~C-x&q-n~*dfkb5k zhb!-3Ig@&fv}T~lUE!lqVbgIjU>>zFX+S+x&@ASv4z@o9Dk;;uQ#93<2*L~dMmE;d znJ4Q-U(BnOqo6g!q^U5(dJzgsP(-tNc=9t<jXFx|5Lm#S&fbCtq0T$Gt<8i=cQ<8) zX`+a^(JR6+mqUGolqI*aTf?(r*c}q36N`;Chhvy$!CKJrGM&W>O2`k`69&8`MOuBm z-ZaHi$lOevm{+3U7*|u1+use&z!*ODaF=#rTtt>Q-zg2F->2xTsChM^zoCwuFz~GE ze5Rsq-EqTs)6mP-H{&JUa+M4K<^72kT!fLWu41^Uo^|KhZ&eM^S~w?t3u#xrmO0y| z6Oq5B^G+Lq!-5*Pa`yUCn}YiQmN9YAyP`Z4uxvdg`VcwYL+q^>)#A$xdgwx%p#>&t z&G0phcby(PJywv(d61YTd=L?vk~FiC2rCuN2`kl=2t8HfD1%9s96j}JIQR2k(>>xx zLzG7Vl+^=LzJKS6@{d~o@A~fMwl;sP!$-%`+Xm7h1V4zqh9Y5$QSg__Bp1TfIq8`l z^7;66i#9=71;vWIz8GNS!(n^qoIb2S$aDlg@`Nmt&7c7xv0f!A25477_tGsYE0j@^ z+hi#;80F@|ZBbAUg-g?>Su8m-YRT=8p`$1<7T`X4YU~4+xxaCB;b`o4N9@SM)qR0P zXCrDvIiJg_LuJ6IHeq;{mVH}S${szz%Y+}L+G@k)IF+w;BBz73i$t*2`rH&3PC7zB z`T3G-vougZGnT2`Dw5EqJITGk!k}(j)GjewC*p=2snhb^?DA?`>z%UGdqCILa}%9l zCONGxqHT{e%ar7P|1aC{kC_YFYk<i8_LQOh&kur;xg(%Fw*e^R16EG}K4pIdF*!-r zHiHkL|03lTTjac3oH(=e2UH1oTe$`X%up~3JI&~#6-X;Y3Y*tU)q9|L5{Nbp-Nl26 zYMZ~To_B*^nbc4_Y{k0zhLkZ+#w2QFzgG%F8n#f8qhh$@be9Y=1o-?X%X*45)Jzm% zaL*()#%S~cY_|ADdxO}nn}uI!P5xRZrPUYbYQ!-y$#QnB9Jcy2I#oqLs!Uqq;aW)Z zEMmr*>&3UaA6}N2P|v?K+iEDPgi2miBm$QGClFIERwcXEJ6j&Nr(mt8w1WpZj2167 zlm_A0=h^&X=Ig~YqochkzSYb4@GkG*;4acq*?ak(#d)@@g{&ME`N{cGyy;f>a&*TM zrAv5r;|@No-u0SXn>XB|5z{;WxUO!@)&C;fk1fzc6y|NaBYpolS27%ly)P2?2qbqd z%cqT~3BISZdv`}T{vzIIxmQnts`sm|&A3&!t6GuuEH!OEtDuq6O>$urue#boDUQ8~ zjf~%}8cdI#*JyS~_nafigEccm{%SPEE+eIoNg?fC{Q<EV$edY+<QUjhW+`B1Dqrsr zHvox|WnZaLQX!DEE#aM%mRmS7wOwwYbvV(37V|Coo_o-ENQFn-Ic~vwL)dY(wKU>A z)%Xj#&fZ^ybB9VL<n90`qzrIc=>AV9<*(d{X^X($E<~UkTbndi(96|jh>O8>#%}Ud zV`yQ+)x%RlWA^=xy4xn`hE<7?NIdT!(C&U#ss2?88369Y@+td2xf3Gmbwns)6?K6s zt`Mx}ezHcMG8&ha8CwxxqB3N;X}L{F2YEE`msd%=Jz&Vwn~Oe^;O$Hf*7_N~yofP} zO^$YRGHQl$Q|RLA?hJ~Z)#I(;ny3bwgRUb!hgG72>&CE)sABj9fW__{v|Y>U$`}-o zbZ{*;F(-q$-aI+BZEiJ$=$14H>=$5tnqQjZJ{<4GKbIC}JEvcC=PfULp$qhXP~PTs zy<Q(8{ki_xo0JE+1%xgW5JHOo96}RwD`Q=N6|l9w(;xRNIF{e?Z!JlnkKSHDHJU!7 z6)_c92kQng%)fk7YPg!$x*db~;q7WI?MY^|&*0T|LG2lO$s?32Su#NnR@p-;+LqjS z?Y*J7Cy<;^)$Br4R>)6`*+T}?*VTeT1wGA#G*M8DCPjP=IZVz?r2ZT*YIy6%Y_UJl zw^DJqYbB&$i1fy_)nFDxzqoSTer~-h4SS|>kgaq{;sUf-eN=abVIf{^Jq^_Yyb!dh z3d5%ojY`bffn#_%H$5hwK<=?L?jX&r9SG@2d*eUcx6w7eRTuf8@@hys9lQIca{C;< zS9j+oGUd{$$KNoJE3ZZM4E*QVg;-#IQUH(`-2p)LUno$2OnLskuJI371KqzZBm>%s z&We8*n+G4lMV;t&m?jgJ3H}5Eu(b3NQzSZH$|*?hS0Mm(NLHeLexMO&&x;ZY0Sece zm>7fmx%u47jNFoR{Ec7s*PUsjgS)+ZwHg%-twZhzn!3W7%6)yE+%VXduo?pQkxCqu z&@7CdP_PI>N*sLEQ%CE@sjH@2hcqugFtfaAZ3gDFxGzC6hRV@m&s&6u8uWuyK1M^- zLs&3N%q$YUN#0Gi+7yLjVHbS%O1*X<HN|?WhJU4>MbMrnf~1*qxU`4BBCnVCkY5N~ zFIbWpG$ALvN`Cjk2yA@3yR2Dl)h5mf9sbo+qid<HsyfUQ%_7-iyH59fjv(SxM5SS# z9Qqmu(l;4Xr_c~ExjbR$f~+5=Wk3fA6!Vv^d5xE^sOVI0qYS67ob@!-0loYb;-P{D z)g?SKqWUEEZ_<=n!aeF;DwL8%v|^aWj~8CPlP;Hm(MsTZoHo?LgdbHei~DA$=6)SK z*J;Cr-KWlaPQcIGl$r$^sfiQ^o4HBBjym7)$uVA18m`iyCW)Vi?fOu}P$`xC{qYWX z`}$)ggdnQBqS*)Z(;5SaY@jpTM)gdmzK3!Y_{I!A$Q}?CY(pP3HwnaGV_ck^a?$eS zt80WbV#C8LE-tVQz6678bmGc-!V#j}xxW`&i_rwiH_WQt5-QlvHJ^878Fy?MiOJgz zluS-}8Oh+*L`ZKZ(j=QkN7-Ju?yI-HNQ)qUo(!lM#zbX&LXo~;wl`cXYQGIjib6AI z9)wHRmI|0~7b_Zx$NE8k#RhZpmqmFWc+ssAzyZAlEOP#rL;AneRBGM7cZ&c_DPDx% zht$j!GiMP4VXA9M*c)(6*K7GCoyJtYfJRKrQ$Jr|D-bXj5Rq2X#t*RyTHNj*(W~x0 zhgv3tXR1z0I>@!2OnU78v#K&r_C07`K8YXy&T2FWEz&U?G8OoRSeYwd*q&&z+#rD> zCGjkN^}V{IbFEx;ckjm|Vfc_vNsGGABcG)WfdS1B!FkG}xcrw!8JKTQlM(6SJ);_8 zg|%-cU|@@A-HfQI1g64Bl;UM1iES!cN-Qpc;CGB#I!2(@7}rA#_;-pMjKYqkhlG|E z^2}6UR(REmP$i>@F9W43M_crW%aECy`(ui^32%n691ZS~SCBJ8TSJNE2h;13h)myP z9;6sT+mt1)&-klNmf#L?D^7q%%BRUE#pga1dFW8tug6ExaE<omDjWnIyL!rKNfRqk za<ghJ_k2ex?`sv5=q+=lEoiPcoZ%vQWjFoF(vO}o0bf&Si2JB4c1R1X-QwfX^!|D? zC<`%>TT1;tq2p5mx3|(<^+OpnT7*ESgjJL|LL!+$hv5r<B%Sx&zMjh7L5M|~gsU}o z-cP&P`F(9!7*ADjw{_B+huKyG$rQ(Q93y)i(p95f^2IXoOrxby%9;e22vIU}eo;Nb zzPPvbLpf^D!%~ifh?Mf_3J?R#s0Q~L)c82xm#hgd{dDSKtmyKar`WG2N<*8=t)FI( zg24_)_2$t~U@b&d1j$elV4WU-WFWcAf>_Pw_+n2wdAz2sNZK&9)4J_~J9_C|c4*B# z)df%M;j5@E5$*?Qbr!OVJl5*L0lR~OV{2eGTv2Ci(S9f0To#my_zP-V5>s?*6n1;5 z3oaqwSy?xX=*!cL8_LqLzcmhhQ1v=C5SourR?aY4s8tJ=tWKI*T(=f4l8wbXeVLiI zbyzn&B7$Lb`clxhn}mPlwCPv;Q&5)5gq$6=Dk_skb8twUZ*oFBjQD`)Q}xXpN7v9% zi-ya0ns3DU{M2!(AV=E%pi0+q<oJ+Q18)7|Wnxj-!T}Y&sz$I*`*oWieuhSSDZ>LT zGJ&ESWO!a!U;Bu1Jj2f4^a8%(=9IfiQtbpjb!`&^U4hgc9Da#?1Nzdz4~fA0)f!u4 zW`-x~>vNS+0Z38aGU!X|rvodM?PWY6Hq+$WXatqn^dEiB0)BiV<VUewS33*8#>dBL zT`wUQ46yF1K({!pe&P`mrpNFbnC8h8*5f742}>3B?NfAXvwD$O=Ok1f^|&5WDa<sk zEowTDkX~g>HjMo&B9$n*C%EW@OeZ&=7+=Y`{%S1DI6txW6Fg+i>J$mfbxR7;Te>W& zz5;@#m3s``LLmvL@w&omK$P8={IcFm-68S^Q5msi52L9k+ucpKx|S8n9tu{+xDFFS z8-Ah)f1BG^FMWq~zGoF*gPJ8q-VNQ;#kdz+Sxmbqij`23cvX@_mWUz0fyZ3jG>#z( zuXC4+%Ws6qR-iX{oZdGz==OE2e6mVJVRN@Is0k)dF->a9ov*O3!^rNra_QDU@Usih z?cA!1aw?v3uVYHcO>6y!@t#B@?z+g+CuR^AnRGpH1*|YvUi45fN^CH_H0Z+U{xH>> zX^4Fzj$sUN7(Xx)kNJ<MWMhfHZYW(;%EPE!;&r)O!#wPAb#Wd<>uUcz3v@O0W((+) zJ~SlMrLAMDA{*jxocC@}>$^8PbshM`R<vjP#E`ix>dNP4jRwck0RExKuqo@?aY?!8 zqaxtuy4=+#wDAq$Yyt<rbLwG$(|d4>)HuoaJhMhEN{O&<GhMI5f>_DdS!3z8lf9`B z7LLazo>p~dqebW2zyYT;diJfeDOMn{307|3W7Bk8c$~jgTR?_J@BK?(`Pq5+veP&h z&r0LnW1DrumHHf5;*tL{QgSU3uRO{FZoz2eUs>&C@szW_-Gv(g$sOx|PVWA28v8FS zZJD6o?$$)Fz0fq@=>6#{rI65sM0*W-gr59oc#4$GAidePF0AEAXh^EH+xBnQXK%r3 zR{qA){t94e!~YLU`?{RCgwLW7yRJo$%@N#-V8wAJz;z9Vl!?tj0CF6rznTl#`RTLn z!xQ%Z$I{l11hBMi$?n1eblR%7wr~6j%2zW=HWv4Lb*<DP0(Cpo?*&7-F|I`{yBheQ z@Y`v`f!axQPn_?x=yTk=f&+y}MYyR5f(dm3K&Oi{!l$Zn5$3BselF<_CO@ZpuYF*) zznXD_@p1`Zn6wDcLXE-4cKk(w{aKHz=XbLF0}#*uGQ<C8JpWp4{3g2t!U*!-+fS28 zewb7#kppcWx@}-*_U3Q)-7o@!eiH5-Kz0vBh4NN!vuipCS;gy!mPapqsqN}>e%%zW zf@IPE3YMX8f1HQH`W-pCq1ainNer63`iSU6qTwux@s3G?B-la3V<g5ro_lMDr@0pu z_C~MYhZem3YdFgy@rLZ9V*QLpTfz*XvKNs}6vwS%BlBJ>2<Mid-A+_Frp9rx>4K5R zH;h$;ybXuX4jwfY!ta^Tmt0dlxkD=XI4J=kA}wHw`|_zsi72{VljOdXeUmY~x6CgN zkE|YV!yb2UZbG}RbpoopX_|1}e@U2g1eu_p0rC3@h~K{x8~I0H<nLTP`hON0a^t_p zULDXKy?XE@pwcUf>WBPM;JMv=g%8fyJE&_Yu2Pq0t(K*?a))DQFUI>od4mu^m4z*I z--^R^u(v%s&_4TLC~N&<RaZQTt4RjKSi)az0^*53XBY2owF!Zyz+%^j{RK13&P#0k zz2}bDCjh%nC{RBX1b25ktT4p;RdGwjY4z(P9_D3cNy*01F*N8|8ew;g^8RmKfRTs- zl^o0*RQ$FK0Y1w}Rd;nPXfP)DrcJqg#C$ANLqJEQC&(=6myp>awpv%+7%$^J=U%Lz zau({38&4IJ!4H@fV$G)+5L*NX{_BV>39I-Rq-AUyUdyAuxLGX%O*wrAL=GBIa{RB+ zWB4O_(Xq0>%e4NBfDQdB@Wg<kT_seHII@00L$TB5a*hG&7RvL*&BmX;r9y}JwW(X< zFYRgGzz0kIO2z^@=yge)KLZUgiuBb}%!#y2SmWjC$?Wl&cJqXq>|xu8mF>Tf(~iPb zl2va7p%Y=d{kZIn>;-u}T|-;s<5#k5Sh>=O3Zg`|TI)pVm6WVx)+&Zy1h1)Jp?Dfd zYOwk$pxe$^e*A?psa>25k^-Cp;S{n4$a5^~%zjrCrnt<04qq^fB@d??7*i_>N1iYt zMXpx->+#oq-GfbpthdX@iSyp~;k4Yu2Y1L<(KYx%+Kud$U-p+^_Yzg6D^3%1*)7IZ z1{ck`e=gf*u=P_>0C9u?#F6MfqvGFB;Xi~bqUE@Mcjndz_jogB{0kJsew7G}`1y4U zivPlMW_kQl35>awFaPdsoiGK1?a-)pu|AlUt@qXzGD0>p2m!`ZzQM(iJ#HG=Z@@!Y zs6wis<ylZX+~bcClvsxc&Qf7iYBZa<6^7wCT%5xt_=>;2BS3U{gVE9T1yJsaWJI5u zDFqqnq395LsYchK-k-uSaMwvH`WW_?4NZ0>6Gk*xRtcZ688LkWv5Q8CO8+!f(u3K$ zSl9~jxVjYv=*->CMYmvhW`@x_%I<ZU<wI{$qP!TT9;hoAnLAzF#g0oO9lZQJy|M2Y z62{*K2QIp?oqRddgZ3xTM6X!0&4nsztvqoHn7iL?dk;};$W9<3ai9LHlkf9J51k4i ztgnEu{yTN@f4SVwj=KN6-O&m1mVh2i@CNi7eCm0(OU~LoQxLaUGC^Ivn(qDAy9Sfu z_}!Kn-_E{<CA~m&-QCQKzD!KqE^nt?1Y%oRo?9m;-RM8ax5Mh1-`&NN<!d4+*{(6R z08`WNLcL*V<(0H{J*dQlRQR2IRk4lys6RJv`aJ{Km4vdc0o2SZ{4IMR=!<*E8)Rlh zD7e02)k*mkR>yc>J$~qorkqrfouabpZWTqXI=mP@lmJIbc0Z1TwI?b_B;3Q9tsKGd z(zrIv1QdxnJw77$btH-pK!Z*;QQ3*DueJWe@dqzUbvWMmwjLv@F7e76$w*$c*H?57 ztVmJw^a8^zJwWF4h;!j|;#_L^fmX-r;QNMy*5*GeE}x_D9P2=3mo>4;AfEYazD2gj zEtpPK%4}TIdMDW|b4Ei@*f1waK;uajJ+MlHfRdKRR@=KNaqh>g|6g{`x~AJa%>kcA z1u*FT-#-oGKcOR$-xgrI7<@tU9vaS_Bi&Wh&P2qWQ#ejSCSnHPPE9w$()Gn<YEf4= zg<^TGfC}w;{lSGXb`NY!6UiVg%)nAm8uLb;vbWog4kJ1wFbr*2hbYN{SSmOmdI;fO z3+Si#ex}e^?dc~?s;ccENFi`L6|1cvE4WtA6S#r6FUcd{W!%Y^gNTWw%6AZ-!x<}) zKlhcWz}v_l7@~U{NFiyqPL+chyQk^L2n#~0`>lQ|gczVV{=~w5(ii$(YYT!cVdX3) z*Pl$bVibYmk|U@TUQD8NADgo<quX-7hoibp>QaAyV1rP#XSoq{b51vz=H4D_w_xeJ zh6cCPbGOmc@d$mh>gU~*doihYfk>m!-E-CU;jkvk)qWhZ1sNrPYL?mOn7m9uiJq@8 zK7Q&~$$oZ&jfNgu<JfT~uBoP6bG&OvxQrK{UtUt{Bl{E5yHlFDV~U7;T+Hfc_1T!O zc{1yVK<{67)82#p8~%7DiT^u30WQ)XN;-deB#%m{cJT%Rr}T1WURq-8BhMo^NgnUl zn3X-qoc8bE7;ZjKJAM{eP|yab=m^=uU2$(f2XsA9R35jMmpF?pNq|J3BAl;&$`*Ub zEZEd$?L|R}$*c;o2-!`@PGpeXy2t43g44+BuIlxNcd+kM=;e7Yv7_X$f$>84F>GXU z?Ar1y!0)*)R%Mv%&g-<8UqeuWatKx|41rsOFtxm`tb_U^0B9V9hHcKQk1Vu*aXT!7 z4j;pq84=_D6Dl3`&1BS@%oCxW@{j(f>+i`+N4&i*!zvxOU5ElSV(WBT;nXws0<FDg zrqpk+e+KuIUKm_=00MD?{a0}RgBW4=+g>+V>CZHXmR^}a|4+~@*bavrR!i)E+u)E4 z>HGTz2YICtZ5Q(AaN+BCFRxqJ)sB{6i3J60C^iMhmx(nkU2R=z)X0-Eh2m%R`MH)1 zZAxmU8bLQy)V_EpS}~Qp6B#=`Ko4$S?z`TN`%Bf5^~Kha^*b1YSvZ*H>RLGebC{Ne z+TH>3xuSEA#v*#ImGLfL8cnC6a9Iz!KfI^SOKvX?3Vp!eG7f$8z?7*Ij8?CxC2k)# zDnA(zFp#;gSlVupV7gqaLLw=m0-8b4t`NRoj8dqNt0)xepxF%N3Y7^hl~4rcoiwI= z33Z<_Ki0e2`AxojzBTyD#>ph|aJlLEH40~H3Nq<%8rWR){*-0&G;k2ZXYd-evP2k2 z@}bo$>#M=m1XgxR_rau^b~NnigM#?-1!JUkqF)<UXvcd2iVlN_)kTd2nJMady}?K< zia7|Z?^@JOST{5=J|#lKo<qUmF70=wdtwaEk=_?kRaLul@YZ|b398}SdGRd6ng^T; zQ4446CA;3Gg&GHdZ9$T9R{PxjlhC01j?ZD63KWqdo)%&U<a#rn?oZ%&yaFPtF?^H@ zCKMxcjl}|zz(9UZ-LfiQMXq&s?S#09)YXM;EcIzKu7^ao4ljY)Iv87U9P<4tOZ$ii z5Lr~54)3+<i4u#0nUoPic6U<C#2?bW{2Um}7o2kw);f9&W+!G7Bj0k|)uZ8S#KpJ8 ze*97=*qQYlRf@&+O+ZBHPSmp)iOC4}BA&$rnFxp~di6^R#@5#MYJ5G(v^urWkir{2 zqCj9&R=(wO?Y$n?+8@P;F=re7OJ0IWYvwWrIJ#Hh{}rYG=jZ|^hk(<Y{QsR^7j)py zYEyS{f(!b06aEI%)hwC}M9tbPryHW;G6d}8Q|u6#ak0p_cSDp-K8~=3+X6NRQ!4<H zMy-~PmW~uj;%Fpn;;XuyCa0u4G)S@;!uK?wdCgx8loInyoQruv<5Uidr+QD$&Ye^$ zjhDAPzToI{^DZVnj=daPgbulSDe$6AvP*P^Ia5;U3Xu~~#EkV%{)JiNS-6Mzm!)SI zR`MGA2ssp0%souu83JW&EKfY;ZjY~Y;H@WgY<@dH(99NGc&YOi)koCn?sQF}c0({r zdoC=oj#<Ms@bpSLws@Ym7x1n%wz}Aw6r%CVO$~YdA3QA!<7I|$+G`(e0h-ZH!Cg7V z+M?_^Go`_v8x1mLaP@2cM${NpBWu?~7}w<>20*?s!P1|z$Mh*4Z>^1BvK(SADea3Y z>~aDN@dN{i*WvhnnpeHAC2p&Adr%itoj99RmE=|R5<YH6Cb&(YKzUAQp*|5rLEUty z7f>C)RwOv7dz&YRM0CiEhkxsa7jY8Z`mQ1*S|##IB5l~pZ+&08c@>WwZYT3a2cbXS zS?<U{kL^0fsp%^sc5c=wYRqoOm~2N3s&&QV6;5XQyjD^S`fO{t)mXC$>?9)FdAce& zH6CQZ^Po|<Kacefx^0~Xsu6@n+mgmBzaOIfsJPIhi-py*W&<mv<t0qG)}r;*QeqmR z9jM?1h(c$!)ZwH%NXI3)w?%~9dT_$g<{jBhjCLPy)j8dD#@ye9@x4h{W2Z9@=#Om8 zJgEoU1kZ$Sq(}qlJh{y%hWA06KL|^k#F3AJcsRsfcG^jmuh(eH)XlfT<t<rY<Js>i zTiScoWky6rJA^Zu3mG_<I(}5?_X|xS#m5TH1S1K9b;oYmyp1XN<X*^><}Q@T#SZ22 zGa;sJ9)uFi`L3rju*c>e7dQF-8OwiN5p4zlE`%8X%m2%G?@t%vUpIlg6}8Kj`4GI( zUf}~Dx(nu3XMTJ^plE>SS=6*SQzWkuCox$uVm*z~u|D#>@F`vjssrkl+TY1!G{w=o zvH)tPYGNy}D{#1)5GhJLGGfV)CPhc;ho&vAiP!FDPHGcz)5lnhH|h;L_?=$@sBMU- zaoT!!?zP%yES7BT((8PmQRK^J2Sw){RO9U+?H#b?DVDmtWgHT?1`Far=Q;5EgC<aH zA^#tHZxt3+vaAggf&_Pm;O+#1LvYvN?(R;I;BJ8g3GNcyHNoB8-66Q^x0t;rGs(`L zbN;*k;`H-0a`UcQ-PKjSx~txD850*OZ4jZ!*dZxNnB@B?aU53viC>?j0zdw3(kvH4 zBvy^-EH(~my9HS{avpzt<m6CGx~SDgLoR|0<#4vp<1^^SsW<-6hY8d~9Tmjs(jLt` zco=YU11vK;3(IV9karbTG5wDoURC_W><lI<bD!aS#_aZ*tHi7Gwn2SZ^1QPadI@%K z_dPn1J)L!opUtX5pDsHdR6NY<psKWb4uR+1^Ngy*l{CC&;P<>1gARMH3!7avk~q#t zo}b3d+wgHD*=x?3zz0K5KgV9_RNIJU+92=DvWo7TMAcQa4N4#4Y|)OJ@&tim`L?K< z?IrjS?aLfGIjud$f~i~yTsudJSC_<IIFpj=+by5hPQKcy8}J22?Th2_E1!$-p+@*C zUWw^`kwqvvw9Z-@!ma5Kvehk~(Jc$^{E(N_+4K&DEB&+i*rGLsx2FHSC+~5F?(KQs z;MK<yGZQH~4RZ6L<_j^=8?2qY_NbaJE0YL{o$n3`%8+OE?6>n;E?6N3R7Kp7z8`T8 zzn*zq9$U=Epd`hAAo~KBAYG#4R^#*a*u6mxx91t<E}o`EI+U3H(T(Ld$G{j^TDOP= z*W{wj$K;Eqp|L${+C7#-oa(+tXhS+;=-H03o?i@nz(hQP2(Y132RiOg8#`x1Jv#?| zdTnh}D^mw;ZNRFBM#}W}1V<{DDh6%JgMgl|-!(>O+$ANAXXrWNX$7g63E7$Pi5Ypm z<fmZeC1rtZp_P#ep{EjykQwZe9H5q)S_#?M00sGZL5XPO=P>{a$`a~Vmdk$&0Q}Mh z1ku*FFa^So0WpdcS|Vlvc2(jHeBm<?g(#sS1x3*h^?Gj0!-iEEyCZf<P_>S$-A>)3 zB_+?rUcd-KjbkJwxE>C~CtQQXM55?0Eg!#w$cG}=whtY%e|PV>v~$f2&-5~0%1YI; zHXsVdFU%}0{{s?Bk{qE^X(uKc3#QjM->$fh$gT-J_&J#a)PPb(vXP2F$j?XItsBU~ zR)i~O{G`NrALl_5Di!2Sm*t2)J>z>k5X~^~>D?b(O$ZbCDoyLxSL@fm*Xa~>cpOWO zC4!mw>P^5`CYmlRQvWyEn(DCZo^d4AXRe0*q4w`2Ws6oYZb||Mz-!I~b{>U|ge&IZ zF5KOeb**3+z?@!8QM7VlhGY(BQSnU7LZbPHi!UbmBEGa2=;qOZ4G^JtyXKJ)L6~9P zZbun0d&^b5QO?T*D<+!Y;bG0eL!|^68M!|3vfsm1ljlCE1if!df+E$7Bp-P(&BC9i zPs2S^j%b(+4~{OKX#8`rr7?2oR@ijJT$Dm45o7o;PGPJ}A6BCt5k=btZ16oNQ@+n@ zFtV5qd)(3*veD)-(&VCbSZnE3*ae|kX^=8vn~E#&J4IKv%Cbuu{lZIb1Q>*Ap^u!# zx%^c~Acqd%uzg?YJ?XPuHpX+aoDQ3htV*SMIgiEzOPmfriZKRlWcP70N9tGHY9$va zV>jU`s7W~`rafk=PD~Ny`0BN_)*jRcek)ij$bIg%HfU<Mm@79iyo`f~CcC{U<WS4j z^os%id%?1w<DmYnZ+|CA{|DvIY6l2~f2;tarv>1m$43^zpiD!L@r#a^r+2cPz5oG9 zv-$Om_BYS`UCA>0xz|9+vR5&OUScmvG|_sd_5`|$IM$}c_YyQ#Z8v&|1wKUi#}X-k zRA!#8H!RV;hz6nDizMch2Q?zAexp+cf*y)rhIk*{cr!(fd>o%W)kX3)MwwT?_tbbO zwaMjp^}50~zO#l#>8&J|R00V~tgIc5II>a55PwGogBbey=NtvUkWPa}0&<M4M{ca- z)aXQfH<2u<9Pxn-+i&=T33Ma+Ne=IFLbis;e1=3--y+z7zx~{wPhjzSi$A@Q*MXnd zx_u0)VKB|8bByRVRbif{CsfU3#iy5DhLpBrXeL|C47EO6Kb@#h1S*9@p?i_-BXb@y zG-V0lb){re?gb47mRCQ>dMQP77JoY=$5(|Bb4lKw(xEu&S8I$?2J~S>DcRx>r?PKy z%Uy%;vBO{0(G^PWshLxiuA`6AP?|$aP-VX&yIHH}pHUI^8L(wGR2`SLc#)P$^m%Di zU){6P!dNA1LAim{7rI60Z7*UBE&CO{I6tMFC(Ewo)C-QT_{e7PSWo@}96?*qHb@Wt z08_3lSP1{pk9m|ul>#H&uY_cUCCN!%sPrlzR+37QX+|gV-ubb=xIn$<cIkQ>GJ$O0 z1Dhi?Cs!^}YLlznYbLrgttjl%+E^V<Q_@(V-(zU;O6PdjUH>ILHitms5F0px0Nvsv zJCV;rj9h-{(2f7V<zc_|*74R?%f}{u$42R@T>|p#n)d2Vns8gh;Z!VkMMAfXDA{Jg z5K2t%jC`MzwKQpdYuOhsV2u^LB?u~D&v4#utHe{9l1fZ5^o&x}WJ5XR8TfQoN0YCr zy=+KUIDcs>LE6mf91$8UIXE=mKkc7oX}UnFp>7)ghLU<ge!BQEx<E3^5sfDGg<>v1 z+M4l!s0MZ)xv0|N6{~JEABKdTL=4z_yIR`MzA0iHJ;>Y1P#6{Snte2%^`P?kKZ$Ah z+YFDzOPXS4=KANCkOya4bvIXyS5=W+GhQ=fQ+5-+qeFQqgateD9TlS(N^u1B=4}lj zyrSqZF>}>GBAc(=R7KQw_RtBm=|_V++Ra;i=6Zrp5=Eh{Mvl~uM#CvbYPs!-w%kEx z*i=oG(AaWL&&~5KC5p}7iL-TDxk5K;MZ@rInS6^<r0Jg6nA<gq3I;P`4%_gmoRle; zJc-^YhfQ&o9#dHofPq5ok8gK@)3^IxZV)$LS7i2SqB^2SQ$ii}&gdF(G=uVjI4eR> zm{)m&*O_L)LBiLz6FF(|`S&eYqO;<B=(FBrsL4U7^h@2V8#{-0uifqK&Yc{-rQt&; zR^TKo2aKV~@wcJAoh$x0c+$d{V-?IoN#G#H>V40LUzzp|1%$q`<3T$*x9D@6C1HwJ z+q-OZ`})FWdXmoppz{-NUZt`$r^f9CPm1%7P`u4PSLMK<oBeJlm_i_qNimvepFgV@ z=NKA*5OU!}d&!(vkMaqQ1dT>=`q2buORNh!ADc0qkSw%1Td+o<cx~IfF-~r}vaox$ zx_3HRu5hBBwHSp59_7`S+^Fa@?H-bclC8?`lkYxZs(|<2xVff)oJO^H-8ncYoLYb` zB(E*a7ES5GJ_u7!?<%zxLW~+X(mpPx#eP8@`3SRpapgU6XY6YxZ3oMdNvW<W<K`;# zEgC;Ef&;8`IR*9`UqC9S1dDAxe4-@pfNsL`p)b}8nGvtCj^t_Js|MDwW}POf>?P$w zr;m|l^IE9HD~g$w&roQVzoaz<QY#_88bD1~8Q<rSu)$XAb0%#}T#Fs)rXptsMeVS> z5-6zyzqa)Ah~?_8#l7>yx9ah@=iEb?cZls=%C|d0cq#WG!>LQhDy9(hwP&5;yZw{t zs%)u4ynu=PHn}OJRcXW_d!hGBUG|ZK`okX7w)^Tvg#uZrXy<p8eB6h%MAkakZmmpy zhP3@M&<c!F+nL{UEcum;+iKcIYyxc@bJWj1U74Ld?B6rC<Z8^TQ9A{<Btp${qRzhS zO7xLF-Ex-Eft%p+b_G=z)6o_et_!SQ?#_%7Nq^3l9%qzJtP}4u^vqKSd3ksGO-wdd z1<ir+YOOhiAqxMDSm97!1<@dRsHnZ|lwS%yX8#ytqxf_T*lAd&G{I2TH9?9omc3;& zQ-{S2r`5HSO&jEqJIK%<KNhr@zMRK&?Y>T{s>(Ama96b`R&l*?-mEcXtXmCR9=r@K zAX7<z@j0<&laa=WiLw0VCL-r(LZRpgrV!JjuQD>kbFj&pcxN=`3@S{vS>2Fa=;&8z z8fHmLk}&;wiv*wVbbo!ON2H&t-6d#dE=aZ2pzisaJEgrZG0*1gS(ePqxX5fl-6N-? zb^3=3UC{fcj?$2NSGMCswp&=D+xw2!GNhg&U2Rc;={e|b4VkA^((-|}76M9XR{@+{ z7geOzGbzrQcU5oWa6YLzOYfRtNY<Q)UW(xg2wenQxodYs$0!c&aS$#0t~Se;H=`)L z8E1usgLVPQM&jww4)(JC>>{tw_+C=UUA2UVBI`TzG<V8|1Ncd}qLlsg#z$kZFprP; z6`?GjUP6!F+*h}?&iit9er371u|I-SpAAU8JgijRL`dA}JH2#nUuu{SYbQPKyw1=~ z+i`ajo}8*qD=Y~dF4?K-f+@9%Xo;(bF()ZpBB=56XK|Wm@}u4A2x@&Hh9Ow2Cujp5 zTLPcGjzrzUkh>`|t?z*d^PU)|B1Mn8<6tX}@t&?UQpyeYjICAxx3H<3+D65I6Vn|8 zng<aqm8?-yTlq$MiTP{g^0JOZy~5Uv1*^rT?`B||?t%NU!UdjeLgaulhYRKzLv2Z! zD>>D5*2uNR%c%#m<~Ra!*JX(HHfMsGh_kIJ<=}-9kV$H8*uD6w?jl{tM>5c7dJ_GZ z*c>g%Qb)aFm?JlnhJDB@1^kN)&!jq%WlxZj%7ls|Og#m)tCz9FD8I^NBL<v<v_aWy zIJV?cjNYFDhWD*BPkjcpErcN&J*y#Kr}v86!n9Jd7@JH2XjfVs!aIufLubSLF|YU7 zS4OE2cVfP6?w^lJs*Z<fT)2-RE`ALe_<LEKpM$S|vwix%x;Fn;*XIA~+WcQ#oBtoy zwfP_)$?+5<@zj65^8B|Q`&)&XfB5qJS5cesko9q&=>9t{N4#PcExKR6ILU-sgDHVi z6+|G)_UEXe|9sTH3fcU4_8*r|Qr1r#TmTO>LAk&_kz8PM2nZ*bkoSdb+H`pZ;ap|W z<Of(WtC;&6xe#7dYXNXDZ;C(eo-n2tEz)JPqt4;qsaqZ<kw&bVRH=2y4H{k(iq8QI z(nt_gBSh{t&l_uYyNf7X=2FsygFma&5c0M?Z0xwccc~A&wBDyC8CID~SoltR=ohKO z&(|A(YO7%C=tqe{TvFIlEdaMVO=*d@n915cqLa{cte|7;AKeKltqh4PBGeb|4O#Tb z6H_~S$QR2n>26FD_gOMBH4s(nKTzJTqi*?zm{q*~{TR}Vh~fiT`%8n0diugq*^!~w zwRzy~-o>Mg7A58=X|?t}pisIa@uPUSFN~RyX*fjLG8h{>9R``-J`2@HTL)|LZ;7Uj z(NyzZ|B!Q`Z`Mx^CzVE(8juH?`wZP_g`87MQYKTP7-z{#pTQ6%{k<G}S6qe-p+@S; zZ6WxD_=9RNMAdT9Rk$aaMVK+V%xe%Nv=_uCFE!BP`=f9WQt2ozWt;jZC~c&=;FFQ* zA~CSQ=%zqj<TRH?l`w}Ca?vI%!8N&^E2XI3ceK_gr<<{mW2$m45np95KV!ZXBz-2K zJHR;|D1*(Z_ab{k%d-tOkg2vVK%s7fe^mNbFKJEkQjrU5Nv>ponR|2NBw!1C^|T}v zGR^wUNSH+upItQF3-<irXjC-~^y9}2JCqCrjA$~@XtT<m*@P(|j&nNleJuh#-73P* zM|pK;5&kBCZkGa`80dcynEYGm{vB@dH{G@z<bwu^t$;PVHS?~=hH6j8(Tuh;EWZg8 z;JE&#3qIv*zn5bI5ybxdVeQ*sBn+y2B=Y7?FS_|y7P>?O=f$V|f~sfNWXGtiL6mq+ z%&UaKRF#axkI7$+HXvf^_YSc{ciiF^nCgB>FoD%o{SF*Ng7^TpTI~NIsII=gwWF1T zy|#_6or9^qsg3T_KYt@^_fY)TLV2pzF)EOh?iiRH0P+mofpdMhYJ1e4V9ud%A{I8- zDh}@UFf*$*He82;eSB?dEz=I172k?r%3q<2#X(`w-6{6kf=8VO{Zy4q;g}4jAjwc$ z3?{n}Y0(dS<bxGhkH+{pR7BqJi&oHb6bpRk%englcrD&+d_wP#ysEu9^%3#I58`lN z&XO{i>%A|zc5sXWPAW&hCtq9o>o!{W6GcgVfooaQu@f3FcBL)!w@lfS{t#aL9c5OD zIy89DQ&0L!mG5(W=|*$lOkbfL+!VYXtN=0ABc3hXpJy1^UDFib`0?mm7tX<qQR9vG zYu55}LTcu#h<RkJ1V=w7JlKQw1yZ@z3GC|3KH0}*(Hn3yl34wMOaW(w<nZj*Ur~Gk zlJV1^H81@1A_rv*0cK|=gS4tJ^6&Thtb39^N%vrNvNV|4wP~-MaPy16ZIPtf9Uoo6 zogq|72-1)&`>K3XADXs`S?YxZ$YnG5_Vg+u$R-iD5D{^%US(+sg40iyhI!JJ5XT$$ zJiF^+n!o!_O;hUkXG#WLN!Nf>SM_x<npW%8_Jb1|TvA=FKHi5NyH)n{iknoYmOf4* zM#Q=`<m|i+Yo(X3v9RYPrq>|z%=IdT6Kfx!=tNCW3Jy^`kCAY)#4(;rSlI;fZ%XgB zCPg<^$GNbjK4Z&ngYnTu0gnzwqUsucvBzBaQ8_4xs9n%vfKe;YmP&NBvQd8I6OdYx zT>R)TG{2H7ZA_9iN2(qA{3Ipw_%8Bp<|@R<l-)gEs~3lLCK7{7wf6l(*%n?}<L6$j z0s^R5&$IX}+c6o>s$7r2*}4H3Nr(=|&B6#dX8NLsKpOq%=`l)|Xo^Of2cyCs>u=pJ zJkhkk-^NVL_ctpuH!bSY^ori@D5$p?zY`P}ZfH^q5B=%|@<85V-{f(kwez;?h^nwN z9K1DI_<4`MKYaJASB=nO3e6i;N5O1Eygx7U>h=ud2_R-C2Ikj@zn>TR-<AyEQ5*s0 zxH+~z%Gv-4@Df6q=-jlhm?lxxZ@i?;D+hs;q7OhyQ5DIjan1erON54EB*dr4=9>es zTLX~x&ugr$(xXT*y5P=o>hJr+p9m?GzD%4e4hmkkO1xF?`MQZswMfv&09VLbZWw@3 zXew<Z2(UT=Zlz`6VCC5A(FS1%zx*=ljiqER>)~Qq1ZQZNglL6*ka!Pz4%-aOW-qEL zwS<L3&aDPUh;x8Mx_3>o0)*!kzgyYfmkeFCwg}3TK~6GBA|T-?-a)_WO`slkC6I6g z-Bw824J{d7dQmvJylRv=g6B|y3=tPIh}m(vn6?ND>gEC!OjgI1gX4mHm-@13AGg>3 zb)w3Hozfl0S;2AGw==0%JI%Xcep<u|^4?Ja%I$Xv&yL{x46P}!KLJZ^Y71`aJY8VI zt_ZILN-V5t-AeX=Y{7V>#vwsQ#nxNFtJf8t_y!eCG7Kq?PrTsO!bL(Hg)vUJ?KI`i zH<1<)!rikk3Iq`{pW?usn=V_W;B1EKBY1-7DThOG&g79DkUAFM-=0}M-yA3W$Yz=* z>_4;LUYe<`8y+$on>3nFvFVV!^15V~r)ur$6yg9)jmtOIN;;)wpgq%4X!~Q9d;-dg zNqKMz5GiF6ygOWocJznjl7`g{v*+eo#Y^w_zikx0yYrNn@>1VMgE?HK8}Xh{(T2f$ z9|)4_8h8T!>?2zh$W6t|tjF*|q&*upo0fr<C=-i<8eQe2F5BBr?{vgA>}`-L-!u#D z$L|_?rEUnJX74)W*C^(x9`tnPePv*lae6*oJ$vnIjFC2_a53Nfe56ga?UA5zdNc2= zHUxJuwI`?7M9wm}Toijh*RomNPeYA%juf7_!IaQ~99dtGp?)r^_l0?vjkzgq{?)df z<;Zw>l3Q2Abo#o#W6L-tC3cfS#A$-Jt>*mpsJUog2vxhF_w$a*%6WCBex_5dE7JP6 zB9GTE1o&11v%9+AQtqSfUeV%cQ!L?gPcX6e7g0E4z+}M%_Bsmd$g~<Om`fcvij3<) z++qv7|8|tMa=g=(QvHc?*M-k^g=>a%qiCdG=7#gLRxsP)3P6zo8Y8fGxjSFu%{q0q z2FWe^Qp~_qgc3SS!zC9gcjMGLQ$-g@C17zC=;?QNok-N1u}wgmL6XvAwS2c?`5x}# zve>waOQh_$6<zvXuGWO@y8-@7IF%zdqvOKH6U_ZXX1Ko6pl3IS@Ix$^^o){L7ADT` zvC+*;2srHp#{5uNiHAPrj7YoGaV>cI$0ET@s6a$CY7O69(+g0%6+ipsV&&o^3A+*C zRM&wm=Tqgz|K|PwW*D^X9rf%1Dp(tbe}#=WzU>3JUlALDlr9>e_*I5nNDB0`XJ%R4 zS5agpNfmFzs6&ecq1UPM)z6k1NQ#2wQLrH_>@FB9DllxW50J$*#T>hJ(r!*-8rXR` zdDV-Qwv7E{Cn^f_Y*}xG)$$BOk7#IuydB6zV>2uP;#VN%>8Wy}+qZ^=183HwGsb%m zC}zQ?f#PC8dJjP=77L*A+a;yCF6}%_TVy##$jgA%Sm6tjDshM7=Mu99@KEk-7E|Z6 zPI;niVB6Svd@A2Q=)xrzmr8Yk-8RrWV-1&e9f6>I)k){`rSGQw@S)?4NrladG_PWh zA$YK17>7l9yw_n@z)NUm9USgT8hB~bc~?G#Hyo?14~<?pzBJS?wgs2$vGT$XmM3c# za27Jti77_XH(;f&J1o0nAlq5)5_U^Axs<R9GZQtd;D^8I)1ysBZOM!Ep0?|$e@nG@ z6-wN*R$C#9j>umy>F|LgHGR(VK3UefAFh#}h~0;T(~2)d>0$F&w`+HH1mq<zpJvRC zp4wC>de?ZWhehD{w%O`l`yjPyy_Fw3nW4G1z6S@2P0tL%2WMe#gA4vom};B;(C}w( z(c}W+PbP8o9tR}&kmLL<?+i*=P2$XvFHBP+G1M?fvh>Jrv~Z)QK*N>ap%2B$m`uiw z&86f9Q|>4Fm%U#dY5l&|mf|5{SW#J^z!OtpUg>5kdBZuXGal`{ooxCw!=Q9RN17+z z@RSVuv6}-um^fJq!#|AvP<!*>_9irp0xAVe;%%j*(J1xjMa-krdotN~Z^Y3#YZ5SE zh}f3ER_&)GyWiGW3>j!eo!<Y#y0>9cF8ow8uo{R({h4g(7k}ocXJKk@qHSYnXK8A0 z|2KvN|33=`{*erDfbJk6BQ)(h&h0|6*K+aFab7YwIKC{@T02IGvT}Hx$^CALw;!+l zl94%w)I&;lmCn<SWE#AI0oGTO*1;_^Hk<ep2@D>kUt%c%+3O}9Ge7xP8ggqCnCf}P z-My=%UqXzpTqIxWAVj;C?i^D<oCxzn!1r82U*eD!`r8$tsj99{$5a`dsRAqs<A>8n zgpTYgi$rMmX{90q5(y(Z96G^>_b0^7*@UVCyV2V6%dT&R(uL;2n6Kc20iJ{~*Q|GX zl{*+mM=bQ{_aZ&`57?g6C#T<5zNc80s6QhQx<f3Qj$_{s1b_caB1P6CS<zFJ<1(=R ziT+{z+Z+BddcdZ@@;{=)q=f*gXCENOk)d#hJ&KlN)944)^Gt*xJ-iPIK=XWg^^vpo zy)!~xY?idSiKgx2HgOGW4Qpt}>IE5!_}32(*^#*7<+8H=M`ScXlRIi`y+Vq~D}K=7 zHWY-MZ5MkFrf$=R%jfzx&yXpS&G&Cs_?S_t<VQ=zZ_yt<DYvS*2%C$25j0+6bpBGs z`^=NgQkxZRG7mS-9K0SxnTX~#gmhd@?-M+@dg;P52idq<`+)MvbWP`Hk5PW@b{fe_ zKy9zH3L*SG^|Lqn^(eV)OBv6C!6}UnB9kC;GVJwem%}yKh3XKozb>{6rVXLVhUVxh zP=pn)^q}~3ZbO7~`XaNaAq<WVX5bB$^-VXY+Kz+wbYRDl#2sc5$n0d^mF;J|4^)kZ z#Es1A#)}N@C<yAML+Ba6C_0)&5(ubJ%%Xd{VA}Dns%{Jd+S85irh`w#okWDZCq;xn zZp7LTdk;1oZxZRGOM%y*w{P}Hr6Nzevon(U&3ou7mU{WV4<#746qJ|M$eT&)pPGb= z-gmaMca;i$MTHKUf&Qe=%Cr=}JYe;Oh(CzZdVsQey%LSYR{gcJgFz{y$=0QwjYn7) ztCF!aSZ08#d&asN%Ey#(`y;f0QKm*q7q|G<^mfWc1TJ-#cdk68)|y&_MdDNht_^lE z^RjC=SwN`Qwp!+9W5Z0sCK@RxPF2oj3m9#@$rYav4YKk(^+D`}VV)$(h0E)>S47T7 zR4Shf^_ViXMlR@@8t*%O&;00)ovm2zhpu?LmYOFj9m#{8<;dH{1@w)0ITKk3T^CBi z2A3ayIV+*vaNMT{cC@j;4gGH;0{+Yr_?xq`2h`U?;V(917ofO-V8irV-R3vpm5}(O zG}wpv6tLphsuq;;1YKf{p+Gqql21XXNzhO_(UGUeo7|pWbJ|wvufxZ?Sd#LZ?k5g^ zgz1WJZ>qi?zfSfb$E%bl<br`*70kgPF;5@IipU#*ZiOg#W$|tQpyqY~kIRFOm+u+g z$nqpUZwOxiPBwEXRTpXz3wPrNWolWuLR^!nY@Hoq?6Do<XZQn!y4hautPz6S78M`* zv1@(1{Vz>l3qIMvk9sJ_?`jvC0)gkv_;ICskpA3e$b{vl-W-00PS#NAX(#8i4=a~} zEW@tNE+BByRgNadaCM~R<s3-$j`K&U0$Z4_QE;dcL+7?t0bR9N<+)8v6X@RRj8(9( zyb`-0PTx_7-mmAjy?>}5;fhwuFtZx9K~wu$h^o+|^xVM9I9@~|Xe&=&PT$*qyo$rM z$7^^CS3H?O+xn%H?E<>sSi6N-=>%B+DylfgNrj7XYYM%VUUL?!aaMf3+_!E{$`wK| zlrbG&lC>cO8{-c!kk6VhA(pI$cRet#bOyX)2h)Ti2fK_WhMe@11OzRXZx!bB<eT;2 z`fRJrV_BidEc-G?&zV*|8`0-<U;=%|qu~Qv)6J~yh>XhT?o64re6rX<O+IzU_SETf zM{`dY&{W<X&h#gNwm3qCf9S<iCi9P8nr4`;KwS7T0?JbrVAj`;pP03aMTOFDl;ab0 zPb+x%fn!Wk@S5=@wrb$aoV^^ib8zT!qL)3L57%_c9WEm^{}g7T9!94!;kFP7lDvHN zMf_JNS1O9p%2KIF8hG@DyOt1o^_P*Urf)w)efGdGJAUI?FdU$2aOrvq^?lUVh4qM_ z%+G`M^!UAtlg;C~?NCHoePW`HLmVsr$;(*NvG;_@g(;VK=3B4n8L&2-$}{E5P56vT zU}kbij-}|AREcm#17kE&-#12~u{=c%Q*{hT0+GXsXK^naKtGCP5!s%)mCP9xF6-?u ziW*&fvKGOqA0MSTS~}#4-_SUt|Dv;u!CUnx^B^Owh?}nLfvaA84aIIZut`N$Pj^c* z&;@+r|NI$Aa1v2S3wVhqm-}09;pkv$VgL8&GYRV6A;n>8O7VVbX$jg8dfJ|Tx$b`2 zZh9&?QJDb=T5%e&@W4JY#q~{_XTPj);WWm2dcePr0sXfJum5`3A3>V{x32cnzrX@l zjM6r5WkBs%I;Es@-GQj64-8+K<v@jK#TB5QOFSDY8psh7mH!g7<WV#0sJ<KxbGhj} z2(^{O9wVxrrm84y;qIYh5m2na&IWG&(F8egS-ijrsT02<&ge5GC8PaO#12==o8izm zapD<<`;>2QblU437^DrfLgzm*cqB7OhtPCo2$XQ#JA7Nv*r-Lp>fD9dfKy3V{)Ch+ zG7x2UI2Df_cfEr!HZ<<!!di>(G9>`vfbD5NG@>Xx8>+k)7G<6Xo?tRSW+Rt@OEQr) zVghYg&8#Z9RA2g-wh8OsdfKQXXr&w22~8^Cxre}()~_JVPpI8F)C38i83b-$sU{XW z-bwq4qs_-3C`+7HAlM!G-Y)ee=dkg27YB=PE2wAmGA||`4Z-iFeca2e|C->F&)jlv z&Gf0-fbBpNK%@6`;QixsK-=EHoc1*x<10EQI)E?9f!5T@$eLbKOh8Ebt&pLDROC}^ z->q^O+jsGuQ6)tLQEp5<^e=?LNwU3+BmuQ>wg!nA_m{~~G+!){<e9Y(2NJQ^8LJMO zQl8y9-IkS4l*W>hOd)cm9e2+n2Fy5^L7vT20C(PwU8c?h$8Y;}Ep!7hj3X?)0&kFb z-rt>p^9*lMA88c3QewP#$Hd1PwlSL=cG-EM!&N!Ea}R^7Iib(&<2#1E|7^F~P6Usy zRQ8;n!DOqf`9Q$%-57ql4>miNQ2@GbBe$Q#1~VC}tgE&8Tf&#j)jX*V_yup=A;(M+ z5S}?ohp2a~+me_%OfZf;@6ZykVN9>u0+GI5mXyLoivM~r2zP#jeIPpf$-B3U&m|zu zI1)N<=!JAOBjnAl+@#H-b7u__b3oeVmY1~5plu=2PP`hVmNT9Jn6F2q+EP7^ecrh@ z1hy6N$$DMo#hF&{@xF}{xBPBdP8nPIhvT^7=dKj@It_zbqH316ol!)*`fHjBZnq+l zYQ=5`md#2fw8NkQHARd3UyJJDFK%8ltg~<vPkq4^IpbMgm6~YLS?Inj=_g;;hN37p ztlJRxq9IV8LBI;dBx`)*hTNhQ`^Dlds1Zd<EN6FY^BA6coGGsNRRXmfY7`~elq(VV zjX}NW>oUny-3Uk10A>2)k4TmMUN5X=<x#<^(ap;EV}=Zg`ZU{P%O#=g6DXIX?EP84 ziq-nKXPy)yisBPnP>p5tqnDwZUi%epKR<pBN1?<e78G&}=Twr%t7331-Ls_#^@S!F zoMQ`=bL~`6BVTr$XvGeXuYc-JHB1pJgF@JJ>OiLfd7X$S;!%has6a_mUa4RroG1V3 za<qs>5KN=T2cleIhC`28y0BXqu~4D|&0iSq@U;)6fi<)(q@T(WSeXs?PQ&@gYt4ye z&bM_-6}Mx)kwf?C&H4odVPfQxt(gvwO+@eimY)5z3_O><Br^hL=lWOE^ZR8WC8WS7 z$fv+(`9WO<lo8Q?>6ZG2jHFr?ozTiJC_3+%5|LKQ-odg`HOAZwP^LpqF!*ZP{%cA~ z!XSttp<KD~5ua+zC_Dy947U6Yl~kD$cq|Pn^~v+IT2Yrk8ndG8rJOUf$Yd~VkbKS2 zkvqC5^)KG+*XS|gf*7Mp5**p21xeHr!Yr|qxtvbbW7~RM>8v`<5|s~gMrqjv^4Mlu zg<XAZUirN(e(?_<rOI#P!uqL$CHBrsm;$2QHW)69rX~q64I<Ss4hbwu(QZqi8(yzJ z<1yPHEG>hMm&cDpWEk!gYMsk%;|ol+AGr%{f;3O+RYnt(b@#She1z;b)Z%}+bXm>u z#((*qc+zrhKA?lw8(Yy)b|s8lggIV~Tyqu^9t@+=d0iPt^ZPuVj7yDJw<n{Y``^Ar zo<@C0JNUf@V051PPwBM3A9ZC>At6baAyKJ;5jY82s=@xD3VDX{SIc()@+&>`<?^E9 zJv4N|^pN>-!wkc(UQfIlUx)4;q8~Y@nS`UD6(8u4ESIOCq>|cz7L%-zr^sWT9OxU8 zn2_rKvcCHFkmo1qBJE`lVFAeidf%T*tN&g)2WuN`3xIpsg3iIkK|;J=f^tZbvS;~M zROvU^pi}^%ju&wF@>7c5?@{H21Z3m|tJHd8Gkc@wFKdG4`r9%v2oOQN+i7&#bYHfU zkUi60G6?S#H=J|}ZOD&F$c<2S@oT7a1@qPxiR8jAe>`t&9E2RY&DC`B*lfdmc<-x9 z#Rre5G~1;y=EPmujFQ16=)2o@Vgy^Txx41GtybY{bNAjyTgNleO;w}X_7V&dr?FSI z_5)9;9_TaDO6X+1wo)fwb&44`(SVE50*d9Cc|HnJL>aGdo+qtLk$Wpplg7|-XVhVB zd2`wR9GhyX_qQXpQi`9NTjt|eko#FB<9hHU)0a`qrpLunB9eL6rS2Q$J0xH<H(YaK z%$g3;u7bJ?WGTJDk~FhGK2pJEj0RJ<imVb`fMIp$R;;jSKKgaNrY7|hUskR2kXR0( zX{A1v9a*a*7X4ZQI|S9*Wa<`O*Y@V@9y+j?vafbeJ6TqDWlO^viZb~nTLUOD&#=2= zsLAyQoJ~|dR`^Me$d?$#fl;Z;5T5vM-yV;^ct5zoG27dJK8*V;oCl@R#-?zg<Dm|T z-onrsM`sL6U)crkoo4Lg0>5@)sjgkj2|a&5@s+uf53N}*>C#`j0*~B&77AYu@@>CF z{w!^w_X&K9cH7sD=@RYKQqt^DIjYH_Etkf%R$_A+mqUi!lv*4n4`<`;f)@5>kT<o& zJzE2V0qGu9YVq~q`|PYDO5+mcg8E(3FSyrGQ$NLHL9?q<QG~&&xk+f?KA;?1rfbgE z%w?>RkE854>qUQ&N8LVOljRdmGwmE0!Ea-a!WS7|=B}o8t0rVsK)gY@_>ND1);9`s zcXR<3CZfgxQ-)im)$lDnz(u;92eGcnQ6sq@slRQ$s^=LWo-QQcQ6SzG{GD+^Rd8qk zC@ASRwoIA^j)@;k8<f8zW9KVD(~dz8KQ{>Z3A|_e(-PxUFU!eJR^Jt-q|q;r)Zc=k z?O?UOlZ%IC=BAF#DMte9qdSB`qGQqJ!X3o}ZxTLOy~Vs7g85p$_dwyzPoOb#ug`y6 zhdGyCN3!RVk9&vt&T-9Nc0MtYE{fp+YCq7v!pbRS)8rtsryTdgFt5>BKl_U>GyNTz zKK#~@+`R|l^wvzm9x4ZspDyrgFrU46o``Zpq|3;j?F;snSq{;pQEbiEOB_FKzyBku z-*hh=IWO7lm0B0R=3tkxCko!|Nme})d<Tz8Wnao$1ll6yt{f!BgnA8M%Z?XU$kidY zi!!Gi3*|*a0*ButWl*oVmFdGNQ3jqF(L>S=_6KZ4P`u~m#P0GL_LmL%6txyGCwCOc zeJ#w$g-w6lCdK(J{TrDXD2xhRc9<m_kw%jue4}wyWFt!M$Gp!Zwr-0G?q!)Z8hpH{ z1FRYOJ#AMkcWh*u8>-dTMeeG;pY0Rqw~0m#15?Z1R*?(PjlXin0(F!SS|`0DhHtcb zp^Z|S{joAl4#S!4YxkX`PYWC|1vo83qI5?sI4vmKr`WAgoR*4=2M%v#k^Sdep~X8D z-U~Ce0m7HVBp>i0{h6Ri6kpyO^;^uF=mpKobxVvdk>3$Ax~k+(^GAJF;cg>`#-Gz~ zY;7|0c{mO+bG+|%8EshKcqsFg3wjs)7^l=Z(%q;8kCwP5R<NG<D$;TuC*IY|jGj^* z5=`eIT8iUv-)6f6);i<1JU2Yo2)T{1_ZSJJ9`u7$vOk?<b`pZ}i6Erc){sH%<o;2S zyWCxg!lU@(oz%G_`KS266}uX5cax+A1~1H={;2N)6oIQBrKMBw)7`GQ%3n1Jtb9Yd z8}wFAMmvS3Ni_SWJziA|t;Y5;A6_y+qcazRRa)7^KgTUZXi<L*Daa++ND4KMULfHk znMYcFW4mzu;@KOk3bfp0MbjyH)lYk51?-lqgQZ)G(wo$0<PEhf-8B!}9*?|3{B&T- zS8|0|NX2eWT=Vb}wsnGnEy4$Uk~Dg+YG8C?;s$mPbZ{S;l9v4NT?d<>Uf1b<Sx|8s zwQ06f@UyG}wX(~~Ba7TKtjLE1KN)~;`3g@H5>vakx?RK=zF{8@5tTa}nPO)B_AL^z zYmzP8*R4JUe7`;dA1@R<0!Hh3``Q_(eaGT^o%~gb%hb{@flPzhP%lC67xAg2=G;`a zd)9~;xAsR*p#(CSz^l8*4-rA{n0)YWPcw8`;~-cltQjTrl}cJ?c3)z?V{;|2g}vF< zk&{(V4!yHL*~wwrHix@vVY=EuVIr8HnE%+3XzAnUkq>>bD_cV?HdAkrH1@U5snyOb zG-~Do!gpzBEq5mbnI^Xy+||GV{|Gj{9yGo-QiNsF3e722{do68G$#_${&N0p&Fjmi zK99-bsb(xNZ|||aUG#IC1FUM_b$B&9y#xZbCaiU?9z_GR8ayG7kUL|}`?TFk-Mu}Y zH&#`0qmAx{pT?+`(KGv-DuY*Bm3_Nw5(!2(tCtv#DaXEL@26I{7aS-^pF3w%Vj!=A zb7=`kZO^}I9hh`AUxcJcBlrTtFDE~W$0vLBzWt))#hqJyiO>T9Q9JuU39YS4T6|N_ z#)n2mgupe6szT~uBisNA^KQv8yc_%v>*wonu4h1f$6oHC{h`~JHB5qqXSNr)a<ZeU znlr1VA;~T^2u{s0TOv&}axchuh9ZZ|P3+;(UN70HVaExsBwxgu->=WV8mb_*W!T4^ zbhpGisITyC8IsvEo_LhLwz=&q*}h>2{bJ0wXErWgn)sY^oyri#9?@0()m1#U!V%-O zr+uAN2)S$-{{dn=|0B%m675;XeiXF8MxR6_k&ci=_Lpn3)d+iPIYdZP!KUndHzD+m z*>m+!fyYFz+}ggF4dZ$I`0oiBin1X{3`rwO4b>(W-BLIw7U=9@&7fPJZ(a(R25i^# z#XXX(;`gUoRa->V%owF_G{c$sA~w$xk+!7<I}v!asT;C2&LQN_(yKoTlntRRgP*gK zKN4x^G94C)+KN<F+Gmu2)o@<uB6*pgimr#DDY=dp#U5dA&1sIIY_Y8y@~j{C`DsR9 zgQb-7Z^fx&V=a=xD}ePQwj8xks9^5AtTJ^v9m#QhzjA`Z($hEX=HPkz;MD&SEk%w^ zR}(89l+ZdB`G8=*i5<~cKkAakeug|uW6`?{-fe6Bt7Yq#j?du<OY7&wk`%ZOxpWAK zFIp-Yxj*_<M<x_&1%)Qg_|NVW91*WyF5C~Z8h|iW4BWXX+RaF8#S8_m)v*y>3@Dwx ztX;}~7SJrG<Z)n$?ZvYUVXydA&3ZJ-L$n_*n`2N2<{FGoWr%SehW7dZk#<TdJIaW5 z)-;BFon=2%1M{Y7*iYnfQ;Zp#lOwihHOaZ~1xT3_6POQgiBTRQWW$o&q5KMzv&6}= zp)i-^9BZZ`PuNEj4O@yyBEhtxsN^X&P=hqC0184?Hyl1^Ha<`PhoYgz`ztP$+q{WH zOL+ZPY@^2ca*}>CFt77+in-~<HwTO<AZi^zSWjPgLM?5KaOzXFsw+3n4SWg{`*M(f ztBO`?BB&ff`XTEhE+qs=*Bbwu>GbIaoM?n)Yvp`fjH#7Zd|+7--Ip}hLUGX6&+h_q zlN$o#HV_?-XKE_HU~<1fcD8Pivj0jV`uSkRdBpy-h}3|OyVIbR8xGZ;Tk19+I<e@! zn#3Z*1A)6f56BFk*I3|0dh|-U5x6MEy{GQrwvqhqW}DEH#c*ty>a&Tyl4N2&109;) z^}TABE<n8x{2SL)f5}*x$Jcaqw^Li9yyy;U{W@v46g+F99FrJc?&3{TZVghV{TA1S zB)T(Fr@hF-=zAO6+D-?Vl-C+qP=N{;POA4Jy)sQ^wa4L<@_27{`;aW1uBJq8;NGE3 zmF{E|rE-@n2@i$N2`Kcc9F-Y*dwj2vYP+yOPV$4K6uy>Q8w5)3a$?>Jf_O$5Na4Ai ztAHO?zfY0wOV`67)b8Q_qAr>|!v!R|lX+vZeuPJuNSK9D30#3s&y#6ih7{VNPXv!R z*_^o>Tur7!phB!;Lef$EM5=%XaY2bg^69dWCA&NU0scUDFOVVFL+HpOG)2Vsj@jp& zAP##G6AVSnX(krksomsudy}>g97!`kx<>L0zOD3|m&mp75lwSUy03hnM!tfNnd9fQ zMM{zH#cL+LY-B*DM@9#l$Q5ZFTrt==i#xAUiHvI<JQQs~w?m1#L|wA&%Ay)XSXkEw zMmkAO-LQ2<Vu8Ln_q#ZPMdFy|f^2V1(;c&vFuB5-G4A6ca$AseMkhs<aV>WBq&%+b z;N`x%!!?eRjCApol7jp(g701CuUg9Lf=X2jX`t+>Oly1!n2TX4KF`@ALs=Wc$ZMnX zEp@7|O{)a(R!Uiwyc>++BkR3OAg0*!@-KAtnQL1i$cP<JCLY?z?S&qf@`$1jO~b#l zI^r=Irfhnizl%T5u!mTZYg-nmfzsCIM>3b;v`|oe8ETF+G3SeQgD>02vFWR=EWPjC z!CqT~OfAo6*O1)ls9qV-{t~1)kX^D6$Iwa()Bmw`v=V=9`7juY%K2n^Zv&MFdzd#5 zC|Au*h_4P3uo10+#7wW^{tC7`j^jRjSrJuI`PyQ4GC4PVt(ARt+-Z32<#UVr)JRvo z7fJKDmk(;M6DhCDdk~VfFMAqZh|=$~fec0F&*?3DAeh84yjZKB&m9F#R`74TGAj3_ zGka~!?{3ldI2m+@bU!x2=0Lk+%YpvYWByg_Hg2>SZd`w)x5zS3RDRq+$GV)6FpU%R z`EexpeaTS!lIhnJ|E5q8Y_;q(Qx6m*>M<*kv-Y!`F3DBL51?bhnfK=(^`UCqM&3QR zzuB+147)PL){ba-{jCbSPZn(Wd^TRo;$6?NcnB%PCeGvvDF@nVDD;(1y>Ao-{Nd>_ zMjbknEf5Me+4nirWBOo<jVI>gr}+!Kp7ygO-PywR_(t}zNT~zJli1?O+Bu^PZRO+= zt(naXI?6rUrr0`UZGZUy+$J1Be;j>e%^NpA|IhkE;LNt_@b9_qFAYlA?UYb0lUHAn z?SZ&L6wib=7%Xai$v;LM>=2A4Vnlao3KuzCf?Bk1+&G%++oWctw{0<V=m(c_!*dd% z7=ycEnBNbKf<fP30!eWaZ1Xj?Kb>0^v3-ouf7`jT0ozk-P=+xaKzjeVm}!nN6otx+ zX0D^If%p2Osc43D3TXE{Svkhb^@RM;B^6Jw^Q{46?+(yORX$K=egBA@!ljdd%0o(( zSE`<uq;~8)#T@B3_eu{(TgDZPmb{(~kS+t`DHnYt*BYFcpgP;v&rMNInNoXCKPDd% z5uR6?xDxLlvZ}-Q;O}h(?<7hG%qd(O;A_e9uh_)a`(!5-lJS!X7^e|GJ9k%sY*g|Y zEsG3M9f%Kw;*5X8Yqo{ZYmL<5_}SX?*f{E2Km<l(ZbQ0;8AKbu&;Gk0?j$T}R$3+F z=5tuQn}ZK(T*{#}@r%NacM^;Az2Y2Mbn5zYTAv%YcJ-INTdMM-1PhKIf{MAFP{X-C z#{?{Xptoq2iCsz;JYL?~Kmm7=kQ`VGlX7?Y+O);mnO2{<-~L<*_LiopVwc2us>0Fk z^($Bp+;v{N_OVS9o?sI`lc@Q&1^I@4$(k7(BusUg=!rdBtV~LqrGW*!jV%7f58Jst zSM5q2))x=@Iy6)gHS!$A&5UXb0*87A6SiCDBvK?=b>#`*5VnG@fmy7?w|eW3qUW3_ zHOqJ1_;+zjTHQ%{<YoDvPDQ=oQKwkLF)-8ipmGDrrn4R9&1H{YvU8$B@Tx_p4lynj zUQg0L%nNj>MnFFBXsrckp+CGU+-sUZ=%R8YhBX$k%1%6PG`VU6R&MIrrMks=XBpbr z9P<U_fJg1Ct>;OSjyC?ERduXgl`lFzG`#32&lxyZ%PVrmy0wgQXYX)dcTGm=5ARlN zPC<MoS|0{YR;wl0HJRS}whgsb;<Ih)URkcN<K;vCGTu;4Ly2W{$=!+!#D}>xI2BFF zw8^R$stp0p*!KLeolW40p*K&)ssaY+f>;f2xVo15mWDL0a*kyTAOeJkiAoJ%ieAJV z)x9q*Deu)*#}8h=1u4{YE%YHe@UPixk@<4L+gClp6=uL7&fs;jHXiP{>Wlm4xO4*? zlD*d2NP@gwCHkt!kgq$p>>d~VadKyevwhSz!~p_nYcKzsO#&~1pWVqJnQ?_O2-)i* zj>55o#puH^y1UQ=mcD}P??^2ek2&?z;JL*+gaQ$0_&I3UQ$_(?#UNnnAagzH;_hk< zOLO#R<n^}lVxRfDF1FWe_y{D66i3+*O^hVbjLN11rS(xMaxP-wQ~P$E9j;^?@^FJB z#!joerbwIYoVA)RS@%}s#M#deMyFP4V|RMsNANCcsvf;92?Is8DyjMWUO=IP4#Fca zd}T7WO%C#^7nF1r6P_#}c5Hi4P+KhRdRXfer1=`SZ(lK_X0gJR?PCgwCjAlOc}?Hz zCR5hN9$LN*y7`FaM~KKfs1n?FPzf-aUlo1cRUVqazosGlQXA3Fq%yw{6@(mlTyBX? zQueLo@mX=*cSNkZjJ!<9e8`1UdXams>m<Sriqt9)R&$%W5NRDx$2{I}k=p}#!EtD! zN$j2Cj&89S1N(3)p+sruDQ&JREuA$vthXU_el>H=GNik#SNJ8m(WteAZ4k+QNFwk_ z7-3V-6HAkt3?wuKoo4Ys@t28-of(4MKfgLW(#{vMZbL&_?aa_t9154er@NSSfJjFU zYLh<8<|t6kC%;*nQ?5C@8zqLXCv?AVF|7LRV9<dC9!}B38XJPJEOuDR9g}%!V(F&e zqql;NFc{&(!~bxXv(u*Eyn2QK%M|}r$-383Z1p25jvEiSAQlc>&w#o2KE1$~)#W*T zkQ1bvCG2qR=Jy;p_<N#x&r9t|;GfIRe6tjZUSxPvtA}0Zrz)XzAe5~LH<v-s<BWXo zv!#s{@&3r28xLoWvTOxWnTHxCZ0?muU=#+V_C7OV&-#IpAhaguSDw3Lo^z!8Ta!C8 zBF}k-spYg#FaK2zoROS~wJKf}Sz+bC+e|$YH28wCY`vZV$HoTjTfWn4(fyk)kB^^o z)eJT}#32z}ll;8CQeEVeD~4)avkl|yqz~=F6Y&IIw3TA*rC+Lj!#QEFzOT{N`iNr_ zTvDD(kgi%_uZCL!4wa=^VI&d{j!B}OYi8rKwi9Gg&(}gP{Q$X!GIHv|fUZboFLZ5_ z{~6WNCodAgna&3iDwZYsR#@Q(X;HJZ%WAFw<NO$Daj$Fnli-Jssx3WoR;{nXOJnA8 zg2h8oh*j(~I~aQS8U=%MOynb_KwB`n9%Ia5dmD!uUmp}S9%^6BF|ATL1`K*vsU|wv zZmz?kwzJ9NQm_}mp-S7GVnlS#)#TO>CEQ%$+@X|HsatT31;vuPGZ7+UN6EW=<N!)* z4z`WBy~{Qx*eH#4g8{wAy)lhR;q8pm3y@3CbJoTCX7!Nswr!3P@@!5v5Kn1|-8ZqK zx}G?^!k2KjV|HoLPMhqouuFUpPbQBCH?3)5K%!B#Ogcj^4iSCZ?{uv6vU-Id)_EFc z<pKWg^kKy9_WW8unE3>c_0;`^z~yGkaCbxbHzy-{Q$13fcn=|J6_AQOkG+(k)Gw|c z4$pzCk#+p5)PWs@H(KNakK(N<oO|>1Q2iFSBp-Mxwb3cy665XGmCRs4&0sj$oiTI- z4^<Q#DQeNqD*$g6$L?!n>ickR<e(%i&6wFjbxUpLA1sPJRmAD0(^v7Fr*v_^*(0%# z-*paW-}-2ZxJ&HYJHKp8o=^@Q=P!9&<V}GAMdJ|MmWx`foJVFOU2@8Z4W>@0cdXkr z)SGrVQGM?NT(8b;Khv*%{yv=Ok%J|V+sgK4yO!91WEt<Wc<~ssM`gxK-WbyRedciO zy^y|h!{ap&?Dz~6^*JhVWd8zW4LHQVzGP*2N_NNrIvUXbY+2q<fBm@a{QC{|uMlGl zBVOQeARzZZ`9<L1{zuF5PW%bti4nrY&;p1&11_b11@VS?bhHERS>1tnY`h;3ARt-Z z69DvIa{Tz~FCvv+p$OT`tm7a+K#~bTK(K#;@<IGN)KdjoQ)5Rv-G7H|{)(fMD6)VK z+;?38{pa_R1OELX2)%(JP<TSu!P@RAn&wv!Vz21nr+ee44#@MPWqBuI{vG7M&~^L@ z_xBvqry!p{TbB1Ttp5i0pQ)t3q9&uflYY8idg=s!LIS_Dyjy{}`0Gu7Bv<_u(eNwU zD~`3dp1_zn0KrI4H#mQ`EN_yR{{`(yHGY8qW)#WI35k>eoD87<Jf$1>e}^=2aIpC& zRrSta9wGp=j1N!`K$agZ%iDqAKX9Ie`dgCBudjKK!ywoLyru!zuY)#B^dDGHf&sOZ zEG)F2Dp3FC4N;#HmB#=BrVOwb{jC2}z^wc=1%JHZztH|968crJTOF_$#eiT>aDXH~ zT9$V<pfbOM`k74oS3HC(rb+?;3mRCOKMz_AP}b&mcy@-ij)wM6BuBqub!`j<U;+~` z1w>Z@Gxwuqc^?8{G{48Px3RXeH~bA)3IA?e0w9<k{I6?E5a2ZX1?=B4+5dODA>7u@ zB?(C61N5I|!)5*tI9*2vlYi2*+TfPt7GM&R0r{wZyynxA%Kk54mOwzMuCb|=F`y#$ zruy1XPx#GCpC1Qybpyaf05IcEz$JkF{pF?qkkY}~8la!o2Mp97nEwp#GOUx-48VT? z;GbfQ{%l#^oov5{cd|CsH~eQ%vQ0Rmb^tUM0HypB5%`_u-N*5JP#|de54Nm-913`q zc3)8dMib~iPuL{a-(i1@>_1J|W7obC4WOC!0D;%fFRsr0d$1p{|6Qg2&eHU=7WDJ} z9`t|d2a;d9nsEVXe|o_9{j3E7Z~kZCC(HKNgMOoAe|Ixap>2P*Ebl>){~7*&b~pwU zmWEFyvHt9T;U@qq@Gm9)F~sygyu&}bo(`#t%%@2t1<cD+MV>!fmN$&l|A_nJVgKlg z9@{45p5ie+0sYCT|Jky<Lu7vci2qC%{naW4Ny)Br0&Bw@2&Dj4*^idxO(pw}m_J79 z58v|ST7bH(PiEwI=JLd~!C(k@$^x*Vdg7n>vt@ZVy!~H3<-dbdyL@o>1xEfI;8_7n z{-b4iPXUhmhn)032ATff!(w0vgen4M9iCjRqs8xh1|oE<2MFL~JpeOL`~&z8Q>yll z(3XY<rn<k;ZYLv(3KU=<f`O&}v#gt1{{!G3V+)A--~5{ZGj53mFbt=F0uufttDxRL zLObXh|3=a$1OV-i25by|G{9XN`~+uhVEA*G>8~o5`<zA`&`%J3p#MCG)P{dY0-VLa ze8vCd;1c$c%~=51+<-y+*#b5E1K_W|=m#6(uk!xga{jEWyujzmU;6a3ynh+Be>4-; zMqr0(zzjJ6+nJxuME(B~{Qr{$eJV@;XUp<7w))@6|36#Ni1wCOz((f}0@o*Ygg;xB z_y6nc{DY#ZqBsttVqyM((b7Of@<$etVL6&PnmGPIO^q5S(6+bi;-c(=uz;vTzG?g| zlUh3Cj3&wx(-cjpH2%<jP3kx>qmHJDX_jWGjY^6?>wEX@+q?JfyZ0?U=gt1*=bU@) zz2}^Jmpx~2kyu7}p7fm~vl>X{g@@R92vvbcQ}>3)&h?ZidAVd;`}T^|r;gO-L@5x_ zfR}^><I&V1CE|ft`_=BJS8Uvb0i461sf{$C_|()3*4&__nvLxh7)VjJ%jq_AD+!I4 zo2J2J)mT}q$<EEU97T|{fQuw9QIz}E&%3Q<K-dBZdz~5Dn)22ND{&U)=9D2D@QqL? z?)ve>l;yDGe8i4XjJVP2{}5*^3ZX5l#{61H`aiyp;SFQtr7UihJYRAuv18@38}%fN zlb6jQPcID?ME;gO*PH8<`jr!L9TG|VlLTnaI@#BjnZta|KT8Xh0`psuGyCjE)1g@o z-Z;F*qp53_2LpXMxGcN9+x6afk{Hc~w`PagZAB<ZPw9oec}YX>@+7E2GTKB#C46dX zc||D9KG&TmQ*B<^og*K?Xe$trS=u=fO){U8)oan$pi4CdOXk#gG<Elf0^P6$?9ypn z8dbaV7(nkrOZI4RewCEzbKwMU653NfJvuZGL#~O@?_H>(cUH@xg}DyX{BCwhpMrW2 z8#?Ph0HegMNLFdc)EA3yTJ)hKY9a@7da}*3#<=9P=p-2P)hPZpr+U4Vik7yeN}<DK z=nDsRzgi4uawwJ`dWQ{C<V?luGQB-KUb1rZCm8P;ynT#u;}aKHl~STh@yskPFwt?+ zq6ZhpVZO<oB)gTjY?cxWNW*LspmRV?W;Im0kM{+<#-pjvS6KrQ3jEz|P0;pTai_@c zS&xZl!)LrEN4xSpPMfFLZ8x=Q&DM4O@52V9TllkvzW7A;xlPW^Q_67H;K<E4(YF7s z=DJ;&{n~E)Tn*eIrRpXyAzqyR*2Fr@Q)x86=X>q8AnJYMO_<8QtOI1a{>97YR!{A< zU=|g-Nwy%Kue0B^I7h>-v!HVlW7o%P<!syzndo|bXY_ABf;SFUW&Kk{os?JP^f+t| zuRF&Cx*9*Lm<k2&WAc+3CD(r`hZZ=M**2iP0*^9q@2$h_LEa29yIf!1FDH9ZzsM$Z z0^3Ww9<RVQn9-5nVIS0o!IjNeNlNzQN*Li!yaO0xWF4?T<5v$tjeE=+{`ywn?%-u@ zJnEn|R;KXb&TCzlVT)Kq7d8yO^o^8k{CLo0MFbzo*kv~ThfrpiN3s2L<A*kOLj9_~ zk(^s>w1Bqi2*z&VD<|aoS|7dsX#4ltL6|l2vi99`I+PvWk;}8mdu#~yg&q3>*Ls0R zQ~M*X@$ox|Ni3mPzcUge>1ivYq&E2`=u5CZSoibQ*-$ywr>x8C8lSieUM*Y@dz!w| zB;+ZcqEh@sH3wgb_^++Ju6&2la*MwW$jslgh^Slz5$r~J<rgav@-H_oj<=`Rz~HG* z^Y`>~&Wp+9{#5TdFFY~L{i$u=7=Vir=GglY*ClJP-XYPLPLs`eGP8YN67bjXRV0f) z^p_l8=v2H;Lw(UbR-4anH2;kCu^A}^iywMJipO&CohNnci0~(S->w`1d>tY-yVSG) zk>ZVpH1?nfYn;qYtfZ`*Q2s6Cbj2`6VEq`6rrv82%JI#t(}S;KoHk=Pfecw9EcWZ~ z7mmULB?DvqO^=6CVPR~5GYRj-^+R|chk>wPBy4*mW>c*lPOswoF*v`o=4=^$U<{O= z1f>TX=E0|?KG`NR#Oe5*0X;C-@Pj^&7njbm-TT1yC^HrO49s>aBV!MmuJVp8REFD0 z5>%UT42#nnHj?v1UKjqFC-t##_<=x5#-TVAuYy??ZtT7-+1;>sBEEpt*sQo+N1-%5 z&kU-z!_Py@hEp?|KqR^Li;RuZI!UNSm<o?G+l&2-V~5Cn9@>#U1^X)EGYB9ThQ_0* z?k?fL<<t9n<J30IKyCp2IRlMPP2CeCr28&Da71(~UXj*|XT?R3JD@U{gpDg#V})E} z!|MLWpM%?c?$pFTly@F`VLR~6@S?1U)wstItjyLe7rs%rVIWPdh?9uW7fiVEk?)>O zg*3%m3z1JR-&vZndnO3kdi)A>qUBdR-*1^RvwB%D1KpQ-Cf|FQGOH3TnEpneJdtm^ zONsY-ONqfvczGz_FqT5sK4S$9w2$SXd|y)vO+#KSSjS|JXqQtS$#?st$c6ocNFzM^ zdVlgnz6m2G4jT{#QLnAXL-|H_6gn|EJgCgq^KHc_JsyQvs9pUv)`BVm^Lq0A!6<2? z8Oiwj2jLxT@L`ONLLF00Gz;@I#&>w4TB=smRvpLK2zPLpg~rzBF}@}_Reb446L`?! zNit`A^>GTlWdRMXMb57WzQ{CXyV6V)_9sOWW%**z6c~fMrjVuT2U?bf=Jn?5=29_} z#)`!R70Wb<!hFe1%FLM%7LzZ)$t%qlN2CIJz9A7HES1Rf`I>>0pEFs^rxgTw9$(6h z@_M}~;c<oCcq(73ic&v*+k_fYxr*oU<)|nx63yyER-Acps$i&Dy(J1Qo)!c(F9zbT zzQi;6;x&}HAk&g*l(ONWd~FsAy_sbR^;K%&iF`d3N?bMFlE_q7;mLeW6@y$CdC8ir ZS6G=cp<NXDZ%goR2u`;dUS#_b{{b0ENxT36 From bc667014bfb327b88e9f3df777f09043c7e27382 Mon Sep 17 00:00:00 2001 From: Jacob Mulford <39915377+jmulford-bw@users.noreply.github.com> Date: Wed, 9 Dec 2020 10:56:34 -0500 Subject: [PATCH 2/2] DX-1670-1673 added sip uri and tag bxml (#6) * DX-1670-1673 added sip uri and tag bxml * updated version --- bandwidth/voice/bxml/verbs/__init__.py | 2 + bandwidth/voice/bxml/verbs/sip_uri.py | 90 ++++++++++++++++++++++++++ bandwidth/voice/bxml/verbs/tag.py | 38 +++++++++++ bandwidth/voice/bxml/verbs/transfer.py | 7 +- setup.py | 2 +- 5 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 bandwidth/voice/bxml/verbs/sip_uri.py create mode 100644 bandwidth/voice/bxml/verbs/tag.py diff --git a/bandwidth/voice/bxml/verbs/__init__.py b/bandwidth/voice/bxml/verbs/__init__.py index 05b5c3e2..9e153007 100644 --- a/bandwidth/voice/bxml/verbs/__init__.py +++ b/bandwidth/voice/bxml/verbs/__init__.py @@ -18,3 +18,5 @@ from .ring import Ring from .stop_gather import StopGather from .start_gather import StartGather +from .tag import Tag +from .sip_uri import SipUri diff --git a/bandwidth/voice/bxml/verbs/sip_uri.py b/bandwidth/voice/bxml/verbs/sip_uri.py new file mode 100644 index 00000000..37b73361 --- /dev/null +++ b/bandwidth/voice/bxml/verbs/sip_uri.py @@ -0,0 +1,90 @@ +""" +sip_uri.py + +Representation of Bandwidth's sip uri BXML verb + +@copyright Bandwidth INC +""" + +from lxml import etree + +from .base_verb import AbstractBxmlVerb + +SIP_URI_TAG = "SipUri" + + +class SipUri(AbstractBxmlVerb): + + def __init__(self, uri=None, transfer_answer_url=None, transfer_answer_method=None, + username=None, password=None, tag=None, uui=None, + transfer_disconnect_url=None, transfer_disconnect_method=None, + transfer_answer_fallback_url=None, transfer_answer_fallback_method=None, + fallback_username=None, fallback_password=None): + """ + Initializes the SipUri class with the following parameters + + :param str uri: The sip uri + :param str transfer_answer_url: The url to send the transfer event to + :param str transfer_answer_method: The http method of the transfer event request + :param str transfer_disconnect_url: The url to send the transfer disconnect event to + :param str transfer_disconnect_method: The http method of the transfer disconnect event request + :param str username: The username to authenticate on the transfer event url + :param str password: The password to authenticate on the transfer event url + :param str tag: Custom string sent in the callback + :param str uui: The value of the `User-To-User` header to send within the initial `INVITE` + :param str transfer_answer_fallback_url: URL for fallback events + :param str transfer_answer_fallback_method: HTTP method for fallback events + :param str fallback_username: Basic auth username for fallback events + :param str fallback_password: Basic auth password for fallback events + """ + self.uri = uri + self.transfer_answer_url = transfer_answer_url + self.transfer_answer_method = transfer_answer_method + self.username = username + self.password = password + self.tag = tag + self.uui = uui + self.transfer_disconnect_method = transfer_disconnect_method + self.transfer_disconnect_url = transfer_disconnect_url + self.transfer_answer_fallback_url = transfer_answer_fallback_url + self.transfer_answer_fallback_method = transfer_answer_fallback_method + self.fallback_username = fallback_username + self.fallback_password = fallback_password + + def to_etree_element(self): + """ + Converts the class into an etree element. Used for other verb classes to build xml + + :return etree.Element: The etree Element representing this class + """ + root = etree.Element(SIP_URI_TAG) + if self.uri is not None: + root.text = self.uri + if self.transfer_answer_url is not None: + root.set("transferAnswerUrl", self.transfer_answer_url) + if self.transfer_answer_method is not None: + root.set("transferAnswerMethod", self.transfer_answer_method) + if self.username is not None: + root.set("username", self.username) + if self.password is not None: + root.set("password", self.password) + if self.tag is not None: + root.set("tag", self.tag) + if self.uui is not None: + root.set("uui", self.uui) + if self.transfer_disconnect_method is not None: + root.set("transferDisconnectMethod", self.transfer_disconnect_method) + if self.transfer_disconnect_url is not None: + root.set("transferDisconnectUrl", self.transfer_disconnect_url) + if self.transfer_answer_fallback_url is not None: + root.set("transferAnswerFallbackUrl", self.transfer_answer_fallback_url) + if self.transfer_answer_fallback_method is not None: + root.set("transferAnswerFallbackMethod", self.transfer_answer_fallback_method) + if self.fallback_username is not None: + root.set("fallbackUsername", self.fallback_username) + if self.fallback_password is not None: + root.set("fallbackPassword", self.fallback_password) + return root + + def to_bxml(self): + return etree.tostring(self.to_etree_element()).decode() diff --git a/bandwidth/voice/bxml/verbs/tag.py b/bandwidth/voice/bxml/verbs/tag.py new file mode 100644 index 00000000..06fcd28c --- /dev/null +++ b/bandwidth/voice/bxml/verbs/tag.py @@ -0,0 +1,38 @@ +""" +play_audio.py + +Representation of Bandwidth's play audio BXML verb + +@copyright Bandwidth INC +""" + +from lxml import etree + +from .base_verb import AbstractBxmlVerb + +TAG_TAG = "Tag" + + +class Tag(AbstractBxmlVerb): + + def __init__(self, tag=None): + """ + Initializes the Tag class with the following parameters + + :param str tag: The tag to set the call to + """ + self.tag = tag + + def to_etree_element(self): + """ + Converts the class into an etree element. Used for other verb classes to build xml + + :return etree.Element: The etree Element representing this class + """ + root = etree.Element(TAG_TAG) + if self.tag is not None: + root.text = self.tag + return root + + def to_bxml(self): + return etree.tostring(self.to_etree_element()).decode() diff --git a/bandwidth/voice/bxml/verbs/transfer.py b/bandwidth/voice/bxml/verbs/transfer.py index be71c450..be67fd10 100644 --- a/bandwidth/voice/bxml/verbs/transfer.py +++ b/bandwidth/voice/bxml/verbs/transfer.py @@ -17,7 +17,7 @@ class Transfer(AbstractBxmlVerb): def __init__(self, transfer_caller_id=None, call_timeout=None, tag=None, transfer_complete_url=None, transfer_complete_method=None, username=None, password=None, diversion_treatment=None, - diversion_reason=None, phone_numbers=None, + diversion_reason=None, phone_numbers=None, sip_uris=None, transfer_complete_fallback_url=None, transfer_complete_fallback_method=None, fallback_username=None, fallback_password=None): """ @@ -33,6 +33,7 @@ def __init__(self, transfer_caller_id=None, call_timeout=None, tag=None, transfe :param str diversion_treatment: The diversion treatment for the call :param str diversion_reason: The diversion reason for the call :param list<PhoneNumber> phone_numbers: The numbers to receive the transferred call + :param list<SipUri> sip_uris: The sip uris to receive the transferred call :param str transfer_complete_fallback_url: URL for fallback events :param str transfer_complete_fallback_method: HTTP method for fallback events :param str fallback_username: Basic auth username for fallback events @@ -48,6 +49,7 @@ def __init__(self, transfer_caller_id=None, call_timeout=None, tag=None, transfe self.diversion_treatment = diversion_treatment self.diversion_reason = diversion_reason self.phone_numbers = phone_numbers + self.sip_uris = sip_uris self.transfer_complete_fallback_url = transfer_complete_fallback_url self.transfer_complete_fallback_method = transfer_complete_fallback_method self.fallback_username = fallback_username @@ -84,4 +86,7 @@ def to_bxml(self): if self.phone_numbers is not None: for phone_number in self.phone_numbers: root.append(phone_number.to_etree_element()) + if self.sip_uris is not None: + for sip_uri in self.sip_uris: + root.append(sip_uri.to_etree_element()) return etree.tostring(root).decode() diff --git a/setup.py b/setup.py index 0b82f53c..a518e388 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name='bandwidth-sdk', - version='6.13.3', + version='6.14.0', description='Bandwidth\'s set of APIs', long_description=long_description, long_description_content_type="text/markdown",