1. Kumar McMillan
  2. ebay


ebay / ebay / api.py

import sys
import urllib
import time
import warnings
from ebay import transport
from ebay.etree import ET
from ebay.exc import EbayAPIError, EbayInvalidItemID, EbayHTTPError

class XMLNamespace(object):
    def __init__(self, namespace):
        self.namespace = namespace
    def __call__(self, path_parts):
        """out of path parts return a namespaced path."""
        ns_sep = "{%s}" % self.namespace
        path = ns_sep + ("/" + ns_sep).join(path_parts)
        return path

NS = XMLNamespace('urn:ebay:apis:eBLBaseComponents')

__all__ = ['ShoppingAPI']

class EbayAPI(object):
    """Base class for objects that connects to the Ebay API.
    See http://developer.ebay.com/
    # this can be set to "latest" if you are fearless
    api_version = '607'
    def __init__(self, appid, failed_req_sleep_time=1.0, sandbox=False, api_version=None):
        if api_version:
            if api_version != self.api_version:
                warnings.warn("Only tested with API version %s (might not work with %s)" % (
                                                                self.api_version, api_version))
            self.api_version = api_version
        if appid is None:
            raise TypeError("appid cannot be None")
        self.api_hits = 0
        self.appid = appid
        self.failed_req_sleep_time = failed_req_sleep_time
        # is this host just for the shopping API?
        if sandbox:
            self.host = "open.api.sandbox.ebay.com"
            self.host = "open.api.ebay.com"
        self.protocol = "http"
    def _object_from_response(self, response, ResponseClass):
        tree = ET.parse(response)
        return ResponseClass(response=response, tree=tree)
    def request(self, resource, ResponseClass=None, **params):
        """Make an HTTP GET request to the Ebay API.
        Per the `Compatibility Checklist`_, this will retry errors a
        maximum of two times. 
        :returns: file-like object (response) *or* a response wrapped in ResponseClass if not None.
        .. _Compatibility Checklist: http://developer.ebay.com/support/certification/Default.aspx
        if resource[0] == "/":
            resource = resource[1:]
        # todo: switch to non-leaky urllib2 (for older Pythons)
        url = "%s://%s/%s?%s" % (self.protocol, self.host, resource, urllib.urlencode(params))
        def try_request():
            response = transport.urlopen(url)
            # only count successful hits because that's probably 
            # how ebay quota works.
            self.api_hits += 1
            if ResponseClass:
                return self._object_from_response(response, ResponseClass)
                return response
        res = None
        exc = None
            res = try_request()
        except Exception, exc:
            # todo: log this?  do we care?
            return res
        # second try:
            res = try_request()
        except EbayAPIError:
        except Exception, exc:
            etype, val, tb = sys.exc_info()
            raise EbayHTTPError("%s: %s" % (exc.__class__.__name__, exc)), None, tb
            return res