Source code for CMSToolBox.webtools

# pylint: disable=protected-access, unexpected-keyword-arg, bad-option-value, redefined-variable-type, too-many-locals

"""
A high-level module for getting JSON information from web services.
The HTTP vs HTTPS and certificate handling is done here.

:author: Daniel Abercrombie <dabercro@mit.edu>
"""


import os
import time
import re
import stat
import json
import httplib
import ssl
import urllib
import subprocess


[docs]def get_json(host, request, params='', body='', headers=None, port=None, retries=3, **kwargs): """ Function for getting JSON from a URL that handles the connection and certificates with just a couple of bools. :param str host: The name of the host to connect to :param str request: The request to make to the host :param dict params: The parameters to pass to the request :param str body: The body to send in a POST request :param dict headers: Headers to pass to request. If ``None``, ``{'Accept': 'application/json'}`` will be passed. :param int port: The port to access, if a not default value :param int retries: The number of times to try to get the JSON response before giving up :param kwargs: Additional aruments that can be used to change the connection behavior. These are listed below: - use_https (bool) - Uses HTTP connection by default - use_cert (bool) - Does not pass a certificate by default - cert_file (str) - Default is ``$X509_USER_PROXY``. - use_post (bool) - Determines whether to use POST or GET. - cookie_file (str) - Location of a Shibboleth cookie to pass in header - cookie_pem (str) - Location of ``.pem`` file to generate cookie - cookie_key (str) - Location of ``.rsa`` key to generate cookie - cookie_time (float) - Time, in seconds, until generating a new cookie :returns: The JSON from the query :rtype: dict """ check_for_port = host.split(':') if len(check_for_port) == 2: host = check_for_port[0] port = int(check_for_port[1]) use_cert = kwargs.get('use_cert', False) use_https = kwargs.get('use_https', use_cert or bool(kwargs.get('cookie_file'))) if use_https: use_port = port or 443 cert_file = kwargs.get('cert_file', os.getenv('X509_USER_PROXY')) \ if use_cert else None # Python 2.7.something verifies HTTPS connections, # but earlier version of Python do not try: conn = httplib.HTTPSConnection( host, use_port, cert_file=cert_file, key_file=cert_file, context=ssl._create_unverified_context()) except AttributeError: conn = httplib.HTTPSConnection( host, use_port, cert_file=cert_file, key_file=cert_file) else: use_port = port or 80 conn = httplib.HTTPConnection(host, use_port) method = "POST" if kwargs.get('use_post', bool(body)) else "GET" full_request = '%s?%s' % (request, urllib.urlencode(params)) if params else request header = headers or {'Accept': 'application/json'} if kwargs.get('cookie_file'): sso_request_url = 'https://%s:%i%s' % (host, use_port, full_request) header['Cookie'] = get_cookie_header(sso_request_url, kwargs['cookie_file'], kwargs.get('cookie_pem'), kwargs.get('cookie_key'), kwargs.get('cookie_time'))[host] tries = 0 while tries <= retries: conn.request( method, full_request, json.dumps(body), header) res = conn.getresponse() if res.status == 200: result = json.loads(res.read()) conn.close() return result print("STATUS", res.status, "REASON", res.reason) tries += 1 conn.close() return {}