Excerpt |
---|
This example written in Python allows users to manage VoipNow accounts and fetch call statistics. Download. |
Table of Contents | ||
---|---|---|
|
Note |
---|
This demonstrative code SHOULD NOT be used in production. It is designed to show how a client application can interact with the VoipNow SystemAPI. From this perspective, validations and error-checks aiming to demonstrate the most common mistakes are minimal and can be done easily. |
How To Install It
In order to be able to use the SystemAPI Python Tool, you must first check what components you need depending on your operating system and after that follow the installation steps.
...
- Download Visual Studio 2008 Express
- Download Python 2.4.4 installer
- Download fpconst-0.7.2.tar.gz
- Download PyXML-0.8.4.win32-py2.4.exe
- Download SOAPpy-0.12.0.tar.gz
- Download ZSI-2.1-a1.tar.gz
Setup
Download the tool files.
Note | ||
---|---|---|
| ||
Download here. Do not hesitate to contribute in order to make this example better - we welcome Pull Requests! | ||
Note | ||
During the installation procedure, you will be asked to extract some archives. The folder names and locations are not important. You simply need to run the commands shown below. |
Linux
STEP 1: As soon as gcc
and Python
are installed and fpconst
is downloaded, please extract the contents of the fpconst
archive, open the extracted folder, and run the following commands:
...
The following example shows how to add a new service provider. It also fetches the list of charging plans in order to pick a random one to use with the new service provider. For more information on how to get the access token, please check the access management documentation. The code should look like this:
Code Block | python | python |
---|
"""
4PSA VoipNow SystemAPI Client for Python
Copyright (c) 2013, Rack-Soft (www.4psa.com). All rights reserved.
VoipNow is a Trademark of Rack-Soft, Inc
4PSA is a Registered Trademark of Rack-Soft, Inc.
All rights reserved.
This script adds a service provider.
"""
import sys
import string
import random
import SOAPpy
from SOAPpy import SOAPProxy
# To view soap request/response set SOAPpy.Config.debug = 1
SOAPpy.Config.debug = 0
# Authentication data
ACCESS_TOKEN = "CHANGEME"
# Start constructing the Header
soapHeader = SOAPpy.Types.headerType()
#XML template for sending the authentication data
authenticationTemplate = """ <ns1:accessToken>%s</ns1:accessToken>"""
# filling in the template above with our authentication data
credentials = authenticationTemplate % (ACCESS_TOKEN)
soapHeader.userCredentials = SOAPpy.Types.headerType(credentials)
# the namespace for the user credentials
soapHeader.userCredentials._ns = "http://4psa.com/HeaderData.xsd/3.0.0"
soapHeader.userCredentials.userCredentials = SOAPpy.Types.untypedType(credentials)
# We need a charging plan for the new account, so we make a request to
# fetch all the charging plans and then pick a random one from the response list.
# Construct the Body
soapBody = SOAPpy.Types.untypedType("")
soapBody._name = "ns2:GetChargingPlans"
# Set namespaces
soapBody._setAttr("xmlns:ns2", "http://4psa.com/BillingMessages.xsd/3.0.0")
# Set endpoint
endpoint = "https://voipnow2demo.4psa.com/soap2/billing_agent.php"
# Set soapaction
soapaction = "http://4psa.com/Billing/3.0.0:getChargingPlansIn"
# Set service connection
server = SOAPProxy(endpoint, noroot = 1, soapaction = soapaction, header = soapHeader)
#run our soap request
try:
chargingPlans = server._callWithBody(soapBody)
except SOAPpy.Types.faultType, error:
# Catch exception, for situations when the charging plans could not be fetched
print "Error " + error[0] + ": " + error[1]
sys.exit(1)
# Get the id of a random charging plan
chargingPlanID = None
if len(chargingPlans) != 0:
randChargingPlan = chargingPlans[random.randint(0, len(chargingPlans) - 1)]
if hasattr(randChargingPlan, 'ID'):
chargingPlanID = randChargingPlan.ID
if hasattr(randChargingPlan, 'name'):
print "Using charging plan " + randChargingPlan.name + "."
else:
print "Using charging plan with id " + chargingPlanID + "."
#XML template for sending the new service provider data
bodyTemplate = """
<ns3:name>%s</ns3:name>
<ns3:login>%s</ns3:login>
<ns3:password>%s</ns3:password>
<ns3:country>%s</ns3:country>"""
if chargingPlanID != None:
bodyTemplate += """
<ns3:chargingPlanID>%s</ns3:chargingPlanID>"""
# Service Provider data
name = "SPPython" + str(random.randint(1, 1000))
login = "SPPython" + str(random.randint(1, 1000))
password = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10))
country = "us"
# Filling in the template above with the service provider data
if chargingPlanID != None:
body = bodyTemplate % (name, login, password, country, chargingPlanID)
else:
body = bodyTemplate % (name, login, password, country)
soapBody = SOAPpy.Types.untypedType(body)
soapBody._name = "ns2:AddServiceProvider"
# Set namespaces
soapBody._setAttr("xmlns:ns2", "http://4psa.com/ServiceProviderMessages.xsd/3.0.0")
soapBody._setAttr("xmlns:ns3", "http://4psa.com/ServiceProviderData.xsd/3.0.0")
# Set endpoint
endpoint = "https://voipnow2demo.4psa.com/soap2/sp_agent.php"
# Set soapaction
soapaction = "http://4psa.com/ServiceProvider/3.0.0:addServiceProviderIn"
# Set service connection
server = SOAPProxy(endpoint, noroot = 1, soapaction = soapaction, header = soapHeader)
#run our soap request
try:
server._callWithBody(soapBody)
print "Service provider created successfully."
except SOAPpy.Types.faultType, error:
# Catch exception, for situations when the service provider could not be added
print "Error " + error[0] + ": " + error[1] |
Adding Other Account Types
Tip |
---|
These examples can be found in the package downloaded with the SystemAPI Python Tool. |
If you wish to add other account types (organizations, users or extensions), there is not much to change from the program listed above. First of all, you will also need the id of a parent account. This stands for the ID of the service provider that owns the organization (when adding a new organization) or the ID of the organization that owns the user (when adding a new user) or the ID of the user that owns the extension (when adding a new extension). Therefore, the list of appropriate accounts will be fetched and a random one will be chosen as the parent for the new account:
Code Block | ||
---|---|---|
| ||
# We need a parent service provider for the new organization, so we make a request to
# fetch all the service providers.
# Construct the Body
soapBody = SOAPpy.Types.untypedType("")
soapBody._name = "ns2:GetServiceProviders"
# Set namespaces
soapBody._setAttr("xmlns:ns2", "http://4psa.com/ServiceProviderMessages.xsd/3.0.0")
# Set endpoint
endpoint = "https://voipnow2demo.4psa.com/soap2/sp_agent.php"
# Set soapaction
soapaction = "http://4psa.com/ServiceProvider/3.0.0:getServiceProvidersIn"
# Set service connection
server = SOAPProxy(endpoint, noroot = 1, soapaction = soapaction, header = soapHeader)
#run our soap request
try:
serviceProviders = server._callWithBody(soapBody)
except SOAPpy.Types.faultType, error:
# Catch exception, for situations when the service providers could not be fetched
print "Error " + error[0] + ": " + error[1]
sys.exit(1)
# Get the id of a random service provider
serviceProviderID = None
if len(serviceProviders) != 0:
randServiceProvider = serviceProviders[random.randint(0, len(serviceProviders) - 1)]
if hasattr(randServiceProvider, 'ID'):
serviceProviderID = randServiceProvider.ID
if hasattr(randServiceProvider, 'name'):
print "Using parent service provider " + randServiceProvider.name + "."
else:
print "Using parent service provider with id " + serviceProviderID + "."
if serviceProviderID == None:
print "No service providers found on the server. Can not add an organization."
sys.exit(1) |
You will also need to make adjustments to the parameters of the new request, in order to match the new account type:
Code Block | ||
---|---|---|
| ||
# Organization data
name = "OrgPython" + str(random.randint(1, 1000))
login = "OrgPythong" + str(random.randint(1, 1000))
password = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10))
country = "us"
parentID = serviceProviderID
# Filling in the template above with the organization data
if chargingPlanID != None:
body = bodyTemplate % (name, login, password, country, parentID, chargingPlanID)
else:
body = bodyTemplate % (name, login, password, country, parentID)
soapBody = SOAPpy.Types.untypedType(body)
soapBody._name = "ns2:AddOrganization"
# Set namespaces
soapBody._setAttr("xmlns:ns2", "http://4psa.com/OrganizationMessages.xsd/3.0.0")
soapBody._setAttr("xmlns:ns3", "http://4psa.com/OrganizationData.xsd/3.0.0")
# Set endpoint
endpoint = "https://voipnow2demo.4psa.com/soap2/organization_agent.php"
# Set soapaction
soapaction = "http://4psa.com/Organization/3.0.0:addOrganizationIn" |
Adding an user or an extension is very similar. You only need to adjust the namespaces, endpoint and soapaction variables. Also, for extension accounts, you should use the label field instead of name and login.
CallCosts
The DEMO version also provides a CallCosts request. Here is the code:
curl "https://raw.githubusercontent.com/4psa/systemapi-example-python/Demo/DemoAddServiceProvider.py" -o DemoAddServiceProvider.py -L |
Adding Other Account Types
If you wish to add other account types (organizations, users or extensions), there is not much to change from the program listed above. First of all, you will also need the id of a parent account. This stands for the ID of the service provider that owns the organization (when adding a new organization) or the ID of the organization that owns the user (when adding a new user) or the ID of the user that owns the extension (when adding a new extension). Therefore, the list of appropriate accounts will be fetched and a random one will be chosen as the parent for the new account:
Code Block | ||
---|---|---|
| ||
# We need a parent service provider for the new organization | ||
Code Block | ||
| ||
""" 4PSA VoipNow SystemAPI Client for Python Copyright (c) 2013, Rack-Soft (www.4psa.com). All rights reserved. VoipNow is a Trademark of Rack-Soft, Inc 4PSA is a Registered Trademark of Rack-Soft, Inc. All rights reserved. This script fetches the call costs of an extension. """ import sys import random import datetime import SOAPpy from SOAPpy import SOAPProxy # To view soap request/response set SOAPpy.Config.debug = 1 SOAPpy.Config.debug = 0 # Authentication data ACCESS_TOKEN = "CHANGEME" # Start constructing the Header soapHeader = SOAPpy.Types.headerType() #XML template for sending the authentication data authenticationTemplate = """ <ns1:accessToken>%s</ns1:accessToken>""" # filling in the template above with our authentication data credentials = authenticationTemplate % (ACCESS_TOKEN) soapHeader.userCredentials = SOAPpy.Types.headerType(credentials) # the namespace for the user credentials soapHeader.userCredentials._ns = "http://4psa.com/HeaderData.xsd/3.0.0" soapHeader.userCredentials.userCredentials = SOAPpy.Types.untypedType(credentials) # We need an extension to check its call costs, so we make a request to # fetch all the extensionsservice providers. # Construct the Body soapBody = SOAPpy.Types.untypedType("") soapBody._name = "ns2:GetExtensionsGetServiceProviders" # Set namespaces soapBody._setAttr("xmlns:ns2", "http://4psa.com/ExtensionMessagesServiceProviderMessages.xsd/3.0.0") # Set endpoint endpoint = "https://voipnow2demo.4psa.com/soap2/extensionsp_agent.php" # Set soapaction soapaction = "http://4psa.com/UserServiceProvider/3.0.0:getExtensionsIngetServiceProvidersIn" # Set service connection server = SOAPProxy(endpoint, noroot = 1, soapaction = soapaction, header = soapHeader) #run our soap request try: extensionsserviceProviders = server._callWithBody(soapBody) except SOAPpy.Types.faultType, error: # Catch exception, for situations when the extensionsservice providers could not be fetched print "Error " + error[0] + ": " + error[1] sys.exit(1) # Get the identifierid of a random service extensionprovider extensionIdentifierserviceProviderID = None if len(extensionsserviceProviders) != 0: randExtensionrandServiceProvider = extensionsserviceProviders[random.randint(0, len(extensionsserviceProviders) - 1)] if hasattr(randExtensionrandServiceProvider, 'identifierID'): extensionIdentifierserviceProviderID = randExtensionrandServiceProvider.identifierID if hasattr(randExtensionrandServiceProvider, 'name'): print "FetchingUsing callparent costsservice for extensionprovider " + randExtensionrandServiceProvider.name + "." else: print "FetchingUsing callparent costs forservice extensionprovider with identifierid " + extensionIdentifierserviceProviderID + "." if extensionIdentifierserviceProviderID == None: print "No service extensionsproviders found on the server. Can not makeadd the call costs requestan organization." sys.exit(1) # Construct the Body body = SOAPpy.Types.structType() #XML template for sending the new request data bodyTemplate |
You will also need to make adjustments to the parameters of the new request, in order to match the new account type:
Code Block | ||
---|---|---|
| ||
# Organization data name = "OrgPython"" + <userIdentifier>%s</userIdentifier> <interval> <startDate>%s</startDate> <endDate>%s</endDate> </interval>""" # The current date, used for the request data now = datetime.datetime.now() # Request data userIdentifier = extensionIdentifier startDate = "2012-01-01" endDate = now.strftime("%Y-%m-%d")str(random.randint(1, 1000)) login = "OrgPythong" + str(random.randint(1, 1000)) password = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10)) country = "us" parentID = serviceProviderID # Filling in the template above with the request data organization data if chargingPlanID != None: body = bodyTemplate % (name, login, password, country, parentID, chargingPlanID) else: body = bodyTemplate % (userIdentifiername, login, password, startDatecountry, endDateparentID) soapBody = SOAPpy.Types.untypedType(body) soapBody._name = "ns2:CallCostsAddOrganization" # Set namespaces soapBody._setAttr("xmlns:ns2", "http://4psa.com/ReportMessagesOrganizationMessages.xsd/3.0.0") # Set endpoint endpoint = "https://voipnow2demo.4psa.com/soap2/report_agent.php" # Set soapaction soapaction =soapBody._setAttr("xmlns:ns3", "http://4psa.com/ReportOrganizationData.xsd/3.0.0:CallCostsIn" # Set service connection server = SOAPProxy(endpoint, noroot = 1, soapaction = soapaction, header = soapHeader) #run our soap request try: callCosts = server._callWithBody(soapBody) # Display the result print callCosts.totalCalls + " calls have been made between " + startDate + " and " + endDate + " with a total cost of " + callCosts.cost + " " + callCosts.currency except SOAPpy.Types.faultType, error: # Catch exception, for situations when the call costs could not be fetched print "Error " + error[0] + ": " + error[1] sys.exit(1).0.0") # Set endpoint endpoint = "https://voipnow2demo.4psa.com/soap2/organization_agent.php" # Set soapaction soapaction = "http://4psa.com/Organization/3.0.0:addOrganizationIn" |
Adding an user or an extension is very similar. You only need to adjust the namespaces, endpoint and soapaction variables. Also, for extension accounts, you should use the label field instead of name and login.
CallCosts
The DEMO version also provides a CallCosts request. Here is the code:
Code Block |
---|
curl "https://raw.githubusercontent.com/4psa/systemapi-example-python/Demo/DemoCallCosts.py" -o DemoCallCosts.py -L |
Except where otherwise noted, content in this space is licensed under a Creative Commons Attribution 4.0 International.