CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rrapi.py
Go to the documentation of this file.
1 import urllib, re, json, socket
2 
3 """
4 Python object that enables connection to RR v3 API.
5 Errors (not bugs!) and more welcome fixes/suggestions please
6 post to https://savannah.cern.ch/projects/cmsrunregistry/
7 """
8 
10  """
11  API Exception class
12  """
13 
14  def __init__(self, resp):
15  """
16  Construct exception by providing response object.
17  """
18  if type(resp) == str:
19  self.message = resp
20  else:
21  self.url = resp.geturl()
22  self.code = resp.getcode()
23  self.stack = None
24  for line in resp.read().split("\n"):
25  if self.stack == None:
26  m = re.search("<pre>(.*)", line)
27  if m != None:
28  self.stack = m.group(1)
29  m = re.search("^.+\.([^\.]+: .*)$", self.stack)
30  if m != None:
31  self.message = m.group(1)
32  else:
33  self.message = line
34  else:
35  m = re.search("(.*)</pre>", line)
36  if m != None:
37  self.stack = self.stack + "\n" + m.group(1)
38  break
39  else:
40  self.stack = self.stack + "\n" + line
41 
42  def __str__(self):
43  """ Get message """
44  return self.message
45 
46 class RRApi:
47  """
48  RR API object
49  """
50 
51  def __init__(self, url, debug = False):
52  """
53  Construct API object.
54  url: URL to RRv3 API, i.e. http://localhost:8080/rr_user
55  debug: should debug messages be printed out? Verbose!
56  """
57  self.debug = debug
58  self.url = re.sub("/*$", "/api/", url)
59  self.app = self.get(["app"])
60  self.dprint("app = ", self.app)
61 
62  def dprint(self, *args):
63  """
64  Print debug information
65  """
66  if self.debug:
67  print "RRAPI:",
68  for arg in args:
69  print arg,
70  print
71 
72  def get(self, parts, data = None):
73  """
74  General API call (do not use it directly!)
75  """
76 
77  #
78  # Constructing request path
79  #
80 
81  callurl = self.url + "/".join(urllib.quote(p) for p in parts)
82 
83  #
84  # Constructing data payload
85  #
86 
87  sdata = None
88  if data != None:
89  sdata = json.dumps(data)
90 
91  #
92  # Do the query and respond
93  #
94 
95  self.dprint(callurl, "with payload", sdata)
96 
97  resp = urllib.urlopen(callurl, sdata)
98 
99  has_getcode = "getcode" in dir(resp)
100  if self.debug:
101  if has_getcode:
102  self.dprint("Response", resp.getcode(), " ".join(str(resp.info()).split("\r\n")))
103  else:
104  self.dprint("Response", " ".join(str(resp.info()).split("\r\n")))
105 
106  if not has_getcode or resp.getcode() == 200:
107  rdata = resp.read()
108  if re.search("json", resp.info().gettype()):
109  try:
110  return json.loads(rdata)
111  except TypeError as e:
112  self.dprint(e)
113  return rdata
114  else:
115  return rdata
116  else:
117  raise RRApiError(resp)
118 
119  def tags(self):
120  """
121  Get version tags (USER app only)
122  """
123  if self.app != "user":
124  raise RRApiError("Tags call is possible only in user app")
125  return self.get(["tags"])
126 
127  def workspaces(self):
128  """
129  Get workspaces (all apps)
130  """
131  return self.get(["workspaces"])
132 
133  def tables(self, workspace):
134  """
135  Get tables for workspace (all apps)
136  """
137  return self.get([workspace, "tables"])
138 
139  def columns(self, workspace, table):
140  """
141  Get columns for table for workspace (all apps)
142  """
143  return self.get([workspace, table, "columns"])
144 
145  def templates(self, workspace, table):
146  """
147  Get output templates for table for workspace (all apps)
148  """
149  return self.get([workspace, table, "templates"])
150 
151  def count(self, workspace, table, filter = None, query = None, tag = None):
152  """
153  Get number of rows for table for workspace with filter, query (all apps) or tag (USER app only)
154  """
155 
156  #
157  # Constructing request path
158  #
159 
160  req = [ workspace, table ]
161  if tag != None:
162  if self.app != "user":
163  raise RRApiError("Tags are possible only in user app")
164  else:
165  req.append(tag)
166  req.append("count")
167 
168  #
169  # Constructing filter/query payload
170  #
171 
172  filters = {}
173  if filter != None:
174  filters['filter'] = filter
175  if query != None:
176  filters['query'] = query
177 
178  return int(self.get(req, filters))
179 
180  def data(self, workspace, table, template, columns = None, filter = None, query = None, order = None, tag = None):
181  """
182  Get data for table for workspace with filter, query (all apps) or tag (USER app only)
183  """
184 
185  #
186  # Check req parameters
187  #
188 
189  if type(workspace) != str:
190  raise RRApiError("workspace parameter must be str")
191 
192  #
193  # Constructing request path
194  #
195 
196  req = [ workspace, table, template ]
197  if columns != None:
198  req.append(",".join(columns))
199  else:
200  req.append("all")
201  if order != None:
202  req.append(",".join(order))
203  else:
204  req.append("none")
205  if tag != None:
206  if self.app != "user":
207  raise RRApiError("Tags are possible only in user app")
208  else:
209  req.append(tag)
210  req.append("data")
211 
212  #
213  # Constructing filter/query payload
214  #
215 
216  filters = {}
217  if filter != None:
218  filters['filter'] = filter
219  if query != None:
220  filters['query'] = query
221 
222  return self.get(req, filters)
223 
224  def reports(self, workspace):
225  """
226  Get available reports (USER app only)
227  """
228  if self.app != "user":
229  raise RRApiError("Reports available only in user app")
230  return self.get([workspace, "reports"])
231 
232  def report(self, workspace, report):
233  """
234  Get report data (USER app only)
235  """
236  if self.app != "user":
237  raise RRApiError("Reports available only in user app")
238  return self.get([workspace, report, "data"])
239 
240 
241 if __name__ == '__main__':
242 
243  print "RR API library."
def __init__
Definition: rrapi.py:14
def columns
Definition: rrapi.py:139
def __init__
Definition: rrapi.py:51
def templates
Definition: rrapi.py:145
def count
Definition: rrapi.py:151
def tables
Definition: rrapi.py:133
def get
Definition: rrapi.py:72
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def tags
Definition: rrapi.py:119
def report
Definition: rrapi.py:232
def reports
Definition: rrapi.py:224
def data
Definition: rrapi.py:180
dbl *** dir
Definition: mlp_gen.cc:35
double split
Definition: MVATrainer.cc:139
def dprint
Definition: rrapi.py:62
def workspaces
Definition: rrapi.py:127