implements sending update queries - and returns a sensible code for other query actions
[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                 if debug:
42                     print '===> backend call',methodName, self.auth, self.url,'->',
43                     if not result:                        print "[no/empty result]"
44                     elif isinstance (result,str):         print "result is '%s'"%result
45                     elif isinstance (result,list):        print "result is a %d-elts list"%len(result)
46                     else:                                 print "[dont know how to display result]"
47                 return ManifoldResult (code=ManifoldCode.SUCCESS, value=result)
48             except xmlrpclib.Fault, error:
49                 ### xxx this is very rough for now
50                 # until we have some agreement about how the API calls should return error conditions
51                 # in some less unpolite way than this anoanymous exception, we assume it's a problem with the session
52                 # that needs to be refreshed
53                 if debug: print "Session Expired"
54                 if error.faultCode == 8002:
55                     reason="most likely your session has expired"
56                     reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
57                     return ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason)
58             except Exception,error:
59                 print "ManifoldAPI: unexpected exception",error
60                 return ManifoldResult (code=ManifoldResult.UNKNOWN_ERROR, output="%s"%error)
61         return func
62
63     def send_manifold_query (self, query):
64         (action,subject)= (query.action,query.subject)
65         if action=='get':
66             # use self.Get rather than self.server.Get so we catch exceptions as per __getattr__
67             return self.Get(subject, query.filters, query.timestamp, query.fields)
68         if action=='update':
69             return self.Update(subject, query.filters, query.params, query.fields)
70         else:
71             warning="WARNING: ManifoldAPI.send_manifold_query: %s not implemented for now"%action
72             print warning
73             return ManifoldResult(code=ManifoldCode.NOT_IMPLEMENTED, output=warning)