Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all product id from Shopify Python API

I have created one private shopify app. Which can get almost all the information with product id. But I need one option to get product id of all products in a shop with API. I have tried the option below

shopify.Product.find()

but it shows only first 50 products. But my shop has more than 2.4k products.

like image 242
Rafayet Ullah Avatar asked Apr 23 '17 19:04

Rafayet Ullah


4 Answers

Pagination interface has changed in Shopify API, and the old "limit + page" way of doing pagination was removed in api version 2019-07.

In other words: the accepted answer by @Julien will NOT work in this api version and later.

I have re-created the function of the accepted answer using the new way of doing relative cursor based pagination here:

def get_all_resources(resource_type, **kwargs):
    resource_count = resource_type.count(**kwargs)
    resources = []
    if resource_count > 0:
        page=resource_type.find(**kwargs)
        resources.extend(page)
        while page.has_next_page():
            page = page.next_page()
            resources.extend(page)
    return resources
like image 74
Lennart Rolland Avatar answered Oct 27 '22 00:10

Lennart Rolland


Update as of 2019-07: This will no longer work as it has been deprecated and subsequently removed from the Shopify API.

The replacement is detailed in this answer.

Original answer below


Shopify returns paginated responses for lists of resources. The default number of resources per page is 50, and the default page is 1. Your request is thus equivalent to the following:

shopify.Product.find(limit=50, page=1)

Shopify allows you to increase the limit per page to 250. Here's a helper function I use to get all of a given resource:

def get_all_resources(resource, **kwargs):
    resource_count = resource.count(**kwargs)
    resources = []
    if resource_count > 0:
        for page in range(1, ((resource_count-1) // 250) + 2):
            kwargs.update({"limit" : 250, "page" : page})
            resources.extend(resource.find(**kwargs))
    return resources

You use it like this:

products = get_all_resources(shopify.Product)

You can even pass in parameters. Your question asks specifically for the product ID- if you limit the query to only return the IDs, this will be much, much faster (as it doesn't have to pull in any of the product variants):

product_ids = get_all_resources(shopify.Product, fields="id")

Note that if you have 2.4k products, this may take some time!

Documentation: https://help.shopify.com/api/reference/product

like image 36
Julien Avatar answered Oct 26 '22 23:10

Julien


An extension of Lennart Rolland response.

As he stated the preferred answer is no longer applicable in api version 2019-07.

I was unable to get his code sample to work, because of an error "list does not have the function has_next_page()".

So I have written an example using the 'Link' header rel='next' pagination.

def get_all_resources(resource):
    page_info = str()
    resources = list()
    while True:
        resources.extend(resource.find(limit=250, page_info=page_info))
        cursor = shopify.ShopifyResource.connection.response.headers.get('Link')
        if 'next' in cursor:
            page_info = cursor.split(';')[-2].strip('<>').split('page_info=')[1]
        else:
            break
    return resources
like image 41
Spot135 Avatar answered Oct 26 '22 23:10

Spot135


Thought this might be helpful as well:

def get_products():
    """
    Returns a list of all products in form of response JSON
    from Shopify API endpoint connected to storefront.

    * Note: Shopify API allows 250 pruducts per call.

    :return:
        product_list (list):    List containing all product response
                                JSONs from Shopify API.
    """

    products = []
    is_remaining = True
    i = 1
    while is_remaining:

        if i == 1:
            params = {
                "limit": 250,
                "page": i
            }

            response = requests.get(
                "{}/products.json".format(SHOPIFY_ENDPOINT),
                params=params
            )

            products.append(response.json()['products'])
            i += 1

        elif len(products[i-2]) % 250 == 0:
            params = {
                "limit": 250,
                "page": i
            }

            response = requests.get(
                "{}/products.json".format(SHOPIFY_ENDPOINT),
                params=params
            )

            products.append(response.json()['products'])
            i += 1

        else:
            is_remaining = False

    products = [products[i][j]
        for i in range(0, len(products))
        for j in range(0, len(products[i]))
    ]

    return products
like image 45
sgerbhctim Avatar answered Oct 27 '22 01:10

sgerbhctim