Updating Products with Shopify API - Python

Hello, I am having some issues updating products on the shopify API.

I am able to get, delete, and even loop over paginated API calls when pulling large amounts of data. But for some reason, I can’t get the products to update. Below is my code.

Thank you in advance!!!

def add_tag_to_product_by_id(id):
    api_url = f'{url}products/{id}.json'
    #https://(API_KEY):(TOKEN)@(SHOP_URL)/admin/api/2024-01/products/4620786335829.json
    newTagData = {"product": {"id": id, "tags": "new_tagsss, newertags"} }
    #{'product': {'id': 4620786335829, 'tags': 'new_tagsss, newertags'}}
    r = requests.put(api_url, params= newTagData )
    productsOBJ = r.json()
    productsOBJ1 = json.dumps(productsOBJ,indent = 6)
    print(productsOBJ1)
#The Printed response from the code above
{
      "errors": {
            "product": "expected String to be a Hash"
      }
}

I feel like I have tried every variation possible with the put.request call. I look up the “expected String to be a Hash”

This link is to the shopify community answer to that issue above.

Shopify Community 2280911 - Solved

After reading this I then changed my code to this.

def add_tag_to_product_by_id(id):
    api_url = f'{url}products/{id}.json'
    newTagData = {"product": {"id": id, "tags": "new_tagsss, newertags"} }
    print(type(newTagData))
    #

The above code outputs this error which is almost comical.

```python
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict

So the community says make it an object, and shopify says it wants a string. But Hashed!

How do I update a product with a requests.put()?

(PS. Why does the shopify documents not have any python related examples?)

Did you ever figure this out?

I got it to work. And this is the code below. I am no longer able to edit this post.

I have one function being called in the ADD_TAGS function. I also have a one variable that is being called from outside the function. I have add those small details below.

SHOP_URL = os.getenv('SHOP_URL_MYSHOP')
api_version = "2024-01"
url_sm = "https://%s/api/%s/" % (SHOP_URL,api_version)

def get_products(id=None):
    if id is not None:
        endpoint = f'products/{id}.json'
    else:
        endpoint = 'products.json'
    
    gettingDataBool = True
    tryTimes = 0 # at 5 we will stop trying 
    while gettingDataBool:
        try:
            r = requests.get(url+endpoint)
            result = r.json()
            return result
        except:
            if tryTimes < 5:
                tryTimes = tryTimes + 1
                print('WARNING: get_products | Try failed, sleeping for 15 seconds and trying again.')
                time.sleep(15)
            else:
                #this breaks out of the while loop
                print(f'ERROR: get_products | Failed to retrieve data. | ID: {id}')
                exit()

The code below will merge the exsiting tags with the new tags. Then Save with the requests.put() call.

def add_tag_to_product_by_id(id,productTags):
    '''
    Example Usage:
    update_tags = {"tags": "new_tagsssss, nate_dog"}
    add_tag_to_product_by_id(4620786335829,update_tags)

    '''
    #access token added via header
    api_url = f'{url_sm}products/{id}.json'
    req_headers = {
        "X-Shopify-Access-Token": TOKEN,
        "Content-Type": "application/json"
    }
    #print(id)
    productData = get_products(id)
    
    newProductTags = productData['product']['tags'] + ',' +productTags
    #print(api_url)
    gettingDataBool = True
    tryTimes = 0 # at 5 we will stop trying 
    while gettingDataBool:
        try:
            r = requests.put(api_url, headers=req_headers, json={"product": {"tags" : newProductTags} })
            productsOBJ = r.json()
            print(str(id) + ' | ' +productData['product']['title'] + '  |  ' + productTags)
            #if it worked move on. 
            gettingDataBool = False
        except:
            if tryTimes < 5:
                tryTimes = tryTimes + 1
                print('WARNING: add_tag_to_product_by_id | Try failed, sleeping for 10 seconds and trying again.')
                time.sleep(10)
            else:
                print('ERROR: add_tag_to_product_by_id   || ' + str(id) + ' | ' + productTags)
                exit()

I hope this helps. Let me know if you have any issues. I might be able to help.