diff --git a/bigcommerce/api.py b/bigcommerce/api.py index 057a4d3..404a71c 100644 --- a/bigcommerce/api.py +++ b/bigcommerce/api.py @@ -5,7 +5,7 @@ class BigcommerceApi(object): - def __init__(self, host=None, basic_auth=None, + def __init__(self, host=None, api_path=None, basic_auth=None, client_id=None, store_hash=None, access_token=None, rate_limiting_management=None): self.api_service = os.getenv('BC_API_ENDPOINT', 'api.bigcommerce.com') self.auth_service = os.getenv('BC_AUTH_SERVICE', 'login.bigcommerce.com') @@ -14,6 +14,7 @@ def __init__(self, host=None, basic_auth=None, self.connection = connection.Connection(host, basic_auth) elif client_id and store_hash: self.connection = connection.OAuthConnection(client_id, store_hash, access_token, self.api_service, + api_path=api_path, rate_limiting_management=rate_limiting_management) else: raise Exception("Must provide either (client_id and store_hash) or (host and basic_auth)") diff --git a/bigcommerce/connection.py b/bigcommerce/connection.py index 7bffb89..ae28acb 100644 --- a/bigcommerce/connection.py +++ b/bigcommerce/connection.py @@ -53,6 +53,10 @@ def _run_method(self, method, url, data=None, query=None, headers=None): if headers is None: headers = {} + # Support v3 + if self.api_path and 'v3' in self.api_path: + url = 'catalog/{}'.format(url) + # make full path if not given if url and url[:4] != "http": if url[0] == '/': # can call with /resource if you want @@ -156,6 +160,9 @@ def _handle_response(self, url, res, suppress_empty=True): if res.status_code in (200, 201, 202): try: result = res.json() + # Support v3 + if self.api_path and 'v3' in self.api_path: + result = result['data'] #TODO ignore meta field for now except Exception as e: # json might be invalid, or store might be down e.message += " (_handle_response failed to decode JSON: " + str(res.content) + ")" raise # TODO better exception @@ -187,11 +194,11 @@ class OAuthConnection(Connection): """ def __init__(self, client_id, store_hash, access_token=None, host='api.bigcommerce.com', - api_path='/stores/{}/v2/{}', rate_limiting_management=None): + api_path=None, rate_limiting_management=None): self.client_id = client_id self.store_hash = store_hash self.host = host - self.api_path = api_path + self.api_path = api_path if api_path else "/stores/{}/v2/{}" self.timeout = 7.0 # can attach to session? self.rate_limiting_management = rate_limiting_management diff --git a/bigcommerce/resources/__init__.py b/bigcommerce/resources/__init__.py index 541fc4f..c5b0f0d 100644 --- a/bigcommerce/resources/__init__.py +++ b/bigcommerce/resources/__init__.py @@ -20,4 +20,5 @@ from .store import * from .tax_classes import * from .time import * +from .variants import * from .webhooks import * diff --git a/bigcommerce/resources/products.py b/bigcommerce/resources/products.py index d569de9..434b2bd 100644 --- a/bigcommerce/resources/products.py +++ b/bigcommerce/resources/products.py @@ -48,11 +48,17 @@ def rules(self, id=None): else: return ProductRules.all(self.id, connection=self._connection) - def skus(self, id=None): + def skus(self, id=None, **kwargs): if id: - return ProductSkus.get(self.id, id, connection=self._connection) + return ProductSkus.get(self.id, id, connection=self._connection, **kwargs) else: - return ProductSkus.all(self.id, connection=self._connection) + return ProductSkus.all(self.id, connection=self._connection, **kwargs) + + def variants(self, id=None, **kwargs): + if id: + return ProductVariants.get(self.id, id, connection=self._connection, **kwargs) + else: + return ProductVariants.all(self.id, connection=self._connection, **kwargs) def videos(self, id=None): if id: @@ -99,7 +105,9 @@ class ProductImages(ListableApiSubResource, CreateableApiSubResource, count_resource = 'products/images' -class ProductOptions(ListableApiSubResource): +class ProductOptions(ListableApiSubResource, CreateableApiSubResource, + UpdateableApiSubResource, DeleteableApiSubResource, + CollectionDeleteableApiSubResource, CountableApiSubResource): resource_name = 'options' parent_resource = 'products' parent_key = 'product_id' @@ -131,6 +139,13 @@ class ProductSkus(ListableApiSubResource, CreateableApiSubResource, parent_key = 'product_id' count_resource = 'products/skus' +class ProductVariants(ListableApiSubResource, CreateableApiSubResource, + UpdateableApiSubResource, DeleteableApiSubResource, + CollectionDeleteableApiSubResource, CountableApiSubResource): + resource_name = 'variants' + parent_resource = 'products' + parent_key = 'product_id' + count_resource = 'products/variants' class ProductVideos(ListableApiSubResource, CountableApiSubResource, CreateableApiSubResource, DeleteableApiSubResource, diff --git a/bigcommerce/resources/variants.py b/bigcommerce/resources/variants.py new file mode 100644 index 0000000..12cea16 --- /dev/null +++ b/bigcommerce/resources/variants.py @@ -0,0 +1,10 @@ +from .base import * + + +class Variants(ListableApiResource, CreateableApiSubResource, + UpdateableApiSubResource, DeleteableApiSubResource, + CollectionDeleteableApiSubResource, CountableApiSubResource): + resource_name = 'variants' + parent_resource = 'products' + parent_key = 'product_id' + count_resource = 'products/variants' \ No newline at end of file