CMS 3D CMS Logo

url_query.py
Go to the documentation of this file.
1 """
2 Joshua Dawes - CERN, CMS, The University of Manchester
3 
4 File provides a class that handles pycurl requests.
5 
6 Provides methods for performing/closing the request, as well as getting the request response.
7 Note: user agent string from current version of cmsDbUpload
8 """
9 from __future__ import print_function
10 from __future__ import absolute_import
11 
12 import pycurl
13 from StringIO import StringIO
14 from urllib import urlencode
15 import traceback
16 import sys
17 import json
18 from .errors import *
19 from time import sleep
20 
21 class url_query():
22 
23  def __init__(self, url=None, url_data=None, body=None, response_stream=None, timeout=60):
24  if not(url):
25  return None
26  self._url = url
27  self._r = pycurl.Curl()
28 
29  # set options for the request - of note is the fact that we do not verify the peer or the host - because
30  # CERN certificates are self-signed, and we only need the encryption from HTTPS, not the certificate checks.
31 
32  self._r.setopt(self._r.CONNECTTIMEOUT, timeout)
33  user_agent = "User-Agent: ConditionWebServices/1.0 python/%d.%d.%d PycURL/%s" % (sys.version_info[ :3 ] + (pycurl.version_info()[1],))
34  self._r.setopt(self._r.USERAGENT, user_agent)
35  # we don't need to verify who signed the certificate or who the host is
36  self._r.setopt(self._r.SSL_VERIFYPEER, 0)
37  self._r.setopt(self._r.SSL_VERIFYHOST, 0)
38  self._response = StringIO()
39 
40  if body:
41  if isinstance(body, dict):
42  body = urlencode(body)
43  elif isinstance(body, list):
44  body = json.dumps(body)
45 
46  self._r.setopt(self._r.POSTFIELDS, body)
47 
48  if url_data:
49  if isinstance(url_data, dict):
50  url_data = urlencode(url_data)
51  else:
52  exit("URL data '%s' for request to URL '%s' was not valid - should be a dictionary." % (str(url_data), url))
53 
54  # set the URL with url parameters if they were given
55  self._r.setopt(self._r.URL, url + (("?%s" % url_data) if url_data else ""))
56 
57  if response_stream and not isinstance(response_stream, StringIO):
58  response_stream = StringIO()
59  # copy reference to instance variable
60  self._response = response_stream
61  elif not(response_stream):
62  self._response = StringIO()
63 
64  self._r.setopt(self._r.WRITEFUNCTION, self._response.write)
65 
66  def send(self):
67  failed = True
68  max_retries = 5
69  attempt = 0
70  # retry while we're within the limit for the number of retries
71  while failed and attempt < max_retries:
72  try:
73  self._r.perform()
74  failed = False
75  self._r.close()
76  return self._response.getvalue()
77  except Exception as e:
78  failed = True
79  attempt += 1
80  # this catches exceptions that occur with the actual http request
81  # not exceptions sent back from server side
82  if isinstance(e, pycurl.error) and e[0] in [7, 52]:
83  # wait two seconds to retry
84  print("Request failed - waiting 3 seconds to retry.")
85  sleep(3)
86  # do nothing for now
87  pass
88  else:
89  print("Unforesoon error occurred when sending data to server.")
90  traceback.print_exc()
91  if attempt == max_retries:
92  raise NoMoreRetriesException(max_retries)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def send(self)
Definition: url_query.py:66
def __init__(self, url=None, url_data=None, body=None, response_stream=None, timeout=60)
Definition: url_query.py:23
#define str(s)
def exit(msg="")