From fcb8fc362c17deb97495e34123d59d9eb2f1573c Mon Sep 17 00:00:00 2001 From: Dan York Date: Thu, 19 Aug 2010 10:48:56 +0800 Subject: [PATCH 01/19] python3 - updated print statements to functions --- tropo_web_api.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tropo_web_api.py b/tropo_web_api.py index f11cdb8..9797fae 100644 --- a/tropo_web_api.py +++ b/tropo_web_api.py @@ -88,13 +88,13 @@ class Ask(TropoAction): def __init__(self, choices, **options): self._dict = {} - if (isinstance(choices, basestring)): + if (isinstance(choices, str)): self._dict['choices'] = Choices(choices).json else: self._dict['choices'] = choices['choices'] for opt in self.options_array: if opt in options: - if ((opt == 'say') and (isinstance(options['say'], basestring))): + if ((opt == 'say') and (isinstance(options['say'], str))): self._dict['say'] = Say(options['say']).json else: self._dict[opt] = options[opt] @@ -240,7 +240,7 @@ def __init__(self, event, **options): self._dict = {'event': event} for opt in self.options_array: if opt in options: - if ((opt == 'say') and (isinstance(options['say'], basestring))): + if ((opt == 'say') and (isinstance(options['say'], str))): self._dict['say'] = Say(options['say']).json else: self._dict[opt] = options[opt] @@ -280,7 +280,7 @@ def __init__(self, **options): self._dict = {} for opt in self.options_array: if opt in options: - if ((opt == 'say') and (isinstance(options['say'], basestring))): + if ((opt == 'say') and (isinstance(options['say'], str))): self._dict['say'] = Say(options['say']).json else: self._dict[opt] = options[opt] @@ -555,7 +555,7 @@ def message (self, say_obj, to, **options): Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/message.htm """ - if isinstance(say_obj, basestring): + if isinstance(say_obj, str): say = Say(say_obj).obj else: say = say_obj @@ -648,7 +648,7 @@ def RenderJson(self, pretty=False): return json if __name__ == '__main__': - print """ + print (""" This is the Python web API for http://www.tropo.com/ @@ -658,6 +658,6 @@ def RenderJson(self, pretty=False): python test.py -""" +""") From 07ff10c469a124cbcdeeb32d09842cdb73ee9d7f Mon Sep 17 00:00:00 2001 From: Dan York Date: Thu, 19 Aug 2010 10:49:32 +0800 Subject: [PATCH 02/19] python3 - updated print statements. converted 'basestring' to 'str' because in python 3 there is only one type of string. --- test/test.py | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/test/test.py b/test/test.py index a68110b..91f17aa 100755 --- a/test/test.py +++ b/test/test.py @@ -40,8 +40,8 @@ def test_ask(self): say = Say("Please enter a 5 digit zip code").json) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_ask=================" - print "render json: %s" % pretty_rendered + print ("===============test_ask=================") + print ("render json: %s" % pretty_rendered) rendered_obj = jsonlib.loads(rendered) wanted_json = '{"tropo": [{"ask": {"say": {"value": "Please enter a 5 digit zip code"}, "choices": {"value": "[5 digits]"}}}]}' wanted_obj = jsonlib.loads(wanted_json) @@ -59,7 +59,7 @@ def test_call(self): rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) print ("============test_call=============") - print "render json: %s" % pretty_rendered + print ("render json: %s" % pretty_rendered) rendered_obj = jsonlib.loads(rendered) wanted_json = '{"tropo": [{"call": {"to": "%s", "network": "SMS", "channel": "TEXT"}}, {"say": {"value": "Wish you were here"}}]}' % self.MY_PHONE @@ -77,12 +77,12 @@ def test_conference(self): name="Staff Meeting", mute=False) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_conference=================" - print "render json: %s" % pretty_rendered + print ("===============test_conference=================") + print ("render json: %s" % pretty_rendered) rendered_obj = jsonlib.loads(rendered) wanted_json = '{"tropo": [{"conference": {"playTones": true, "mute": false, "name": "Staff Meeting", "id": "foo", "terminator": "#"}}]}' - print "wanted_json: %s" % wanted_json + print ("wanted_json: %s" % wanted_json) wanted_obj = jsonlib.loads(wanted_json) # print "test_conference: %s" % tropo.RenderJson() self.assertEqual(rendered_obj, wanted_obj) @@ -96,8 +96,8 @@ def test_hangup(self): tropo.hangup() rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_hangup=================" - print "render json: %s" % pretty_rendered + print ("===============test_hangup=================") + print ("render json: %s" % pretty_rendered) # print "test_hangup: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -114,8 +114,8 @@ def test_message(self): tropo.message("Hello World", self.MY_PHONE, channel='TEXT', network='SMS', timeout=5) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_message=================" - print "render json: %s" % pretty_rendered + print ("===============test_message=================") + print ("render json: %s" % pretty_rendered) # print "test_message: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -135,8 +135,8 @@ def test_on(self): say="Please hold.") rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_on=================" - print "render json: %s" % pretty_rendered + print ("===============test_on=================") + print ("render json: %s" % pretty_rendered) # print "test_on: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -156,8 +156,8 @@ def test_record(self): choices=choices_obj) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_record=================" - print "render json: %s" % pretty_rendered + print ("===============test_record=================") + print ("render json: %s" % pretty_rendered) # print "test_record: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -174,10 +174,10 @@ def test_redirect(self): tropo.redirect(self.MY_PHONE) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_redirect=================" - print "render json: %s" % pretty_rendered + print ("===============test_redirect=================") + print ("render json: %s" % pretty_rendered) - print "Wanted_Json %s" % tropo.RenderJson() + print ("Wanted_Json %s" % tropo.RenderJson()) rendered_obj = jsonlib.loads(rendered) wanted_json = '{"tropo": [{"redirect": {"to": "%s"}}]}' % self.MY_PHONE wanted_obj = jsonlib.loads(wanted_json) @@ -193,10 +193,10 @@ def test_reject(self): tropo.reject() rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_reject=================" - print "render json: %s" % pretty_rendered + print ("===============test_reject=================") + print ("render json: %s" % pretty_rendered) - print "Want %s" % tropo.RenderJson() + print ("Want %s" % tropo.RenderJson()) rendered_obj = jsonlib.loads(rendered) wanted_json = '{"tropo": [{"reject": {}}]}' wanted_obj = jsonlib.loads(wanted_json) @@ -212,8 +212,8 @@ def test_say(self): tropo.say("Hello, World") rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_say=================" - print "render json: %s" % pretty_rendered + print ("===============test_say=================") + print ("render json: %s" % pretty_rendered) # print "test_say: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -230,8 +230,8 @@ def test_list_say(self): tropo.say(["Hello, World", "How ya doing?"]) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_list_say=================" - print "render json: %s" % pretty_rendered + print ("===============test_list_say=================") + print ("render json: %s" % pretty_rendered) # print "test_say: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -248,8 +248,8 @@ def test_startRecording(self): tropo.startRecording(self.RECORDING_URL) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_startRecording=================" - print "render json: %s" % pretty_rendered + print ("===============test_startRecording=================") + print ("render json: %s" % pretty_rendered) # print "test_startRecording: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -266,8 +266,8 @@ def test_stopRecording(self): tropo.stopRecording() rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_stopRecording=================" - print "render json: %s" % pretty_rendered + print ("===============test_stopRecording=================") + print ("render json: %s" % pretty_rendered) # print "test_stopRecording: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) @@ -286,8 +286,8 @@ def test_transfer(self): tropo.say("Hi. I am a robot") rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) - print "===============test_transfer=================" - print "render json: %s" % pretty_rendered + print ("===============test_transfer=================") + print ("render json: %s" % pretty_rendered) # print "test_transfer: %s" % tropo.RenderJson() rendered_obj = jsonlib.loads(rendered) From 11010a6c1257660b2ca2f513460782550722312c Mon Sep 17 00:00:00 2001 From: Dan York Date: Thu, 19 Aug 2010 18:09:41 +0800 Subject: [PATCH 03/19] Updated README to indicate it is for python 3.x --- README | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README b/README index 636f2db..ad91a84 100644 --- a/README +++ b/README @@ -31,7 +31,12 @@ DESCRIPTION attempts=3, bargein=True, name="zip", timeout=5, voice="dave") ... - NOTE: This module requires python 2.5 or higher. +NOTE ON PYTHON VERSIONS + + This version of the module is for python 3.x. + There is a separate version available for python 2.x at: + + http://github.com/tropo/python-webapi/ TESTS From 996433a579869d39b1d0059259bddaaab50ad8e5 Mon Sep 17 00:00:00 2001 From: Dan York Date: Sat, 4 Sep 2010 01:44:51 +0800 Subject: [PATCH 04/19] Changed module name to "tropo.py" and updated samples --- README | 8 ++++---- samples/itty_hello_world.py | 2 +- samples/itty_session_api.py | 4 ++-- samples/main.py | 24 ++++++++++++------------ test/test.py | 2 +- tropo_web_api.py => tropo.py | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) rename tropo_web_api.py => tropo.py (99%) diff --git a/README b/README index ad91a84..2101ae3 100644 --- a/README +++ b/README @@ -1,14 +1,14 @@ NAME - tropo_web_api - The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ + tropo - The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ FILE - http://github.com/tropo/python-webapi/blob/master/tropo_web_api.py + http://github.com/tropo/python-webapi/blob/master/tropo.py DESCRIPTION Usage: ---- - from tropo_web_api import Tropo + from tropo import Tropo tropo = Tropo() tropo.say("Hello, World") @@ -24,7 +24,7 @@ DESCRIPTION object and communicating back to Tropo via the Tropo class methods, such as "say". In some cases, you'll want to build a class object directly such as in : - choices = tropo_web_api.Choices("[5 digits]").obj + choices = tropo.Choices("[5 digits]").obj tropo.ask(choices, say="Please enter your 5 digit zip code.", diff --git a/samples/itty_hello_world.py b/samples/itty_hello_world.py index f1992a3..53ab801 100755 --- a/samples/itty_hello_world.py +++ b/samples/itty_hello_world.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from itty import * -from tropo_web_api import Tropo, Session +from tropo import Tropo, Session @post('/index.json') def index(request): diff --git a/samples/itty_session_api.py b/samples/itty_session_api.py index f24d308..f8faf14 100755 --- a/samples/itty_session_api.py +++ b/samples/itty_session_api.py @@ -1,13 +1,13 @@ #!/usr/bin/env python """ -Hellow world script for Session API (https://www.tropo.com/docs/webapi/sessionapi.htm) +Hello world script for Session API (https://www.tropo.com/docs/webapi/sessionapi.htm) Upon launch, it will trigger a message to be sent via Jabber to the addess specified in 'number'. """ from itty import * -from tropo_web_api import Tropo, Session +from tropo import Tropo, Session from urllib import urlencode from urllib2 import urlopen diff --git a/samples/main.py b/samples/main.py index 56f0c5a..869a69e 100755 --- a/samples/main.py +++ b/samples/main.py @@ -7,7 +7,7 @@ from google.appengine.ext.webapp import util import cgi import logging -import tropo_web_api +import tropo import GoogleS3 from xml.dom import minidom from google.appengine.api import urlfetch @@ -30,7 +30,7 @@ def HelloWorld(handler, tropo): def WeatherDemo(handler, tropo): """ """ - choices = tropo_web_api.Choices("[5 digits]").obj + choices = tropo.Choices("[5 digits]").obj tropo.ask(choices, say="Please enter your 5 digit zip code.", @@ -56,7 +56,7 @@ def WeatherDemo(handler, tropo): def RecordDemo(handler, tropo): url = "/receive_recording.py" - choices_obj = tropo_web_api.Choices("", terminator="#").json + choices_obj = tropo.Choices("", terminator="#").json tropo.record(say="Tell us about yourself", url=url, choices=choices_obj) json = tropo.RenderJson() @@ -151,7 +151,7 @@ class TropoDemo(webapp.RequestHandler): """ def post(self): if (1): - tropo = tropo_web_api.Tropo() + tropo = tropo.Tropo() tropo.say ("Welcome to the Tropo web API demo") request = "Please press" @@ -166,7 +166,7 @@ def post(self): demo = DEMOS[key][1] request = "%s %s for %s," % (request, key, demo_name) choices_counter += 1 - choices = tropo_web_api.Choices(choices_string).obj + choices = tropo.Choices(choices_string).obj tropo.ask(choices, say=request, attempts=3, bargein=True, name="zip", timeout=5, voice="dave") @@ -190,8 +190,8 @@ class TropoDemoContinue(webapp.RequestHandler): def post (self): json = self.request.body logging.info ("json: %s" % json) - tropo = tropo_web_api.Tropo() - result = tropo_web_api.Result(json) + tropo = tropo.Tropo() + result = tropo.Result(json) choice = result.getValue() logging.info ("Choice of demo is: %s" % choice) @@ -209,8 +209,8 @@ class Weather(webapp.RequestHandler): def post (self): json = self.request.body logging.info ("json: %s" % json) - tropo = tropo_web_api.Tropo() - result = tropo_web_api.Result(json); + tropo = tropo.Tropo() + result = tropo.Result(json); zip = result.getValue() google_weather_url = "%s?weather=%s&hl=en" % (GOOGLE_WEATHER_API_URL, zip) resp = urlfetch.fetch(google_weather_url) @@ -226,7 +226,7 @@ def post (self): wind_condition = doc.find("weather/current_conditions/wind_condition").attrib['data'] city = doc.find("weather/forecast_information/city").attrib['data'] logging.info ("condition: %s temp_f: %s wind_condition: %s city: %s" % (condition, temp_f, wind_condition, city)) - tropo = tropo_web_api.Tropo() + tropo = tropo.Tropo() # condition: Partly Cloudy temp_f: 73 wind_condition: Wind: NW at 10 mph city: Portsmouth, NH temp = "%s degrees" % temp_f wind = self.english_expand (wind_condition) @@ -283,7 +283,7 @@ def put_in_s3 (self, wav): class CallWorld(webapp.RequestHandler): def post(self): - tropo = tropo_web_api.Tropo() + tropo = tropo.Tropo() tropo.call(MY_PHONE, channel='TEXT', network='SMS', answerOnMedia='True') tropo.say ("Wish you were here") json = tropo.RenderJson() @@ -304,7 +304,7 @@ def main(): ('/weather.py', Weather), ('/receive_recording.py', ReceiveRecording), ('/demo_continue.py', TropoDemoContinue), -# ('/tropo_web_api.html', ShowDoc) +# ('/tropo.html', ShowDoc) ], debug=True) diff --git a/test/test.py b/test/test.py index 91f17aa..4a7094b 100755 --- a/test/test.py +++ b/test/test.py @@ -17,7 +17,7 @@ import unittest import sys sys.path = ['..'] + sys.path -from tropo_web_api import Choices, Say, Tropo +from tropo import Choices, Say, Tropo class TestTropoPython(unittest.TestCase): diff --git a/tropo_web_api.py b/tropo.py similarity index 99% rename from tropo_web_api.py rename to tropo.py index 9797fae..e8814b7 100644 --- a/tropo_web_api.py +++ b/tropo.py @@ -4,7 +4,7 @@ Usage: ---- -from tropo_web_api import Tropo +from tropo import Tropo tropo = Tropo() tropo.say("Hello, World") @@ -20,7 +20,7 @@ object and communicating back to Tropo via the Tropo class methods, such as "say". In some cases, you'll want to build a class object directly such as in : - choices = tropo_web_api.Choices("[5 digits]").obj + choices = tropo.Choices("[5 digits]").obj tropo.ask(choices, say="Please enter your 5 digit zip code.", From a9f4263ed38564ab2de1f06fb7348980f8f923c6 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 13:15:36 -0600 Subject: [PATCH 05/19] Fix formatting --- tropo.py | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tropo.py b/tropo.py index 6f5e748..2cbcd46 100644 --- a/tropo.py +++ b/tropo.py @@ -72,18 +72,18 @@ class Ask(TropoAction): "allowSignals": String or Array, "bargein": Boolean, "choices": Object, #Required - "interdigitTimeout": Float, - "minConfidence": Integer, + "interdigitTimeout": Float, + "minConfidence": Integer, "name": String, "recognizer": String, "required": Boolean, "say": Object, - "sensitivity": Float, - "speechCompleteTimeout": Float, + "sensitivity": Float, + "speechCompleteTimeout": Float, "speechIncompleteTimeout": Float, "timeout": Float, "voice": String, - + } } """ @@ -139,7 +139,7 @@ def __init__(self, to, **options): else: self._dict[opt] = options[opt] - + class Choices(TropoAction): """ @@ -317,25 +317,25 @@ def __init__(self, event, **options): self._dict['say'] = Say(options['say'], voice=options['voice']).json else: self._dict['say'] = Say(options['say']).json - + elif ((opt == 'ask') and (isinstance(options['ask'], basestring))): if('voice' in options): self._dict['ask'] = Ask(options['ask'], voice=options['voice']).json else: self._dict['ask'] = Ask(options['ask']).json - + elif ((opt == 'message') and (isinstance(options['message'], basestring))): if('voice' in options): self._dict['message'] = Message(options['message'], voice=options['voice']).json else: self._dict['message'] = Message(options['message']).json - + elif ((opt == 'wait') and (isinstance(options['wait'], basestring))): self._dict['wait'] = Wait(options['wait']).json - + elif(opt != 'voice'): self._dict[opt] = options[opt] - + self._dict['event'] = event class Record(TropoAction): @@ -365,7 +365,7 @@ class Record(TropoAction): "say": Object, "timeout": Float, "transcription": Array or Object, - "url": String, #Required + "url": String, #Required "username": String, "voice": String} } """ @@ -482,7 +482,7 @@ class StartRecording(TropoAction): "method": String, "url": String,#Required "username": String, - "password": String, + "password": String, "transcriptionID": String "transcriptionEmailFormat":String "transcriptionOutURI": String} } @@ -562,7 +562,7 @@ def __init__(self, to, **options): elif(key == "message"): newDict['message'] = val newDict['event'] = 'connect' - + elif(key == "ring"): newDict['say'] = val newDict['event'] = 'ring' @@ -589,7 +589,7 @@ class Wait(TropoAction): "milliseconds": Integer,#Required "allowSignals": String or Array """ - + action = 'wait' options_array = ['allowSignals'] @@ -670,7 +670,7 @@ class Session(object): """ Session is the payload sent as an HTTP POST to your web application when a new session arrives. (See https://www.tropo.com/docs/webapi/session) - + Because 'from' is a reserved word in Python, the session object's 'from' property is called fromaddress in the Python library """ @@ -683,7 +683,7 @@ def __init__(self, session_json): setattr(self, "fromaddress", val) else: setattr(self, key, val) - setattr(self, 'dict', session_dict) + setattr(self, 'dict', session_dict) class Tropo(object): @@ -721,7 +721,7 @@ def ask(self, choices, **options): if hasattr (self, 'voice'): if (not 'voice' in options): options['voice'] = self.voice - + # # **Sun May 15 21:21:29 2011** -- egilchri self._steps.append(Ask(choices, **options).obj) @@ -851,7 +851,7 @@ def transfer(self, to, **options): See https://www.tropo.com/docs/webapi/transfer """ self._steps.append(Transfer(to, **options).obj) - + def wait(self, milliseconds, **options): """ Allows the thread to sleep for a given amount of time in milliseconds @@ -860,7 +860,7 @@ def wait(self, milliseconds, **options): See https://www.tropo.com/docs/webapi/wait """ self._steps.append(Wait(milliseconds, **options).obj) - + def RenderJson(self, pretty=False): """ Render a Tropo object into a Json string. @@ -878,7 +878,7 @@ def RenderJson(self, pretty=False): return json if __name__ == '__main__': - print """ + print(""" This is the Python web API for http://www.tropo.com/ @@ -888,6 +888,6 @@ def RenderJson(self, pretty=False): python test.py -""" +""") From 2e0b77633d766b93e68276bee1600419d7ce0e5a Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 18:19:19 -0600 Subject: [PATCH 06/19] remove tabs, print is a function --- tropo.py | 341 ++++++++++++++----------------------------------------- 1 file changed, 87 insertions(+), 254 deletions(-) diff --git a/tropo.py b/tropo.py index 2cbcd46..3ed17f9 100644 --- a/tropo.py +++ b/tropo.py @@ -65,30 +65,23 @@ class Ask(TropoAction): Class constructor options: attempts, bargein, choices, minConfidence, name, recognizer, required, say, timeout, voice Request information from the caller and wait for a response. - (See https://www.tropo.com/docs/webapi/ask) + (See https://www.tropo.com/docs/webapi/ask.htm) { "ask": { "attempts": Integer, - "allowSignals": String or Array, "bargein": Boolean, "choices": Object, #Required - "interdigitTimeout": Float, "minConfidence": Integer, "name": String, "recognizer": String, "required": Boolean, "say": Object, - "sensitivity": Float, - "speechCompleteTimeout": Float, - "speechIncompleteTimeout": Float, "timeout": Float, - "voice": String, - - } } + "voice": String } } """ action = 'ask' - options_array = ['attempts', 'allowSignals', 'bargein', 'choices', 'interdigitTimeout', 'minConfidence', 'name', 'recognizer', 'required', 'say', 'sensitivity', 'speechCompleteTimeout', 'speechIncompleteTimeout', 'timeout', 'voice'] + options_array = ['attempts', 'bargein', 'choices', 'minConfidence', 'name', 'recognizer', 'required', 'say', 'timeout', 'voice', 'allowSignals'] def __init__(self, choices, **options): self._dict = {} @@ -108,15 +101,14 @@ class Call(TropoAction): """ Class representing the "call" Tropo action. Builds a "call" JSON object. Class constructor arg: to, a String - Class constructor options: answerOnMedia, channel, from, headers, name, network, recording, required, timeout, machineDetection + Class constructor options: answerOnMedia, channel, from, headers, name, network, recording, required, timeout Convenience function: Tropo.call() - (See https://www.tropo.com/docswebapi/call) + (See https://www.tropo.com/docswebapi/call.htm) { "call": { "to": String or Array,#Required "answerOnMedia": Boolean, - "allowSignals": String or Array "channel": string, "from": string, "headers": Object, @@ -124,11 +116,10 @@ class Call(TropoAction): "network": String, "recording": Array or Object, "required": Boolean, - "timeout": Float. - "machineDetection: Boolean or Object" } } + "timeout": Float } } """ action = 'call' - options_array = ['answerOnMedia', 'allowSignals', 'channel', '_from', 'headers', 'name', 'network', 'recording', 'required', 'timeout', 'machineDetection'] + options_array = ['answerOnMedia', 'channel', '_from', 'headers', 'name', 'network', 'recording', 'required', 'timeout', 'allowSignals'] def __init__(self, to, **options): self._dict = {'to': to} @@ -139,14 +130,14 @@ def __init__(self, to, **options): else: self._dict[opt] = options[opt] - + class Choices(TropoAction): """ Class representing choice made by a user. Builds a "choices" JSON object. Class constructor options: terminator, mode - (See https://www.tropo.com/docs/webapi/ask) + (See https://www.tropo.com/docs/webapi/ask.htm) """ action = 'choices' options_array = ['terminator', 'mode'] @@ -164,22 +155,18 @@ class Conference(TropoAction): Convenience function: Tropo.conference() Class constructor options: mute, name, playTones, required, terminator - (See https://www.tropo.com/docs/webapi/conference) + (See https://www.tropo.com/docs/webapi/conference.htm) { "conference": { "id": String,#Required - "allowSignals": String or Array, - "interdigitTimeout":Integer, "mute": Boolean, "name": String, "playTones": Boolean, "required": Boolean, - "terminator": String, - "joinPrompt": Object, - "leavePrompt": Object } } + "terminator": String } } """ action = 'conference' - options_array = ['allowSignals', 'interdigitTimeout', 'mute', 'name', 'playTones', 'required', 'terminator', 'joinPrompt', 'leavePrompt'] + options_array = ['mute', 'name', 'playTones', 'required', 'terminator', 'allowSignals'] def __init__(self, id, **options): self._dict = {'id': id} @@ -194,7 +181,7 @@ class Hangup(TropoAction): Class constructor options: Convenience function: Tropo.hangup() - (See https://www.tropo.com/docs/webapi/hangup) + (See https://www.tropo.com/docs/webapi/hangup.htm) { "hangup": { } } """ @@ -203,57 +190,6 @@ class Hangup(TropoAction): def __init__(self): self._dict = {} - -class JoinPrompt(TropoAction): - """ - Class representing join prompts for the conference method. Builds a "joinPrompt" JSON object. - Class constructor options: value, voice - - (See https://www.tropo.com/docs/webapi/conference) - """ - action = 'joinPrompt' - options_array = ['voice'] - - def __init__(self, value, **options): - self._dict = {'value': value} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - -class LeavePrompt(TropoAction): - """ - Class representing leave prompts for the conference method. Builds a "leavePrompt" JSON object. - Class constructor options: value, voice - - (See https://www.tropo.com/docs/webapi/conference) - """ - action = 'leavePrompt' - options_array = ['voice'] - - def __init__(self, value, **options): - self._dict = {'value': value} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - - -class MachineDetection(TropoAction): - """ - Class representing machine detection for the call method. Builds a "machineDetection" JSON object. - Class constructor options: introduction, voice - - (See https://www.tropo.com/docs/webapi/call) - """ - action = 'machineDetection' - options_array = ['introduction', 'voice'] - - def __init__(self, introduction, **options): - self._dict = {'introduction': introduction} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - - class Message(TropoAction): """ Class representing the "message" Tropo action. Builds a "message" JSON object. @@ -262,7 +198,7 @@ class Message(TropoAction): Class constructor options: answerOnMedia, channel, from, name, network, required, timeout, voice Convenience function: Tropo.message() - (See https://www.tropo.com/docs/webapi/message) + (See https://www.tropo.com/docs/webapi/message.htm) { "message": { "say": Object,#Required "to": String or Array,#Required @@ -295,49 +231,27 @@ class On(TropoAction): Class constructor options: name,next,required,say Convenience function: Tropo.on() - (See https://www.tropo.com/docs/webapi/on) + (See https://www.tropo.com/docs/webapi/on.htm) { "on": { "event": String,#Required "name": String, "next": String, "required": Boolean, - "say": Object - "voice": String } } + "say": Object } } """ action = 'on' - options_array = ['name','next','required','say', 'voice', 'ask', 'message', 'wait'] + options_array = ['name','next','required','say'] def __init__(self, event, **options): - self._dict = {} + self._dict = {'event': event} for opt in self.options_array: if opt in options: if ((opt == 'say') and (isinstance(options['say'], basestring))): - if('voice' in options): - self._dict['say'] = Say(options['say'], voice=options['voice']).json - else: - self._dict['say'] = Say(options['say']).json - - elif ((opt == 'ask') and (isinstance(options['ask'], basestring))): - if('voice' in options): - self._dict['ask'] = Ask(options['ask'], voice=options['voice']).json - else: - self._dict['ask'] = Ask(options['ask']).json - - elif ((opt == 'message') and (isinstance(options['message'], basestring))): - if('voice' in options): - self._dict['message'] = Message(options['message'], voice=options['voice']).json - else: - self._dict['message'] = Message(options['message']).json - - elif ((opt == 'wait') and (isinstance(options['wait'], basestring))): - self._dict['wait'] = Wait(options['wait']).json - - elif(opt != 'voice'): + self._dict['say'] = Say(options['say']).json + else: self._dict[opt] = options[opt] - self._dict['event'] = event - class Record(TropoAction): """ Class representing the "record" Tropo action. Builds a "record" JSON object. @@ -345,34 +259,33 @@ class Record(TropoAction): Class constructor options: attempts, bargein, beep, choices, format, maxSilence, maxTime, method, minConfidence, name, password, required, say, timeout, transcription, url, username Convenience function: Tropo.record() - (See https://www.tropo.com/docs/webapi/record) + (See https://www.tropo.com/docs/webapi/record.htm) { "record": { - "asyncUpload": Boolean, - "allowSignals": Boolean, "attempts": Integer, "bargein": Boolean, "beep": Boolean, "choices": Object, "format": String, - "interdigitTimeout": Float, "maxSilence": Float, "maxTime": Float, "method": String, + "minConfidence": Integer, "name": String, "password": String, "required": Boolean, "say": Object, "timeout": Float, "transcription": Array or Object, - "url": String, #Required + "url": String,#Required ????? "username": String, "voice": String} } """ action = 'record' - options_array = ['asyncUpload', 'attempts', 'bargein', 'beep', 'choices', 'format', 'maxSilence', 'maxTime', 'method', 'name', 'password', 'required', 'say', 'timeout', 'transcription', 'username', 'allowSignals', 'voice', 'interdigitTimeout'] - def __init__(self, url, **options): - self._dict = {'url': url} + options_array = ['attempts', 'bargein', 'beep', 'choices', 'format', 'maxSilence', 'maxTime', 'method', 'minConfidence', 'name', 'password', 'required', 'say', 'timeout', 'transcription', 'url', 'username', 'allowSignals', 'voice'] + + def __init__(self, **options): + self._dict = {} for opt in self.options_array: if opt in options: if ((opt == 'say') and (isinstance(options['say'], basestring))): @@ -387,7 +300,7 @@ class Redirect(TropoAction): Class constructor options: name, required Convenience function: Tropo.redirect() - (See https://www.tropo.com/docs/webapi/redirect) + (See https://www.tropo.com/docs/webapi/redirect.htm) { "redirect": { "to": Object,#Required @@ -410,7 +323,7 @@ class Reject(TropoAction): Class constructor options: Convenience function: Tropo.reject() - (See https://www.tropo.com/docs/webapi/reject) + (See https://www.tropo.com/docs/webapi/reject.htm) { "reject": { } } """ @@ -426,10 +339,9 @@ class Say(TropoAction): Class constructor options: attempts, bargein, choices, minConfidence, name, recognizer, required, say, timeout, voice Convenience function: Tropo.say() - (See https://www.tropo.com/docs/webapi/say) + (See https://www.tropo.com/docs/webapi/say.htm) { "say": { - "allowSignals": String or Array, "voice": String, "as": String, "name": String, @@ -446,7 +358,7 @@ def __init__(self, message, **options): for opt in self.options_array: if opt in options: if (opt == "_as"): - dict['as'] = options[opt] + dict['as'] = options['_as'] else: dict[opt] = options[opt] self._list = [] @@ -474,21 +386,18 @@ class StartRecording(TropoAction): Class constructor options: format, method, username, password Convenience function: Tropo.startRecording() - (See https://www.tropo.com/docs/webapi/startrecording) + (See https://www.tropo.com/docs/webapi/startrecording.htm) { "startRecording": { - "asyncUpload":Boolean, "format": String, "method": String, "url": String,#Required "username": String, - "password": String, - "transcriptionID": String - "transcriptionEmailFormat":String - "transcriptionOutURI": String} } + "password": String } } """ action = 'startRecording' - options_array = ['asyncUpload', 'format', 'method', 'username', 'password', 'transcriptionID', 'transcriptionEmailFormat', 'transcriptionOutURI'] + options_array = ['format', 'method', 'username', 'password'] + def __init__(self, url, **options): self._dict = {'url': url} for opt in self.options_array: @@ -502,7 +411,7 @@ class StopRecording(TropoAction): Class constructor options: Convenience function: Tropo.stopRecording() - (See https://www.tropo.com/docs/webapi/stoprecording) + (See https://www.tropo.com/docs/webapi/stoprecording.htm) { "stopRecording": { } } """ action = 'stopRecording' @@ -517,109 +426,53 @@ class Transfer(TropoAction): Class constructor options: answerOnMedia, choices, from, name, required, terminator Convenience function: Tropo.transfer() - (See https://www.tropo.com/docs/webapi/transfer) + (See https://www.tropo.com/docs/webapi/transfer.htm) { "transfer": { "to": String or Array,#Required - "allowSignals":String or Array, "answerOnMedia": Boolean, "choices": Object, - "from": String, + # # **Wed May 18 21:14:05 2011** -- egilchri "headers": Object, - "interdigitTimeout":Float, - "machineDetection": Boolean or Object + # # **Wed May 18 21:14:05 2011** -- egilchri + + "from": String, "name": String, - "playTones":Boolean, "required": Boolean, - "ringRepeat":Integer, "terminator": String, - "timeout": Float, - "voice": String, - } } + "timeout": Float } } """ action = 'transfer' - options_array = ['answerOnMedia', 'choices', '_from', 'name', 'on', 'required', 'allowSignals', 'headers', 'interdigitTimeout', 'ringRepeat', 'timeout', 'machineDetection', 'playTones', 'voice'] + options_array = ['answerOnMedia', 'choices', '_from', 'name', 'on', 'required', 'allowSignals', 'headers'] + def __init__(self, to, **options): - self._dict = {'to': to} - for opt in self.options_array: - if opt in options: - if opt == "on": - whisper = [] - for key, val in options['on'].iteritems(): - newDict = {} - - if(key == "ask"): - newDict['ask'] = val - newDict['event'] = 'connect' - - elif(key == "say"): - newDict['say'] = val - newDict['event'] = 'connect' - - elif(key == "wait"): - newDict['wait'] = val - newDict['event'] = 'connect' - - elif(key == "message"): - newDict['message'] = val - newDict['event'] = 'connect' - - elif(key == "ring"): - newDict['say'] = val - newDict['event'] = 'ring' - - whisper.append(newDict) - - self._dict['on'] = whisper - if (opt == '_from'): - self._dict['from'] = options['_from'] - elif(opt == 'choices'): - self._dict['choices'] = options['choices'] - elif(opt != 'on'): - self._dict[opt] = options[opt] - -class Wait(TropoAction): - """ - Class representing the "wait" Tropo action. Builds a "wait" JSON object. - Class constructor arg: milliseconds, an Integer - Class constructor options: allowSignals - Convenience function: Tropo.wait() - - (See https://www.tropo.com/docs/webapi/wait) - { "wait": { - "milliseconds": Integer,#Required - "allowSignals": String or Array - """ - - action = 'wait' - options_array = ['allowSignals'] - - def __init__(self, milliseconds, **options): - self._dict = {'milliseconds': milliseconds} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] + self._dict = {'to': to} + for opt in self.options_array: + if opt in options: + if (opt == '_from'): + self._dict['from'] = options['_from'] + elif(opt == 'choices'): + self._dict['choices'] = options['choices'] + else: + self._dict[opt] = options[opt] + class Result(object): """ Returned anytime a request is made to the Tropo Web API. Method: getValue - (See https://www.tropo.com/docs/webapi/result) + (See https://www.tropo.com/docs/webapi/result.htm) { "result": { "actions": Array or Object, - "calledId": String, - "callId": String, "complete": Boolean, - "connectedDuration": Integer, - "duration": Integer, "error": String, "sequence": Integer, "sessionDuration": Integer, "sessionId": String, - "state": String, - "userType": String} } + "state": String } } """ - options_array = ['actions','complete','error','sequence', 'sessionDuration', 'sessionId', 'state', 'userType', 'connectedDuration', 'duration', 'calledID', 'callId'] + options_array = ['actions','complete','error','sequence', 'sessionDuration', 'sessionId', 'state'] + def __init__(self, result_json): result_data = jsonlib.loads(result_json) result_dict = result_data['result'] @@ -641,14 +494,6 @@ def getValue(self): # return dict['value'] Fixes issue 17 return dict['value'] - - def getUserType(self): - """ - Get the userType of the previously POSTed Tropo action. - """ - userType = self._userType - return userType - # # **Tue May 17 07:17:38 2011** -- egilchri def getInterpretation(self): @@ -669,8 +514,8 @@ def getInterpretation(self): class Session(object): """ Session is the payload sent as an HTTP POST to your web application when a new session arrives. - (See https://www.tropo.com/docs/webapi/session) - + (See https://www.tropo.com/docs/webapi/session.htm) + Because 'from' is a reserved word in Python, the session object's 'from' property is called fromaddress in the Python library """ @@ -709,15 +554,15 @@ def setVoice(self, voice): def ask(self, choices, **options): """ - Sends a prompt to the user and optionally waits for a response. - Arguments: "choices" is a Choices object - See https://www.tropo.com/docs/webapi/ask + Sends a prompt to the user and optionally waits for a response. + Arguments: "choices" is a Choices object + See https://www.tropo.com/docs/webapi/ask.htm """ # # **Sun May 15 21:21:29 2011** -- egilchri # Settng the voice in this method call has priority. - # Otherwise, we can pick up the voice from the Tropo object, - # if it is set there. + # Otherwise, we can pick up the voice from the Tropo object, + # if it is set there. if hasattr (self, 'voice'): if (not 'voice' in options): options['voice'] = self.voice @@ -729,10 +574,11 @@ def ask(self, choices, **options): def call (self, to, **options): """ - Places a call or sends an an IM, Twitter, or SMS message. To start a call, use the Session API to tell Tropo to launch your code. - Arguments: to is a String. - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/call + Places a call or sends an an IM, Twitter, or SMS message. To start a call, use the Session API to tell Tropo to launch your code. + + Arguments: to is a String. + Argument: **options is a set of optional keyword arguments. + See https://www.tropo.com/docs/webapi/call.htm """ self._steps.append(Call (to, **options).obj) @@ -742,24 +588,25 @@ def conference(self, id, **options): This is a voice channel only feature. Argument: "id" is a String Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/conference + See https://www.tropo.com/docs/webapi/conference.htm """ self._steps.append(Conference(id, **options).obj) def hangup(self): """ This method instructs Tropo to "hang-up" or disconnect the session associated with the current session. - See https://www.tropo.com/docs/webapi/hangup + See https://www.tropo.com/docs/webapi/hangup.htm """ self._steps.append(Hangup().obj) def message (self, say_obj, to, **options): """ A shortcut method to create a session, say something, and hang up, all in one step. This is particularly useful for sending out a quick SMS or IM. - Argument: "say_obj" is a Say object + + Argument: "say_obj" is a Say object Argument: "to" is a String Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/message + See https://www.tropo.com/docs/webapi/message.htm """ if isinstance(say_obj, basestring): say = Say(say_obj).obj @@ -773,20 +620,15 @@ def on(self, event, **options): Possible events are: "continue", "error", "incomplete" and "hangup". Argument: event is an event Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/on + See https://www.tropo.com/docs/webapi/on.htm """ - if hasattr (self, 'voice'): - if (not 'voice' in options): - options['voice'] = self.voice - - self._steps.append(On(event, **options).obj) def record(self, **options): """ - Plays a prompt (audio file or text to speech) and optionally waits for a response from the caller that is recorded. + Plays a prompt (audio file or text to speech) and optionally waits for a response from the caller that is recorded. Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/record + See https://www.tropo.com/docs/webapi/record.htm """ self._steps.append(Record(**options).obj) @@ -795,14 +637,14 @@ def redirect(self, id, **options): Forwards an incoming call to another destination / phone number before answering it. Argument: id is a String Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/redirect + See https://www.tropo.com/docs/webapi/redirect.htm """ self._steps.append(Redirect(id, **options).obj) def reject(self): """ Allows Tropo applications to reject incoming sessions before they are answered. - See https://www.tropo.com/docs/webapi/reject + See https://www.tropo.com/docs/webapi/reject.htm """ self._steps.append(Reject().obj) @@ -812,14 +654,14 @@ def say(self, message, **options): In the case of an text channel it will send the text back to the user via i nstant messaging or SMS. Argument: message is a string Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/say + See https://www.tropo.com/docs/webapi/say.htm """ #voice = self.voice # # **Sun May 15 21:21:29 2011** -- egilchri # Settng the voice in this method call has priority. - # Otherwise, we can pick up the voice from the Tropo object, - # if it is set there. + # Otherwise, we can pick up the voice from the Tropo object, + # if it is set there. if hasattr (self, 'voice'): if (not 'voice' in options): options['voice'] = self.voice @@ -832,14 +674,14 @@ def startRecording(self, url, **options): Allows Tropo applications to begin recording the current session. Argument: url is a string Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/startrecording + See https://www.tropo.com/docs/webapi/startrecording.htm """ self._steps.append(StartRecording(url, **options).obj) def stopRecording(self): """ Stops a previously started recording. - See https://www.tropo.com/docs/webapi/stoprecording + See https://www.tropo.com/docs/webapi/stoprecording.htm """ self._steps.append(StopRecording().obj) @@ -848,19 +690,10 @@ def transfer(self, to, **options): Transfers an already answered call to another destination / phone number. Argument: to is a string Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/transfer + See https://www.tropo.com/docs/webapi/transfer.htm """ self._steps.append(Transfer(to, **options).obj) - def wait(self, milliseconds, **options): - """ - Allows the thread to sleep for a given amount of time in milliseconds - Argument: milliseconds is an Integer - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/wait - """ - self._steps.append(Wait(milliseconds, **options).obj) - def RenderJson(self, pretty=False): """ Render a Tropo object into a Json string. @@ -878,7 +711,7 @@ def RenderJson(self, pretty=False): return json if __name__ == '__main__': - print(""" + print (""" This is the Python web API for http://www.tropo.com/ From 19cf0f48694242625b8709006729b354fb9f72c8 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 19:27:22 -0600 Subject: [PATCH 07/19] fix formatting --- tropo.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tropo.py b/tropo.py index 3ed17f9..8624464 100644 --- a/tropo.py +++ b/tropo.py @@ -130,7 +130,6 @@ def __init__(self, to, **options): else: self._dict[opt] = options[opt] - class Choices(TropoAction): """ @@ -434,7 +433,7 @@ class Transfer(TropoAction): # # **Wed May 18 21:14:05 2011** -- egilchri "headers": Object, # # **Wed May 18 21:14:05 2011** -- egilchri - + "from": String, "name": String, "required": Boolean, @@ -515,7 +514,7 @@ class Session(object): """ Session is the payload sent as an HTTP POST to your web application when a new session arrives. (See https://www.tropo.com/docs/webapi/session.htm) - + Because 'from' is a reserved word in Python, the session object's 'from' property is called fromaddress in the Python library """ From acb118660b654455c4da6573befde39b889cd38c Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 20:19:56 -0600 Subject: [PATCH 08/19] formatting --- tropo.py | 83 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/tropo.py b/tropo.py index e8814b7..2f51d70 100644 --- a/tropo.py +++ b/tropo.py @@ -8,22 +8,22 @@ tropo = Tropo() tropo.say("Hello, World") -json = tropo.RenderJson() +json = tropo.RenderJson() ---- -You can write this JSON back to standard output to get Tropo to perform +You can write this JSON back to standard output to get Tropo to perform the action. For example, on Google Appengine you might write something like: handler.response.out.write(json) -Much of the time, a you will interact with Tropo by examining the Result -object and communicating back to Tropo via the Tropo class methods, such +Much of the time, a you will interact with Tropo by examining the Result +object and communicating back to Tropo via the Tropo class methods, such as "say". In some cases, you'll want to build a class object directly such as in : choices = tropo.Choices("[5 digits]").obj - tropo.ask(choices, - say="Please enter your 5 digit zip code.", + tropo.ask(choices, + say="Please enter your 5 digit zip code.", attempts=3, bargein=True, name="zip", timeout=5, voice="dave") ... @@ -80,7 +80,7 @@ class Ask(TropoAction): "required": Boolean, "say": Object, "timeout": Float, - "voice": String } } + "voice": String } } """ action = 'ask' @@ -118,7 +118,7 @@ class Call(TropoAction): "network": String, "recording": Array or Object, "required": Boolean, - "timeout": Float } } + "timeout": Float } } """ action = 'call' options_array = ['answerOnMedia', 'channel', 'from', 'headers', 'name', 'network', 'recording', 'required', 'timeout'] @@ -160,7 +160,7 @@ class Conference(TropoAction): "name": String, "playTones": Boolean, "required": Boolean, - "terminator": String } } + "terminator": String } } """ action = 'conference' options_array = ['mute', 'name', 'playTones', 'required', 'terminator'] @@ -174,8 +174,8 @@ def __init__(self, id, **options): class Hangup(TropoAction): """ Class representing the "hangup" Tropo action. Builds a "hangup" JSON object. - Class constructor arg: - Class constructor options: + Class constructor arg: + Class constructor options: Convenience function: Tropo.hangup() (See https://www.tropo.com/docs/webapi/hangup.htm) @@ -206,7 +206,7 @@ class Message(TropoAction): "network": String, "required": Boolean, "timeout": Float, - "voice": String } } + "voice": String } } """ action = 'message' options_array = ['answerOnMedia', 'channel', 'from', 'name', 'network', 'required', 'timeout', 'voice'] @@ -231,7 +231,7 @@ class On(TropoAction): "name": String, "next": String, "required": Boolean, - "say": Object } } + "say": Object } } """ action = 'on' options_array = ['name','next','required','say'] @@ -248,7 +248,7 @@ def __init__(self, event, **options): class Record(TropoAction): """ Class representing the "record" Tropo action. Builds a "record" JSON object. - Class constructor arg: + Class constructor arg: Class constructor options: attempts, bargein, beep, choices, format, maxSilence, maxTime, method, minConfidence, name, password, required, say, timeout, transcription, url, username Convenience function: Tropo.record() @@ -271,7 +271,7 @@ class Record(TropoAction): "timeout": Float, "transcription": Array or Object, "url": String,#Required ????? - "username": String } } + "username": String } } """ action = 'record' options_array = ['attempts', 'bargein', 'beep', 'choices', 'format', 'maxSilence', 'maxTime', 'method', 'minConfidence', 'name', 'password', 'required', 'say', 'timeout', 'transcription', 'url', 'username'] @@ -297,7 +297,7 @@ class Redirect(TropoAction): { "redirect": { "to": Object,#Required "name": String, - "required": Boolean } } + "required": Boolean } } """ action = 'redirect' options_array = ['name', 'required'] @@ -311,13 +311,13 @@ def __init__(self, to, **options): class Reject(TropoAction): """ Class representing the "reject" Tropo action. Builds a "reject" JSON object. - Class constructor arg: - Class constructor options: + Class constructor arg: + Class constructor options: Convenience function: Tropo.reject() (See https://www.tropo.com/docs/webapi/reject.htm) - { "reject": { } } + { "reject": { } } """ action = 'reject' @@ -338,7 +338,7 @@ class Say(TropoAction): "name": String, "required": Boolean, "value": String #Required - } } + } } """ action = 'say' options_array = ['as', 'name', 'required'] @@ -380,7 +380,7 @@ class StartRecording(TropoAction): "method": String, "url": String,#Required "username": String, - "password": String } } + "password": String } } """ action = 'startRecording' options_array = ['format', 'method', 'username', 'password'] @@ -399,7 +399,7 @@ class StopRecording(TropoAction): Convenience function: Tropo.stopRecording() (See https://www.tropo.com/docs/webapi/stoprecording.htm) - { "stopRecording": { } } + { "stopRecording": { } } """ action = 'stopRecording' @@ -422,7 +422,7 @@ class Transfer(TropoAction): "name": String, "required": Boolean, "terminator": String, - "timeout": Float } } + "timeout": Float } } """ action = 'transfer' options_array = ['answerOnMedia', 'choices', 'from', 'name', 'required', 'terminator'] @@ -441,7 +441,7 @@ def __init__(self, to, **options): class Result(object): """ - Returned anytime a request is made to the Tropo Web API. + Returned anytime a request is made to the Tropo Web API. Method: getValue (See https://www.tropo.com/docs/webapi/result.htm) @@ -483,7 +483,7 @@ def getValue(self): class Session(object): """ - Session is the payload sent as an HTTP POST to your web application when a new session arrives. + Session is the payload sent as an HTTP POST to your web application when a new session arrives. (See https://www.tropo.com/docs/webapi/session.htm) """ def __init__(self, session_json): @@ -521,7 +521,7 @@ def ask(self, choices, **options): def call (self, to, **options): """ - Places a call or sends an an IM, Twitter, or SMS message. To start a call, use the Session API to tell Tropo to launch your code. + Places a call or sends an an IM, Twitter, or SMS message. To start a call, use the Session API to tell Tropo to launch your code. Arguments: to is a String. Argument: **options is a set of optional keyword arguments. @@ -531,8 +531,8 @@ def call (self, to, **options): def conference(self, id, **options): """ - This object allows multiple lines in separate sessions to be conferenced together so that the parties on each line can talk to each other simultaneously. - This is a voice channel only feature. + This object allows multiple lines in separate sessions to be conferenced together so that the parties on each line can talk to each other simultaneously. + This is a voice channel only feature. Argument: "id" is a String Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/conference.htm @@ -548,7 +548,7 @@ def hangup(self): def message (self, say_obj, to, **options): """ - A shortcut method to create a session, say something, and hang up, all in one step. This is particularly useful for sending out a quick SMS or IM. + A shortcut method to create a session, say something, and hang up, all in one step. This is particularly useful for sending out a quick SMS or IM. Argument: "say_obj" is a Say object Argument: "to" is a String @@ -563,8 +563,8 @@ def message (self, say_obj, to, **options): def on(self, event, **options): """ - Adds an event callback so that your application may be notified when a particular event occurs. - Possible events are: "continue", "error", "incomplete" and "hangup". + Adds an event callback so that your application may be notified when a particular event occurs. + Possible events are: "continue", "error", "incomplete" and "hangup". Argument: event is an event Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/on.htm @@ -573,7 +573,7 @@ def on(self, event, **options): def record(self, **options): """ - Plays a prompt (audio file or text to speech) and optionally waits for a response from the caller that is recorded. + Plays a prompt (audio file or text to speech) and optionally waits for a response from the caller that is recorded. Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/record.htm """ @@ -581,7 +581,7 @@ def record(self, **options): def redirect(self, id, **options): """ - Forwards an incoming call to another destination / phone number before answering it. + Forwards an incoming call to another destination / phone number before answering it. Argument: id is a String Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/redirect.htm @@ -590,15 +590,15 @@ def redirect(self, id, **options): def reject(self): """ - Allows Tropo applications to reject incoming sessions before they are answered. + Allows Tropo applications to reject incoming sessions before they are answered. See https://www.tropo.com/docs/webapi/reject.htm """ self._steps.append(Reject().obj) def say(self, message, **options): """ - When the current session is a voice channel this key will either play a message or an audio file from a URL. - In the case of an text channel it will send the text back to the user via i nstant messaging or SMS. + When the current session is a voice channel this key will either play a message or an audio file from a URL. + In the case of an text channel it will send the text back to the user via i nstant messaging or SMS. Argument: message is a string Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/say.htm @@ -607,7 +607,7 @@ def say(self, message, **options): def startRecording(self, url, **options): """ - Allows Tropo applications to begin recording the current session. + Allows Tropo applications to begin recording the current session. Argument: url is a string Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/startrecording.htm @@ -623,7 +623,7 @@ def stopRecording(self): def transfer(self, to, **options): """ - Transfers an already answered call to another destination / phone number. + Transfers an already answered call to another destination / phone number. Argument: to is a string Argument: **options is a set of optional keyword arguments. See https://www.tropo.com/docs/webapi/transfer.htm @@ -649,14 +649,13 @@ def RenderJson(self, pretty=False): if __name__ == '__main__': print (""" - + This is the Python web API for http://www.tropo.com/ - + To run the test suite, please run: - + cd test python test.py - """) From bb84ad747a8c3e54a8d04d1851dde1bd1640c5b2 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 22:01:08 -0600 Subject: [PATCH 09/19] rename to ciscotropowebapi --- tropo.py => ciscotropowebapi.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tropo.py => ciscotropowebapi.py (100%) diff --git a/tropo.py b/ciscotropowebapi.py similarity index 100% rename from tropo.py rename to ciscotropowebapi.py From 4d595569969a75e729d665a091ae9af9fb4c6220 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 1 Apr 2017 22:03:26 -0600 Subject: [PATCH 10/19] fix samples. add setup.py, gitignore --- .gitignore | 95 +++++++++++++++++++++++++++++++++++++ samples/itty_hello_world.py | 2 +- samples/itty_session_api.py | 2 +- samples/main.py | 4 +- setup.py | 21 ++++++++ test/test.py | 20 ++++---- 6 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 .gitignore create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8d87f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject +*.un~ diff --git a/samples/itty_hello_world.py b/samples/itty_hello_world.py index 53ab801..621fd03 100755 --- a/samples/itty_hello_world.py +++ b/samples/itty_hello_world.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from itty import * -from tropo import Tropo, Session +from ciscotropowebapi import Tropo, Session @post('/index.json') def index(request): diff --git a/samples/itty_session_api.py b/samples/itty_session_api.py index f8faf14..42e3359 100755 --- a/samples/itty_session_api.py +++ b/samples/itty_session_api.py @@ -7,7 +7,7 @@ """ from itty import * -from tropo import Tropo, Session +from ciscotropowebapi import Tropo, Session from urllib import urlencode from urllib2 import urlopen diff --git a/samples/main.py b/samples/main.py index 869a69e..7bbcbfa 100755 --- a/samples/main.py +++ b/samples/main.py @@ -7,7 +7,7 @@ from google.appengine.ext.webapp import util import cgi import logging -import tropo +import ciscotropowebapi import GoogleS3 from xml.dom import minidom from google.appengine.api import urlfetch @@ -151,7 +151,7 @@ class TropoDemo(webapp.RequestHandler): """ def post(self): if (1): - tropo = tropo.Tropo() + tropo = ciscotropowebapi.Tropo() tropo.say ("Welcome to the Tropo web API demo") request = "Please press" diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..62b413f --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ + +from distutils.core import setup + +setup(name = "ciscotropowebapi", + version = "0.1.0", + url = "http://github.com/rsp2k/ciscotropowebapi", + maintainer = "supportedsystems", + maintainer_email = "python-ciscotropowebapi@supported.systems", + description = "Python library for building voice/SMS/IM/Twitter apps at Tropo.com", + long_description = "This module implements a set of classes and methods for manipulating the Web API for the Tropo cloud communications service at http://www.tropo.com/", + platforms = ["Platform Independent"], + license = "MIT", + classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python" + ], + py_modules = ['ciscotropowebapi'], +) diff --git a/test/test.py b/test/test.py index 4a7094b..a0be925 100755 --- a/test/test.py +++ b/test/test.py @@ -14,13 +14,13 @@ except ImportError: import json as jsonlib -import unittest +import unittest import sys sys.path = ['..'] + sys.path -from tropo import Choices, Say, Tropo +from ciscotropowebapi import Choices, Say, Tropo -class TestTropoPython(unittest.TestCase): +class TestTropoPython(unittest.TestCase): """ Class implementing a set of unit tests for TropoPython. """ @@ -130,7 +130,7 @@ def test_on(self): tropo = Tropo() - tropo.on(event="continue", + tropo.on(event="continue", next="/weather.py?uri=end", say="Please hold.") rendered = tropo.RenderJson() @@ -152,7 +152,7 @@ def test_record(self): tropo = Tropo() url = "/receive_recording.py" choices_obj = Choices("", terminator="#").json - tropo.record(say="Tell us about yourself", url=url, + tropo.record(say="Tell us about yourself", url=url, choices=choices_obj) rendered = tropo.RenderJson() pretty_rendered = tropo.RenderJson(pretty=True) @@ -317,12 +317,12 @@ def test_transfer(self): tropo.conference(ID) tropo.hangup() tropo.message ("Hello, World", TO) - tropo.on(event="continue", + tropo.on(event="continue", next="http://example.com/weather.py", say="Please hold.") - tropo.record(say="Please say something for posterity", - url=URL, + tropo.record(say="Please say something for posterity", + url=URL, choices = Choices("", terminator="#").json) tropo.redirect(ID) tropo.reject(ID) @@ -331,8 +331,8 @@ def test_transfer(self): tropo.transfer(TO) tropo.message("Hello, World", - TO, - channel='TEXT', + TO, + channel='TEXT', network='SMS') else: From bd6d1593637470f050ee7927b64c0b6e823305a8 Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:06:28 -0600 Subject: [PATCH 11/19] Update README --- README | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README b/README index 2101ae3..a88abc4 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ NAME - tropo - The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ + ciscotropowebapi - The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ FILE http://github.com/tropo/python-webapi/blob/master/tropo.py @@ -8,7 +8,7 @@ DESCRIPTION Usage: ---- - from tropo import Tropo + from ciscotropowebapi import Tropo tropo = Tropo() tropo.say("Hello, World") @@ -31,12 +31,6 @@ DESCRIPTION attempts=3, bargein=True, name="zip", timeout=5, voice="dave") ... -NOTE ON PYTHON VERSIONS - - This version of the module is for python 3.x. - There is a separate version available for python 2.x at: - - http://github.com/tropo/python-webapi/ TESTS From ca0fd3dca5c256b4010d903bbdca77cc54b8fa2f Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:07:36 -0600 Subject: [PATCH 12/19] Update README --- README | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README b/README index a88abc4..bb6c0b5 100644 --- a/README +++ b/README @@ -1,10 +1,8 @@ -NAME - ciscotropowebapi - The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ +# ciscotropowebapi -FILE - http://github.com/tropo/python-webapi/blob/master/tropo.py +The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ -DESCRIPTION +# Description Usage: ---- @@ -32,7 +30,7 @@ DESCRIPTION ... -TESTS +# Tests Run testsuite by issuing: From 99833e68b4fc69156c4cc97a830b9f7e4eb95da4 Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:07:46 -0600 Subject: [PATCH 13/19] Rename README to README.md --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From dbd2b92f81873f26b80578186b99b13e90b19246 Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:08:13 -0600 Subject: [PATCH 14/19] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index bb6c0b5..52ead26 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,6 @@ The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ # Description - Usage: - - ---- from ciscotropowebapi import Tropo tropo = Tropo() From 045e5e18c8fc24f8922c8f722563a9a8854041cd Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:09:30 -0600 Subject: [PATCH 15/19] Update README.md --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 52ead26..feac401 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,15 @@ The TropoPython module. This module implements a set of classes and methods for python test.py CLASSES - Ask - Call - Choices - Conference - Hangup - Message - On - Record +* Ask +* Call +* Choices +* Conference +* Hangup +* Message +* On +* Record + Redirect Reject Result From c613e7763475dab59c0fd597d0a5f7f6e1829f69 Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:09:43 -0600 Subject: [PATCH 16/19] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index feac401..28e1b75 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ The TropoPython module. This module implements a set of classes and methods for cd test python test.py -CLASSES +# Classes + * Ask * Call * Choices From 3db2c2179dd01a25dbc5bbf626cf324f62a2797c Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:10:25 -0600 Subject: [PATCH 17/19] Update README.md --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 28e1b75..d4ec001 100644 --- a/README.md +++ b/README.md @@ -44,19 +44,19 @@ The TropoPython module. This module implements a set of classes and methods for * Message * On * Record +* Redirect +* Reject +* Result +* Say +* Session +* StartRecording +* StopRecording +* Transfer +* Tropo +* unittest.TestCase(__builtin__.object) +* TestTropoPython - Redirect - Reject - Result - Say - Session - StartRecording - StopRecording - Transfer - Tropo - unittest.TestCase(__builtin__.object) - TestTropoPython - +# Details of each class class Ask | Class representing the "ask" Tropo action. Builds an "ask" JSON object. | Class constructor arg: choices, a Choices object From b27e7abbe18228d211976785c9b8e4ee47e015bf Mon Sep 17 00:00:00 2001 From: rsp2k Date: Sat, 1 Apr 2017 22:11:20 -0600 Subject: [PATCH 18/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4ec001..0747e16 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ciscotropowebapi -The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI for the Tropo cloud communications service at http://www.tropo.com/ +This module is for working with the Cisco Tropo Web API cloud communications service at http://www.tropo.com/ # Description from ciscotropowebapi import Tropo From 2c9d5797239a29c6b0d02a08bf8687cc0c34801c Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sun, 2 Apr 2017 13:44:15 -0600 Subject: [PATCH 19/19] fix keywords --- ciscotropowebapi.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ciscotropowebapi.py b/ciscotropowebapi.py index 2f51d70..bab95eb 100644 --- a/ciscotropowebapi.py +++ b/ciscotropowebapi.py @@ -46,6 +46,8 @@ import logging +import keyword + class TropoAction(object): """ @@ -493,6 +495,10 @@ def __init__(self, session_json): for key in session_dict: val = session_dict[key] logging.info ("key: %s val: %s" % (key, val)) + if key in keyword.kwlist: + key = key + '_' + logging.info ("changed key: %s val: %s" % (key, val)) + setattr(self, key, val)