Note: The Python examples below now use requests instead of httplib2. By using requests.post() with the necessary authentication, headers, and SSL options, the code is simpler and compatible with modern Python versions (e.g., 3.11). Successful HTTP 200 responses are parsed with getparser() from xmlrpc.client; otherwise, a ProtocolError is raised. This approach streamlines SSL handling, authentication, and header management.
* Digest Authentication for Trusted Numbers Manipulation and CLI Mapping
See introduction to XMLAPI for details on Authentication:
https://support.sippysoft.com/a/solutions/articles/106909
#!/usr/bin/env python ## username should be the Web Login of the Customer, password - API password ## 1.2.3.4 should be replaced with target IP/hostname of Sippy import requests try: from urllib.parse import splituser, splitpasswd from xmlrpc.client import ServerProxy, getparser, ProtocolError except ImportError: from urllib import splituser, splitpasswd from xmlrpclib import ServerProxy, getparser, ProtocolError class HTTPSDigestAuthTransport: def request(self, host, handler, request_body, verbose=0): auth, host = splituser(host) username, password = splitpasswd(auth) url = "https://" + host + handler headers = {'Content-Type': 'text/xml'} # Using requests with Digest Authentication equivalent (auth=(username, password)) resp = requests.post(url, data=request_body, headers=headers, auth=(username, password), verify=True) if resp.status_code != 200: raise ProtocolError(url, resp.status_code, resp.reason, resp.headers) p, u = getparser(0) p.feed(resp.content) return u.close() transport = HTTPSDigestAuthTransport() client = ServerProxy("https://username:[email protected]/xmlapi/xmlapi", transport) ## add a mapping res = client.addCLIMapping({ 'i_account' : 34, 'cli' : '123456', 'lang' : 'en' }) print(res['result']) ## retrieve list of trusted numbers res = client.listCLIMappings({ 'i_account' : 34 }) if res['result'] == 'OK': for cli, lang in res['list']: print(cli, lang)
* Trusted Authentication for Trusted Numbers Manipulation and CLI Mapping
In this example i_customer should be supplied to selected XMLAPI method, which is mandatory for most methods in trusted mode.
#!/usr/bin/env python ## 1.2.3.4 should be replaced with target IP/hostname of Sippy import requests try: from xmlrpc.client import ServerProxy, getparser, ProtocolError except ImportError: from xmlrpclib import ServerProxy, getparser, ProtocolError class HTTPSTrustedAuthTransport: def request(self, host, handler, request_body, verbose=0): url = "https://" + host + handler headers = {'Content-Type': 'text/xml'} # Using requests.post() without explicit credentials # (In trusted mode, authentication may differ) resp = requests.post(url, data=request_body, headers=headers, verify=True) if resp.status_code != 200: raise ProtocolError(url, resp.status_code, resp.reason, resp.headers) p, u = getparser(0) p.feed(resp.content) return u.close() transport = HTTPSTrustedAuthTransport() client = ServerProxy("https://1.2.3.4/xmlapi/xmlapi", transport) ## add a mapping res = client.addCLIMapping({ 'i_customer': 1, 'i_account' : 34, 'cli' : '123456', 'lang' : 'en' }) print(res['result']) ## retrieve list of trusted numbers res = client.listCLIMappings({ 'i_customer': 1, 'i_account' : 34 }) if res['result'] == 'OK': for cli, lang in res['list']: print(cli, lang)
* Manage Call-Back Calls
#!/usr/bin/env python import requests try: from urllib.parse import splituser, splitpasswd from xmlrpc.client import ServerProxy, getparser, ProtocolError except ImportError: from urllib import splituser, splitpasswd from xmlrpclib import ServerProxy, getparser, ProtocolError my_number = '12061234567' destination_number = '12067654321' authname = '000124' class HTTPSDigestAuthTransport: def request(self, host, handler, request_body, verbose=0): auth, host = splituser(host) username, password = splitpasswd(auth) url = "https://" + host + handler headers = {'Content-Type': 'text/xml'} resp = requests.post(url, data=request_body, headers=headers, auth=(username, password), verify=True) if resp.status_code != 200: raise ProtocolError(url, resp.status_code, resp.reason, resp.headers) p, u = getparser(0) p.feed(resp.content) return u.close() transport = HTTPSDigestAuthTransport() client = ServerProxy("https://username:password@sippy_ip/xmlapi/xmlapi", transport) res = client.make2WayCallback({ 'authname': authname, 'cld_first': my_number, 'cld_second': destination_number, 'credit_time': 3600 # call should not continue more than an hour }) if res['result'] == 'OK': print(res['i_callback_request'])
* Refunding an Account
#!/usr/bin/env python import requests try: from urllib.parse import splituser, splitpasswd from xmlrpc.client import ServerProxy, getparser, ProtocolError except ImportError: from urllib import splituser, splitpasswd from xmlrpclib import ServerProxy, getparser, ProtocolError class HTTPSDigestAuthTransport: def request(self, host, handler, request_body, verbose=0): auth, host = splituser(host) username, password = splitpasswd(auth) url = "https://" + host + handler headers = {'Content-Type': 'text/xml'} resp = requests.post(url, data=request_body, headers=headers, auth=(username, password), verify=True) if resp.status_code != 200: raise ProtocolError(url, resp.status_code, resp.reason, resp.headers) p, u = getparser(0) p.feed(resp.content) return u.close() transport = HTTPSDigestAuthTransport() client = ServerProxy("https://username:password@sippy_ip/xmlapi/xmlapi", transport) res = client.accountAddFunds({ 'i_account': 34, 'amount': 1.23, 'currency': 'USD', 'payment_notes': 'Test credit' }) print(res['result'])
* Python multicall example
https://support.sippysoft.com/a/solutions/articles/3000108533