Skip to content

Commit 9609fd3

Browse files
Merge pull request #94 from Bandwidth/DX-2684
DX-2684 Integration Tests Calls API
2 parents 2afb475 + 46d8f60 commit 9609fd3

36 files changed

+2152
-8
lines changed

bandwidth/model/bxml/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import response
2+
from . import bxml
3+
from . import verbs

bandwidth/model/bxml/bxml.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
bxml.py
3+
4+
Class that allows user to generate BXML programatically in python
5+
BXML is the parent element
6+
7+
@copyright Bandwidth INC
8+
"""
9+
10+
BXML_TAG = "Bxml"
11+
XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'
12+
13+
14+
class Bxml:
15+
16+
def __init__(self):
17+
"""
18+
Creates the Bxml class
19+
"""
20+
self.verbs = []
21+
22+
def add_verb(self, verb):
23+
"""
24+
Adds the Verb to the already existing verbs
25+
26+
:param Verb verb: The Verb to add
27+
"""
28+
self.verbs.append(verb)
29+
30+
def to_bxml(self):
31+
"""
32+
Converts the Bxml class to its XML representation
33+
34+
:rtype str: The XML representation of the Bxml class
35+
"""
36+
xml_string = XML_HEADER
37+
xml_string += '<' + BXML_TAG + '>'
38+
for verb in self.verbs:
39+
xml_string += verb.to_bxml()
40+
xml_string += '</' + BXML_TAG + '>'
41+
42+
return xml_string

bandwidth/model/bxml/response.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
response.py
3+
4+
Class that allows user to generate BXML programatically in python
5+
6+
@copyright Bandwidth INC
7+
"""
8+
9+
RESPONSE_TAG = "Response"
10+
XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'
11+
12+
13+
class Response:
14+
15+
def __init__(self):
16+
"""
17+
Creates the Response class
18+
"""
19+
self.verbs = []
20+
21+
def add_verb(self, verb):
22+
"""
23+
Adds the Verb to the already existing verbs
24+
25+
:param Verb verb: The Verb to add
26+
"""
27+
self.verbs.append(verb)
28+
29+
def to_bxml(self):
30+
"""
31+
Converts the Response class to its XML representation
32+
33+
:rtype str: The XML representation of the Response class
34+
"""
35+
xml_string = XML_HEADER
36+
xml_string += '<' + RESPONSE_TAG + '>'
37+
for verb in self.verbs:
38+
xml_string += verb.to_bxml()
39+
xml_string += '</' + RESPONSE_TAG + '>'
40+
41+
return xml_string
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from .hangup import Hangup
2+
from .send_dtmf import SendDtmf
3+
from .gather import Gather
4+
from .pause import Pause
5+
from .phone_number import PhoneNumber
6+
from .redirect import Redirect
7+
from .speak_sentence import SpeakSentence
8+
from .transfer import Transfer
9+
from .play_audio import PlayAudio
10+
from .forward import Forward
11+
from .record import Record
12+
from .pause_recording import PauseRecording
13+
from .resume_recording import ResumeRecording
14+
from .stop_recording import StopRecording
15+
from .start_recording import StartRecording
16+
from .conference import Conference
17+
from .bridge import Bridge
18+
from .ring import Ring
19+
from .stop_gather import StopGather
20+
from .start_gather import StartGather
21+
from .tag import Tag
22+
from .sip_uri import SipUri
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
base_verb.py
3+
4+
Defines the abstract class for all BXML verbs
5+
6+
@copyright Bandwidth INC
7+
"""
8+
9+
from abc import ABC, abstractmethod
10+
11+
12+
class AbstractBxmlVerb(ABC):
13+
14+
@abstractmethod
15+
def to_bxml(self):
16+
"""
17+
Converts the class into its xml representation
18+
19+
:return str: The string xml representation
20+
"""
21+
pass
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
bridge.py
3+
4+
Representation of Bandwidth's speak sentence BXML verb
5+
6+
@copyright Bandwidth INC
7+
"""
8+
9+
from lxml import etree
10+
11+
from .base_verb import AbstractBxmlVerb
12+
13+
import re
14+
15+
BRIDGE_TAG = "Bridge"
16+
17+
class Bridge(AbstractBxmlVerb):
18+
19+
def __init__(self, call_id, bridge_complete_url=None, bridge_complete_method=None,
20+
bridge_target_complete_url=None, bridge_target_complete_method=None,
21+
username=None, password=None, tag=None, bridge_complete_fallback_url=None,
22+
bridge_complete_fallback_method=None, bridge_target_complete_fallback_url=None,
23+
bridge_target_complete_fallback_method=None, fallback_username=None,
24+
fallback_password=None):
25+
"""
26+
Initializes the Bridge class with the following parameters
27+
28+
:param str call_id: The call to bridge
29+
:param str bridge_complete_url: URL to send the bridge complete event to
30+
:param str bridge_complete_method: HTTP method to send the bridge complete event
31+
:param str bridge_target_complete_url: URL to send the bridge target complete event to
32+
:param str bridge_target_complete_method: HTTP method to send the bridge target complete event
33+
:param str username: HTTP basic auth username for events
34+
:param str password: HTTP basic auth password for events
35+
:param str tag: Custom tag to include in callbacks
36+
:param str bridge_complete_fallback_url: Fallback url for bridge complete events
37+
:param str bridge_complete_fallback_method: HTTP method for bridge complete fallback
38+
:param str bridge_target_complete_fallback_url: Fallback url for bridge target complete events
39+
:param str bridge_target_complete_fallback_method: HTTP method for bridge target complete fallback
40+
:param str fallback_username: Basic auth username for fallback events
41+
:param str fallback_password: Basic auth password for fallback events
42+
"""
43+
self.call_id = call_id
44+
self.bridge_complete_url = bridge_complete_url
45+
self.bridge_complete_method = bridge_complete_method
46+
self.bridge_target_complete_url = bridge_target_complete_url
47+
self.bridge_target_complete_method = bridge_target_complete_method
48+
self.username = username
49+
self.password = password
50+
self.tag = tag
51+
self.bridge_complete_fallback_url = bridge_complete_fallback_url
52+
self.bridge_complete_fallback_method = bridge_complete_fallback_method
53+
self.bridge_target_complete_fallback_url = bridge_target_complete_fallback_url
54+
self.bridge_target_complete_fallback_method = bridge_target_complete_fallback_method
55+
self.fallback_username = fallback_username
56+
self.fallback_password = fallback_password
57+
58+
def to_bxml(self):
59+
root = etree.Element(BRIDGE_TAG)
60+
root.text = self.call_id
61+
if self.bridge_complete_url is not None:
62+
root.set("bridgeCompleteUrl", self.bridge_complete_url)
63+
if self.bridge_complete_method is not None:
64+
root.set("bridgeCompleteMethod", self.bridge_complete_method)
65+
if self.bridge_target_complete_url is not None:
66+
root.set("bridgeTargetCompleteUrl", self.bridge_target_complete_url)
67+
if self.bridge_target_complete_method is not None:
68+
root.set("bridgeTargetCompleteMethod", self.bridge_target_complete_method)
69+
if self.username is not None:
70+
root.set("username", self.username)
71+
if self.password is not None:
72+
root.set("password", self.password)
73+
if self.tag is not None:
74+
root.set("tag", self.tag)
75+
if self.bridge_complete_fallback_url is not None:
76+
root.set("bridgeCompleteFallbackUrl", self.bridge_complete_fallback_url)
77+
if self.bridge_complete_fallback_method is not None:
78+
root.set("bridgeCompleteFallbackMethod", self.bridge_complete_fallback_method)
79+
if self.bridge_target_complete_fallback_url is not None:
80+
root.set("bridgeTargetCompleteFallbackUrl", self.bridge_target_complete_fallback_url)
81+
if self.bridge_target_complete_fallback_method is not None:
82+
root.set("bridgeTargetCompleteFallbackMethod", self.bridge_target_complete_fallback_method)
83+
if self.fallback_username is not None:
84+
root.set("fallbackUsername", self.fallback_username)
85+
if self.fallback_password is not None:
86+
root.set("fallbackPassword", self.fallback_password)
87+
return etree.tostring(root).decode()
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
conference.py
3+
4+
Representation of Bandwidth's conference BXML verb
5+
6+
@copyright Bandwidth INC
7+
"""
8+
9+
from lxml import etree
10+
11+
from .base_verb import AbstractBxmlVerb
12+
13+
CONFERENCE_TAG = "Conference"
14+
15+
16+
class Conference(AbstractBxmlVerb):
17+
18+
def __init__(self, conference_name, mute=None, hold=None, call_ids_to_coach=None,
19+
conference_event_url=None, conference_event_method=None,
20+
username=None, password=None, tag=None, conference_event_fallback_url=None,
21+
conference_event_fallback_method=None, fallback_username=None,
22+
fallback_password=None):
23+
"""
24+
Init for Conference
25+
26+
:param str conference_name: The name of the conference
27+
:param boolean mute: Determines if conference members should be on mute
28+
:param boolean hold: Determines if conference members should be on hold
29+
:param string|list<string> call_ids_to_coach: A string of comma separated call IDs to coach, or an array of call IDs to coach
30+
:param string conference_event_url: The url to receive conference events
31+
:param string conference_event_method: The HTTP method to send conference events
32+
:param string username: Basic auth username for events
33+
:param string password: Basic auth password for events
34+
:param string tag: Custom tag to be included in events
35+
:param string conference_event_fallback_url: Fallback URL for conference events
36+
:param string conference_event_fallback_method: HTTP method for fallback URL requests
37+
:param string fallback_username: Basic auth username for fallback requests
38+
:param string fallback_password: Basic auth password for fallback requests
39+
"""
40+
self.conference_name = conference_name
41+
self.mute = mute
42+
self.hold = hold
43+
self.call_ids_to_coach = call_ids_to_coach
44+
self.conference_event_url = conference_event_url
45+
self.conference_event_method = conference_event_method
46+
self.username = username
47+
self.password = password
48+
self.tag = tag
49+
self.conference_event_fallback_url = conference_event_fallback_url
50+
self.conference_event_fallback_method = conference_event_fallback_method
51+
self.fallback_username = fallback_username
52+
self.fallback_password = fallback_password
53+
54+
def to_bxml(self):
55+
root = etree.Element(CONFERENCE_TAG)
56+
root.text = self.conference_name
57+
58+
if self.mute is not None:
59+
strn = "true" if self.mute else "false"
60+
root.set("mute", strn)
61+
if self.hold is not None:
62+
strn = "true" if self.hold else "false"
63+
root.set("hold", strn)
64+
if self.call_ids_to_coach is not None:
65+
strn = None
66+
if isinstance(self.call_ids_to_coach, str):
67+
strn = self.call_ids_to_coach
68+
else:
69+
strn = ",".join(self.call_ids_to_coach)
70+
root.set("callIdsToCoach", strn)
71+
if self.conference_event_url is not None:
72+
root.set("conferenceEventUrl", self.conference_event_url)
73+
if self.conference_event_method is not None:
74+
root.set("conferenceEventMethod", self.conference_event_method)
75+
if self.tag is not None:
76+
root.set("tag", self.tag)
77+
if self.username is not None:
78+
root.set("username", self.username)
79+
if self.password is not None:
80+
root.set("password", self.password)
81+
if self.conference_event_fallback_url is not None:
82+
root.set("conferenceEventFallbackUrl", self.conference_event_fallback_url)
83+
if self.conference_event_fallback_method is not None:
84+
root.set("conferenceEventFallbackMethod", self.conference_event_fallback_method)
85+
if self.fallback_username is not None:
86+
root.set("fallbackUsername", self.fallback_username)
87+
if self.fallback_password is not None:
88+
root.set("fallbackPassword", self.fallback_password)
89+
90+
return etree.tostring(root).decode()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
forward.py
3+
4+
Representation of Bandwidth's forward BXML verb
5+
6+
@copyright Bandwidth INC
7+
"""
8+
9+
from lxml import etree
10+
11+
from .base_verb import AbstractBxmlVerb
12+
13+
FORWARD_TAG = "Forward"
14+
15+
16+
class Forward(AbstractBxmlVerb):
17+
18+
def __init__(self, to=None, from_=None, call_timeout=None, diversion_treatment=None, diversion_reason=None):
19+
"""
20+
Initializes the Forward class with the following parameters
21+
22+
:param str to: The phone number destination of the call
23+
:param str from_: The phone number that the recipient will receive the call from
24+
:param int call_timeout: The number of seconds to wait before timing out the call
25+
:param str diversion_treatment: The diversion treatment for the call
26+
:param str diversion_reason: The diversion reason for the call
27+
"""
28+
self.to = to
29+
self.from_ = from_
30+
self.call_timeout = call_timeout
31+
self.diversion_treatment = diversion_treatment
32+
self.diversion_reason = diversion_reason
33+
34+
def to_bxml(self):
35+
root = etree.Element(FORWARD_TAG)
36+
if self.to is not None:
37+
root.set("to", self.to)
38+
if self.call_timeout is not None:
39+
root.set("callTimeout", str(self.call_timeout))
40+
if self.from_ is not None:
41+
root.set("from", self.from_)
42+
if self.diversion_treatment is not None:
43+
root.set("diversionTreatment", self.diversion_treatment)
44+
if self.diversion_reason is not None:
45+
root.set("diversionReason", self.diversion_reason)
46+
return etree.tostring(root).decode()

0 commit comments

Comments
 (0)