8000 Support nesting TwiML verbs via `with` (#366) · chiewxia/twilio-python@0eec3b6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0eec3b6

Browse files
dougblacktmconnors
authored andcommitted
Support nesting TwiML verbs via with (twilio#366)
* Support nesting TwiML verbs via `with` * Introduce `nest()` to preserve `append()` behavior
1 parent 75b96ea commit 0eec3b6

File tree

5 files changed

+70
-34
lines changed

5 files changed

+70
-34
lines changed

tests/unit/twiml/test_messaging_response.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,25 @@ def test_response(self):
2323
)
2424

2525
def test_response_chain(self):
26-
r = MessagingResponse().message('Hello').redirect(url='example.com')
26+
with MessagingResponse() as r:
27+
r.message('Hello')
28+
r.redirect(url='example.com')
2729

2830
assert_equal(
2931
self.strip(r),
3032
'<?xml version="1.0" encoding="UTF-8"?><Response><Message>Hello</Message><Redirect>example.com</Redirect></Response>'
3133
)
3234

35+
def test_nested_verbs(self):
36+
with MessagingResponse() as r:
37+
with r.message('Hello') as m:
38+
m.media('example.com')
39+
40+
assert_equal(
41+
self.strip(r),
42+
'<?xml version="1.0" encoding="UTF-8"?><Response><Message>Hello<Media>example.com</Media></Message></Response>'
43+
)
44+
3345

3446
class TestMessage(TwilioTest):
3547

tests/unit/twiml/test_voice_response.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,30 @@ def test_response(self):
3030
)
3131

3232
def test_response_chain(self):
33-
r = VoiceResponse().hangup().leave().sms(
34-
'twilio sms',
35-
to='+11234567890',
36-
from_='+10987654321'
37-
)
33+
with VoiceResponse() as r:
34+
r.hangup()
35+
r.leave()
36+
r.sms(
37+
'twilio sms',
38+
to='+11234567890',
39+
from_='+10987654321'
40+
)
3841

3942
assert_equal(
4043
self.strip(r),
4144
'<?xml version="1.0" encoding="UTF-8"?><Response><Hangup /><Leave /><Sms from="+10987654321" to="+11234567890">twilio sms</Sms></Response>'
4245
)
4346

47+
def test_nested_verbs(self):
48+
with VoiceResponse() as r:
49+
with r.gather() as g:
50+
g.say('Hello', voice='man')
51+
52+
assert_equal(
53+
self.strip(r),
54+
'<?xml version="1.0" encoding="UTF-8"?&g 57A6 t;<Response><Gather><Say voice="man">Hello</Say></Gather></Response>'
55+
)
56+
4457

4558
class TestSay(TwilioTest):
4659

twilio/twiml/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,25 @@ def append(self, verb):
7474
"""
7575
Add a TwiML doc
7676
:param verb: TwiML Document
77-
:return:
77+
:return: self
7878
"""
7979
if not isinstance(verb, TwiML):
8080
raise TwiMLException('Only appending of TwiML is allowed')
8181

8282
self.verbs.append(verb)
8383
return self
8484

85+
def nest(self, verb):
86+
"""
87+
Add a TwiML doc. Unlike `append()`, this returns the created verb.
88+
:param verb: TwiML verb
89+
:return: the TwiML verb
90+
"""
91+
if not isinstance(verb, TwiML):
92+
raise TwiMLException('Only nesting of TwiML is allowed')
93+
self.verbs.append(verb)
94+
return verb
95+
8596
def xml(self):
8697
"""
8798
Convert to XML

twilio/twiml/messaging_response.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def message(self,
3232
:param kwargs: other attributes
3333
:return: <Response> element
3434
"""
35-
return self.append(Message(
35+
return self.nest(Message(
3636
body=body,
3737
to=to,
3838
from_=from_,
@@ -51,7 +51,7 @@ def redirect(self, url, method=None, **kwargs):
5151
:param kwargs: other attributes
5252
:return: <Response> element
5353
"""
54-
return self.append(Redirect(
54+
return self.nest(Redirect(
5555
method=method,
5656
url=url,
5757
**kwargs
@@ -80,7 +80,7 @@ def body(self, body):
8080
:param body: body of message
8181
:return: <Message> element
8282
"""
83-
return self.append(Body(body))
83+
return self.nest(Body(body))
8484

8585
def media(self, url):
8686
"""
@@ -89,7 +89,7 @@ def media(self, url):
8989
:param url: media URL
9090
:return: <Message> element
9191
"""
92-
return self.append(Media(url))
92+
return self.nest(Media(url))
9393

9494

9595
class Body(TwiML):

twilio/twiml/voice_response.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def dial(self,
4545
:param kwargs: additional attributes
4646
:return: <Response> element
4747
"""
48-
return self.append(Dial(
48+
return self.nest(Dial(
4949
number=number,
5050
action=action,
5151
method=method,
@@ -67,7 +67,7 @@ def echo(self,
6767
6868
:return: <Response> element
6969
"""
70-
return self.append(Echo(
70+
return self.nest(Echo(
7171
**kwargs
7272
))
7373

@@ -91,7 +91,7 @@ def enqueue(self,
9191
:param kwargs: additional attributes
9292
:return: <Response> element
9393
"""
94-
return self.append(Enqueue(
94+
return self.nest(Enqueue(
9595
name,
9696
action=action,
9797
method=method,
@@ -133,7 +133,7 @@ def gather(self,
133133
:param kwargs: additional attributes
134134
:return: <Response> element
135135
"""
136-
return self.append(Gather(
136+
return self.nest(Gather(
137137
action=action,
138138
method=method,
139139
timeout=timeout,
@@ -155,15 +155,15 @@ def hangup(self):
155155
156156
:return: <Response> element
157157
"""
158-
return self.append(Hangup())
158+
return self.nest(Hangup())
159159

160160
def leave(self):
161161
"""
162162
Add a new <Leave> element
163163
164164
:return: <Response> element
165165
"""
166-
return self.append(Leave())
166+
return self.nest(Leave())
167167

168168
def pause(self, length=None):
169169
"""
@@ -172,7 +172,7 @@ def pause(self, length=None):
172172
:param length: time in seconds to pause
173173
:return: <Response> element
174174
"""
175-
return self.append(Pause(length=length))
175+
return self.nest(Pause(length=length))
176176

177177
def play(self,
178178
url=None,
@@ -188,7 +188,7 @@ def play(self,
188188
:param kwargs: additional attributes
189189
:return: <Response> element
190190
"""
191-
return self.append(Play(
191+
return self.nest(Play(
192192
url=url,
193193
loop=loop,
194194
digits=digits,
@@ -225,7 +225,7 @@ def record(self,
225225
:param kwargs: additional attributes
226226
:return: <Response> element
227227
"""
228-
return self.append(Record(
228+
return self.nest(Record(
229229
action=action,
230230
method=method,
231231
timeout=timeout,
@@ -249,7 +249,7 @@ def redirect(self, url, method=None, **kwargs):
249249
:param kwargs: additional attributes
250250
:return: <Response> element
251251
"""
252-
return self.append(Redirect(url, method=method, **kwargs))
252+
return self.nest(Redirect(url, method=method, **kwargs))
253253

254254
def reject(self, reason=None, **kwargs):
255255
"""
@@ -259,7 +259,7 @@ def reject(self, reason=None, **kwargs):
259259
:param kwargs: additional attributes
260260
:return: <Response> element
261261
"""
262-
return self.append(Reject(reason=reason, **kwargs))
262+
return self.nest(Reject(reason=reason, **kwargs))
263263

264264
def say(self,
265265
body,
@@ -277,7 +277,7 @@ def say(self,
277277
:param kwargs: additional attributes
278278< 10000 div class="diff-text-inner"> :return: <Response> element
279279
"""
280-
return self.append(Say(
280+
return self.nest(Say(
281281
body,
282282
loop=loop,
283283
language=language,
@@ -305,7 +305,7 @@ def sms(self,
305305
:param kwargs: additional attributes
306306
:return: <Response> element
307307
"""
308-
return self.append(Sms(
308+
return self.nest(Sms(
309309
body,
310310
to=to,
311311
from_=from_,
@@ -351,7 +351,7 @@ def client(self,
351351
:param kwargs: additional attributes
352352
:return: <Dial> element
353353
"""
354-
return self.append(Client(
354+
return self.nest(Client(
355355
name,
356356
method=method,
357357
url=url,
@@ -401,7 +401,7 @@ def conference(self,
401401
:param kwargs: additional attributes
402402
:return: <Dial> element
403403
"""
404-
return self.append(Conference(
404+
return self.nest(Conference(
405405
name,
406406
muted=muted,
407407
start_conference_on_enter=start_conference_on_enter,
@@ -443,7 +443,7 @@ def number(self,
443443
:param kwargs: additional attributes
444444
:return: <Dial> element
445445
"""
446-
return self.append(Number(
446+
return self.nest(Number(
447447
number,
448448
send_digits=send_digits,
449449
url=url,
@@ -472,7 +472,7 @@ def queue(self,
472472
:param kwargs: additional attributes
473473
:return: <Dial> element
474474
"""
475-
return self.append(Queue(
475+
return self.nest(Queue(
476476
queue_name,
477477
url=url,
478478
method=method,
@@ -490,7 +490,7 @@ def sim(self,
490490
:param sid: sim sid
491491
:return: <Dial> element
492492
"""
493-
return self.append(Sim(
493+
return self.nest(Sim(
494494
sid,
495495
**kwargs
496496
))
@@ -519,7 +519,7 @@ def sip(self,
519519
:param kwargs: additional attributes
520520
:return: <Dial> element
521521
"""
522-
return self.append(Sip(
522+
return self.nest(Sip(
523523
uri,
524524
username=username,
525525
password=password,
@@ -653,7 +653,7 @@ def task(self, attributes, **kwargs):
653653
:param attributes: Attributes for a task
654654
:return: <Task> element
655655
"""
656-
return self.append(Task(attributes, **kwargs))
656+
return self.nest(Task(attributes, **kwargs))
657657

658658

659659
class Task(TwiML):
@@ -700,7 +700,7 @@ def say(self,
700700
:param kwargs: additional attributes
701701
:return: <Gather> element
702702
"""
703-
return self.append(Say(
703+
return self.nest(Say(
704704
body,
705705
loop=loop,
706706
language=language,
@@ -722,7 +722,7 @@ def play(self,
722722
:param kwargs: additional attributes
723723
:return: <Gather> element
724724
"""
725-
return self.append(Play(
725+
return self.nest(Play(
726726
url=url,
727727
loop=loop,
728728
digits=digits,
@@ -736,7 +736,7 @@ def pause(self, length=None):
736736
:param length: time to pause
737737
:return: <Gather> element
738738
"""
739-
return self.append(Pause(length=length))
739+
return self.nest(Pause(length=length))
740740

741741

742742
class Pause(TwiML):

0 commit comments

Comments
 (0)
0