easyBay

py.

News

March 22nd, 2006: Do you have questions or tips about using easyBay? Check out
                  the easyBay group (optional mailing list) at Google Groups!

March 18th, 2006: A sample ebay.ini file is now in the trunk.

March 6th, 2006: Clepy presentation is online. View the slides.

March 5th, 2006: Grab easyBay from the trunk:
                   svn co http://svn.brianbeck.com/easyBay/trunk
                 Or from the Cheese Shop:
                   http://python.org/pypi/easyBay

py.

Basic Usage

# Want a prettier introduction to easyBay?
#   Then check out the presentation Talking to eBay with Python.

# Confused by anything here?
#   Maybe we can help on the mailing list.

# Still here? Here we go...

from easyBay import eBay

# ebay.ini stores things like your developer key, token, etc.
# You could also pass those in as arguments to eBay()

api = eBay(config="ebay.ini")

response = api.GetItem(ItemID=5052303617)

# Where GetItem is any call available in eBay's XML API,
# and the keyword arguments are any input field for that call

# See developer.ebay.com for an API reference

# Get elements of the XML response using attribute access

print response.Item.Title

r = response # Long names get me down

# You can also loop over elements

for url in r.Item.SiteHostedPicture.PictureURL:
    print url # Items can have multiple pictures

# It's really safe, working even for non-existent or single elements

for title in r.Item.Title:
   print "This will only print once."

for fake in r.Item.FakeAttribute:
   print "This will never print."

# You don't have to worry about catching exceptions for accessing nodes
# that aren't there. Just check to see if they are non-zero if there's
# any doubt (usually there won't be)

if r.Item.FakeAttribute:
    print "This will never print."

if r.Item.Title:
   print "This will print."

# Leaf nodes are actually fancy strings

if isinstance(r.Item.Title, unicode):
   print "This will print."

# ...that still don't freak out when you try to access a subelement

if r.Item.Title.Whoa:
   print "This won't raise an exception, but won't print."

# If the XML element has an attribute, access it like a dictionary
# <CurrentPrice currencyID="USD">32.99</CurrentPrice>

print r.Item.SellingStatus.CurrentPrice, \
      r.Item.SellingStatus.CurrentPrice['currencyID'] # 32.99 USD

# "Uh-oh," you ask, "but won't that override string slicing and stuff?"
# Nope, the normal __getitem__ behavior still works too

print r.Item.SellingStatus.CurrentPrice[0] # 3
print r.Item.SellingStatus.CurrentPrice[2:] # .99
dollars, cents = r.Item.SellingStatus.CurrentPrice.split('.')

py.

Advanced Usage

# Now for something a little fancier, like the time of the first
# bid for that last item we retrieved

# DateISO is just an alias for mx.DateTime.ISO.ParseDateTimeUTC

r = api.GetAllBidders(ItemID=r.Item.ItemID, CallMode='ViewAll')
firstBid = min(DateISO(offer.TimeBid) for offer in r.BidArray.Offer)

# How many days has it been since the first bid?

print (DateTime.now() - firstBid.localtime()).days

py.

Exceptions

# Handling exceptions is simple

try:
    # This will raise an error, I forgot to put ItemID= so no
    # arguments will be passed into the request
    r = api.GetItem(5052303617)
except eBay.RequestError, e:
    print e.ErrorCode, e.ShortMessage
    print dir(e) # There are a few more fields too

# There's also a SystemError. If you want to catch both, catch eBayError

# The exceptions are tucked away in the eBay class to avoid naming conflicts
# and namespace pollution (SystemError is already a built-in exception)

class eBay(object):
    class eBayError(Exception):
        ...
    class RequestError(eBayError):
        ...
    class SystemError(eBayError):
        ....

# You probably won't ever raise your own eBayError, only catch them
# They are raised automatically based on the result of the request

# See: http://developer.ebay.com/DevZone/XML/docs/Support/ErrorMessages.htm

py.

return types

# There are only a few element types you have to worry about
# Strings, integers, decimals, booleans, and dates
# Everything is a unicode string by default, since it's XML

# The first few are easy

title = r.Item.Title # Unicode string
title = str(r.Item.Title) # If something isn't unicode-aware

bidCount = int(r.Item.SellingStatus.BidCount)
price = float(r.Item.SellingStatus.ConvertedCurrentPrice)

# eBay returns booleans as 'true', 'false', '0', or '1'
# However, bool('false') returns True because it's a non-empty string
# So the quickest way is to title-case whatever it is and eval it

reserveMet = eval(r.Item.SellingStatus.ReserveMet.title())

# Or use this utility function to do the same thing

reserveMet = makeBool(r.Item.SellingStatus.ReserveMet)

# Use that DateISO alias I mentioned before to convert dates
# It's an alias for mx.DateTime.ISO.ParseDateTimeUTC if you like typing

startTime = DateISO(r.Item.ListingDetails.StartTime)

# If I wanted to store and parse the entire eBay XML schema, I could
# make it do all these conversions automatically, but right now this
# framework assumes no information about the API and I'd like to keep
# it that way

py.

more examples

# Here's an example of initializing the API without a config file

from API import eBay

api = eBay(dev='12345', app='67890', cert='ABCDE', token='FGHIJ')

# You can change things around even after initialization

api._app = 'KLMNO'
api._token = 'PQRST'
api._server = 'api.sandbox.ebay.com'

# Search for iPod listings ending within the next day

from mx import DateTime # http://www.egenix.com/files/python/mxDateTime.html

thisTimeTomorrow = DateTime.now().gmtime() + DateTime.oneDay

response = api.GetSearchResults(Query="iPod", EndTimeTo=thisTimeTomorrow)
results = response.SearchResultItemArray.SearchResultItem

for result in results:
    item = result.Item
    print "Item: (%s) %s" % (item.ItemID, item.Title)
    print "Price: %.2f %s" % (float(item.SellingStatus.CurrentPrice),
                              item.SellingStatus.CurrentPrice['currencyID'])