Wiki

Clone wiki

premix / Home

Introduction

Premix provides an easy to use Python wrapper around the Best Buy Remix APIs. It also runs on Google App Engine.

Quick Start

If you prefer examples over prose, feel free to skip to the Usage section below for examples that cover most aspects of the API.

Still with me? Here are the highlights.

There are two main classes that you'll work with: premix.StoreQuery and premix.ProductQuery.

The class method all() on the query classes gives you a new query object that will return all stores and products respectively. You can get a single store query by its store id by using the StoreQuery.id() method. You can get a single product by its sku by using the ProductQuery.sku() method.

You can narrow or expand the results returned by applying conditionals with the filter() ("AND") and extend() ("OR") methods. Both methods takes 2 parameters. The first parameter is a conditional string of the form 'store_id >'. The conditional string consists of an attribute name followed by a space and then one of the conditional operators: =, !=, <>, <, <=, >, >=. The space is required. The second parameter to the filter() and extend() methods are the value to compare against the conditional string. Wildcards (*) are allowed in strings and dates should be strings of the format YYYY-MM-DD.

The filter() conditions are applied by and-ing and the extend() conditions are applied by or-ing. In this way, complex queries can be constructed. The first conditional applied is considered a filter() even if it is applied with extend() (because you can't really extend the results returned from the all() query).

Applying a conditional doesn't modify the existing query object, but instead returns a new query object with the new conditional applied. In this way, you can build up multiple conditionals for a query.

For a store query, you can use the area() method to apply a geographic filter. It takes a postal code and a radius in miles.

To query for store/product availability you can combine a StoreQuery and a ProductQuery by using either the products() method or the stores() method respectively. This doesn't modify the existing query, but returns a copy with the "joined" query added to any existing filters.

You can order the results by passing the attribute name you wish to sort by to the order() method. If you wish to reverse the order, preface the attribute name with a '-' (dash). The order() method returns a new query, leaving the existing query unmodified.

You can limit the attributes returned for the results by passing a list of attributes to the show() method. Again, this doesn't modify the existing query, but returns a copy with the new show attributes set.

You run a query by calling its fetch() method. This method requires that you pass it a Best Buy Remix API key. You can also specify the page number of results you'd like returned, a Commission Junction ID, pid to construct bestbuy.com URLs with, and finally you can specify the number of times to retry the query if there's a problem.

The result of fetching a query is either a StoreQueryResults or ProductQueryResults object. This object will contain meta information about the query like the total number of results, and a list of stores or products depending on the type of query. In addition, there are two convenience properties on the results object, next and previous which will return the next and previous page results object (if there is one, else None). It will fetch() using the same query and parameters as those used to fetch the initial results.

The Store and Product objects contain the returned attributes as properties on the class, but the property names are converted from their Remix camel case names into PEP8 (lowercase with underscores). For example, the store attribute 'postalCode' is accessed by the Store property, postal_code. You can get a list of available attributes from the attributes property on Store and Product instances.

Usage

Store

Query All Stores

>>> from premix import StoreQuery
>>> api_key = '123456790123456789012345'
>>> store_query = StoreQuery.all()
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores?format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/stores?format=json&apiKey=123456790123456789012345'
>>> results.canonical_url
'/v1/stores?format=json&apiKey=123456790123456789012345'
>>> results.query_time
'0.004'
>>> results.total_time
'0.004'
>>> results.total
1052
>>> results.total_pages
106
>>> results.current_page
1
>>> results.begin
1
>>> results.end
10
>>> results.stores
[<premix.Store object at 0x2759f0>, <premix.Store object at 0x275b50>, <premix.Store object at 0x275cb0>, <premix.Store object at 0x275e10>, <premix.Store object at 0x275f70>, <premix.Store object at 0x27a0f0>, <premix.Store object at 0x27a250>, <premix.Store object at 0x27a3b0>, <premix.Store object at 0x27a510>, <premix.Store object at 0x27a670>]

Store Object

>>> store = results.stores[0]
>>> store.attributes
['address', 'city', 'country', 'full_postal_code', 'hours', 'lat', 'lng', 'name', 'phone', 'postal_code', 'region', 'store_id']
>>> store.store_id
1504
>>> store.city
'Caguas'
>>> store.name
'Caguas, PR'
>>> store.region
'PR'
>>> store.address
'Las Catalinas Mall'
>>> store.country
'US'
>>> store.postal_code
'00725'
>>> store.full_postal_code
'00725'
>>> store.lng
-66.034454
>>> store.lat
18.205647
>>> store.phone
'787-258-0110'
>>> store.hours
'10:00am - 9:00pm Monday - Friday, 11:00am - 6:00pm Saturday, 11:00am - 6:00pm Sunday'

Store Query Paging

>>> store_query.url(api_key, page=2)
'http://api.remix.bestbuy.com/v1/stores?page=2&format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key, page=2)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/stores?page=2&format=json&apiKey=123456790123456789012345'
>>> results.canonical_url
'/v1/stores?page=2&format=json&apiKey=123456790123456789012345'
>>> results.total_pages
106
>>> results.current_page
2
>>> results.begin
11
>>> results.end
20
>>> results.stores
[<premix.Store object at 0x2819f0>, <premix.Store object at 0x281b50>, <premix.Store object at 0x281cb0>, <premix.Store object at 0x281e10>, <premix.Store object at 0x281f70>, <premix.Store object at 0x2820f0>, <premix.Store object at 0x282250>, <premix.Store object at 0x2823b0>, <premix.Store object at 0x282510>, <premix.Store object at 0x282670>]

Store Query Paging Properties

>>> initial_results = store_query.fetch(api_key)
>>> initial_results.query_url
'http://api.remix.bestbuy.com/v1/stores?format=json&apiKey=123456790123456789012345'
>>> initial_results.canonical_url
'/v1/stores?format=json&apiKey=123456790123456789012345'
>>> initial_results.current_page
1
>>> initial_results.previous
None
>>> results = initial_results.next
>>> results.query_url
'http://api.remix.bestbuy.com/v1/stores?page=2format=json&apiKey=123456790123456789012345'
>>> results.canonical_url
'/v1/stores?page=2&format=json&apiKey=123456790123456789012345'
>>> results.total_pages
106
>>> results.current_page
2
>>> results.begin
11
>>> results.end
20
>>> previous_results = results.previous
>>> previous_results.query_url
'http://api.remix.bestbuy.com/v1/stores?format=json&apiKey=123456790123456789012345'
>>> previous_results.canonical_url
'/v1/stores?format=json&apiKey=123456790123456789012345'
>>> previous_results.current_page
1

Show Only Certain Fields

>>> store_query = StoreQuery.all().show(['address', 'city', 'postal_code'])
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores?show=address%2Ccity%2CpostalCode&format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/stores?show=address%2Ccity%2CpostalCode&format=json&apiKey=123456790123456789012345'
>>> results.stores
[<premix.Store object at 0x438950>, <premix.Store object at 0x71bb90>, <premix.Store object at 0x71bb10>, <premix.Store object at 0x71ba50>, <premix.Store object at 0x71b890>, <premix.Store object at 0x2759b0>, <premix.Store object at 0x275c90>, <premix.Store object at 0x275c50>, <premix.Store object at 0x275bd0>, <premix.Store object at 0x275cb0>]
>>> store = results.stores[0]
>>> store.attributes
['address', 'city', 'postal_code']
>>> store.address
'Las Catalinas Mall'
>>> store.city
'Caguas'
>>> store.postal_code
'00725'
>>> store.store_id
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "premix.py", line 382, in __getattr__
    raise AttributeError, name
AttributeError: store_id
>>> store.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "premix.py", line 382, in __getattr__
    raise AttributeError, name
AttributeError: name
>>> store_query_show_default = store_query.show_default() #Gimme the usual.
>>> results = store_query_show_default.fetch(api_key)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/stores?format=json&apiKey=123456790123456789012345'
>>> store = results.stores[0]
>>> store.attributes
['address', 'city', 'country', 'full_postal_code', 'hours', 'lat', 'lng', 'name', 'phone', 'postal_code', 'region', 'store_id']

Get Store By ID

>>> store_query = StoreQuery.id(4)
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores/4.json?apiKey=12345'
>>> store = store_query.fetch(api_key, retry=3)
>>> store
<premix.Store object at 0x275af0>
>>> store_query = StoreQuery.id(999999)
>>> store = store_query.fetch(api_key)
>>> store is None
True

Query Store By Area And Distance

>>> store_query = StoreQuery.all().area(55405, 10).show(['name', 'distance'])
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(area(55405,10))?show=name%2Cdistance&format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.total_pages
1
>>> results.total
10
>>> store = results.stores[0]
>>> store.name
'Brooklyn Center Minneapolis'
>>> store.distance
6.0999999999999996

Query With Single Filter

>>> store_query = StoreQuery.all().filter('postal_code =', '787*')
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(postalCode=787%2A)?format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.total_pages
1
>>> results.total
5
>>> results.current_page
1
>>> results.begin
1
>>> results.end
5
>>> results.stores
[<premix.Store object at 0x27d110>, <premix.Store object at 0x27d270>, <premix.Store object at 0x27d3d0>, <premix.Store object at 0x27d530>, <premix.Store object at 0x27d690>]

Query With Filter and Extend

>>> store_query = StoreQuery.all().filter('postal_code =', '787*').extend('city =', 'Edina')
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(postalCode=787%2A|city=Edina)?format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.total
6
>>> results.stores
[<premix.Store object at 0x27d990>, <premix.Store object at 0x27daf0>, <premix.Store object at 0x27dc50>, <premix.Store object at 0x27ddb0>,
<premix.Store object at 0x27deb0>, <premix.Store object at 0x27ddc0>]

Query With Multiple Filters And Sort

>>> store_query = StoreQuery.all().filter('postal_code =', '787*').filter('city =', 'Austin').order('-postal_code')
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(postalCode=787%2A&city=Austin)?sort=postalCode.desc&format=json&apiKey=123456790123456789012345'
>>> results = store_query.fetch(api_key)
>>> results.total
4
>>> results.stores
[<premix.Store object at 0x27d990>, <premix.Store object at 0x27daf0>, <premix.Store object at 0x27dc50>, <premix.Store object at 0x27ddb0>]
>>> results = store_query.fetch(api_key, page=2)
>>> results.total_pages
1
>>> results.total
4
>>> results.current_page
2
>>> results.begin
11
>>> results.end
4
>>> results.stores
[]

Product

Query All Products

>>> from premix import ProductQuery
>>> product_query = ProductQuery.all()
>>> product_query.url(api_key)
'http://api.remix.bestbuy.com/v1/products?format=json&apiKey=123456790123456789012345'
>>> results = product_query.fetch(api_key)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/products?format=json&apiKey=123456790123456789012345'
>>> results.canonical_url
'/v1/products?format=json&apiKey=123456790123456789012345'
>>> results.query_time
'0.128'
>>> results.total_time
'0.152'
>>> results.total
452394
>>> results.total_pages
45240
>>> results.current_page
1
>>> results.begin
1
>>> results.end
10
>>> results.products
[<premix.Product object at 0x28e850>, <premix.Product object at 0x28e9f0>, <premix.Product object at 0x28eb90>, <premix.Product object at 0x28ed30>, <premix.Product object at 0x28eed0>, <premix.Product object at 0x291090>, <premix.Product object at 0x291230>, <premix.Product object at 0x2913d0>, <premix.Product object at 0x291570>, <premix.Product object at 0x291710>]

Product Object

>>> product = results.products[0]
>>> product.attributes
['accessories_image', 'active', 'active_update_date', 'add_to_cart_url', 'affiliate_add_to_cart_url', 'affiliate_url', 'album_title', 'alternate_views_image', 'angle_image', 'artist_id', 'artist_name', 'back_view_image', 'category_path', 'cj_affiliate_add_to_cart_url', 'cj_affiliate_url', 'class', 'class_id', 'customer_review_average', 'customer_review_count', 'department', 'department_id', 'energy_guide_image', 'format', 'free_shipping', 'image', 'in_store_availability', 'in_store_availability_text', 'in_store_availability_update_date', 'item_update_date', 'large_front_image', 'large_image', 'left_view_image', 'medium_image', 'name', 'new', 'online_availability', 'online_availability_text', 'online_availability_update_date', 'original_release_date', 'parental_advisory', 'price_update_date', 'print_only', 'product_id', 'regular_price', 'release_date', 'remote_control_image', 'right_view_image', 'sale_price', 'shipping_cost', 'short_description', 'sku', 'special_order', 'start_date', 'subclass', 'subclass_id', 'thumbnail_image', 'top_view_image', 'type', 'upc', 'url']
>>> product.sku
15206162
>>> product.product_id
675935
>>> product.department
'VIDEO/COMPACT DISC'
>>> product.url
'http://www.bestbuy.com/site/olspage.jsp?skuId=15206162&type=product&id=675935'

Product Query Paging

>>> product_query.url(api_key, page=2)
'http://api.remix.bestbuy.com/v1/products?page=2&format=json&apiKey=123456790123456789012345'
>>> results = product_query.fetch(api_key, page=2)
>>> results.query_url
'http://api.remix.bestbuy.com/v1/products?page=2&format=json&apiKey=123456790123456789012345'
>>> results.canonical_url
'/v1/products?page=2&format=json&apiKey=123456790123456789012345'
>>> results.total_pages
45240
>>> results.current_page
2
>>> results.begin
11
>>> results.end
20
>>> results.products
[<premix.Product object at 0x27acd0>, <premix.Product object at 0x27a030>, <premix.Product object at 0x27a4d0>, <premix.Product object at 0x27a5b0>, <premix.Product object at 0x287110>, <premix.Product object at 0x2872b0>, <premix.Product object at 0x287450>, <premix.Product object at 0x2875f0>, <premix.Product object at 0x287790>, <premix.Product object at 0x287930>]

Get Product By SKU With All Fields And Include Commission Junction ID

>>> product_query = ProductQuery.sku(8880044).show_all()
>>> product_query.url(api_key, pid=123456)
'http://api.remix.bestbuy.com/v1/products/8880044.json?apiKey=123456790123456789012345&PID=123456'
>>> product = product_query.fetch(api_key, pid=123456)
>>> product.attributes
['accessories_image', 'active', 'active_update_date', 'add_to_cart_url', 'affiliate_add_to_cart_url', 'affiliate_url', 'alternate_views_image', 'amg_rating', 'angle_image', 'aspect_ratio', 'back_view_image', 'cast', 'category_path', 'cj_affiliate_add_to_cart_url', 'cj_affiliate_url', 'class', 'class_id', 'crew', 'customer_review_average', 'customer_review_count', 'department', 'department_id', 'energy_guide_image', 'format', 'free_shipping', 'image', 'in_store_availability', 'in_store_availability_text', 'in_store_availability_update_date', 'item_update_date', 'large_front_image', 'large_image', 'left_view_image', 'length_in_minutes', 'medium_image', 'mpaa_rating', 'name', 'new', 'offers', 'online_availability', 'online_availability_text', 'online_availability_update_date', 'plot', 'price_update_date', 'print_only', 'product_id', 'regular_price', 'related', 'release_date', 'remote_control_image', 'right_view_image', 'sale_price', 'shipping_cost', 'short_description', 'sku', 'special_order', 'start_date', 'studio', 'subclass', 'subclass_id', 'theatrical_release_date', 'thumbnail_image', 'top_view_image', 'type', 'upc', 'url']
>>> product_query = ProductQuery.sku(999999999)
>>> product = product_query.fetch(api_key)
>>> product is None
True

Query With Single Filter

>>> product_query = ProductQuery.all().filter('manufacturer =', 'canon')
>>> product_query.url(api_key)
'http://api.remix.bestbuy.com/v1/products(manufacturer=canon)?format=json&apiKey=123456790123456789012345'
>>> results = product_query.fetch(api_key)
>>> results.total_pages
17
>>> results.total
170
>>> results.current_page
1
>>> results.begin
1
>>> results.end
10
>>> results.products
[<premix.Product object at 0x2a6850>, <premix.Product object at 0x2a6a90>, <premix.Product object at 0x2a6cd0>, <premix.Product object at 0x2a6f10>, <premix.Product object at 0x2ab170>, <premix.Product object at 0x2ab3b0>, <premix.Product object at 0x2ab5f0>, <premix.Product object at 0x2ab830>, <premix.Product object at 0x2aba70>, <premix.Product object at 0x2abcb0>]

Query With Multiple Filters, Sort, and Show Certain Fields

>>> product_query = ProductQuery.all().filter('manufacturer =', 'canon').filter('sale_price <', 33).order('name').show(['sku', 'name'])
>>> product_query.url(api_key)
'http://api.remix.bestbuy.com/v1/products(manufacturer=canon&salePrice<33)?show=sku%2Cname&sort=name&format=json&apiKey=123456790123456789012345'
>>> results = product_query.fetch(api_key)
>>> results.total
49
>>> results.products
[<premix.Product object at 0x27e750>, <premix.Product object at 0x27e7b0>, <premix.Product object at 0x27e810>, <premix.Product object at 0x27e870>, <premix.Product object at 0x27e8d0>, <premix.Product object at 0x27e930>, <premix.Product object at 0x27e990>, <premix.Product object at 0x27e9f0>, <premix.Product object at 0x27ea50>, <premix.Product object at 0x27eab0>]
>>> product = results.products[0]
>>> product.sku
7124104
>>> product.name
'Canon 16 Ink Tank Twin-Pack - Multicolor'
>>> product.department
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "premix.py", line 382, in __getattr__
    raise AttributeError, name
AttributeError: department
>>> results = product_query.fetch(api_key, page=6)
>>> results.total_pages
5
>>> results.total
49
>>> results.current_page
6
>>> results.begin
51
>>> results.end
49
>>> results.products
[]

Store/Product Availability

>>> store_query = StoreQuery.all().area(10010, 20).show(['name', 'distance'])
>>> store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(area(10010,20))?show=name%2Cdistance&format=json&apiKey=123456790123456789012345'
>>> product_query = ProductQuery.all().filter('name =', 'ipod* touch* 32gb*').filter('manufacturer =', 'apple*').show(['name', 'sale_price'])
>>> product_query.url(api_key)
'http://api.remix.bestbuy.com/v1/products(name=ipod%2A%20touch%2A%2032gb%2A&manufacturer=apple%2A)?show=name%2CsalePrice&format=json&apiKey=123456790123456789012345'
>>> store_product_query = store_query.products(product_query)
>>> store_product_query.url(api_key)
'http://api.remix.bestbuy.com/v1/stores(area(10010,20))+products(name=ipod%2A%20touch%2A%2032gb%2A&manufacturer=apple%2A)?show=name%2Cdistance%2Cproducts.name%2Cproducts.salePrice&format=json&apiKey=123456790123456789012345'
>>> results = store_product_query.fetch(api_key)
>>> results.total
18
>>> store = results.stores[0]
>>> store.name
'Chelsea NY'
>>> store.products
[<premix.Product object at 0x27e650>]
>>> product = store.products[0]
>>> product.sale_price
399.99000000000001
>>> product_store_query = product_query.stores(store_query)
>>> product_store_query.url(api_key)
'http://api.remix.bestbuy.com/v1/products(name=ipod%2A%20touch%2A%2032gb%2A&manufacturer=apple%2A)+stores(area(10010,20))?show=name%2CsalePrice%2Cstores.name%2Cstores.distance&format=json&apiKey=123456790123456789012345'
>>> results = product_store_query.fetch(api_key)
>>> results.total
1
>>> product = results.products[0]
>>> product.name
'Apple&#174; iPod&#174; touch 32GB* MP3 Player (1st Generation) - Black'
>>> product.stores
[<premix.Store object at 0x2882d0>, <premix.Store object at 0x288330>, <premix.Store object at 0x288390>, <premix.Store object at 0x2883f0>, <premix.Store object at 0x288450>, <premix.Store object at 0x2884b0>, <premix.Store object at 0x288510>, <premix.Store object at 0x288570>, <premix.Store object at 0x2885d0>, <premix.Store object at 0x288630>, <premix.Store object at 0x288690>, <premix.Store object at 0x2886f0>, <premix.Store object at 0x288750>, <premix.Store object at 0x2887b0>, <premix.Store object at 0x288810>, <premix.Store object at 0x288870>, <premix.Store object at 0x2888d0>, <premix.Store object at 0x288930>]
>>> store = product.stores[0]
>>> store.name
'Chelsea NY'

Error Handling

If a query's fetch() request cannot be completed for any reason, an IOError will be raised.

>>> store_query = StoreQuery.all()
>>> store_query.fetch('notavalidkey') #Nice try, kiddo.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "premix.py", line 229, in fetch
    raise IOError(m['X-Mashery-Error-Code'])
IOError: ERR_403_DEVELOPER_INACTIVE

If the request completes, but the server was unable to successfully run the query (e.g. too many results in an availability query), all of the attributes of the result will return None with the exception of the error info attributes described below.

>>> store_query = StoreQuery.all()
>>> product_query = ProductQuery.all()
>>> product_store_query = product_query.stores(store_query)
>>> results = product_store_query.fetch(api_key) #Umm, I don't think so.
>>> results.total is None
True
>>> results.products is None
True

Error Info

>>> store_query = StoreQuery.all()
>>> results = store_query.fetch(api_key)
>>> results.error_code is None
True
>>> results.error_status is None
True
>>> results.error_message is None
True
>>> results.error is None
True
>>> product_query = ProductQuery.all()
>>> product_store_query = product_query.stores(store_query)
>>> results = product_store_query.fetch(api_key)
>>> results.products is None
True
>>> results.total is None
True
>>> results.error_code
400
>>> results.error_status
'400 Bad Request'
>>> results.error_message
'Sorry, there are too many product matches (> 101).  Please narrow your query.'
>>> results.error
{'status': '400 Bad Request', 'message': 'Sorry, there are too many product matches (> 101).  Please narrow your query.', 'code': 400, 'examples': ['/v1/products/8880044.xml?apiKey=<YourApiKey> : Get product with sku 8880044, as xml', '/v1/products/8880044.json?apiKey=<YourApiKey> : 8880044, as json', '/v1/products/8880044.json?callback=myFunction&apiKey=<YourApiKey> : 8880044, as json, with a JSONP callback', '/v1/products?apiKey=<YourApiKey> : Get the first page of all products, sorted by name, as xml', '/v1/products?format=json&apiKey=<YourApiKey> : The first page of all products, as json', '/v1/products?page=7&apiKey=<YourApiKey> : The seventh page', "/v1/products(manufacturer='canon')?apiKey=<YourApiKey> : All products manufatured by Canon", '/v1/products(salePrice<20.33)?apiKey=<YourApiKey> : All products with sale price less than $20.33', "/v1/products(manufacturer='canon'&salePrice<20.33)?apiKey=<YourApiKey> : Canon products with sale price less than $20.33", '/v1/products?show=sku,name,url&apiKey=<YourApiKey> : For each product, show only the sku, name, and buy url attributes', '/v1/products?sort=name.desc&apiKey=<YourApiKey> : All products, sorted backwards by name', "/v1/products(manufacturer='canon'&salePrice<33)?show=name&sort=regularPrice&page=2&apiKey=<YourApiKey> : (Combined) Canon products with sale price less than $33, page 2, sorted by regular price, showing the product name only", '/v1/products(sku in(8880044,8740311))?apiKey=<YourApiKey> : Products matching the skus 8880044 & 8740311', '/v1/categories/cat00000.json?apiKey=<YourApiKey> : Categories with id cat00000, as json', '/v1/categories(id in(cat00000,abcat0100000))?apiKey=<YourApiKey> : Categories with ids cat00000 and abcat0100000', '/v1/stores(area(94103,10))+products(manufacturer=nikon)?apiKey=<YourApiKey> : (Join) All stores within 10 miles of the 94103 zip code which carry nikon products, and a list of those products', '/v1/stores(area(38.89,-77.03,10))?apiKey=<YourApiKey> : All stores within 10 miles of the latitude 38.89 and longitude -77.03']}

Running The Tests

# python premix.py --help
Usage: premix.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -k, --key        Best Buy Remix API key to run tests with

Examples:
  premix.py                             - run default set of tests
  premix.py StoreTest                   - run all StoreTest tests
  premix.py ProductTest.test_query_all  - run ProductTest.test_query_all

To run the unit tests, simply run premix.py and pass your API key with the '-k' or '--key' option:

# python premix.py -k 123456790123456789012345
.....................
----------------------------------------------------------------------
Ran 21 tests in 14.945s

OK

OR

Enter your API key when prompted:

# python premix.py
Enter an API Key: 123456790123456789012345
.....................
----------------------------------------------------------------------
Ran 21 tests in 14.945s

OK

Release History

  • December 11, 2009 - 1.0.2 (Download: Zip)
    • More tolerant live data unit tests.
  • October 22, 2009 - 1.0.1
    • Fixed bug with error message if Remix sends an incorrect response.
    • More tolerant live data unit tests.
  • July 23, 2009 - 1.0
    • Added extend() to complement filter() and tests.
    • Added result convenience properties next and previous and tests.
    • More tolerant live data unit tests.
  • July 16, 2009 - 0.9.3
    • More tolerant live data unit tests.
  • March 5, 2009 - 0.9.2
    • Fix to retry logic and new unit test.
    • More tolerant live data unit tests.
  • February 25, 2009 - 0.9.1
    • Added support for Commission Junction Affiliate IDs.
    • Added a retry parameter to fetch() to optionally allow fetch retries in case of errors.
    • More tolerant live data unit tests where possible.
  • February 18, 2009 - 0.9
    • Initial Release

Roadmap

  • Add optional use of memcache for results.
  • Add search “bias” support
  • Add Category support

About The Developer

Premix was developed by gumptionthomas (Thomas Bohmbach, Jr.) of Gumption, LLC.

Contributing

Patches are gladly accepted through bitbucket's "Pull Request" functionality.

Updated