Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bandwidth/model/bxml/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import response
from . import bxml
from . import verbs
42 changes: 42 additions & 0 deletions bandwidth/model/bxml/bxml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
bxml.py

Class that allows user to generate BXML programatically in python
BXML is the parent element

@copyright Bandwidth INC
"""

BXML_TAG = "Bxml"
XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'


class Bxml:

def __init__(self):
"""
Creates the Bxml 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 Bxml class to its XML representation

:rtype str: The XML representation of the Bxml class
"""
xml_string = XML_HEADER
xml_string += '<' + BXML_TAG + '>'
for verb in self.verbs:
xml_string += verb.to_bxml()
xml_string += '</' + BXML_TAG + '>'

return xml_string
41 changes: 41 additions & 0 deletions bandwidth/model/bxml/response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
response.py

Class that allows user to generate BXML programatically in python

@copyright Bandwidth INC
"""

RESPONSE_TAG = "Response"
XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'


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 += '</' + RESPONSE_TAG + '>'

return xml_string
22 changes: 22 additions & 0 deletions bandwidth/model/bxml/verbs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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
from .tag import Tag
from .sip_uri import SipUri
21 changes: 21 additions & 0 deletions bandwidth/model/bxml/verbs/base_verb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
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
87 changes: 87 additions & 0 deletions bandwidth/model/bxml/verbs/bridge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
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()
90 changes: 90 additions & 0 deletions bandwidth/model/bxml/verbs/conference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
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<string> 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()
46 changes: 46 additions & 0 deletions bandwidth/model/bxml/verbs/forward.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
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()
Loading