I am trying to use the Shopify API from my Django app hosted on Google App Engine.
For my local single threaded scripts I am using a modified version of this to make sure that I don't go over Shopify's rate limit:
# Setup local bucket to limit API Calls
bucket = TokenBucket(40, .5)
api_call_success = False
while not api_call_success:
if bucket.tokens < 1:
sleep(.5)
else:
[... do an API call ...]
bucket.consume(1)
api_call_success = True
This works for my local scripts, but it won't work for my Google App Engine hosted application where there may be multiple tenants, and multiple sessions occurring at once.
I have been trying to research the best way to handle this rate limiting, and presently was going to try to constantly write each users/stores request response header to memcache so that I could always check the 'x-shopify-shop-api-call-limit' to see what the previous call limit (and time of the call) was. So I tried something like this:
fill_rate = .5
capacity = 40
# get memcache key info
last_call_time = memcache.get(memKey+"_last_call_time")
last_call_value = memcache.get(memKey+"_last_call_value")
# Calculate how many tokens should be available
now = datetime.datetime.utcnow()
delta = fill_rate * ((now - last_call_time).seconds)
tokensAvailable = min(capacity, delta + last_call_value)
# Check if we can perform operation
if tokensAvailble > 1:
[... Some work involving Shopify API call ...]
# Do some work and then update memcache
memcache.set_multi( {"_last_call_time": datetime.datetime.strptime(resp_dict['date'], '%a, %d %b %Y %H:%M:%S %Z'), "_last_call_value": resp_dict['x-shopify-shop-api-call-limit'].split('/',1)[0]}, key_prefix=memKey, time=120)
else:
[... wait ...]
Can anyone recommend a better way to manage this rate limiting?