1 # Manifold API Python interface
4 from myslice.config import Config
6 from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException
13 def __init__(self, auth=None, cainfo=None):
21 self.multicall = False
22 self.url = config.manifold_url
23 self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True)
25 def __repr__ (self): return "ManifoldAPI[%s]"%self.url
27 # a one-liner to give a hint of what the return value looks like
28 def _print_result (self, result):
29 if not result: print "[no/empty result]"
30 elif isinstance (result,str): print "result is '%s'"%result
31 elif isinstance (result,list): print "result is a %d-elts list"%len(result)
32 else: print "[dont know how to display result]"
34 # xxx temporary code for scaffolding a ManifolResult on top of an API that does not expose error info
35 # as of march 2013 we work with an API that essentially either returns the value, or raises
36 # an xmlrpclib.Fault exception with always the same 8002 code
37 # since most of the time we're getting this kind of issues for expired sessions
38 # (looks like sessions are rather short-lived), for now the choice is to map these errors on
39 # a SESSION_EXPIRED code
40 def __getattr__(self, methodName):
41 def func(*args, **kwds):
43 if debug: print "====> ManifoldAPI.%s"%methodName,"auth",self.auth,"args",args,"kwds",kwds
44 result=getattr(self.server, methodName)(self.auth, *args, **kwds)
46 print '<==== backend call %s(*%s,**%s) returned'%(methodName,args,kwds),
47 print '.ctd. Authmethod=',self.auth['AuthMethod'], self.url,'->',
48 self._print_result(result)
49 ### attempt to cope with old APIs and new APIs
50 if isinstance (result, dict) and 'code' in result:
51 if debug: print "taken as new API"
52 # this sounds like a result from a new API
53 # minimal treatment is required, but we do want to turn this into a
55 if result['code'] != 2: # in the manifold world, this can be either
56 # 0 (ok) 1 (partial result) or 2 (which means error)
57 if debug: print "OK (new API)"
58 return ManifoldResult(code=result['code'], value=result['value'])
60 if debug: print "KO (new API) - raising ManifoldException"
61 raise ManifoldException(ManifoldResult(code=result['code'], output=result['description']))
63 if debug: print "taken as old API"
64 # we're talking to an old API
65 # so if we make it here it should mean success
66 return ManifoldResult (code=ManifoldCode.SUCCESS, value=result)
67 except xmlrpclib.Fault, error:
68 ### xxx this is very rough for now
69 # until we have some agreement about how the API calls should return error conditions
70 # in some less unpolite way than this anonymous exception, we assume it's a problem with the session
71 # that needs to be refreshed
72 if error.faultCode == 8002:
73 if debug: print "KO (old API - 8002) - raising ManifoldException"
74 reason="most likely your session has expired"
75 reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
78 raise ManifoldException ( ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason))
80 if debug: print "KO (old API - other) - raising ManifoldException"
81 reason="xmlrpclib.Fault with faultCode = %s (not taken as session expired)"%error.faultCode
82 raise ManifoldException ( ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output=reason))
83 except Exception,error:
84 if debug: print "KO (unexpected exception)",error
85 raise ManifoldException ( ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error) )
88 def send_manifold_query (self, query):
89 # We use a dictionary representation of the query for forwarding it to the API
90 ret = self.forward(query.to_dict())