CMS 3D CMS Logo

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