All pastes #932480 Raw Edit

Miscellany

public python v1 · immutable
·published 2008-03-07 19:43 UTC
rendered paste body
"""An implementation of the SRPC client protocol in Python.Includes a simple proxy for working over HTTP.Example usage:    >>> serv = srpc.http_proxy('http://awesomeblag.org/srpc')    >>> post = serv.post.view(1)    >>> post    {u'content': u'baz', u'title': u'bar', u'author': u'foo'}    >>> post[u'content'] = u'hello, world'    >>> serv.post.edit(1, post)    >>> serv.post.view(1)    {u'content': u'hello, world', u'title': u'bar', u'author': 'foo'}"""import reimport urllib2import simplejson__all__ = ['SRPCRequest', 'SRPCError']name_re = re.compile(r'^[a-zA-Z_]([a-zA-Z0-9_]|\.[a-zA-Z_])*[a-zA-Z0-9_]?$')def valid_name(name):    return name_re.match(name) is not Noneclass SRPCRequest(object):    def __init__(self, name, *params):        if valid_name(name):            self.name = name            self.params = params        else:            raise ArgumentError("%s is not a valid name" % (name, ))    def to_dict(self):        return {'version': '1.0', 'name': self.name, 'params': self.params}    def __str__(self):        return simplejson.dumps(self.to_dict())    def dump(self, stream):        simplejson.dump(self.to_dict(), stream)class SRPCError(StandardError):    def __init__(self, name, result):        self.name = name        self.result = result    def __str__(self):        if self.result:            return '%s: %s' % (self.name, self.result)        else:            return self.nameclass SRPCWrongVersion(SRPCError):    def __init__(self, expected):        self.expected = expected    def __str__(self):        return 'Expected version %s, using 1.0' % (self.expected, )class SRPCWrongProc(SRPCError):    def __init__(self, name):        self.name = name    def __str__(self):        return 'Unknown procedure %s' % (self.name, )class SRPCWrongParams(SRPCError, TypeError):    def __init__(self, result):        self.result = result    def __str__(self):        res = 'Wrong parameters to procedure'        if self.result:            return '%s (%s)' % (res, self.result)        else:            return resdef do_request(infile, outfile, name, *params):    req = SRPCRequest(name, *params)    req.dump(outfile)    resp = simplejson.load(infile)    if resp['error'] is None:        return resp['result']    else:        raise SRPCError(resp.version, resp.error, resp.result)class SRPCAttrProxy(object):    def __init__(self, infile, outfile, name):        self.infile = infile        self.outfile = outfile        self.name = name    def __call__(self, *params):        return do_request(self.infile, self.outfile, self.name, *params)    def __getattr__(self, name):        if name == 'stream' or name == 'name':            return object.__getattr__(self, name)        else:            return SRPCAttrProxy(self.infile, self.outfile,                '%s.%s' % (self.name, name))class SRPCProxy(object):    def __init__(self, infile, outfile):        self.infile = infile        self.outfile = outfile    def __getattr__(self, name):        if name == 'stream':            return object.__getattr__(self, name)        else:            return SRPCAttrProxy(self.infile, self.outfile, name)class SRPCHTTPFile(object):    def __init__(self, url):        self.url = url        self.handle = None    def write(self, data):        self.handle = urllib2.urlopen(self.url, data)    def read(self):        self.handle.read()def http_proxy(url):    return SRPCProxy(SRPCHTTPFile(url))