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'])