Focusing on managing products, variants, and collections through the API.
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
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?)
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.