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/ISSUES b/ISSUES deleted file mode 100644 index c12a392..0000000 --- a/ISSUES +++ /dev/null @@ -1,7 +0,0 @@ -Known issues with this python module for the Tropo Web API can be found at: - - http://github.com/tropo/tropo-webapi-python/issues - -Please also use that URL to raise any issues, report any bugs or add any suggestions or requests. - -Thanks. diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/MANIFEST b/MANIFEST deleted file mode 100644 index 66b1bd8..0000000 --- a/MANIFEST +++ /dev/null @@ -1,6 +0,0 @@ -LICENSE -MANIFEST.in -README -setup.py -tropo.py -test/test.py diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 4b86614..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include MANIFEST.in LICENSE - diff --git a/README.md b/README.md index e89f071..0747e16 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,62 @@ -# Tropo Python Module +# ciscotropowebapi -tropo - The TropoPython module. 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/ +This module is for working with the Cisco Tropo Web API cloud communications service at http://www.tropo.com/ -For more information about the Tropo Web API that is used with this module, please see: +# Description + from ciscotropowebapi import Tropo - http://www.tropo.com/docs/webapi/ - -As this python module is still in development, please report any bugs or issues by raising an issue here: - - http://github.com/tropo/tropo-webapi-python/issues - -## File - - http://github.com/tropo/tropo-webapi-python/blob/master/tropo.py - -## Description - -Usage: - -```python -from tropo import Tropo - -tropo = Tropo() -tropo.say("Hello, World") -json = tropo.RenderJson() -``` - -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 -as "say". In some cases, you'll want to build a class object directly such as in : - -```python - choices = tropo.Choices("[5 digits]").obj - - tropo.ask(choices, - say="Please enter your 5 digit zip code.", - attempts=3, bargein=True, name="zip", timeout=5, voice="dave") - ... -``` - -## Note on Python versions - -This module is for python 2.x and requires python 2.5 or higher. -There is a separate version available for python 3.x at: - - https://github.com/tropo/tropo-webapi-python/tree/python3 - -## License + tropo = Tropo() + tropo.say("Hello, World") + json = tropo.RenderJson() + ---- + + 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 + 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.", + attempts=3, bargein=True, name="zip", timeout=5, voice="dave") + ... -MIT, see LICENSE.txt -## Tests +# Tests -Run testsuite by issuing: + Run testsuite by issuing: cd test python test.py -## Classes -```python - Ask - Call - Choices - Conference - Hangup - Message - On - Record - Redirect - Reject - Result - Say - Session - StartRecording - StopRecording - Transfer - Tropo - unittest.TestCase(__builtin__.object) - TestTropoPython - +# Classes + +* Ask +* Call +* Choices +* Conference +* Hangup +* Message +* On +* Record +* 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 @@ -113,7 +85,7 @@ Run testsuite by issuing: class Call | 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 + | Class constructor options: answerOnMedia, channel, from, headers, name, network, recording, required, timeout | Convenience function: Tropo.call() | | (See https://www.tropo.com/docs/webapi/call.htm) @@ -182,7 +154,7 @@ Run testsuite by issuing: | Class representing the "message" Tropo action. Builds a "message" JSON object. | Class constructor arg: say_obj, a Say object | Class constructor arg: to, a String - | Class constructor options: answerOnMedia, channel, _from, name, network, required, timeout, voice + | Class constructor options: answerOnMedia, channel, from, name, network, required, timeout, voice | Convenience function: Tropo.message() | | (See https://www.tropo.com/docs/webapi/message.htm) @@ -309,7 +281,7 @@ Run testsuite by issuing: class Say | Class representing the "say" Tropo action. Builds a "say" JSON object. | Class constructor arg: message, a String, or a List of Strings - | Class constructor options: attempts, bargein, choices, minConfidence, name, recognizer, required, say, timeout, voice, _as + | 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.htm) @@ -328,9 +300,6 @@ Run testsuite by issuing: class Session | 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 | | Methods defined here: | @@ -595,7 +564,7 @@ Run testsuite by issuing: class Transfer | Class representing the "transfer" Tropo action. Builds a "transfer" JSON object. | Class constructor arg: to, a String, or List - | Class constructor options: answerOnMedia, choices, _from, name, required, terminator + | Class constructor options: answerOnMedia, choices, from, name, required, terminator | Convenience function: Tropo.transfer() | | (See https://www.tropo.com/docs/webapi/transfer.htm) @@ -643,7 +612,7 @@ Run testsuite by issuing: | 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. Use "_from" instead of "from". + | Argument: **options is a set of optional keyword arguments. | See https://www.tropo.com/docs/webapi/call.htm | | conference(self, id, **options) @@ -662,7 +631,7 @@ Run testsuite by issuing: | | Argument: "say_obj" is a Say object | Argument: "to" is a String - | Argument: **options is a set of optional keyword arguments. Use "_from" instead of "from". + | Argument: **options is a set of optional keyword arguments. | See https://www.tropo.com/docs/webapi/message.htm | | on(self, event, **options) @@ -691,7 +660,7 @@ Run testsuite by issuing: | 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. Use "_as" instead of "as". + | Argument: **options is a set of optional keyword arguments. | See https://www.tropo.com/docs/webapi/say.htm | | startRecording(self, url, **options) @@ -707,6 +676,6 @@ Run testsuite by issuing: | 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. Use "_from" instead of "from". + | Argument: **options is a set of optional keyword arguments. | See https://www.tropo.com/docs/webapi/transfer.htm -``` + diff --git a/build/lib/tropo.py b/build/lib/tropo.py deleted file mode 100644 index 6f5e748..0000000 --- a/build/lib/tropo.py +++ /dev/null @@ -1,893 +0,0 @@ -""" -The TropoPython module. This module implements a set of classes and methods for manipulating the Voxeo Tropo WebAPI. - -Usage: - ----- -from tropo import Tropo - -tropo = Tropo() -tropo.say("Hello, World") -json = tropo.RenderJson() ----- - -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 -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.", - attempts=3, bargein=True, name="zip", timeout=5, voice="dave") - ... - -NOTE: This module requires python 2.5 or higher. - -""" - -try: - import cjson as jsonlib - jsonlib.dumps = jsonlib.encode - jsonlib.loads = jsonlib.decode -except ImportError: - try: - from django.utils import simplejson as jsonlib - except ImportError: - try: - import simplejson as jsonlib - except ImportError: - import json as jsonlib - -class TropoAction(object): - """ - Class representing the base Tropo action. - Two properties are provided in order to avoid defining the same attributes for every action. - """ - @property - def json(self): - return self._dict - - @property - def obj(self): - return {self.action: self._dict} - -class Ask(TropoAction): - """ - Class representing the "ask" Tropo action. Builds an "ask" JSON object. - Class constructor arg: choices, a Choices object - Convenience function: Tropo.ask() - 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) - - { "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, - - } } - - """ - action = 'ask' - options_array = ['attempts', 'allowSignals', 'bargein', 'choices', 'interdigitTimeout', 'minConfidence', 'name', 'recognizer', 'required', 'say', 'sensitivity', 'speechCompleteTimeout', 'speechIncompleteTimeout', 'timeout', 'voice'] - - def __init__(self, choices, **options): - self._dict = {} - if (isinstance(choices, basestring)): - self._dict['choices'] = Choices(choices).json - else: -# self._dict['choices'] = choices['choices'] - self._dict['choices'] = choices.json - for opt in self.options_array: - if opt in options: - if ((opt == 'say') and (isinstance(options['say'], basestring))): - self._dict['say'] = Say(options['say']).json - else: - self._dict[opt] = options[opt] - -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 - Convenience function: Tropo.call() - - (See https://www.tropo.com/docswebapi/call) - - { "call": { - "to": String or Array,#Required - "answerOnMedia": Boolean, - "allowSignals": String or Array - "channel": string, - "from": string, - "headers": Object, - "name": String, - "network": String, - "recording": Array or Object, - "required": Boolean, - "timeout": Float. - "machineDetection: Boolean or Object" } } - """ - action = 'call' - options_array = ['answerOnMedia', 'allowSignals', 'channel', '_from', 'headers', 'name', 'network', 'recording', 'required', 'timeout', 'machineDetection'] - - def __init__(self, to, **options): - self._dict = {'to': to} - for opt in self.options_array: - if opt in options: - if (opt == "_from"): - self._dict['from'] = options[opt] - 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) - """ - action = 'choices' - options_array = ['terminator', 'mode'] - - 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 Conference(TropoAction): - """ - Class representing the "conference" Tropo action. Builds a "conference" JSON object. - Class constructor arg: id, a String - Convenience function: Tropo.conference() - Class constructor options: mute, name, playTones, required, terminator - - (See https://www.tropo.com/docs/webapi/conference) - - { "conference": { - "id": String,#Required - "allowSignals": String or Array, - "interdigitTimeout":Integer, - "mute": Boolean, - "name": String, - "playTones": Boolean, - "required": Boolean, - "terminator": String, - "joinPrompt": Object, - "leavePrompt": Object } } - """ - action = 'conference' - options_array = ['allowSignals', 'interdigitTimeout', 'mute', 'name', 'playTones', 'required', 'terminator', 'joinPrompt', 'leavePrompt'] - - def __init__(self, id, **options): - self._dict = {'id': id} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - -class Hangup(TropoAction): - """ - Class representing the "hangup" Tropo action. Builds a "hangup" JSON object. - Class constructor arg: - Class constructor options: - Convenience function: Tropo.hangup() - - (See https://www.tropo.com/docs/webapi/hangup) - - { "hangup": { } } - """ - action = 'hangup' - - 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. - Class constructor arg: say_obj, a Say object - Class constructor arg: to, a String - Class constructor options: answerOnMedia, channel, from, name, network, required, timeout, voice - Convenience function: Tropo.message() - - (See https://www.tropo.com/docs/webapi/message) - { "message": { - "say": Object,#Required - "to": String or Array,#Required - "answerOnMedia": Boolean, - "channel": string, - "from": String, - "name": String, - "network": String, - "required": Boolean, - "timeout": Float, - "voice": String } } - """ - action = 'message' - options_array = ['answerOnMedia', 'channel', '_from', 'name', 'network', 'required', 'timeout', 'voice'] - - def __init__(self, say_obj, to, **options): - self._dict = {'say': say_obj['say'], 'to': to} - for opt in self.options_array: - if opt in options: - if (opt == "_from"): - self._dict['from'] = options[opt] - else: - self._dict[opt] = options[opt] - - -class On(TropoAction): - """ - Class representing the "on" Tropo action. Builds an "on" JSON object. - Class constructor arg: event, a String - Class constructor options: name,next,required,say - Convenience function: Tropo.on() - - (See https://www.tropo.com/docs/webapi/on) - - { "on": { - "event": String,#Required - "name": String, - "next": String, - "required": Boolean, - "say": Object - "voice": String } } - """ - action = 'on' - options_array = ['name','next','required','say', 'voice', 'ask', 'message', 'wait'] - - def __init__(self, event, **options): - self._dict = {} - 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[opt] = options[opt] - - self._dict['event'] = event - -class Record(TropoAction): - """ - Class representing the "record" Tropo action. Builds a "record" JSON object. - 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() - - (See https://www.tropo.com/docs/webapi/record) - - { "record": { - "asyncUpload": Boolean, - "allowSignals": Boolean, - "attempts": Integer, - "bargein": Boolean, - "beep": Boolean, - "choices": Object, - "format": String, - "interdigitTimeout": Float, - "maxSilence": Float, - "maxTime": Float, - "method": String, - "name": String, - "password": String, - "required": Boolean, - "say": Object, - "timeout": Float, - "transcription": Array or Object, - "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} - for opt in self.options_array: - if opt in options: - if ((opt == 'say') and (isinstance(options['say'], basestring))): - self._dict['say'] = Say(options['say']).json - else: - self._dict[opt] = options[opt] - -class Redirect(TropoAction): - """ - Class representing the "redirect" Tropo action. Builds a "redirect" JSON object. - Class constructor arg: to, a String - Class constructor options: name, required - Convenience function: Tropo.redirect() - - (See https://www.tropo.com/docs/webapi/redirect) - - { "redirect": { - "to": Object,#Required - "name": String, - "required": Boolean } } - """ - action = 'redirect' - options_array = ['name', 'required'] - - def __init__(self, to, **options): - self._dict = {'to': to} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - -class Reject(TropoAction): - """ - Class representing the "reject" Tropo action. Builds a "reject" JSON object. - Class constructor arg: - Class constructor options: - Convenience function: Tropo.reject() - - (See https://www.tropo.com/docs/webapi/reject) - - { "reject": { } } - """ - action = 'reject' - - def __init__(self): - self._dict = {} - -class Say(TropoAction): - """ - Class representing the "say" Tropo action. Builds a "say" JSON object. - Class constructor arg: message, a String, or a List of Strings - 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) - - { "say": { - "allowSignals": String or Array, - "voice": String, - "as": String, - "name": String, - "required": Boolean, - "value": String #Required - } } - """ - action = 'say' - # added _as because 'as' is reserved - options_array = ['_as', 'name', 'required', 'voice', 'allowSignals'] - - def __init__(self, message, **options): - dict = {} - for opt in self.options_array: - if opt in options: - if (opt == "_as"): - dict['as'] = options[opt] - else: - dict[opt] = options[opt] - self._list = [] - if (isinstance (message, list)): - for mess in message: - new_dict = dict.copy() - new_dict['value'] = mess - self._list.append(new_dict) - else: - dict['value'] = message - self._list.append(dict) - - @property - def json(self): - return self._list[0] if len(self._list) == 1 else self._list - - @property - def obj(self): - return {self.action: self._list[0]} if len(self._list) == 1 else {self.action: self._list} - -class StartRecording(TropoAction): - """ - Class representing the "startRecording" Tropo action. Builds a "startRecording" JSON object. - Class constructor arg: url, a String - Class constructor options: format, method, username, password - Convenience function: Tropo.startRecording() - - (See https://www.tropo.com/docs/webapi/startrecording) - - { "startRecording": { - "asyncUpload":Boolean, - "format": String, - "method": String, - "url": String,#Required - "username": String, - "password": String, - "transcriptionID": String - "transcriptionEmailFormat":String - "transcriptionOutURI": String} } - """ - action = 'startRecording' - options_array = ['asyncUpload', 'format', 'method', 'username', 'password', 'transcriptionID', 'transcriptionEmailFormat', 'transcriptionOutURI'] - def __init__(self, url, **options): - self._dict = {'url': url} - for opt in self.options_array: - if opt in options: - self._dict[opt] = options[opt] - -class StopRecording(TropoAction): - """ - Class representing the "stopRecording" Tropo action. Builds a "stopRecording" JSON object. - Class constructor arg: - Class constructor options: - Convenience function: Tropo.stopRecording() - - (See https://www.tropo.com/docs/webapi/stoprecording) - { "stopRecording": { } } - """ - action = 'stopRecording' - - def __init__(self): - self._dict = {} - -class Transfer(TropoAction): - """ - Class representing the "transfer" Tropo action. Builds a "transfer" JSON object. - Class constructor arg: to, a String, or List - Class constructor options: answerOnMedia, choices, from, name, required, terminator - Convenience function: Tropo.transfer() - - (See https://www.tropo.com/docs/webapi/transfer) - { "transfer": { - "to": String or Array,#Required - "allowSignals":String or Array, - "answerOnMedia": Boolean, - "choices": Object, - "from": String, - "headers": Object, - "interdigitTimeout":Float, - "machineDetection": Boolean or Object - "name": String, - "playTones":Boolean, - "required": Boolean, - "ringRepeat":Integer, - "terminator": String, - "timeout": Float, - "voice": String, - } } - """ - action = 'transfer' - options_array = ['answerOnMedia', 'choices', '_from', 'name', 'on', 'required', 'allowSignals', 'headers', 'interdigitTimeout', 'ringRepeat', 'timeout', 'machineDetection', 'playTones', 'voice'] - 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] - -class Result(object): - """ - Returned anytime a request is made to the Tropo Web API. - Method: getValue - (See https://www.tropo.com/docs/webapi/result) - - { "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} } - """ - options_array = ['actions','complete','error','sequence', 'sessionDuration', 'sessionId', 'state', 'userType', 'connectedDuration', 'duration', 'calledID', 'callId'] - def __init__(self, result_json): - result_data = jsonlib.loads(result_json) - result_dict = result_data['result'] - - for opt in self.options_array: - if result_dict.get(opt, False): - setattr(self, '_%s' % opt, result_dict[opt]) - - def getValue(self): - """ - Get the value of the previously POSTed Tropo action. - """ - actions = self._actions - - if (type (actions) is list): - dict = actions[0] - else: - dict = actions - # 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): - """ - Get the value of the previously POSTed Tropo action. - """ - actions = self._actions - - if (type (actions) is list): - dict = actions[0] - else: - dict = actions - return dict['interpretation'] - -# # **Tue May 17 07:17:38 2011** -- egilchri - - -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 - """ - def __init__(self, session_json): - session_data = jsonlib.loads(session_json) - session_dict = session_data['session'] - for key in session_dict: - val = session_dict[key] - if key == "from": - setattr(self, "fromaddress", val) - else: - setattr(self, key, val) - setattr(self, 'dict', session_dict) - - -class Tropo(object): - """ - This is the top level class for all the Tropo web api actions. - The methods of this class implement individual Tropo actions. - Individual actions are each methods on this class. - - Each method takes one or more required arguments, followed by optional - arguments expressed as key=value pairs. - - The optional arguments for these methods are described here: - https://www.tropo.com/docs/webapi/ - """ - def __init__(self): - self._steps = [] - -# # **Sun May 15 21:05:01 2011** -- egilchri - def setVoice(self, voice): - self.voice = voice - -# # end **Sun May 15 21:05:01 2011** -- egilchri - - 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 - """ -# # **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. - 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) - - - 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 - """ - self._steps.append(Call (to, **options).obj) - - 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. - Argument: "id" is a String - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/conference - """ - 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 - """ - 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: "to" is a String - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/message - """ - if isinstance(say_obj, basestring): - say = Say(say_obj).obj - else: - say = say_obj - self._steps.append(Message(say, to, **options).obj) - - 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". - Argument: event is an event - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/on - """ - 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. - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/record - """ - self._steps.append(Record(**options).obj) - - 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 - """ - 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 - """ - 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. - Argument: message is a string - Argument: **options is a set of optional keyword arguments. - See https://www.tropo.com/docs/webapi/say - """ - #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. - if hasattr (self, 'voice'): - if (not 'voice' in options): - options['voice'] = self.voice -# # **Sun May 15 21:21:29 2011** -- egilchri - - self._steps.append(Say(message, **options).obj) - - 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 - """ - self._steps.append(StartRecording(url, **options).obj) - - def stopRecording(self): - """ - Stops a previously started recording. - See https://www.tropo.com/docs/webapi/stoprecording - """ - self._steps.append(StopRecording().obj) - - 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 - """ - 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. - """ - steps = self._steps - topdict = {} - topdict['tropo'] = steps - if pretty: - try: - json = jsonlib.dumps(topdict, indent=4, sort_keys=False) - except TypeError: - json = jsonlib.dumps(topdict) - else: - json = jsonlib.dumps(topdict) - return json - -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 - - -""" - - diff --git a/tropo.py b/ciscotropowebapi.py similarity index 55% rename from tropo.py rename to ciscotropowebapi.py index 6f5e748..bab95eb 100644 --- a/tropo.py +++ b/ciscotropowebapi.py @@ -44,6 +44,11 @@ except ImportError: import json as jsonlib +import logging + +import keyword + + class TropoAction(object): """ Class representing the base Tropo action. @@ -65,41 +70,33 @@ 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, + "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'] 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'] - self._dict['choices'] = choices.json + 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] @@ -108,15 +105,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/docs/webapi/call.htm) { "call": { "to": String or Array,#Required "answerOnMedia": Boolean, - "allowSignals": String or Array "channel": string, "from": string, "headers": Object, @@ -124,29 +120,23 @@ 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'] def __init__(self, to, **options): self._dict = {'to': to} for opt in self.options_array: if opt in options: - if (opt == "_from"): - self._dict['from'] = options[opt] - else: - self._dict[opt] = options[opt] - - + 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 +154,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'] def __init__(self, id, **options): self._dict = {'id': id} @@ -194,66 +180,15 @@ 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": { } } + { "hangup": { } } """ action = 'hangup' 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,13 +197,13 @@ 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 "answerOnMedia": Boolean, "channel": string, - "from": String, + "from": Object, "name": String, "network": String, "required": Boolean, @@ -276,17 +211,13 @@ class Message(TropoAction): "voice": String } } """ action = 'message' - options_array = ['answerOnMedia', 'channel', '_from', 'name', 'network', 'required', 'timeout', 'voice'] + options_array = ['answerOnMedia', 'channel', 'from', 'name', 'network', 'required', 'timeout', 'voice'] def __init__(self, say_obj, to, **options): self._dict = {'say': say_obj['say'], 'to': to} for opt in self.options_array: if opt in options: - if (opt == "_from"): - self._dict['from'] = options[opt] - else: - self._dict[opt] = options[opt] - + self._dict[opt] = options[opt] class On(TropoAction): """ @@ -295,48 +226,26 @@ 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'): + if ((opt == 'say') and (isinstance(options['say'], str))): + self._dict['say'] = Say(options['say']).json + else: self._dict[opt] = options[opt] - - self._dict['event'] = event class Record(TropoAction): """ @@ -345,37 +254,35 @@ 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 - "username": String, - "voice": String} } + "url": String,#Required ????? + "username": 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'] + + 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] @@ -387,7 +294,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 +317,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,11 +333,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, "required": Boolean, @@ -438,17 +343,13 @@ class Say(TropoAction): } } """ action = 'say' - # added _as because 'as' is reserved - options_array = ['_as', 'name', 'required', 'voice', 'allowSignals'] + options_array = ['as', 'name', 'required'] def __init__(self, message, **options): dict = {} for opt in self.options_array: if opt in options: - if (opt == "_as"): - dict['as'] = options[opt] - else: - dict[opt] = options[opt] + dict[opt] = options[opt] self._list = [] if (isinstance (message, list)): for mess in message: @@ -474,21 +375,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 +400,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,110 +415,51 @@ 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, - "headers": Object, - "interdigitTimeout":Float, - "machineDetection": Boolean or Object + "from": Object, "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', 'required', 'terminator'] + 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'] = {'value' : 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): + logging.info ("result POST data: %s" % result_json) result_data = jsonlib.loads(result_json) result_dict = result_data['result'] @@ -635,55 +474,32 @@ def getValue(self): actions = self._actions if (type (actions) is list): + logging.info ("Actions is a list") dict = actions[0] else: + logging.info ("Actions is a dict") dict = actions - # 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): - """ - Get the value of the previously POSTed Tropo action. - """ - actions = self._actions - - if (type (actions) is list): - dict = actions[0] - else: - dict = actions + logging.info ("Actions is: %s" % actions) return dict['interpretation'] -# # **Tue May 17 07:17:38 2011** -- egilchri - 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 + (See https://www.tropo.com/docs/webapi/session.htm) """ def __init__(self, session_json): + logging.info ("POST data: %s" % session_json) session_data = jsonlib.loads(session_json) session_dict = session_data['session'] for key in session_dict: val = session_dict[key] - if key == "from": - setattr(self, "fromaddress", val) - else: - setattr(self, key, val) - setattr(self, 'dict', session_dict) + 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) class Tropo(object): @@ -701,67 +517,51 @@ class Tropo(object): def __init__(self): self._steps = [] -# # **Sun May 15 21:05:01 2011** -- egilchri - def setVoice(self, voice): - self.voice = voice - -# # end **Sun May 15 21:05:01 2011** -- egilchri - 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. - 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) - 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) 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. - Argument: "id" is a String + 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 + 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 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): + if isinstance(say_obj, str): say = Say(say_obj).obj else: say = say_obj @@ -770,23 +570,18 @@ 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". - Argument: event is an event + 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,36 +590,25 @@ 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) 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 + 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. - if hasattr (self, 'voice'): - if (not 'voice' in options): - options['voice'] = self.voice -# # **Sun May 15 21:21:29 2011** -- egilchri - self._steps.append(Say(message, **options).obj) def startRecording(self, url, **options): @@ -832,35 +616,26 @@ 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) def transfer(self, to, **options): """ Transfers an already answered call to another destination / phone number. - Argument: to is a string + 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. @@ -868,6 +643,7 @@ def RenderJson(self, pretty=False): steps = self._steps topdict = {} topdict['tropo'] = steps + logging.info ("topdict: %s" % topdict) if pretty: try: json = jsonlib.dumps(topdict, indent=4, sort_keys=False) @@ -878,7 +654,7 @@ def RenderJson(self, pretty=False): return json if __name__ == '__main__': - print """ + print (""" This is the Python web API for http://www.tropo.com/ @@ -887,7 +663,6 @@ def RenderJson(self, pretty=False): cd test python test.py - -""" +""") diff --git a/dist/README b/dist/README deleted file mode 100644 index 592cef0..0000000 --- a/dist/README +++ /dev/null @@ -1 +0,0 @@ -We rename our tar ball to ciscotropo-webapi-python-xx.yy.zz.tar.gz diff --git a/dist/ciscotropo-webapi-python-0.1.4.tar.gz b/dist/ciscotropo-webapi-python-0.1.4.tar.gz deleted file mode 100644 index 01632db..0000000 Binary files a/dist/ciscotropo-webapi-python-0.1.4.tar.gz and /dev/null differ diff --git a/dist/tropo-webapi-python-0.1.0.tar.gz b/dist/tropo-webapi-python-0.1.0.tar.gz deleted file mode 100644 index 952db80..0000000 Binary files a/dist/tropo-webapi-python-0.1.0.tar.gz and /dev/null differ diff --git a/dist/tropo-webapi-python-0.1.1.tar.gz b/dist/tropo-webapi-python-0.1.1.tar.gz deleted file mode 100644 index feb17f1..0000000 Binary files a/dist/tropo-webapi-python-0.1.1.tar.gz and /dev/null differ diff --git a/dist/tropo-webapi-python-0.1.2.tar.gz b/dist/tropo-webapi-python-0.1.2.tar.gz deleted file mode 100644 index 4cdea56..0000000 Binary files a/dist/tropo-webapi-python-0.1.2.tar.gz and /dev/null differ diff --git a/samples/appengine/GoogleS3.py b/samples/GoogleS3.py similarity index 100% rename from samples/appengine/GoogleS3.py rename to samples/GoogleS3.py diff --git a/samples/README b/samples/README deleted file mode 100644 index 5d4c321..0000000 --- a/samples/README +++ /dev/null @@ -1,15 +0,0 @@ -These sample applications demonstrate the usage of this "tropo" python module with -the Tropo cloud communications service at http://www.tropo.com - -To use these examples you need to have: - -1. an account at http://www.tropo.com/ (free for developers) -2. a web server where your app runs that is publicly accessible over the Internet - -For #2, you could use either: -- a hosted service such as Google App Engine -- your own server running a separate web server such as "itty" - ( http://github.com/toastdriven/itty ) -- a server running an existing web server that can execute python programs - -Sample applications will eventually be provided for all these types. diff --git a/samples/appengine/app.yaml b/samples/app.yaml similarity index 100% rename from samples/appengine/app.yaml rename to samples/app.yaml diff --git a/samples/appengine/setup.py b/samples/appengine/setup.py deleted file mode 100644 index 15eb8a5..0000000 --- a/samples/appengine/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -AWS_ACCESS_KEY_ID = 'Your Amazons S3 Access Key' -AWS_SECRET_ACCESS_KEY = 'You Amazon S3 Secret Key' -S3_BUCKET_NAME = "Your Amazon S3 Bucket Name" -MY_PHONE = "Your Cell Phone" -THEIR_PHONE = "Another Cell Phone" -THIS_URL = "http://YOUR_APP_ENGINE_APP.appspot.com" - -# For storing audio files -AMAZON_S3_URL = "http://s3.amazonaws.com" -# Bare bones weather API -GOOGLE_WEATHER_API_URL = "http://www.google.com/ig/api" -SIP_PHONE = "A SIP Phone Address" diff --git a/samples/gh-12-test_voice.py b/samples/gh-12-test_voice.py deleted file mode 100644 index 54b3d9f..0000000 --- a/samples/gh-12-test_voice.py +++ /dev/null @@ -1,43 +0,0 @@ -# tests fix of gh-12 . Need a way to set the default voice -# for a Tropo object. -# added a new method "setVoice" on the Tropo object - -# These examples show precdence of setVoice vs using "voice="..." in -# the method call. - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session, TropoAction, Choices - -@post('/index.json') -def index(request): - s = Session(request.body) - t = Tropo() - t.setVoice('dave') - # we use what has been set in Tropo object - t.say(['hello world!']) - # we use what is set in the method call - t.say(['hello world!'], voice="allison") - - # we use the voice that has been set in Tropo object - choices = Choices("[5 digits]").obj - t.ask(choices, - say="Please enter your 5 digit zip code.", - attempts=3, bargein=True, name="zip", timeout=5) - - # we use the voice passed in the method call. - choices = Choices("[5 digits]").obj - t.ask(choices, - say="Please enter your 5 digit zip code.", - attempts=3, bargein=True, name="zip", timeout=5, voice="allison") - - - json = t.RenderJson() - print json - return json - - -run_itty() - diff --git a/samples/gh-14.test_call.py b/samples/gh-14.test_call.py deleted file mode 100644 index 12d82c9..0000000 --- a/samples/gh-14.test_call.py +++ /dev/null @@ -1,31 +0,0 @@ -# tests fix of gh-14 for "from" parameter in the "call" function. -# Proposed convention is to use "_from" as the parameter -# so as not to conflict with "from" Python reserved word. - -# _from arg works - -# Invoke using a token - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session - -TO_NUMBER = '1xxxxxxxxxx' -FROM_NUMBER = '1yyyyyyyyyy' - - -@post('/index.json') -def index(request): - s = Session(request.body) - t = Tropo() - t.call(to='tel:+' + TO_NUMBER, _from='tel:+' + FROM_NUMBER) - t.say('This is your mother. Did you brush your teeth today?') - json = t.RenderJson() - print json - return json - - -run_itty() - diff --git a/samples/gh-14.test_message.py b/samples/gh-14.test_message.py deleted file mode 100644 index ad24a18..0000000 --- a/samples/gh-14.test_message.py +++ /dev/null @@ -1,30 +0,0 @@ -# tests fix of gh-14 for "_from" parameter in the "message" function. -# Proposed convention is to use "_from" as the parameter -# so as not to conflict with "from" Python reserved word. - -# _from arg works - -# Invoke using a token - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session - -TO_NUMBER = '1xxxxxxxxxx' -FROM_NUMBER = '1yyyyyyyyyy' - - -@post('/index.json') -def index(request): - t = Tropo() - t.message("Hello World", TO_NUMBER, channel='VOICE', _from='tel:+' + FROM_NUMBER) - json = t.RenderJson() - print json - return json -#retest - - -run_itty() - diff --git a/samples/gh-14.test_say.py b/samples/gh-14.test_say.py deleted file mode 100644 index 019c02d..0000000 --- a/samples/gh-14.test_say.py +++ /dev/null @@ -1,25 +0,0 @@ -# tests fix of gh-14 for "_as" parameter in the "say" function. -# Proposed convention is to use "_from" as the parameter -# so as not to conflict with "from" Python reserved word. - - - - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session - -@post('/index.json') -def index(request): - s = Session(request.body) - t = Tropo() - t.say('12345', _as='DIGITS', voice='dave') - json = t.RenderJson() - print json - return json - - -run_itty() - diff --git a/samples/gh-14.test_transfer.py b/samples/gh-14.test_transfer.py deleted file mode 100644 index a033ad9..0000000 --- a/samples/gh-14.test_transfer.py +++ /dev/null @@ -1,33 +0,0 @@ -# tests fix of gh-14 for "from" parameter in the "transfer" function. -# Proposed convention is to use "_from" as the parameter -# so as not to conflict with "from" Python reserved word. - -# _from arg works -# _from arg works with straight json - -# Invoke by calling up app access number - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session - -TO_NUMBER = '1xxxxxxxxxx' -FROM_NUMBER = '1yyyyyyyyyy' - - -@post('/index.json') -def index(request): - s = Session(request.body) - t = Tropo() - t.say ("One moment please.") - t.transfer(TO_NUMBER, _from="tel:+" + FROM_NUMBER) - t.say("Hi. I am a robot") - json = t.RenderJson() - print json - return json - - -run_itty() - diff --git a/samples/gh-14_test.py b/samples/gh-14_test.py deleted file mode 100644 index e24822d..0000000 --- a/samples/gh-14_test.py +++ /dev/null @@ -1,20 +0,0 @@ -# tests fix of gh-14. Proposed convention is to use "_as" as -# the attribute in "say" function, so as not to conflict with "as" -# Python reserved word. - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session - -@post('/index.json') -def index(request): - s = Session(request.body) - t = Tropo() - t.say('12345', _as='DIGITS', voice='allison') - json = t.RenderJson() - print json - return json - -run_itty() diff --git a/samples/gh-17.test.py b/samples/gh-17.test.py deleted file mode 100644 index 9c9f1ad..0000000 --- a/samples/gh-17.test.py +++ /dev/null @@ -1,43 +0,0 @@ -from itty import * -from tropo import Tropo, Result - -# Fixes issue gh-17 getValue() should work with "value" property -# and not "interpretation" - -@post('/index.json') -def index(request): - t = Tropo() - t.ask(choices = "yes(yes,y,1), no(no,n,2)", timeout=60, name="reminder", say = "Hey, did you remember to take your pills?") - t.on(event = "continue", next ="/continue") - t.on(event = "incomplete", next ="/incomplete") - json = t.RenderJson() - print json - return json - -@post("/continue") -def index(request): - r = Result(request.body) - t = Tropo() - - answer = r.getValue() - - t.say("You said " + str(answer)) - - if answer == "yes" : - t.say("Ok, just checkin.") - else : - t.say("What are you waiting for?") - - json = t.RenderJson() - print json - return json - -@post("/incomplete") -def index(request): - t = Tropo() - t.say("Sorry, that wasn't on of the options.") - json = t.RenderJson() - print json - return json - -run_itty() diff --git a/samples/gh-20-test_ask.py b/samples/gh-20-test_ask.py deleted file mode 100644 index 4a44d08..0000000 --- a/samples/gh-20-test_ask.py +++ /dev/null @@ -1,44 +0,0 @@ -# tests fix of gh-20 . Extracting out of Result - -# Added a new method on the Result object, called getInterpretation() - - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session, Result - - -@post('/index.json') -def index(request): - - t = Tropo() - - t.ask(choices = "yes(yes,y,1), no(no,n,2)", timeout = 15, name = "directory", minConfidence = 1, attempts = 3, say = "Are you trying to reach the sales department??") - - t.on(event = "continue", next ="/continue") - - json = t.RenderJson() - - print json - return json - -@post("/continue") -def index(request): - - r = Result(request.body) - print "Result : %s" % r - - t = Tropo() - - answer = r.getInterpretation() - value = r.getValue() - - t.say("You said " + answer + ", which is a " + value) - - json = t.RenderJson() - print json - return json - -run_itty() diff --git a/samples/gh-21.choices.py b/samples/gh-21.choices.py deleted file mode 100644 index dbd795c..0000000 --- a/samples/gh-21.choices.py +++ /dev/null @@ -1,51 +0,0 @@ -# tests fix of gh-21 . Sorting out syntax of choices for ask. - -# Fixed an error in the way the Ask class init function was -# taking apart the choices argument passed to it. - -# Then, I corrected the original example provided for gh-21. -# Correct way to provide "choices" argument to "ask" is shown in -# the example below. - - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - -from itty import * -from tropo import Tropo, Session, Result, Choices - - -@post('/index.json') -def index(request): - - t = Tropo() - - choices = Choices("[4-5 DIGITS]", mode="dtmf", terminator = "#") - t.ask(choices, timeout=15, name="digit", say = "What's your four or five digit pin? Press pound when finished.") - - t.on(event = "continue", next ="/continue") - - json = t.RenderJson() - - print json - return json - -@post("/continue") -def index(request): - - r = Result(request.body) - print "Result : %s" % r -# dump(r) - t = Tropo() - - answer = r.getInterpretation() - - t.say("You said ") - t.say (answer, _as="DIGITS") - - json = t.RenderJson() - print json - return json - -run_itty() - diff --git a/samples/gh-22.transfer.py b/samples/gh-22.transfer.py deleted file mode 100644 index 87aa97a..0000000 --- a/samples/gh-22.transfer.py +++ /dev/null @@ -1,39 +0,0 @@ -# tests fix of gh-22 . headers parameter for transfer() - -# Fixes an error whereby we weren't passing -# the "headers" parameter to transfer() - -# Sample below shows how to pass in headers. - - -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - - -from itty import * -from tropo-webapi-python/tropo import Tropo, Session - - -#TO_NUMBER = '1xxxxxxxxxx' -TO_NUMBER = '16039570051' - - -@post('/index.json') -def index(request): - - s = Session(request.body) - t = Tropo() - - t.say("Hello. , , , Transferring") -# t.transfer(to="sip:9991489767@sip.tropo.com", headers={"x-callername":"Kevin Bond"}) - - t.transfer(TO_NUMBER, headers={"x-callername":"Kevin Bond"}) - - json = t.RenderJson() - print json - return json - - -run_itty() - - diff --git a/samples/gh-23.ask_timeout.py b/samples/gh-23.ask_timeout.py deleted file mode 100644 index fc48ba4..0000000 --- a/samples/gh-23.ask_timeout.py +++ /dev/null @@ -1,80 +0,0 @@ -# tests example clarifying gh-23 . How to use timeout, and nomatch parameters -# in "say" within "ask" - - -from itty import * -from tropo import Tropo, Session, Result - - -@post("/index.json") -def index (request): - t = Tropo() - t.ask(choices = "[4 DIGITs]", - timeout=5, - bargein="true", - name="year", - attempts=3, - required="true", - say = [{'event':'timeout', - 'value':"Sorry, I did not hear anything"}, - {'event':'nomatch:1', - 'value':"Don't think that was a year."}, - {'event':'nomatch:2', - 'value':"Nope, still not a year."}, - {'value': "What is your birth year?"} - ]) - - json = t.RenderJson() - print json - return json - - - -# @post("/index.json") -def index_straight_json (request): - json = """{ - "tropo":[ - { - "ask":{ - "attempts":3, - "say":[ - { - "value":"Sorry, I did not hear anything.", - "event":"timeout" - }, - { - "value":"Don't think that was a year. ", - "event":"nomatch:1" - }, - { - "value":"Nope, still not a year.", - "event":"nomatch:2" - }, - { - "value":"What is your birth year?" - } - ], - "choices":{ - "value":"[4 DIGITS]" - }, - "bargein":true, - "timeout":5, - "name":"year", - "required":true - } - } - ] - -} -""" - print json - return json - - - - - - - - -run_itty() diff --git a/samples/gh-5.hello_cgi.py b/samples/gh-5.hello_cgi.py deleted file mode 100644 index 57a7ece..0000000 --- a/samples/gh-5.hello_cgi.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/python - -# Hello, World CGI script. -# Addresses gh-5. -# Steps: -# 1. edit Apache httpd.conf file -# Alias /tropo/ "/path/to/examples/" -# -# Options +ExecCGI -# SetHandler cgi-script -# Allow from all -# AllowOverride All -# -# 2. Create Web API app in Tropo and assign it the url -# http://my_webserver.com/tropo/g-5.hello_cgi.py -# 3. Place this file in examples folder and chmod it executable -# 4. Dial up Tropo app, and hear "Hello, World ..." - -import cgi -from tropo import Tropo - -def hello(): - t = Tropo() - t.say(['hello world! I am a C G I script.']) - json = t.RenderJson() - print json - return json - - - -print "Content-type: text/json" -print -print - -hello() - diff --git a/samples/itty_hello_world.py b/samples/itty_hello_world.py index 7d1f55f..621fd03 100755 --- a/samples/itty_hello_world.py +++ b/samples/itty_hello_world.py @@ -1,16 +1,13 @@ #!/usr/bin/env python -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - from itty import * -from tropo import Tropo, Session +from ciscotropowebapi import Tropo, Session @post('/index.json') def index(request): s = Session(request.body) t = Tropo() - t.say(['hello world!', 'how are you doing?']) + t.say(['hello workd!', 'how are you doing?']) return t.RenderJson() run_itty(server='wsgiref', host='0.0.0.0', port=8888) diff --git a/samples/itty_session_api.py b/samples/itty_session_api.py index 4b48603..42e3359 100755 --- a/samples/itty_session_api.py +++ b/samples/itty_session_api.py @@ -1,16 +1,13 @@ #!/usr/bin/env python """ -Hello 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'. """ -# Sample application using the itty-bitty python web framework from: -# http://github.com/toastdriven/itty - from itty import * -from tropo import Tropo, Session +from ciscotropowebapi import Tropo, Session from urllib import urlencode from urllib2 import urlopen @@ -24,9 +21,9 @@ def index(request): base_url = 'http://api.tropo.com/1.0/sessions' -token = 'xxxxxxxxxx' # Insert your token here +token = 'xxxxxxxxxx' action = 'create' -number = 'username@domain' # change to the Jabber ID to which you want to send the message +number = 'username@domain' message = 'hello from the session API!' params = urlencode([('action', action), ('token', token), ('numberToDial', number), ('message', message)]) diff --git a/samples/appengine/main.py b/samples/main.py similarity index 52% rename from samples/appengine/main.py rename to samples/main.py index 21bcf6d..7bbcbfa 100755 --- a/samples/appengine/main.py +++ b/samples/main.py @@ -1,13 +1,13 @@ """ This script is intended to be used with Google Appengine. It contains -a number of demos that illustrate the Tropo Web API for Python. +a number of demos that illustrate the TropoPython API. """ from google.appengine.ext import webapp 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 @@ -15,103 +15,116 @@ from setup import * +AMAZON_S3_URL = "http://s3.amazonaws.com" +GOOGLE_WEATHER_API_URL = "http://www.google.com/ig/api" -def HelloWorld(handler, t): +def HelloWorld(handler, tropo): """ - This is the traditional "Hello, World" function. The idiom is used throughout the API. We construct a Tropo object, and then flesh out that object by calling "action" functions (in this case, tropo.say). Then call tropo.Render, which translates the Tropo object into JSON format. Finally, we write the JSON object to the standard output, so that it will get POSTed back to the API. + This is the traditional "Hello, World" function. The idiom is used throughout the API. We consturct a Tropo object, and then flesh out that object by calling "action" functions (in this case, tropo.say). Then call tropo.Render, which translates the Tropo object into JSON format. Finally, we write the JSON object to the standard output, so that it will get POSTed back to the API. """ - t.say (["Hello, World", "How ya doing?"]) - json = t.RenderJson() + tropo.say (["Hello, World", "How ya doing?"]) + json = tropo.RenderJson() logging.info ("HelloWorld json: %s" % json) handler.response.out.write(json) -def WeatherDemo(handler, t): +def WeatherDemo(handler, tropo): """ """ - choices = tropo.Choices("[5 digits]") + choices = tropo.Choices("[5 digits]").obj - t.ask(choices, + tropo.ask(choices, say="Please enter your 5 digit zip code.", attempts=3, bargein=True, name="zip", timeout=5, voice="dave") - t.on(event="continue", + tropo.on(event="continue", +# next="%s/weather.py?uri=end" % THIS_URL, next="/weather.py?uri=end", say="Please hold.") - t.on(event="error", + tropo.on(event="error", +# next="%s/weather.py?uri=error" % THIS_URL, next="/weather.py?uri=error", say="Ann error occurred.") - json = t.RenderJson() + json = tropo.RenderJson() logging.info ("Json result: %s " % json) - logging.info ("WeatherDemo json: %s" % json) + pretty = tropo.PrettyJson() + logging.info ("WeatherDemo json: %s" % pretty) - handler.response.out.write(json) + handler.response.out.write(pretty) -def RecordDemo(handler, t): +def RecordDemo(handler, tropo): - url = "%s/receive_recording.py" % THIS_URL + url = "/receive_recording.py" choices_obj = tropo.Choices("", terminator="#").json - t.record(say="Tell us about yourself", url=url, + tropo.record(say="Tell us about yourself", url=url, choices=choices_obj) - json = t.RenderJson() + json = tropo.RenderJson() logging.info ("Json result: %s " % json) handler.response.out.write(json) -def SMSDemo(handler, t): +def SMSDemo(handler, tropo): - t.message("Hello World", MY_PHONE, channel='TEXT', network='SMS', timeout=5) - json = t.RenderJson() + tropo.message("Hello World", YOUR_PHONE_NUMBER, channel='TEXT', network='SMS', timeout=5) + json = tropo.RenderJson() logging.info ("Json result: %s " % json) handler.response.out.write(json) -def RecordHelloWorld(handler, t): +def RecordHelloWorld(handler, tropo): """ - Demonstration of recording a message. + This is the traditional "Hello, World" function. The idiom is used throughout the API. We construct a Tropo object, and then flesh out that object by calling "action" functions (in this case, tropo.say). Then call tropo.Render, which translates the Tropo object into JSON format. Finally, we write the JSON object to the standard output, so that it will get POSTed back to the API. """ - url = "%s/receive_recording.py" % THIS_URL - t.startRecording(url) - t.say ("Hello, World.") - t.stopRecording() - json = t.RenderJson() + # http://www.s3fm.com/ + url = "/receive_recording.py" + tropo.startRecording(url) + tropo.say ("Hello, World.") + tropo.stopRecording() + json = tropo.RenderJson() logging.info ("RecordHelloWorld json: %s" % json) handler.response.out.write(json) -def RedirectDemo(handler, t): +def RedirectDemo(handler, tropo): """ - Demonstration of redirecting to another number. + This is the traditional "Hello, World" function. The idiom is used throughout the API. We construct a Tropo object, and then flesh out that object by calling "action" functions (in this case, tropo.say). Then call tropo.Render, which translates the Tropo object into JSON format. Finally, we write the JSON object to the standard output, so that it will get POSTed back to the API. """ - # t.say ("One moment please.") - t.redirect(SIP_PHONE) - json = t.RenderJson() - logging.info ("RedirectDemo json: %s" % json) + tropo.say ("One moment please.") + tropo.redirect(MY_PHONE) + json = tropo.RenderJson() + logging.info ("RecordHelloWorld json: %s" % json) handler.response.out.write(json) -def TransferDemo(handler, t): +def TransferDemo(handler, tropo): """ - Demonstration of transfering to another number + This is the traditional "Hello, World" function. The idiom is used throughout the API. We construct a Tropo object, and then flesh out that object by calling "action" functions (in this case, tropo.say). Then call tropo.Render, which translates the Tropo object into JSON format. Finally, we write the JSON object to the standard output, so that it will get POSTed back to the API. """ - t.say ("One moment please.") - t.transfer(MY_PHONE) - t.say("Hi. I am a robot") - json = t.RenderJson() - logging.info ("TransferDemo json: %s" % json) + # http://www.s3fm.com/ + tropo.say ("One moment please.") + tropo.transfer(MY_PHONE) + tropo.say("Hi. I am a robot") + json = tropo.RenderJson() + logging.info ("RecordHelloWorld json: %s" % json) handler.response.out.write(json) -def CallDemo(handler, t): - t.call(THEIR_PHONE) - json = t.RenderJson() +def CallDemo(handler, tropo): + tropo.call(THEIR_PHONE) + json = tropo.RenderJson() logging.info ("CallDemo json: %s " % json) handler.response.out.write(json) +# handler.response.out.write('{"tropo":[{"call":{"to":["tel:+16039570525"]}},{"say":[{"value":"Hello, happy you were the first phone to answer!"}]}]}') + +def ConferenceDemo(handler, tropo): + tropo.say ("Have some of your friends launch this demo. You'll be on the world's simplest conference call. Now, for a little music, while we wait for the others.") + tropo.conference("partyline", terminator="#", name="Family Meeting") + tropo.say("http://denalidomain.com/music/keepers/Fontella%20Bass%20This%20Little%20Light%20Of%20Mine.mp3") +# tropo.call(MY_PHONE) -def ConferenceDemo(handler, t): - t.say ("Have some of your friends launch this demo. You'll be on the world's simplest conference call.") - t.conference("partyline", terminator="#", name="Family Meeting") - json = t.RenderJson() - logging.info ("ConferenceDemo json: %s " % json) +# tropo.call(THEIR_PHONE) + tropo.say ("How do you like the conference so far?") + json = tropo.RenderJson() + logging.info ("CallDemo json: %s " % json) handler.response.out.write(json) @@ -137,36 +150,37 @@ class TropoDemo(webapp.RequestHandler): A bundle of information about the call, such as who is calling, is passed in via the POST data. """ def post(self): - t = tropo.Tropo() - t.say ("Welcome to the Tropo web API demo") - - request = "Please press" - choices_string = "" - choices_counter = 1 - for key in sorted(DEMOS.iterkeys()): - if (len(choices_string) > 0): - choices_string = "%s,%s" % (choices_string, choices_counter) - else: - choices_string = "%s" % (choices_counter) - demo_name = DEMOS[key][0] - demo = DEMOS[key][1] - request = "%s %s for %s," % (request, key, demo_name) - choices_counter += 1 - choices = tropo.Choices(choices_string) - - t.ask(choices, say=request, attempts=3, bargein=True, name="zip", timeout=5, voice="dave") - - t.on(event="continue", + if (1): + tropo = ciscotropowebapi.Tropo() + tropo.say ("Welcome to the Tropo web API demo") + + request = "Please press" + choices_string = "" + choices_counter = 1 + for key in sorted(DEMOS.iterkeys()): + if (len(choices_string) > 0): + choices_string = "%s,%s" % (choices_string, choices_counter) + else: + choices_string = "%s" % (choices_counter) + demo_name = DEMOS[key][0] + demo = DEMOS[key][1] + request = "%s %s for %s," % (request, key, demo_name) + choices_counter += 1 + choices = tropo.Choices(choices_string).obj + + tropo.ask(choices, say=request, attempts=3, bargein=True, name="zip", timeout=5, voice="dave") + + tropo.on(event="continue", next="/demo_continue.py", say="Please hold.") - t.on(event="error", + tropo.on(event="error", next="/demo_continue.py", say="An error occurred.") - json = t.RenderJson() - logging.info ("Json result: %s " % json) - self.response.out.write(json) + json = tropo.RenderJson() + logging.info ("Json result: %s " % json) + self.response.out.write(json) class TropoDemoContinue(webapp.RequestHandler): @@ -176,34 +190,26 @@ class TropoDemoContinue(webapp.RequestHandler): def post (self): json = self.request.body logging.info ("json: %s" % json) - t = tropo.Tropo() + tropo = tropo.Tropo() result = tropo.Result(json) choice = result.getValue() logging.info ("Choice of demo is: %s" % choice) for key in DEMOS: - if (choice == key): - demo_name = DEMOS[key][0] - demo = DEMOS[key][1] - demo(self, t) - break + + if (choice == key): + demo_name = DEMOS[key][0] + demo = DEMOS[key][1] + demo(self, tropo) + break + + class Weather(webapp.RequestHandler): def post (self): json = self.request.body logging.info ("json: %s" % json) - - uri = self.request.get ('uri') - logging.info ("uri: %s" % uri) - - t = tropo.Tropo() - - if (uri == "error"): - t.say ("Oops. There was some kind of error") - json = t.RenderJson() - self.response.out.write(json) - return - + tropo = tropo.Tropo() result = tropo.Result(json); zip = result.getValue() google_weather_url = "%s?weather=%s&hl=en" % (GOOGLE_WEATHER_API_URL, zip) @@ -220,28 +226,25 @@ 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)) - t = tropo.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) - t.say("Current city is %s . Weather conditions are %s. Temperature is %s. %s ." % (city, condition, temp, wind)) - json = t.RenderJson() + tropo.say("Current city is %s . Weather conditions are %s. Temperature is %s. Winds are %s ." % (city, condition, temp, wind)) + json = tropo.RenderJson() self.response.out.write(json) -# Wind: N at 0 mph - def english_expand(self, expr): - logging.info ("expr is : %s" % expr) - expr = expr.replace("Wind: NW", "Wind is from the North West") - expr = expr.replace("Wind: NE", "Wind is from the North East") - expr = expr.replace("Wind: N", "Wind is from the North") - expr = expr.replace("Wind: SW", "Wind is from the South West") - expr = expr.replace("Wind: SE", "Wind is from the South East") - expr = expr.replace("Wind: S", "Wind is from the South") - expr = expr.replace("mph", "miles per hour") - return expr + result = expr.replace("NW", "North West") + result = expr.replace("NE", "North East") + result = expr.replace("N", "North") + result = expr.replace("SW", "South West") + result = expr.replace("SE", "South East") + result = expr.replace("S", "South") + result = expr.replace("mph", "miles per hour") + return result class ReceiveRecording(webapp.RequestHandler): @@ -257,11 +260,15 @@ def put_in_s3 (self, wav): conn = GoogleS3.AWSAuthConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) key_name = "testing.wav" - logging.info ("Putting content in %s in %s bucket" % (key_name, S3_BUCKET_NAME)) + + logging.info ("Puting content in %s in %s bucket" % (key_name, S3_BUCKET_NAME)) responsedict={} + logging.info ("really putting stuff in %s %s" % (S3_BUCKET_NAME, key_name)) + audio_type = 'audio/wav' + response = conn.put( S3_BUCKET_NAME, key_name, @@ -276,10 +283,10 @@ def put_in_s3 (self, wav): class CallWorld(webapp.RequestHandler): def post(self): - t = tropo.Tropo() - t.call(MY_PHONE, channel='TEXT', network='SMS', answerOnMedia='True') - t.say ("Wish you were here") - json = t.RenderJson() + tropo = tropo.Tropo() + tropo.call(MY_PHONE, channel='TEXT', network='SMS', answerOnMedia='True') + tropo.say ("Wish you were here") + json = tropo.RenderJson() logging.info ("Json result: %s " % json) self.response.out.write(json) @@ -293,14 +300,16 @@ def get(self): def main(): application = webapp.WSGIApplication([('/', MainHandler), ('/hello_tropo.py', TropoDemo), +# ('/hello_tropo.py', CallWorld), ('/weather.py', Weather), ('/receive_recording.py', ReceiveRecording), ('/demo_continue.py', TropoDemoContinue), -# ('/tropo_web_api.html', ShowDoc) +# ('/tropo.html', ShowDoc) ], debug=True) util.run_wsgi_app(application) + if __name__ == '__main__': main() diff --git a/samples/record_test.py b/samples/record_test.py deleted file mode 100644 index f5f4513..0000000 --- a/samples/record_test.py +++ /dev/null @@ -1,14 +0,0 @@ -from itty import * -from tropo import Tropo, Session, Result - -@post('/index') -def index(request): - - t = Tropo() - VOICE = 'Grace' - - t.record(name='voicemail.mp3', say='Your call is important. Please leave a short message after the tone: ', url = 'http://www.example.com', beep = True, format = 'audio/mp3', voice = VOICE) - - return t.RenderJson() - -run_itty(server='wsgiref', port=8888) \ No newline at end of file diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 index 6e6b87a..62b413f --- a/setup.py +++ b/setup.py @@ -1,12 +1,11 @@ -#!/usr/bin/env python from distutils.core import setup -setup(name = "ciscotropo-webapi-python", - version = "0.1.4", - url = "http://github.com/tropo/tropo-webapi-python", - maintainer = "Cisco", - maintainer_email = "support@tropo.com", +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"], @@ -18,6 +17,5 @@ "Operating System :: OS Independent", "Programming Language :: Python" ], - py_modules = ['tropo'], + py_modules = ['ciscotropowebapi'], ) - diff --git a/test/test.py b/test/test.py index 37ad766..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. """ @@ -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 @@ -73,16 +73,16 @@ def test_conference(self): """ tropo = Tropo() - tropo.conference(self.ID, playTones=True, mute=False, - name="Staff Meeting") + tropo.conference(self.ID, playTones=True,terminator="#", + 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"}}]}' - print "wanted_json: %s" % wanted_json + wanted_json = '{"tropo": [{"conference": {"playTones": true, "mute": false, "name": "Staff Meeting", "id": "foo", "terminator": "#"}}]}' + 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) @@ -130,13 +130,13 @@ 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() 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) @@ -152,12 +152,12 @@ 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) - 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) @@ -313,17 +313,16 @@ def test_transfer(self): tropo.ask("[5 digits]", say = Say("Please enter a 5 digit zip code").json) - tropo.call (TO) 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) @@ -332,8 +331,8 @@ def test_transfer(self): tropo.transfer(TO) tropo.message("Hello, World", - TO, - channel='TEXT', + TO, + channel='TEXT', network='SMS') else: diff --git a/test/test1.py b/test/test1.py deleted file mode 100644 index f484cad..0000000 --- a/test/test1.py +++ /dev/null @@ -1,37 +0,0 @@ -import sys -sys.path = ['..'] + sys.path -from tropo import Choices, MachineDetection, JoinPrompt, LeavePrompt, On, Ask, Say, Tropo - -t = Tropo() - -#CPA -mc = MachineDetection(introduction="THis is a CPA test", voice="Victor").json -t.call("+14071234321", machineDetection=mc) - -#CPA with Boolean value which will detect CPA with 30 seconds of silence. -t.call("+14071234321", machineDetection=True) - - -#Conference with join/leave prompts -jp = JoinPrompt(value="Someone just joined the conference", voice="Victor").json -lp = LeavePrompt(value="Someone just left the conference", voice="Victor").json -t.conference(id="1234", joinPrompt=jp, leavePrompt=lp) - - -whisper = {} - -c = Choices(value="1", mode="dtmf") -ask = Ask(say="Press 1 to accept this call", choices=c).json -whisper["ask"] = ask - -say = Say("You are now being connected to the call").json -whisper["say"] = say - -say1 = Say("http://www.phono.com/audio/holdmusic.mp3").json -whisper["ring"] = say1 - -t.transfer(to="+14071234321", on=whisper) -t.on(event="incomplete", say="You are now being disconnected. Goodbye") - -print t.RenderJson() - diff --git a/test/tropoTestMachineDetection.py b/test/tropoTestMachineDetection.py deleted file mode 100644 index db647d4..0000000 --- a/test/tropoTestMachineDetection.py +++ /dev/null @@ -1,28 +0,0 @@ -from itty import * -from tropo import Tropo, Result, MachineDetection - -@post('/index.json') -def index(request): - - t = Tropo() - - mc = MachineDetection(introduction="This is a test. Please hold while I determine if you are a Machine or Human. Processing. Finished. THank you for your patience.", voice="Victor").json - t.call(to="+14071234321", machineDetection=mc) - - t.on(event="continue", next="/continue.json") - - return t.RenderJson() - -@post("/continue.json") -def index(request): - - r = Result(request.body) - t = Tropo() - - userType = r.getUserType() - - t.say("You are a " + userType) - - return t.RenderJson() - -run_itty(server='wsgiref', host='0.0.0.0', port=8888) \ No newline at end of file