Skip to content

Instantly share code, notes, and snippets.

@wowkin2
Last active September 26, 2024 09:28
Show Gist options
  • Save wowkin2/079844c867a1a06ce15ea1e4ffdee87c to your computer and use it in GitHub Desktop.
Save wowkin2/079844c867a1a06ce15ea1e4ffdee87c to your computer and use it in GitHub Desktop.
Solution: "Exceeded 4 calls per second for api client" Python Shopify API - shopify_python_api

Solution for API call limit "shopify_python_api"

If you are using Python Shopify API and getting following error
"Exceeded 4 calls per second for api client. Reduce request rates to resume uninterrupted service."
but want your script to continue working with some timeout after that,
you can use following script from shopify_limits_patch.py.

For that just copy shopify_limits_patch.py to your project and import shopify_limits_patch.

Or if you want to call it implicitly import it, remove last line patch_shopify_with_limits()
and call it before all your shopify calls.


This is solution for issue described here: Shopify/shopify_python_api#256

If you have any suggestions for code - leave comment :)

import time
import pyactiveresource.connection
from shopify.base import ShopifyConnection
def patch_shopify_with_limits():
func = ShopifyConnection._open
def patched_open(self, *args, **kwargs):
while True:
try:
return func(self, *args, **kwargs)
except pyactiveresource.connection.ClientError as e:
if e.response.code == 429:
retry_after = float(e.response.headers.get('Retry-After', 4))
print('Service exceeds Shopify API call limit, '
'will retry to send request in %s seconds' % retry_after)
time.sleep(retry_after)
else:
raise e
ShopifyConnection._open = patched_open
patch_shopify_with_limits()
import os
from threading import Thread
import shopify
import shopify_limits_patch
def foo():
for _ in range(15):
shopify.Variant.find()
def main():
# Add your Shopify URL here: "https://<shop_name>.myshopify.com/admin"
shopify.ShopifyResource.set_site(os.environ.get('SHOPIFY_URL'))
for i in range(15):
t = Thread(target=foo)
t.start()
if __name__ == '__main__':
main()
@macksal
Copy link

macksal commented Jun 20, 2024

Still working in 2024!

@b4p3p
Copy link

b4p3p commented Sep 25, 2024

It works perfectly in late 2024, the only change i made is

retry_after = float(e.response.headers.get('retry-after', 4))

I created a shopify_patched module, and inside the init file, i added

from .shopify_limits_patch import shopify

To import the library, i replaced all:

import shopify

with

from app_api.api_modules.shopify_patched import shopify

Is that correct?

@wowkin2
Copy link
Author

wowkin2 commented Sep 26, 2024

@b4p3p yeah, this way of import also works. Probably even better than proposed in 2018 😅
Can't check if 'retry-after' should be lower cased or any other. But people that use it - can easily do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment