CMS 3D CMS Logo

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