I want to query an XML-RPC server using Python script.
First obstacle was that the server uses authentication, and I had to resort to requests.Session to overcome this. Now I did, and I can query the server over RPC, but I'm using rather ugly mechanism to do it - glueing strings. This, of course, produces just XML data, which I would again have to process manually to convert it into usable list or dictionary.
I found there's an xmlrpc module for Python which allows to cleanly work with a server; however, I can't find how to auth myself prior to using XML-RPC.
Here's the code that I already wrote, using requests:
from requests import Session
myserver_address='http://myserver.test.com/admin'
myserver_RPC=myserver_address+'?RPC2'
myserver_header={'Content-Type': "text/xml; charset=UTF-8"}
myserver_login={"srvAction":"LoginAdmin", "login":"testuser", "password":"testpassword", "Submit":"Login", "select_locale":"en"}
myserver_login2={"srvAction":"LoginOrg", "selectSection":"20", "submit":"Continue"}
method_header = '<methodCall xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"><methodName>'
param_header = '</methodName><params>'
param_body_header = '<param><value><string>'
param_body_footer = '</string></value></param>'
method_footer = '</params></methodCall>'
def myserver_get_xml(myserver_method, myserver_method_param):
param_body = ''
for param in myserver_method_param:
param_body = param_body + param_body_header + str(param) + param_body_footer
myserver_post = method_header + myserver_method + param_header + param_body + method_footer
page = s.post(myserver_RPC, myserver_post)
return page.text
s = Session()
s.get(myserver_address)
s.post(myserver_address, myserver_login)
s.post(myserver_address, myserver_login2)
s.headers.update(myserver_header)
result_xml = myserver_get_xml('myserverServer.getNetworkTree', ['31', ] )
print(result_xml)
So the question is:
how to use xmlrpc module within an authenticated session?
if that's not possible, is there something nice to convert XML into dictionary (preferrably) or list?
Example output:
<?xml version="1.0" encoding="UTF-8"?><methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"><params><param><value><array><data><value><array><data><value>10.0.0.0/16</value><value><i4>1</i4></value><value>31</value></data></array></value><value><array><data><value>10.1.0.0/16</value><value><i4>2</i4></value><value>31</value></data></array></value></data></array></value></param></params></methodResponse>
You would need to implement your own
xmlrpclib.Transport
class and specify that as your transport parameter when you instantiated the xmlrpclib.ServerProxy. See the example of a proxied transport implementation on https://docs.python.org/2/library/xmlrpclib.html#example-of-client-usage. You probably have to implement and modifiedTransport.make_connection
only, which needs to return anhttplib.HTTPConnection
instance which has the Cookie header set from the http response headers from your login actions. You can't really use theSession
class to make requests, as it is not compatible with the httplib.HTTPConnection class that is used by the rest of theTransport
class methods. So to keep things simple, you might be able to perform the login with aSession
instance, extract the headers (in particular the cookie header) and create an HTTPConnection with these headers.I'm not sure if it will work like this, I haven't tested it. I hope it gives you enough information to try this approach.