See introduction to XMLAPI for details on Authentication:
https://support.sippysoft.com/a/solutions/articles/106909
Starting from Sippy 4.4 it's possible to use MULTICALL in XMLAPI.
This feature allows to "pack" N XMLAPI call into a single request to send to Server, instead of sending them one by one.
Measured benchmark for the addDID() xmlapi call showed 3 times faster execution in multicall compared with regular one-by-one addition of 1000 DIDs:
- 5m 20s in regular mode
- 1m 39s in multicall.
PYTHON example (updated):
Note: This updated Python example replaces httplib2 with the requests library to handle HTTP requests. By using requests.post() along with the appropriate URL, request body, and headers, the process is simplified, ensuring compatibility with newer Python versions (e.g., 3.11). Also requests by default writes more information about its internal work for example, errors or warnings about SSL settings.
#!/usr/bin/env python import requests from requests.auth import HTTPDigestAuth try: from urllib.parse import urlparse from xmlrpc.client import ServerProxy, getparser, ProtocolError, MultiCall except ImportError: from urlparse import urlparse from xmlrpclib import ServerProxy, getparser, ProtocolError, MultiCall class HTTPSDigestAuthTransport: def request(self, host, handler, request_body, verbose=0): parsed = urlparse("https://" + host) username = parsed.username password = parsed.password hostname = parsed.hostname port = parsed.port or 443 url = f"https://{hostname}:{port}{handler}" if verbose: print(f"Making request to: {url}") response = requests.post(url, data=request_body, headers={'content-type': 'text/xml'}, auth=HTTPDigestAuth(username, password), verify=True) if response.status_code != 200: raise ProtocolError(url, response.status_code, response.reason, None) p, u = getparser(0) p.feed(response.content) return u.close() if __name__ == "__main__": transport = HTTPSDigestAuthTransport() client = ServerProxy("https://username:[email protected]/xmlapi/xmlapi", transport) multicall = MultiCall(client) multicall.getAccountCallStats({"i_account": 1}) multicall.getAccountCallStats({"i_account": 1}) multicall.getAccountInfo({"i_account": -1}) # expect error here multicall.getAccountCallStats({"i_account": 1}) for res in multicall().results: if isinstance(res, dict): print("Fault", res) else: print(res[0])
PYTHON example (using httplib2):
Below is an example using httplib2. Although the scripts above are now based on requests, this code is still functional in Python 3 and might be useful for backward compatibility or for users who prefer httplib2.
#!/usr/bin/env python import warnings warnings.simplefilter("ignore", DeprecationWarning) import httplib2 try: from urllib.parse import splituser, splitpasswd from xmlrpc.client import ServerProxy, getparser, ProtocolError, MultiCall except ImportError: from urllib import splituser, splitpasswd from xmlrpclib import ServerProxy, getparser, ProtocolError, MultiCall class HTTPSDigestAuthTransport: def request(self, host, handler, request_body, verbose=0): auth, host = splituser(host) username, password = splitpasswd(auth) h = httplib2.Http(disable_ssl_certificate_validation=True) if verbose: h.debuglevel = 1 h.add_credentials(username, password) resp, content = h.request("https://" + host + handler, "POST", body=request_body, headers={'content-type':'text/xml'}) if resp.status != 200: raise ProtocolError("https://" + host + handler, resp.status, resp.reason, None) p, u = getparser(0) p.feed(content) return u.close() transport = HTTPSDigestAuthTransport() client = ServerProxy("https://username:[email protected]/xmlapi/xmlapi", transport) multicall = MultiCall(client) multicall.getAccountCallStats({ "i_account" : 1}) multicall.getAccountCallStats({ "i_account" : 1}) multicall.getAccountInfo({ "i_account" : -1}) # expect error here multicall.getAccountCallStats({ "i_account" : 1}) for res in multicall().results: if isinstance(res, dict): print ("Fault", res) else: print (res[0])
More python examples:
https://support.sippysoft.com/a/solutions/articles/107511
PHP example:
<? set_include_path(get_include_path() . PATH_SEPARATOR . '/home/ssp/sippy_web/lib'); include 'xmlrpc/xmlrpc.inc'; $customer_web_login = "username"; $customer_api_password = "password"; $params = array(new xmlrpcval(array( "i_environment" => new xmlrpcval('1', "int"), ), 'struct')); $msg = new xmlrpcmsg('getAccountCallStats', $params); $params2 = array(new xmlrpcval(array( "i_account" => new xmlrpcval('-1', "int"), // expect error ), 'struct')); $msg2 = new xmlrpcmsg('getAccountInfo', $params2); $cli = new xmlrpc_client('https://1.2.3.4/xmlapi/xmlapi'); $cli->request_charset_encoding = 'UTF-8'; $cli->setSSLVerifyPeer(false); $cli->return_type = 'phpvals'; $cli->setDebug(2); //$cli->setCredentials($customer_web_login, $customer_api_password, CURLAUTH_DIGEST); $r = $cli->multicall(Array($msg, $msg, $msg2, $msg), 10, '', FALSE); print_r($r); ?>