YAYPM
(→Examples) |
(→Examples) |
||
Line 119: | Line 119: | ||
* [[YAYPM:Simple IVR]] | * [[YAYPM:Simple IVR]] | ||
+ | * [[YAYPM:Simple IVR with Inline Callbacks]] | ||
* [[YAYPM:Bridge and then unbridge]] | * [[YAYPM:Bridge and then unbridge]] | ||
* [[YAYPM:Bridge and then redirect after a hangup]] | * [[YAYPM:Bridge and then redirect after a hangup]] |
Revision as of 12:32, 1 November 2012
Contents |
What is YAYPM?
Yet Another Yate Python Module. It allows to write YATE modules in PYTHON. PYTHON modules comunicate with YATE core via external protocol or run in python interperter embedded in pymodule.
Base concept
YAYPM base concept - deferred - comes from Twisted framework. Twisted project is very well documented, so look there for in-depth explanations of deferreds and its asynchronous programming model, as it won't be repeated here.
For the needs of this tutorial it is enough to say that, deferred is a promise to carry a computation in case of occurence of a specified event. What will be computed is defined by adding success and failure callbacks.
YAYPM allows to create deferreds for specified YATE messages.
YAYPM Installation
Connecting to YATE
There are two ways: via external protocol and embedded python interpreter:
if __name__ == "__main__": f = TCPDispatcherFactory(start) reactor.connectTCP("localhost", 5039, f) installSignalHandlers = 1 elif __name__ == "__embedded_yaypm_module__": yaypm.embededStart(start) installSignalHandlers = 0 reactor.run(installSignalHandlers)
Waiting for messages
In YAYPM program connection with YATE is represented by instance of class Dispatcher. Its method onmsg creates deferreds whose callbacks will be fired when a message comes from YATE:
def onmsg(self, name, guard = lambda _: True, until = None, autoreturn = False):
Where:
- name
- name of YATE message to fire on
- guard
- one argument boolean function, that defines additional conditions that message must fulfill to trigger the deffered
- until
- when in call, usually, one does not want to wait for an event infinitely. Until parameter allow to specify another deferred which when fired will trigger errback and stop the wait.
- autoreturn
- kind of syntactic sugar, when set to true, before firing callbacks message will be returned automaticly
So, for example:
... d = yate.onmsg("call.route", lambda m: m["called"] == "ivr") ...
creates deferred that will fire its callback on message "call.route" with "called" attribute set to "ivr", and:
... end = yate.onmsg("chan.hangup", lambda m : m["id"] == callid, autoreturn = True) d = yate.onmsg("call.answered", lambda m : m["targetid"] == callid, until = end) ...
wait for call.answered with "targetid" set to "callid" until call termination i.e.: arrival of chan.hangup with "id" set to callid.
Sending messages
Dispatcher's method msg creates messages:
... notify = yate.msg("chan.notify", {"targetid": notify}) ...
There are two ways to send message asynchronously and synchronously. The latter one returns a result:
... notify = yate.msg("chan.notify", {"targetid": notify}) #asynchronously notify.enqueue() #or synchronously d = notify.dispatch() # d is a deferred that will fire when message is processed by yate. Its callback will be given information whether is was processed successfully. ...
Answering messages
To return a message use Message ret method. It is possible to pass return value:
... route.ret(True, "dumb/") ...
There is a subtle difference between Message classes created by TCPDispatcher and EmbeddedDispatcher. Messages created by TCPDispatcher are normal python objects. Messages created by EmbeddedDispatcher are just proxies to true YATE messages. So they may be accessed only as long as underlying YATE message exists. That means that some programms that works well with TCPDispatcher might not work with EmbeddedDispatcher:
... #That is possible with TCPDispatcher but will raise an Exception with EmbeddedDispatcher: route.ret(True, "dumb/") print route["called"] ...
Watching messages
Difference in onwatch and onmsg is that deferred created with onwatch fires after message is processed:
def onwatch(self, name, guard = lambda _: True, until = None):
Where:
- name
- name of YATE message to fire on
- guard
- one argument boolean function, that defines additional conditions that message must fulfill to trigger the deffered
- until
- when in call, usually, one does not want to wait for an event infinitely. Until parameter allow to specify another deferred which when fired will trigger errback and stop the wait.