Local updates for dev.myslice.info to work with api v2
[myslice.git] / manifold / manifoldapi.py
1 # Manifold API Python interface
2 import xmlrpclib
3
4 from myslice.config import Config
5
6 from manifoldresult import ManifoldResult, ManifoldCode
7
8 debug=False
9 debug=True
10
11 class ManifoldAPI:
12
13     def __init__(self, auth=None, cainfo=None):
14         
15         config = Config()
16         self.auth = auth
17         self.cainfo = cainfo
18         self.errors = []
19         self.trace = []
20         self.calls = {}
21         self.multicall = False
22         self.url = config.manifold_url
23         self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True)
24
25     def __repr__ (self): return "ManifoldAPI[%s]"%self.url
26
27     # xxx temporary code for scaffolding a ManifolResult on top of an API that does not expose error info
28     # as of march 2013 we work with an API that essentially either returns the value, or raises 
29     # an xmlrpclib.Fault exception with always the same 8002 code
30     # since most of the time we're getting this kind of issues for expired sessions
31     # (looks like sessions are rather short-lived), for now the choice is to map these errors on 
32     # a SESSION_EXPIRED code
33     def __getattr__(self, methodName):
34         def func(*args, **kwds):
35             if (debug): 
36                 print "entering ManifoldAPI.%s"%methodName,
37                 print "args",args,
38                 print "kwds",kwds
39             try:
40                 result=getattr(self.server, methodName)(self.auth, *args, **kwds)
41                 ### attempt to cope with old APIs and new APIs
42                 if isinstance (result, dict) and 'code' in result:
43                     # this sounds like a result from a new API, leave it untouched
44                     return result # jordan
45                 else:
46                     if debug:
47                         print '<=== backend call', methodName, args, kwds
48                         print '.... ctd', 'Authmethod=',self.auth['AuthMethod'], self.url,'->',
49                         if not result:                        print "[no/empty result]"
50                         elif isinstance (result,str):         print "result is '%s'"%result
51                         elif isinstance (result,list):        print "result is a %d-elts list"%len(result)
52                         else:                                 print "[dont know how to display result]"
53                     return ManifoldResult (code=ManifoldCode.SUCCESS, value=result)
54             except xmlrpclib.Fault, error:
55                 ### xxx this is very rough for now
56                 # until we have some agreement about how the API calls should return error conditions
57                 # in some less unpolite way than this anonymous exception, we assume it's a problem with the session
58                 # that needs to be refreshed
59                 if error.faultCode == 8002:
60                     reason="most likely your session has expired"
61                     reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
62                     return ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason)
63                 else:
64                     reason="xmlrpclib.Fault with faultCode = %s (not taken as session expired)"%error.faultCode
65                     return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output=reason)
66             except Exception,error:
67                 print "ManifoldAPI: unexpected exception",error
68                 return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error)
69         return func
70
71     def send_manifold_query (self, query):
72         # We use a dictionary representation of the query for forwarding it to the API
73         ret = self.forward(query.to_dict())
74         print "="*80
75         print "Result:"
76         print ret
77         print "="*80
78         print ret
79         return ret
80
81 #old#        (action,subject)= (query.action,query.subject)
82 #old#        # use e.g. self.Get rather than self.server.Get so we use the __getattr__ code
83 #old#        if action=='get':
84 #old## this makes the backend to squeak and one can't login anymore...
85 #old##            return self.Get(subject, query.filters, query.timestamp, query.fields)
86 #old#            return self.Get(subject, query.filters, {}, query.fields)
87 #old#        elif action=='update':
88 #old#            answer=self.Update(subject, query.filters, query.params, query.fields)
89 #old#            if not isinstance (answer, ManifoldResult): print "UNEXECPECTED answer", answer
90 #old#            return answer
91 #old#        else:
92 #old#            warning="WARNING: ManifoldAPI.send_manifold_query: %s not implemented for now"%action
93 #old#            print warning
94 #old#            print 3
95 #old#            return ManifoldResult(code=ManifoldCode.NOT_IMPLEMENTED, output=warning)