CMS 3D CMS Logo

das.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #pylint: disable-msg=C0301,C0103
3 
4 """
5 DAS command line tool
6 """
7 from __future__ import print_function
8 __author__ = "Valentin Kuznetsov"
9 
10 import sys
11 if sys.version_info < (2, 6):
12  raise Exception("DAS requires python 2.6 or greater")
13 
14 import re
15 import time
16 import json
17 import urllib
18 import urllib2
19 from optparse import OptionParser, OptionGroup
20 
22  """
23  DAS cache client option parser
24  """
25  def __init__(self, usage = None):
26  if usage is None:
27  usage = 'usage: %prog [options] --query "dataset=/HT/Run2011A-*/AOD"'
28  self.parser = OptionParser(usage=usage)
29  group = OptionGroup(self.parser,"Das options","These options relate to the Das client interface.")
30  group.add_option("-v", "--verbose", action="store",
31  type="int", default=0, dest="verbose",
32  help="verbose output")
33  group.add_option("--query", action="store", type="string",
34  default=False, dest="query",
35  help="specify query for your request")
36  group.add_option("--host", action="store", type="string",
37  default='https://cmsweb.cern.ch', dest="host",
38  help="specify host name of DAS cache server, default https://cmsweb.cern.ch")
39  group.add_option("--idx", action="store", type="int",
40  default=0, dest="idx",
41  help="start index for returned result set, aka pagination, use w/ limit")
42  group.add_option("--limit", action="store", type="int",
43  default=10, dest="limit",
44  help="number of returned results (results per page)")
45  group.add_option("--format", action="store", type="string",
46  default="json", dest="format",
47  help="specify return data format (json or plain), default json")
48  self.parser.add_option_group(group)
49  def get_opt(self):
50  """
51  Returns parse list of options
52  """
53  return self.parser.parse_args()
54 
55 def get_value(data, filters):
56  """Filter data from a row for given list of filters"""
57  for ftr in filters:
58  if ftr.find('>') != -1 or ftr.find('<') != -1 or ftr.find('=') != -1:
59  continue
60  row = dict(data)
61  for key in ftr.split('.'):
62  if isinstance(row, dict) and key in row:
63  row = row[key]
64  if isinstance(row, list):
65  for item in row:
66  if isinstance(item, dict) and key in item:
67  row = item[key]
68  break
69  yield str(row)
70 
71 def get_data(host, query, idx, limit, debug):
72  """Contact DAS server and retrieve data for given DAS query"""
73  params = {'input':query, 'idx':idx, 'limit':limit}
74  path = '/das/cache'
75  pat = re.compile('http[s]{0,1}://')
76  if not pat.match(host):
77  msg = 'Invalid hostname: %s' % host
78  raise Exception(msg)
79  url = host + path
80  headers = {"Accept": "application/json"}
81  encoded_data = urllib.urlencode(params, doseq=True)
82  url += '?%s' % encoded_data
83  req = urllib2.Request(url=url, headers=headers)
84  if debug:
85  hdlr = urllib2.HTTPHandler(debuglevel=1)
86  opener = urllib2.build_opener(hdlr)
87  else:
88  opener = urllib2.build_opener()
89  fdesc = opener.open(req)
90  data = fdesc.read()
91  fdesc.close()
92 
93  pat = re.compile(r'^[a-z0-9]{32}')
94  if data and isinstance(data, str) and pat.match(data) and len(data) == 32:
95  pid = data
96  else:
97  pid = None
98  count = 5 # initial waiting time in seconds
99  timeout = 30 # final waiting time in seconds
100  while pid:
101  params.update({'pid':data})
102  encoded_data = urllib.urlencode(params, doseq=True)
103  url = host + path + '?%s' % encoded_data
104  req = urllib2.Request(url=url, headers=headers)
105  try:
106  fdesc = opener.open(req)
107  data = fdesc.read()
108  fdesc.close()
109  except urllib2.HTTPError as err:
110  print(err)
111  return ""
112  if data and isinstance(data, str) and pat.match(data) and len(data) == 32:
113  pid = data
114  else:
115  pid = None
116  time.sleep(count)
117  if count < timeout:
118  count *= 2
119  else:
120  count = timeout
121  return data
122 
123 def main():
124  """Main function"""
125  optmgr = DASOptionParser()
126  opts, _ = optmgr.get_opt()
127  host = opts.host
128  debug = opts.verbose
129  query = opts.query
130  idx = opts.idx
131  limit = opts.limit
132  if not query:
133  raise Exception('You must provide input query')
134  data = get_data(host, query, idx, limit, debug)
135  if opts.format == 'plain':
136  jsondict = json.loads(data)
137  mongo_query = jsondict['mongo_query']
138  if 'filters' in mongo_query:
139  filters = mongo_query['filters']
140  data = jsondict['data']
141  if isinstance(data, dict):
142  rows = [r for r in get_value(data, filters)]
143  print(' '.join(rows))
144  elif isinstance(data, list):
145  for row in data:
146  rows = [r for r in get_value(row, filters)]
147  print(' '.join(rows))
148  else:
149  print(jsondict)
150  else:
151  print(data)
152 
def __init__(self, usage=None)
Definition: das.py:25
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def get_data(host, query, idx, limit, debug)
Definition: das.py:71
def main()
Definition: das.py:123
def get_value(data, filters)
Definition: das.py:55
def get_opt(self)
Definition: das.py:49
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
#define str(s)