Shopify Embedded SDK with Python and Flask

Vasily Dernis
6 min readMar 28, 2016

--

I finally had a chance to play around with the Shopify Embedded SDK and wanted to document my experience in building a simple “Hello World” using Python, Flask and the Shopify Embedded SDK.

Ground work

  • Sign up as an app developer with Shopify.
  • Create an application by selecting Apps from the left menu and clicking create a new app at the top right. Fill out the application name and select “enabled” for the Shopify web admin embedded settings.
  • The redirection URL will be used at the end of the permission authorization and app installation process.
  • All thats left is to agree to the Developer terms and conditions and proceed to create our app.

Note: All of our urls are using SSL (https). Since our application will be embedded in an iframe, the browser will automatically block mixed content. Additionally if we decide to use the javascript API that Shopify provides, we will run into some funky issues. Later in the tutorial I’ll go into how to enable mixed content and allow unsigned certs for development purposes. Lets just use SSL!

  • Set up a development store. We will install our application in our dev store to test it out. In the left menu select development stores and in the top right click on “create a new store”. Fill out the information and click on “Create store”

Setting up our app

Things should be setup at this point on Shopify. Lets start creating our application directory structure.

mkdir HelloShopify
mkdir HelloShopify/helloshopify
mkdir HelloShopify/helloshopify/templates
mkdir HelloShopify/helloshopify/static
mkdir HelloShopify/helloshopify/shopify_bp

shopify_bp will be our flask blueprint where the Shopify magic will happen. Lets also install the libraries we’ll be using.

pip install flask
pip install flask-sqlalchemy
pip install shopifyapi
pip install flask-manager

While we are at it, might as well setup our configuration.

HelloShopify/helloshopify/config.py

The SHOPIFY_API_KEY and SHOPIFY_SHARED_SECRET are retrieved from the developers panel in the “apps” section. Select your app and click on “show secrets” to display and copy your shared secret key.

Installing our application in our dev store

  1. A user initiates the install request
  2. Using our API key, shared secret, desired scope and redirect_uri we generate a permission url. Shopify api has a convenience method for us to use called create_permission_url()
  3. Normally at this point we would redirect the user to the permission url. However, since we are building an embedded application we have to render a template and redirect the user through javascript (otherwise the redirect would get rejected). This step is the difference in the installation process between regular and embedded apps.
  4. Shopify presents the user with an installation screen showing the scope our application is requesting and asks the user for permission. Once the user accepts, they are forwarded to the redirect uri that we supplied in step #2
  5. We validate the request, this time using the request_token() which uses the one-time code param to return a token which we can store and then use to issue commands on behalf of the store.

Lets initialize our database extension…

HelloShopify/helloshopify/extensions.py

and our Shop model

HelloShopify/helloshopify/shopify_bp/models.py

Now lets create the views.py for our shopify_bp blueprint and create the views that will install our application in the target dev store.

We also need to render a template to facilitate the javascript redirect.

HelloShopify/helloshopify/templates/shopify_bp/install.html

The install method handles steps 1–4. While the finalize method handles step 5. This is the route we put into the Redirection URLs field when we were setting up our application. The finalize method also sets the shopify_token into our session and saves the shop info into our database.

After the application is installed in the store we want to render it. This is our index view. Before we render we want to ensure that the incoming request is valid and we do that using the following flow:

  1. A user initiates a request to our application.
  2. If we already have a shopify_token in our session then all we need to do is make sure that the shop didn’t uninstall our app. We do this by querying our database for the shopify_url that is in the session. If it is found in our database then we consider the request valid, otherwise we prompt the user to install our application.
  3. If no session is found then using our API key and the shared secret, we validate the request params. Shopify api provides a validate_params class method to assist us. If the params happen to be invalid we request the user to install our application otherwise we proceed ot the next step.
  4. We check if we have the shop url in our database (it could be removed through a webhook) if the shop is not in our database then we ask the user to install our application.
  5. The last step is to set the token, url and id of the shop into the session for use by our application.

A decorator would allow us to wrap the views that require Shopify validation in order to render (such as the index view)

HelloShopify/helloshopify/shopify_bp/decorators.py

We need an accompanying index template for our view. As an added bonus lets include the Javascript API.

HelloShopify/helloshopify/templates/shopify_bp/index.html

We wrap up our shopify_bp blueprint by creating an __init__.py file in the shopify_bp directory with the following code

from .views import shopify_bp

We still need to intialize our Flask app. We can do that in the __init__.py file.

HelloShopify/helloshopify/__init__.py

Congrats, you’ve made it this far! Now lets get our application launched! Lets use Flask-Script library to manage our cli stuff. Lets create our manage.py file:

HelloShopify/manage.py

Initialize our database and launch our application:

python manage.py initdb
python manage.py run_debug

Open up your browser and go to https://localhost:5000/shopify?shop=<shop_name>.myshopify.com and you should be prompted to install the application to your test store.

Conclusion

At this point our app should be ready to go and fully installed. You can find the full source here. Enjoy!

Mixed Content on Chrome and Cert Issue

I ran into a little bit of difficulty getting some aspects of the app loading due to SSL. Here is what worked for me to get the dev up and running.

  • Launch Chrome in such that it allows running insecure content by running the following in terminal. Note that your paths might be different.
open /Volumes/Macintosh\ HD/Applications/Google\ Chrome.app — allow-running-insecure-content &
  • If your app is installed showing as installed but does not display your content. Open up developer tools in chrome and check to see if you got a “Failed to load resource: net::ERR_INSECURE_RESPONSE”. Click through on that link and authorize chrome to load the url.

Further Troubleshooting

  • In the app developer panel in the callback url dont forget the SSL (https:// instead of http://).
  • Redirection URL contains www. when its not supposed to
  • If ShopifyApp.Ready is not firing, make sure that in your app settings you are using SSL in the URL

Basically most of the issues I’ve encountered center around matching the URLs you put in the developers panel and what our Flask app is actually listening / routing to.

Acknowledgements

  1. Good blog post and intro to the embedded SDK that goes much further into detail on how authentication works and also the Javascript API
  2. Shopify developer community
  3. Shopify oauth documentation
  4. SSL issues with Javascript API

Other resources

  1. Flask Shopify extension (not maintained and probably doesn’t work but could provide some insights).
  2. Django Shopify

I hope you enjoyed my post. Follow me here on medium or on twitter and let me know if you have any questions.

--

--

Vasily Dernis

Tech lead Relitek Inc — Specializing in application development both frontend and backend.