How to fetch shopify products based on multiple varying tags which are given dynamically in python?

Viewed 4046

I am trying to fetch products from shopify by filtering based on tags. Tags will be dynamic, more than one, and will change.

import json
import time
import requests

API_KEY = 'xxxx'
PASSWORD = 'xxxx'
SHOP_NAME = 'xxxx'
API_VERSION = '2020-04' #change to the API version
shop_url = "https://%s:%s@%s.myshopify.com/admin/api/%s" % (API_KEY, PASSWORD, SHOP_NAME, API_VERSION)

def callShopifyGraphQL(GraphQLString, data):
    headers = {
        "X-Shopify-Storefront-Access-Token": 'xxxxxx',
        "accept":"application/json"      
    }
    response = requests.post(shop_url+'/graphql', json={'query': GraphQLString, 'variables': data}, headers=headers)
    answer = json.loads(response.text)
    return answer['data']

str1 = '0-12'
str2 = 'physical'

graphQLquery7 = """ {
  products(first:100, query:"tag:$tags") {
    edges {
      node {
        id
        tags
        title
        onlineStoreUrl
      }
    }
  }
}"""

tag = dict({
  "tags":[str1,str2]
})

resp = callShopifyGraphQL(graphQLquery7, tag)
print json.dumps(resp)


# This query works fine and gives multiple products
# graphQLquery2 = """{
#   products(first:100, query:"tag:[0-12, physical]") {
#     edges {
#       cursor
#       node {
#         id
#         tags
        
#         title
#         onlineStoreUrl
#       }
#     }
#   }
# }"""

The Output that I am getting is basically a JSON with products empty

{u'extensions': {u'cost': {u'requestedQueryCost': 102, u'throttleStatus': {u'restoreRate': 50.0, u'currentlyAvailable': 998, u'maximumAvailable': 1000.0}, u'actualQueryCost': 2}}, u'data': {u'products': {u'edges': []}}}
{"products": {"edges": []}}

I am unable to pass my tags as a variable in the query. I am currently using GraphQl because I couldn't find REST APIs fetch product based on multiple tags which would vary.

EDIT: Removed Python tag as this was not a python issue and I have added the answer as well lisitng two methods on how to do this

2 Answers

You must use the flowing syntax:

{
  products(first:10, query:"tag:tag1 OR tag:tag2 OR tag:tag3"){
    edges {
      node {
        id
        tags
        title
        onlineStoreUrl
      }
    }
  }
}

Where you can use OR or AND if you like for all of the tags to be included or any of the listed.

Install the GraphiQL App and test the queries before implementing them, it helps a lot in the development process.

More about the Search Query for GraphQL can be seen here: https://shopify.dev/concepts/about-apis/search-syntax

I finally found the answer to my own question ->

  1. The first way is a workaround(or a cheap python trick) which might be applicable only for the scenario mentioned in the question. Since the query is being passed in as a string(a multiline string), I can simply use placeholders to add variables in it by abusing the line continuation properties of the parenthesis ( and the comma ,.
graphQLquery1 = """ {
  products(first:100, query:"tag:[%s, %s]") {
    edges {
      node {
        id
        tags
        title
        onlineStoreUrl
      }
    }
  }
}"""%('3+', 'personal-social')

data = None
resp = callShopifyGraphQL(graphQLquery1, data)

However, this is not how one should use variables in a GraphQl query.

  1. Below is a more proper solution of using variables in GraphQl
graphQLquery2 = """ query($tags: String){
products(first:100, query:$tags) {
    edges {
      node {
        id
        tags
        title
        onlineStoreUrl
      }
    }
  }
}"""

str1 = '0-12'
str2 = 'physical'
tags = dict({
  "tags":[str1,str2]
})
resp = callShopifyGraphQL(graphQLquery2, tags)
Related