NewsBlur-viq/vendor/paypalapi/response.py

113 lines
3.9 KiB
Python
Executable file

# coding=utf-8
"""
PayPalResponse parsing and processing.
"""
import logging
from pprint import pformat
from vendor.paypalapi.compat import is_py3
from urllib.parse import parse_qs
logger = logging.getLogger('paypal.response')
class PayPalResponse(object):
"""
Parse and prepare the reponse from PayPal's API. Acts as somewhat of a
glorified dictionary for API responses.
NOTE: Don't access self.raw directly. Just do something like
PayPalResponse.someattr, going through PayPalResponse.__getattr__().
"""
def __init__(self, query_string, config):
"""
query_string is the response from the API, in NVP format. This is
parseable by urlparse.parse_qs(), which sticks it into the
:attr:`raw` dict for retrieval by the user.
:param str query_string: The raw response from the API server.
:param PayPalConfig config: The config object that was used to send
the query that caused this response.
"""
# A dict of NVP values. Don't access this directly, use
# PayPalResponse.attribname instead. See self.__getattr__().
self.raw = parse_qs(query_string)
self.config = config
logger.debug("PayPal NVP API Response:\n%s" % self.__str__())
def __str__(self):
"""
Returns a string representation of the PayPalResponse object, in
'pretty-print' format.
:rtype: str
:returns: A 'pretty' string representation of the response dict.
"""
return pformat(self.raw)
def __getattr__(self, key):
"""
Handles the retrieval of attributes that don't exist on the object
already. This is used to get API response values. Handles some
convenience stuff like discarding case and checking the cgi/urlparsed
response value dict (self.raw).
:param str key: The response attribute to get a value for.
:rtype: str
:returns: The requested value from the API server's response.
"""
# PayPal response names are always uppercase.
key = key.upper()
try:
value = self.raw[key]
if len(value) == 1:
# For some reason, PayPal returns lists for all of the values.
# I'm not positive as to why, so we'll just take the first
# of each one. Hasn't failed us so far.
return value[0]
return value
except KeyError:
# The requested value wasn't returned in the response.
raise AttributeError(self)
def __getitem__(self, key):
"""
Another (dict-style) means of accessing response data.
:param str key: The response key to get a value for.
:rtype: str
:returns: The requested value from the API server's response.
"""
# PayPal response names are always uppercase.
key = key.upper()
value = self.raw[key]
if len(value) == 1:
# For some reason, PayPal returns lists for all of the values.
# I'm not positive as to why, so we'll just take the first
# of each one. Hasn't failed us so far.
return value[0]
return value
def items(self):
items_list = []
for key in list(self.raw.keys()):
items_list.append((key, self.__getitem__(key)))
return items_list
def iteritems(self):
for key in list(self.raw.keys()):
yield (key, self.__getitem__(key))
def success(self):
"""
Checks for the presence of errors in the response. Returns ``True`` if
all is well, ``False`` otherwise.
:rtype: bool
:returns ``True`` if PayPal says our query was successful.
"""
return self.ack.upper() in (self.config.ACK_SUCCESS,
self.config.ACK_SUCCESS_WITH_WARNING)
success = property(success)