Complete examples for Python

8 1 11

I am a beginner with Shopify APIs and so far it has been a mixed experience.


I am using Python which seems to give me 2 options; the "python api" based on a port of "active resources" and just "plain old REST".


I went with the first option hoping it would have some paved way, especially when it comes to authentication. However now I find myself in a peculiar situation where there is almost no example code or documentation at all, and the example code that is there is either out-dated, for a different use-case or incomplete. On the other hand, the documentation for the REST API seems really good. So I have to jump around in git and the documentation and "guess" my way to why my code fails. It does not help that the error messages produced by "active resources" is utter crap.


I have seen some examples in the README for python api on github and also a few snippets in the community posts but really I feel like I am fumbling completely in the dark.




So far I have managed to create an app using embedded admin screen that successfully authenticates to get an "offline access_token" that I store in my DB and reuse when available. Awesome!


But now I want to actually inject some features into the app customer's shop by inserting a script_tag. There is no example and not even a test case to look at!


My naive code pieced together from guesswork fails with 401 every time. I have tried countless remedies. Why does my credentials seem to work fine during authentication but not with script_tag? And before you ask, I am using the following scope: ["write_products", "read_products", "read_script_tags", "write_script_tags"] during authentication.


My code for the script_tag looks like this, and fails with an error (see below) in the .save() call:


bob={"event": "onload", "src": f"{src}"}
script =
if st.errors:
    print(f"ERROR: {st.errors.full_messages()}")

And the authentication before this looks like this:


        self.current_app = current_app
        self.scope = ["write_products", "read_products", "read_script_tags", "write_script_tags"]
        self.request = request
        self.shop_url = self.request.args.get('shop', shop_url)
        if not self.shop_url:
            print("--request args: ")
            raise Exception("NO SHOP URL")
        # self.url_shceme = self.cred('shopify-app-preferred-url-scheme', 'invalid')
        self.api_url = str(f"https://{self.shop_url}/admin/api/{api_version}")
        print(f"ShopifySessionManager:  api_key={api_key}, api_secret={api_secret}, api_version={api_version}, self.shop_url={self.shop_url}, self.api_url={self.api_url}")
        shopify.Session.setup( api_key=api_key, secret=api_secret)

    def create_session(self, token=None):
        print(f"CREATING SESSION WITH api_url={self.api_url}, token='{token}', shop_url={self.shop_url}, api-version={self.cred('shopify-app-api-version')}")
        self.session = shopify.Session(self.api_url, self.cred('shopify-app-api-version'), token)

The resulting output looks like this:

CREATING SESSION WITH api_url=, token='1afbf7ca***************37d4a3425',, api-version=2019-04
shopify_app     | LOLOLO:
shopify_app     | UPSERTING SCRIPT TAG WITH '{'event': 'onload', 'src': ''}'


The resulting error I am seeing now (possibly redacted for sensitive info):


pyactiveresource.connection.UnauthorizedAccess: Response(code=401, body="b'{"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)"}'", headers={'Date': 'Sun, 15 Sep 2019 22:17:42 GMT', 'Content-Type': 'application/json; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'close', 'Set-Cookie': '__cfduid=da23de8c5f2**********b70e609367701568585861; expires=Mon, 14-Sep-20 22:17:41 GMT; path=/;; HttpOnly', 'X-Sorting-Hat-PodId': '34', 'X-Sorting-Hat-ShopId': '5263130659', 'Referrer-Policy': 'origin-when-cross-origin', 'X-Frame-Options': 'DENY', 'X-ShopId': '5263130659', 'X-ShardId': '34', 'WWW-Authenticate': 'Basic Realm="Shopify API Authentication"', 'Strict-Transport-Security': 'max-age=7889238', 'X-Request-Id': 'cfb8e7c6-***************740f4136eced', 'X-Shopify-Stage': 'production', 'Content-Security-Policy': "default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' https://* shopify-pos://*; block-all-mixed-content; child-src 'self' https://* shopify-pos://*; connect-src 'self' wss://* https://*; frame-ancestors 'none'; img-src 'self' data: blob: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; upgrade-insecure-requests; report-uri /csp-report?source%5Baction%5D=create&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fscript_tags&source%5Bsection%5D=admin_api&source%5Buuid%5D=cfb8e7c6-0c90-4507-a9bc-740f4136eced", 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'X-Permitted-Cross-Domain-Policies': 'none', 'X-XSS-Protection': '1; mode=block; report=/xss-report?source%5Baction%5D=create&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fscript_tags&source%5Bsection%5D=admin_api&source%5Buuid%5D=cfb8e7c6-***************740f4136eced', 'X-Dc': 'gcp-us-central1,gcp-us-central1', 'set-cookie': '__cfduid=da23de8c5f2c**********70e609367701568585861; expires=Mon, 14-Sep-20 22:17:41 GMT; path=/;; HttpOnly', 'Expect-CT': 'max-age=604800, report-uri=""', 'Server': 'cloudflare', 'CF-RAY': '516df8e4792bdfdf-FRA'}, msg="Unauthorized")

So I have the following questions(and many more):


  • Are there really no Python examples/documentation?
  • What is the canonical example for script_tag get, put, post and delete using python api?
  • What is the difference between shopify.ShopifyResource.set_user(api_key) and shopify.Session.setup( api_key=api_key, secret=api_secret), and do I need both? Why?
  • When I create a session with self.session = shopify.Session(self.api_url, self.cred('shopify-app-api-version'), token), do I have to make it active with shopify.ShopifyResource.activate_session(self.session)?
  • Do I need to set the "current shop" active? If not, when do I have to worry about that?
  • What is "user_status":1?


I suspect the reason I am struggling is that I am mixing code from different use-cases into one Frankenstein program. It would be really useful to know exactly how I should use the API differently for offline/online access tokens, how managing apps is different from the rest etc.


Any help much appreciated!