Python GraphQL example with rate limiting and error checking

DaVinci007
New Member
2 1 13

This is a post for everyone who went through the same problems I did trying to make the Shopify Python API work.

 

DON'T!

 

Instead, I suggest you use GraphQL requests with this python function. 

 

The main advantages are:

  • better documentation
  • much more features
  • better query rate compared to the API (Python or REST) if you return only the wanted items and fields.

 

Here is a complete example to get you started.  It covers rate limiting and error checking as well.

 

import json
import time
import requests

API_KEY = 'myAPIKEY'
PASSWORD = 'myAPIPassword'
SHOP_NAME = 'myShopName'
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):
    response = requests.post(shop_url+'/graphql.json', json={'query': GraphQLString})
    if response.status_code==400:
        raise ValueError('GraphQL error:' + response.text)
    answer = json.loads(response.text)
    throttleStatus = None
    if 'errors' in answer:
        try:
            throttleStatus = answer['errors'][0]['extensions']['code']
        except:
            pass
        if throttleStatus != 'THROTTLED':
            raise ValueError('GraphQL error:' + repr(answer['errors']))
    qlRequired = answer['extensions']['cost']['requestedQueryCost']
    qlLimit = answer['extensions']['cost']['throttleStatus']['maximumAvailable']
    qlAvail = answer['extensions']['cost']['throttleStatus']['currentlyAvailable']
    print('GraphQL throttling status: ' + str(qlAvail) + '/' + str(int(qlLimit)))
    while throttleStatus=='THROTTLED':
        print('Waiting (GraphQL throttling)... ' + str(qlAvail) + '/' + str(int(qlLimit)) + ' used, requested ' + str(qlRequired))
        time.sleep(1)
        response = requests.post(shop_url+'/graphql.json', json={'query': GraphQLString})
        answer = json.loads(response.text)
        try: 
            throttleStatus = answer['errors'][0]['extensions']['code']
        except:
            throttleStatus = None
            pass
    return answer['data']

graphQLquery = """{
  products(first: 100) {
    edges {
      node {
        handle
        id
        description
      }
    }
  }
}"""

for i in range(1,125):
    callShopifyGraphQL(graphQLquery)

 

Replies 3 (3)
Anonymous
Not applicable

Hello DaVinci,

 

thx much for your post! 

 

@Shopify

The Python documentation at your GitHub repo is crap and will not work. I spend hours tried to get it working. This is not userfriendly. If you have much work and can't keep the docs up-to-date, tell the community.

 

Keep developing.

klau
Shopify Partner
5 1 0

Hello DaVinci,

I tried your example, I am getting a UnicodeError: label empty or too long on line: callShopifyGraphQL(graphQLquery)

Do you mind pointing me in the right direction?  I too are hitting the API limitation of Shopify.  Thanks!

klau
Shopify Partner
5 1 0

For anyone who have my issue, this stackoverflow thread fixed my problem:

https://stackoverflow.com/questions/51901399/python-requests-encoding-with-idna-codec-failed-unicode...