Created
April 10, 2012 22:07
-
-
Save chrisguitarguy/2354951 to your computer and use it in GitHub Desktop.
Python xmlrpc lib Transport that used Requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
A replacement transport for Python xmlrpc library. | |
Usage: | |
>>> import xmlrpclib | |
>>> from transport import RequestsTransport | |
>>> s = xmlrpclib.ServerProxy('http://yoursite.com/xmlrpc', transport=RequestsTransport()) | |
>>> s.demo.sayHello() | |
Hello! | |
""" | |
try: | |
import xmlrpc.client as xmlrpc | |
except ImportError: | |
import xmlrpclib as xmlrpc | |
import requests | |
class RequestsTransport(xmlrpc.Transport): | |
""" | |
Drop in Transport for xmlrpclib that uses Requests instead of httplib | |
""" | |
# change our user agent to reflect Requests | |
user_agent = "Python XMLRPC with Requests (python-requests.org)" | |
# override this if you'd like to https | |
use_https = False | |
def request(self, host, handler, request_body, verbose): | |
""" | |
Make an xmlrpc request. | |
""" | |
headers = {'User-Agent': self.user_agent} | |
url = self._build_url(host, handler) | |
try: | |
resp = requests.post(url, data=request_body, headers=headers) | |
except ValueError: | |
raise | |
except Exception: | |
raise # something went wrong | |
else: | |
try: | |
resp.raise_for_status() | |
except requests.RequestException as e: | |
raise xmlrpc.ProtocolError(url, resp.status_code, | |
str(e), resp.headers) | |
else: | |
return self.parse_response(resp) | |
def parse_response(self, resp): | |
""" | |
Parse the xmlrpc response. | |
""" | |
p, u = self.getparser() | |
p.feed(resp.text) | |
p.close() | |
return u.close() | |
def _build_url(self, host, handler): | |
""" | |
Build a url for our request based on the host, handler and use_http | |
property | |
""" | |
scheme = 'https' if self.use_https else 'http' | |
return '%s://%s/%s' % (scheme, host, handler) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The parse_response method is problematic, as it passes a unicode to a method that expects binary. We can simply pass the raw response object. My version (which also passes through TLS client certs) becomes:
Duly note the lack (!) of a
parse_response
method as we simply use the one from the parent class. See also http://docs.python-requests.org/en/latest/user/quickstart/#raw-response-content