- Python support is implemented in the pyroute plugin - see the Plugins page for general details about plugins in repro
- see the pyroute plugin files in the repository for the latest documentation and examples
- the provide_route method in your script will receive various details about each SIP request message
- it can return various things
- a list of 0, 1 or more URIs to be appended to the target set
- an integer which will be used as a SIP error code (e.g. 500 for server errors)
- a tuple such as (500, 'Grumpy server today') to indicate a SIP error code with a verbose response message
Here is a sample:
import resip def on_load(): '''Do initialisation when module loads''' resip.log_debug('on_load invoked') def provide_route(method, request_uri, headers, transport_type, body, cookies, new_headers): '''Process a request URI and return the target URI(s)''' resip.log_debug('method = ' + method) resip.log_debug('request_uri = ' + request_uri) resip.log_debug('From = ' + headers["From"]) resip.log_debug('To = ' + headers["To"]) resip.log_debug('transport_type = ' + transport_type) resip.log_debug('body = ' + body) resip.log_debug('len(cookies) = %d' % len(cookies)) if 'WSSessionInfo' in cookies: resip.log_debug('found cookie WSSessionInfo = ' + cookies['WSSessionInfo']) # This is how we can signal an error to the caller: if method == 'MESSAGE': return (500, 'No MESSAGE for me') routes = list() routes.append('sip:firstname.lastname@example.org') routes.append('sip:email@example.com') # We can add extension headers through the new_headers # This will not allow you to overwrite any normal header new_headers['X-Foo'] = 'Bar'; return routes
Some notes for reSIProcate developers
- we use the PyCXX wrappers around the Python C API
- PyCXX does not provide thread integration support, so we have some extra classes to help with threading, see Daniel's blog entry on the subject, it has also been discussed on the python-dev mailing list
- to expose reSIProcate's methods to the Python script, we use the PyCXX Py::ExtensionModule. This is a very convenient way to build the table of function pointers and wrap the arguments and return types used by the C API.
- The initial implementation uses this to give Python users a way to call reSIProcate logger functions
- It could also be used to provide access to the user database or the registration database
- To clone or to wrap?
- Currently, we don't make any attempt to provide any SIP data types such as Uri or SipMessage
- If we do provide them, we have to decide on a strategy:
- clone: copy the reSIProcate data into a Python object graph. This would be good if we had a collection of Python classes that we share with other SIP projects. This approach may provide better compatibility if users want to mix and match Python code with different SIP and RTC solutions.
- wrap: we create Python classes that carry pointers to reSIProcate classes. Methods on these classes would access the underlying data. This approach may provide better performance.