Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more

Updating Products with Shopify API - Python

Updating Products with Shopify API - Python

ECS_NW
Excursionist
15 0 2

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))
    #<class 'dict'>
    final_dictionary = json.loads(newTagData)
    print(type(final_dictionary))
    #<class 'dict'>
    #r = requests.get(api_url)
    r = requests.put(api_url, params=final_dictionary)
    productsOBJ = r.json()
    productsOBJ1 = json.dumps(productsOBJ,indent = 6)
    print(productsOBJ1)

 

The above code outputs this error which is almost comical. 

 

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?)

Replies 2 (2)

mv5
Shopify Partner
31 2 4

Did you ever figure this out? 

ECS_NW
Excursionist
15 0 2

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.