Giter Club home page Giter Club logo

bigcommerce-api-python's Issues

406 Not Acceptable ({"error":"Invalid format."}) during api.oauth_fetch_token call

Expected behavior

api = bigcommerce.api.BigcommerceApi(
client_id=config['bigcommerce'].get('client_id'),
store_hash=context, access_token='')

token = api.oauth_fetch_token(
config['bigcommerce'].get('client_secret'), code, context, scope,
config['bigcommerce'].get('redirect_uri'))
print(token)

{'access_token': '', 'scope': '', 'user':, 'context': ''}

Actual behavior

Python 3.6.3
bigcommerce==0.18.0

api = bigcommerce.api.BigcommerceApi(
client_id=config['bigcommerce'].get('client_id'),
store_hash=context, access_token='')

token = api.oauth_fetch_token(
config['bigcommerce'].get('client_secret'), code, context, scope,
config['bigcommerce'].get('redirect_uri'))

bigcommerce.exception.ClientRequestException: 406 Not Acceptable @ https://login.bigcommerce.com/oauth2/token: b'{"error":"Invalid format."}'

Steps to reproduce behavior

Upgrade bigcommerce to 0.18.0 (from the bigcommerce==0.17.3)

pip install bigcommerce==0.18.0
running in powershell terminal

Is there any side-effect on api

Should I somehow clear any session on the api after using it for future use.

In bigcommerce/hello-world-app-python-flask at line #93 it mentions a side-effect behavior, or maybe I got it wrong.

Currently some of my app unit-tests pass or fail on a simple api connection test and the error is Authorization issue. I'm wondering if I need to take care of clearing the "session" object or some sort after using the api for couple of store.

By the way, shopify python api wrapper requires clearing the session header after api usage to be able to use it for another api connection:

shopify.ShopifyResource.clear_session()

Cannot generate a valid jwt-login-token... Something to do with APP_CLIENT_SECRET?

I am new to bigCommerce so bare with me please. Any help is appreciated.

Expected behavior

I am working with ex_login_token.py... I expect the JWT token to be able to log me in. ((SSO))

Actual behavior

when i go to use the token https://myURL.com/login/token/<jwt-login-token> i get redirected instead to the login page of my bc store with the error Invalid login..

I have a working flask app installed in my bigcommerce store. I might need to merge that app and the python script somehow so that the APP_CLIENT_SECRET is works. but i have little knowledge in a lot of places. I need help filling a few gaps

Unset Price Value On Product Variations

Expected behavior

I'm trying to unset the price value on all the variations of a product.

product = api.Products.get(productId)
variations = product.skus()

for variation in variations:
     print("-- Setting Variations Back To Regular Price")
     variation_object = product.skus(variation.id)
     variation_object.update(price="")

Actual behavior

Above snippet sets all the product variations price to 0.00 instead of null. I'm not sure if this is an API issue, or a Python issue. Any suggestions or feedback would be much appreciated.

unable to write to google api.GoogleProductSearchMappings.all(idNo).update()

Expected behavior

the following code should enable google shopping

google = api.GoogleProductSearchMappings.all(idNo).update(enabled=True)
print google 

Actual behavior

google = api.GoogleProductSearchMappings.all(idNo).update(enabled=True)
print google 

NONE

No change in item google shopping settings

Steps to reproduce behavior

google = api.GoogleProductSearchMappings.all(idNo).update(enabled=True)
print google 

lambda from __getattr__ getting called with "connection" as a keyword argument?

This code:

#!/usr/bin/env python2
import bigcommerce
import bigcommerce.api
BIG_URL = 'store-45eg5.mybigcommerce.com'
BIG_USER = 'henry'
BIG_KEY = '10f0f4f371f7953c4d7d7809b62463281f15c829'

api = bigcommerce.api.BigcommerceApi(host=BIG_URL, basic_auth=(BIG_USER, BIG_KEY))
def get_category_id(name):
    get_request = api.Categories.get(name)
    try:
        cat_list = api.Categories.all(name=name)
        if cat_list:
            return cat_list[0]['id']
        else:
            return None
    except:
        return None
def create_category(name):
    rp = api.Categories.create(name)
    if rp.status == 201:
        return rp.json()['id']
    else:
        return get_category_id(name)
create_category('anothertestingcat')

Gives this traceback:

Traceback (most recent call last):
File "./bigcommerceimporter.py", line 50, in
create_category('anothertestingcat')
File "./bigcommerceimporter.py", line 44, in create_category
rp = api.Categories.create(name)
File "/home/henry/big_test_zone/local/lib/python2.7/site-packages/bigcommerce/api.py", line 57, in
return lambda _args, *_kwargs: (getattr(self.resource_class, item))(_args, connection=self.connection, *_kwargs)
TypeError: create() got multiple values for keyword argument 'connection'

I believe this is a bug/glitch in or around line 57 in api.py. It looks like lambda from getattr is getting called with "connection" as a keyword argument when it shouldn't be.

Odoo Connector

Could this be used as a connector for bigcommerce and Odoo?

Go SDK + CloudQuery Source Plugin

Hi Team, hopefully this is right place to ask, if not, I'd appreciate if you can direct me.

I'm the founder of cloudquery.io, a high performance open source ELT framework.

Our users are interested in an BigCommerce plugin, but as we cannot maintain all the plugins ourselves, I was curious if this would be an interesting collaboration, where we would help implement an initial source plugin, and you will help maintain it.

This will give your users the ability to sync BigCommerce data to any of their datalakes/data-warehouses/databases easily using any of the growing list of CQ destination plugins.

Best,
Yevgeny

api.Products.count() doesn't work anymore?

Expected behavior

api = bigcommerce.api.BigcommerceApi(
client_id=clientID,
store_hash=store_hash,
access_token=accessToken)
count = api.Products.count()
print(count)

prints count

Actual behavior

api = bigcommerce.api.BigcommerceApi(
client_id=clientID,
store_hash=store_hash,
access_token=accessToken)
count = api.Products.count()

AttributeError: type object 'Products' has no attribute 'count'

Steps to reproduce behavior

python 3 pip install bigcommerce-api
running in powershell terminal

Shipment hasn't field "items"

How get items of shipment using this lib?
Doc of shipment has point "items" https://developer.bigcommerce.com/api/objects/v2/shipment

order = client.Orders.get(1)
shipment = order.shipments()[0]
# or
shipments = client.OrderShipments.all(1)[0] # id of order

# it returns <function items>
items = shipments.items 

# it returns a list of fields without items
items = shipments.items()

# it returns KeyError: 'items'
shipment['items']

How can I get it using this lib?

ProductVideos cannot create, delete, or delete_all

From the documentation in the following URL, you would think you can create, delete, and delete_all videos for a product:

https://developer.bigcommerce.com/legacy/v2-catalog-products/v2-product-videos

newer documentation:

https://developer.bigcommerce.com/api-reference/catalog/catalog-api/product-videos/

Expected behavior

I expected that you would be able to something like this and it create a video:
video = api.ProductVideos.create(parentid=product_id, url=video_url)

Actual behavior

If I try to create a video I get the following error:
AttributeError: type object 'ProductVideos' has no attribute 'create'

Steps to reproduce behavior

product_id = "id of product"
video_url = "some youtube video url"
video = api.ProductVideos.create(parentid=product_id, url=video_url)

Is there a way to update products in batches (more than 1 at a time)?

Currently, I'm using the following to update information about a single product.

api.Products.get(1234).update(inventory_level=20)

Is there a way to update multiple products? I've tried something like this, but got a 404 error.

api.Products.get([123, 456]).update(inventory_level=20)

ERROR:
404 Not Found @ products/[123,456]: b'[{"status":404,"message":"The requested resource was not found."}]'

BigCommerce allow 10 product updates at a time, so I'm trying to see if that is possible.
https://developer.bigcommerce.com/api-reference/catalog/catalog-api/products/updateproducts

Unused Exception

As pointed out in #21 NotLoggedInException is unused in the client library. In v0.11 this should be removed entirely.

force_reset not working

Expected behavior

I need to create a customer and force them to reset their passwords on login. I tried the following...
api.Customers.create(first_name=first, last_name=last, email=email, force_reset=True)
-or-
api.Customers.create(first_name=first, last_name=last, email=email, _authentication:{force_reset=True})

Actual behavior

ClientRequestException: 400 Bad Request @ customers: [{"status":400,"message":"The field 'force_reset' is not supported by this resource."}]

How can i use the api to set reset_pass_on_login to true?

Using v3 Catalog/Product filters

Expected behavior

I'm trying to use the v3 Products API's, but I need to filter by "id:not_in". As far as I know, Python does not allow colons in variable names. So what is the work-around to this?

I expect that all the filters using a colon will not work.

# v3 products
include_fields = "sku, price"
sort = "sku"
id:not_in = "689"
endpoint = '/catalog/products'
response = api.get(endpoint, include_fields=include_fields, id:not_in=id:not_in, limit=5, page=1, sort=sort)

The expected result would be a list of products where the IDs are not in the list of IDs.

Actual behavior

id:not_in = "689"
NameError: name 'not_in' is not defined

Steps to reproduce behavior

Use above filter to reproduce.

Helper method for creating an authorize URL

Would be nice to have a method that generates the authorize URL

Also, the developer site doesn't document what the authorize URL is. I had to guess what it is:

https://login.bigcommerce.com/oauth2/authorize

Pagination on a subresource

I recently ran across a problem where a customer has 100 skus for a product. The API only allows me to get the first 50.

    opts.update({"limit": 50, "page": 1})
    for product in self.con.Products.all(**opts):
         for sku in product.skus():
              print sku

It would be nice if we could pass parameters to the sub resource's all/get method and have it cascade to the connection instance to perform the gets

    stop = False
    skuopts = {"limit": 50, "page": 1}
    while not stop:
       for sku in product.skus(**skuopts):
             print sku

My other option would be to iterate using the SubResource explicitly and passing in the product id and the product's connection, but the connection property is privatized.

    opts.update({"limit": 50, "page": 1})
    for product in self.con.Products.all(**opts):
        stop = False
        skuopts = {"limit": 50, "page": 1}
        while not stop:
           for sku in self.con.ProductSkus.all(product.id, product._connection, **skuopts):
               print sku

This would require exposing the connection object from within the parent resource.

Rate Limit only firing once

I have this code for rate limiting:


def ratelimit():
    print("Ratelimit Called")

api = bigcommerce.api.BigcommerceApi(client_id='xxxx', store_hash='xxxx,
                                     access_token='xxxx',
                                     rate_limiting_management={'min_requests_remaining': 3,
                                                               'wait': True,
                                                               'callback_function': ratelimit()})

for product in api.Products.iterall(): 
      
      ...

The rate limit function is only being fired once at the start of the program, and I'm getting this error:

bigcommerce.exception.RateLimitingException: 429 Too Many Requests @ products: b''

Old releases, broken functions, V3 support

The README.md suggests that api.Products.iterall() and api.Products.count() should exist but they do not appear to.

Also, the releases page says that the last release was 2019. They're haven't been any substantial updates since then?

Also, the forum entry at #59 says the following:

Hi @sabotagebeats, the pagination values you're referring to come from the V3 BC API, whereas this library is for the older V2 API and has not yet been updated for V3.

Has V3 been since released?

Lastly, when I call (api).Products.all() for some page equal-to-or-greater-than the page-count (the page after the last page of results), I get a single string with a value of "_connection" back. So, when there are products, we get a Product. Otherwise, we get a string with "_connection". I would expect an empty result or, at worst, a None. Can you explain what's going on here? How is pagination supposed to work? I'm having issues finding documentation and what little documentation is available (above) seems broken or inaccurate. Since the source-code is reflective, there are no clues there, either.

500 errors for Store.all()

We see 500 errros for some of our requests. Below is the stack trace we see in python (you can see that accessing Store.all() triggers the error). Any help would be much appreciated.

Task bigcommerce_app.helpers.
import_orders.import_orders with id 251b17ba-0bea-4f7e-964a-2d262115905c raised exception:
"ServerException('500 Internal Server Error @ store: An error has occurred.',)"


Task was called with args: (<APIUser: API User [email protected]>,) kwargs: {}.

The contents of the full traceback was:

Traceback (most recent call last):
  File "/app/.heroku/python/lib/python2.7/site-packages/celery/app/trace.py", line 238, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/app/.heroku/python/lib/python2.7/site-packages/celery/app/trace.py", line 416, in __protected_call__
    return self.run(*args, **kwargs)
  File "./bigcommerce_app/helpers/import_orders.py", line 18, in import_orders
    return get_unimported_orders(client, apiuser)
  File "./bigcommerce_app/helpers/import_orders.py", line 44, in get_unimported_orders
    storeinfo = get_storeinfo(client)
  File "./bigcommerce_app/helpers/import_orders.py", line 22, in get_storeinfo
    store = client.Store.all()
  File "/app/.heroku/python/lib/python2.7/site-packages/bigcommerce/api.py", line 55, in <lambda>
    return lambda *args, **kwargs: (getattr(self.resource_class, item))(*args, connection=self.connection, **kwargs)
  File "/app/.heroku/python/lib/python2.7/site-packages/bigcommerce/resources/base.py", line 82, in all
    request = cls._make_request('GET', cls.resource_name, connection, params=params)
  File "/app/.heroku/python/lib/python2.7/site-packages/bigcommerce/resources/base.py", line 42, in _make_request
    return connection.make_request(method, url, data, params, headers)
  File "/app/.heroku/python/lib/python2.7/site-packages/bigcommerce/connection.py", line 120, in make_request
    return self._handle_response(url, response)
  File "/app/.heroku/python/lib/python2.7/site-packages/bigcommerce/connection.py", line 154, in _handle_response

    raise ServerException("%d %s @ %s: %s" % (res.status_code, res.reason, url, res.content), res)
ServerException: 500 Internal Server Error @ store: An error has occurred.

Zip payment method not returning in API

Expected behavior

Zip should be returned as a payment method in the PaymentMethods API resource when it is enabled.

Actual behavior

Zip is not returned as a payment method.

Steps to reproduce behavior

  1. Enable Zip as a payment method in the store
  2. Connect to API and run api.PaymentMethods.all()
  3. Zip is not returned as one of the enabled payment methods

429 error shouldn't appear should it?

Hi, I'm having 429 error getting information from the api

I'm creating the client object with:

BigcommerceApi(
            client_id=settings.BIGCOMMERCE_APP_CLIENT_ID,
            store_hash=self.store_hash,
            access_token=self.access_token,
            rate_limiting_management={
                'min_requests_remaining': 3,
                'wait': True,
                'callback_function': None
            })

And it still gets error

imagen

Expected behavior

Not exception

Actual behavior

Exception raised

Steps to reproduce behavior

I were trying to get products data from an customer that have a lot of skus and products

for product in self.client.Products.iterall():
    # some processing ...

    skus = product.skus()  # <- here it raises
    # more code ...

dependency on streql

The pip install fails to install streql on python 2.7 on Windows7. It complains that it cannot find vcvarsall.bat. I looked through the API and noticed that streql is only imported, but not used in the code. I was able to use the api on Windows7 by removing that line in connection.py. I don't want to have to install microsoft Visual Anything unless I have to.

Getting subresources alongside products (not separately)

The API supports getting subresources within the same request as products:

image

However, the client seems to only provide access one at a time via a separate API call.

image

There's no way to just request products and subresources in one call?

Updating customer password gives random 400 errors

Overview

I am trying to update the customer password in one of my applications. Sample code:

import bigcommerce

big_commerce_url_info = xxx
big_commerce_store_hash = xxx
big_commerce_client_id = xxx
big_commerce_auth_token = xxx
customer_id = xxx
password = xxx

try:
    api = bigcommerce.api.BigcommerceApi(client_id=big_commerce_client_id, store_hash=big_commerce_store_hash, access_token=big_commerce_auth_token)
    api.Customers.get(customer_id).update(_authentication=dict(password=password))
except Exception as e:
    print("ERROR: ", str(e))

Expected behavior

It should update the password every single time.

Actual behavior

It updates the password most of the times for most customers but some times it randomly gives the following error:

ERROR: 400 Bad Request @ customers/1705: b'[{"status":400,"message":"The field \'password\' is invalid."}]'

Steps to reproduce the behavior

Just run the code multiple times and it will randomly fail at some point.

Order status .iterall() infinite loop

Expected behavior

list(client.OrderStatuses.iterall()) should yield a list identical (in this case, since there's only one page) to client.OrderStatuses.all()

Actual behavior

iterall() appears to infinite loop, presumably because it doesn't accept a page parameter, ignores that field and therefore will always return rows.

It seems like the simplest fix here would be to define an override, either through mixin or directly on any listable model which doesn't support paging.

Unable to get ['meta']['pagination']['total_pages'] from products = api.Products.all()

Expected behavior

in requests library, total_pages returned in json.

Actual behavior

products = api.Products.all()
does not return all items, it returns only the first page of items.

products = api.Products.all(page=2)
produces second page but does not return total pages.

products = api.Products.all(limit=250)
produces 250 items, no total_pages

count = api.Products.count()
products = api.Products.all(limit=count)

fails with exception: bigcommerce.exception.ClientRequestException: 413 Request Entity Too Large @ products: [{"status":413,"message":"The specified limit exceeds the maximum allowed.","details":{"max_limit":250}}]

This makes it impossible to iterate pagination within the bigcommerce-api-python library.

Steps to reproduce behavior

api = bigcommerce.api.BigcommerceApi(client_id=clientID, store_hash=store_hash, access_token=accessToken)
count = api.Products.count()
products = api.Products.all(limit=count)

Order field "custom_status" update returns an error

Expected behavior

when i do something lile this
BCPYTHONCLIENT.Orders.get(10).update(custom_status='Completed')
update succefully

Actual behavior

resturns an errror
bigcommerce.exception.ClientRequestException: 400 Bad Request @ orders/10: b'[{"status":400,"message":"The field 'custom_status' is not supported by this resource."}]'

Steps to reproduce behavior

Throttling for "Rate Limit Exceeded" - 509 and 429's

I built in sleep "delay" and "max_retries" into my original version of the API to address the 509 errors. I do not want to have to wrap every operation throughout my application to address the retries. I'd prefer it be built into the API so that it is transparent. It could also be configurable when instantiating the API class.

The 429's are nice in that it gives you a "retry-after" in the header.

What are your thoughts on this? Is there a good reason that this should not be part of the API?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.