def http_request(cls, url, method='GET', body=None, headers=None): """Make an HTTP request with the given method to the given URL, returning the resulting `httplib.HTTPResponse` instance. If the `body` argument is a `Resource` instance, it is serialized to XML by calling its `to_element()` method before submitting it. Requests are authenticated per the Recurly API specification using the ``recurly.API_KEY`` value for the API key. Requests and responses are logged at the ``DEBUG`` level to the ``recurly.http.request`` and ``recurly.http.response`` loggers respectively. """ urlparts = urlsplit(url) headers = {} if headers is None else dict(headers) headers.update({ 'Accept': 'application/xml', 'User-Agent': 'recurly-python/%s' % recurly.__version__, }) if recurly.API_KEY is None: raise recurly.UnauthorizedError('recurly.API_KEY not set') headers['Authorization'] = 'Basic %s' % base64.b64encode( '%s:' % recurly.API_KEY) log = logging.getLogger('recurly.http.request') if log.isEnabledFor(logging.DEBUG): log.debug("%s %s HTTP/1.1", method, url) for header, value in headers.iteritems(): if header == 'Authorization': value = '<redacted>' log.debug("%s: %s", header, value) log.debug('') if method in ('POST', 'PUT') and body is not None: if isinstance(body, Resource): log.debug(body.as_log_output()) else: log.debug(body) if isinstance(body, Resource): body = ElementTree.tostring(body.to_element(), encoding='UTF-8') headers['Content-Type'] = 'application/xml; charset=utf-8' if method in ('POST', 'PUT') and body is None: headers['Content-Length'] = '0' resp = urlfetch.fetch(url=url, payload=body, method=cls._get_urlfetch_method(method), headers=headers) log = logging.getLogger('recurly.http.response') if log.isEnabledFor(logging.DEBUG): log.debug("HTTP/1.1 %d %s", str(resp.status_code)) for header in resp.headers: log.debug(str(header) + ' : ' + str(resp.headers[header])) log.debug('') return resp
def http_request(cls, url, method='GET', body=None, headers=None): """Make an HTTP request with the given method to the given URL, returning the resulting `http_client.HTTPResponse` instance. If the `body` argument is a `Resource` instance, it is serialized to XML by calling its `to_element()` method before submitting it. Requests are authenticated per the Recurly API specification using the ``recurly.API_KEY`` value for the API key. Requests and responses are logged at the ``DEBUG`` level to the ``recurly.http.request`` and ``recurly.http.response`` loggers respectively. """ if recurly.API_KEY is None: raise recurly.UnauthorizedError('recurly.API_KEY not set') headers = {} if headers is None else dict(headers) headers.setdefault('Accept', 'application/xml') headers.update({'User-Agent': recurly.USER_AGENT}) headers['X-Api-Version'] = recurly.api_version() headers['Authorization'] = 'Basic %s' % base64.b64encode( six.b('%s:' % recurly.API_KEY)).decode() if isinstance(body, Resource): body = ElementTree.tostring(body.to_element(), encoding='UTF-8') headers['Content-Type'] = 'application/xml; charset=utf-8' if method in ('POST', 'PUT') and body is None: headers['Content-Length'] = '0' print(body) resp = requests.get(url, headers=headers) print(resp) resp_headers = resp.headers recurly.cache_rate_limit_headers(resp_headers) return resp
def test_error_printable(self): """ Make sure __str__/__unicode__ works correctly in Python 2/3""" str(recurly.UnauthorizedError('recurly.API_KEY not set'))
def http_request(cls, url, method='GET', body=None, headers=None): """Make an HTTP request with the given method to the given URL, returning the resulting `http_client.HTTPResponse` instance. If the `body` argument is a `Resource` instance, it is serialized to XML by calling its `to_element()` method before submitting it. Requests are authenticated per the Recurly API specification using the ``recurly.API_KEY`` value for the API key. Requests and responses are logged at the ``DEBUG`` level to the ``recurly.http.request`` and ``recurly.http.response`` loggers respectively. """ if recurly.API_KEY is None: raise recurly.UnauthorizedError('recurly.API_KEY not set') is_non_ascii = lambda s: any(ord(c) >= 128 for c in s) if is_non_ascii(recurly.API_KEY) or is_non_ascii(recurly.SUBDOMAIN): raise recurly.ConfigurationError("""Setting API_KEY or SUBDOMAIN to unicode strings may cause problems. Please use strings. Issue described here: https://gist.github.com/maximehardy/d3a0a6427d2b6791b3dc""" ) urlparts = urlsplit(url) connection_options = {} if recurly.SOCKET_TIMEOUT_SECONDS: connection_options['timeout'] = recurly.SOCKET_TIMEOUT_SECONDS if urlparts.scheme != 'https': connection = http_client.HTTPConnection(urlparts.netloc, **connection_options) elif recurly.CA_CERTS_FILE is None: connection = http_client.HTTPSConnection(urlparts.netloc, **connection_options) else: connection_options['context'] = ssl.create_default_context( cafile=recurly.CA_CERTS_FILE) connection = http_client.HTTPSConnection(urlparts.netloc, **connection_options) headers = {} if headers is None else dict(headers) headers.setdefault('Accept', 'application/xml') headers.update({'User-Agent': recurly.USER_AGENT}) headers['X-Api-Version'] = recurly.api_version() headers['Authorization'] = 'Basic %s' % base64.b64encode( six.b('%s:' % recurly.API_KEY)).decode() log = logging.getLogger('recurly.http.request') if log.isEnabledFor(logging.DEBUG): log.debug("%s %s HTTP/1.1", method, url) for header, value in six.iteritems(headers): if header == 'Authorization': value = '<redacted>' log.debug("%s: %s", header, value) log.debug('') if method in ('POST', 'PUT') and body is not None: if isinstance(body, Resource): log.debug(body.as_log_output()) else: log.debug(body) if isinstance(body, Resource): body = ElementTree.tostring(body.to_element(), encoding='UTF-8') headers['Content-Type'] = 'application/xml; charset=utf-8' if method in ('POST', 'PUT') and body is None: headers['Content-Length'] = '0' connection.request(method, url, body, headers) resp = connection.getresponse() resp_headers = cls.headers_as_dict(resp) log = logging.getLogger('recurly.http.response') if log.isEnabledFor(logging.DEBUG): log.debug("HTTP/1.1 %d %s", resp.status, resp.reason) log.debug(resp_headers) log.debug('') recurly.cache_rate_limit_headers(resp_headers) return resp
def http_request(cls, url, method='GET', body=None, headers=None): """Make an HTTP request with the given method to the given URL, returning the resulting `http_client.HTTPResponse` instance. If the `body` argument is a `Resource` instance, it is serialized to XML by calling its `to_element()` method before submitting it. Requests are authenticated per the Recurly API specification using the ``recurly.API_KEY`` value for the API key. Requests and responses are logged at the ``DEBUG`` level to the ``recurly.http.request`` and ``recurly.http.response`` loggers respectively. """ urlparts = urlsplit(url) if urlparts.scheme != 'https': connection = http_client.HTTPConnection(urlparts.netloc, timeout=120) elif recurly.CA_CERTS_FILE is None: connection = http_client.HTTPSConnection(urlparts.netloc, timeout=120) else: connection = _ValidatedHTTPSConnection(urlparts.netloc, timeout=120) headers = {} if headers is None else dict(headers) headers.update({ 'Accept': 'application/xml', 'User-Agent': 'recurly-python/%s' % recurly.__version__, }) if recurly.API_KEY is None: raise recurly.UnauthorizedError('recurly.API_KEY not set') headers['Authorization'] = 'Basic %s' % base64.b64encode( six.b('%s:' % recurly.API_KEY)).decode() log = logging.getLogger('recurly.http.request') if log.isEnabledFor(logging.DEBUG): log.debug("%s %s HTTP/1.1", method, url) for header, value in six.iteritems(headers): if header == 'Authorization': value = '<redacted>' log.debug("%s: %s", header, value) log.debug('') if method in ('POST', 'PUT') and body is not None: if isinstance(body, Resource): log.debug(body.as_log_output()) else: log.debug(body) if isinstance(body, Resource): body = ElementTree.tostring(body.to_element(), encoding='UTF-8') headers['Content-Type'] = 'application/xml; charset=utf-8' if method in ('POST', 'PUT') and body is None: headers['Content-Length'] = '0' connection.request(method, url, body, headers) resp = connection.getresponse() log = logging.getLogger('recurly.http.response') if log.isEnabledFor(logging.DEBUG): log.debug("HTTP/1.1 %d %s", resp.status, resp.reason) if six.PY2: for header in resp.msg.headers: log.debug(header.rstrip('\n')) else: log.debug(resp.msg._headers) log.debug('') return resp