Serverless Shopify Apps Using Python and AWS Chalice

Naveed Khan
Jun 28 · 7 min read

Recently I was tasked with doing a security review of our Shopify integration and I wanted to go all the way in by building a Shopify App using Serverless technology. It proved to be quite a challenge, and I am sharing my learnings and code here with the hope of helping anyone else trying to figure this out.

Shopify, as you might be aware, is a popular E-Commerce platform. Shopify Apps are standalone web applications that integrate with Shopify through OAuth to extend its functionality or to provide custom behavior.

The idea of extending a platform with web apps sounds great but I did not want to setup my own server infrastructure to run these apps. This lends perfectly to a serverless deployment, but managing a serverless deployment with all its configurations and API endpoints can be a hassle. That’s where AWS Chalice comes into picture.

Image for post
Image for post
Photo by Roberto Cortese on Unsplash

Chalice is a framework for writing serverless applications using Python and AWS Lambda. You can completely manage your serverless deployments with a command line tool and it also includes a local development environment. Because Chalice uses local files, you can use Git to version control all your changes. I’ve linked my GitHub repo at the bottom of this post that you may use as a starting point for your own apps.

If you are interested in learning more about Chalice my friend Larry has put together a two-part video series that you may find useful. Check them out here Part 1 and Part 2.

Shopify Partner Account: To create and deploy Shopify applications you need a Shopify Partner Account and a Development Store, you can do that on the Shopify Partner Page. They have documented it well so I am not going to go into a lot of detail in this post, feel free to reach out if you are stuck or need help.

AWS: As the title implies, you will also need an AWS account, what I like about using serverless features is that you can start for free and pay for what you use.

Docker: If you want to follow my guide you will need Docker installed locally on your computer. Supposedly VirtualEnv can be used as well, however I prefer the complete control I get with Docker.

Once you’re ready, go ahead and create a new App in the Shopify dashboard. I used a Custom App for my development, but you can create a Public one if you plan to make yours available to many stores.

Image for post
Image for post
Create a Shopify App on the Apps Page

Note that creating the App in Shopify just defines sort of an entry point, you must next write the actual code for the application and deploy it on web so Shopify can integrate with it. As discussed above we will be writing our app code in Python and deploying it on AWS Lambda using the Chalice framework. To get going we need to install Chalice on our local development environment and configure AWS so we can deploy it when we are ready.

We need Python, PIP and Chalice installed to get started. Depending on your operating system this can be done as explained on the Getting Started with Chalice page. I have already setup everything using Docker so you can just clone my repo and run the chalice-env script to get going.

% git clone https://github.com/naveed125/shopify-serverless-app.git
Cloning into 'shopify-serverless-app'...
remote: Enumerating objects: 36, done.
remote: Counting objects: 100% (36/36), done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 36 (delta 6), reused 31 (delta 5), pack-reused 0
Unpacking objects: 100% (36/36), done.
% cd shopify-serverless-app

You will now need to create two configuration files.

  1. Create a ./aws/config file with your AWS credentials. I’ve included a template at ./aws/config.tmpl that you can start with. Here is how the file should look like:
[default]
aws_access_key_id=YOUR_ACCESS_KEY_ID
aws_secret_access_key=YOUR_SECRET_ACCESS_KEY
region=YOUR_REGION

I suggest creating a new IAM user for this exercise, watch this video by aws team if you are not sure.

2. Create the Chalice config file. You can start with copying app/.chalice/config.json.tmpl from my repo into app/.chalice/config. Here is how it should look like:

{
"version": "2.0",
"app_name": "app",
"stages": {
"dev": {
"api_gateway_stage": "api",
"environment_variables": {
"SHOPIFY_API_KEY": "YOUR APP KEY HERE",
"SHOPIFY_API_SECRET": "YOUR APP SECRET HERE",
"AWS_API_BASE_URL": "YOUR APP AWS BASE URL"
}
}
}
}

You can get the Shopify App Key and Secret from the Shopify Partner Dashboard on the App page as shown below. We’ll get the AWS_API_BASE_URL after deploying our app to AWS.

Image for post
Image for post
Shopify App API Key

It is now time to start our Docker container with everything we need. Use the chalice-env script included in my repo to do so as I am showing below:

% ./chalice-env
Sending build context to Docker daemon 171.5kB
Step 1/5 : FROM python:3.8-slim-buster
---> 9d84edf35a0a
Step 2/5 : WORKDIR /app
---> Using cache
---> f33a7bc64917
Step 3/5 : COPY app /app
---> 167e6a39a672
Step 4/5 : COPY aws/config /root/.aws/config
---> d3023b0e3cd5
Step 5/5 : RUN pip install chalice httpie
---> Running in 1544f2b62117
Collecting chalice
...
---> bf6023df9a24
Successfully built bf6023df9a24
Successfully tagged shopify_serverless_app:latest
root@44434b3339a2:/app#

You are now ready to do your work. Try running the local Chalice instance and hitting it with Httpie that’s included in the Dockerfile. Httpie is just a nicer alternative to curl and I’ve included in the Dockerfile:

# chalice local &
Serving on http://127.0.0.1:8000
# http localhost:8000
127.0.0.1 - - [28/Jun/2020 21:39:12] "GET / HTTP/1.1" 200 -
HTTP/1.1 200 OK
Content-Length: 9
Content-Type: text/plain
Date: Sun, 28 Jun 2020 21:39:12 GMT
Server: BaseHTTP/0.6 Python/3.8.3
STATUS OK

We now need to code two end-points in your Python app to make Shopify OAuth work. Read the full Shopify OAuth guide before continuing. Namely our app needs the following end-points:

  1. Ask for Permission
  2. Confirm Install and Retrieve the Access Token

Checkout app/app.py in my repo to see how it works.

We are ready to deploy our code to AWS Lambda, but first we need to make sure that Chalice has permissions to do so. I did not find good documentation on this and others have found this to be a pain point as well.

Following is the AWS policy that worked for me, it is a bit broad, so don’t use it for production.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"apigateway:DELETE",
"apigateway:PUT",
"apigateway:PATCH",
"apigateway:POST",
"apigateway:GET"
],
"Resource": "arn:aws:apigateway:*::*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"lambda:*",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:ListRolePolicies"
],
"Resource": "*"
}
]
}

I’ve included this in the aws/aws-policy.tmpl as a template. You need to set this up in the AWS Dashboard, once done, you can deploy your code to AWS as shown here:

# chalice deploy
Creating deployment package.
Updating policy for IAM role: app-dev
Updating lambda function: app-dev
Updating rest API
Resources deployed:
- Lambda ARN: arn:aws:lambda:XXXXXX:XXXXXXXXXXX:function:app-dev
- Rest API URL: https://XXXXXXXXXXX.execute-api.XXXXXXXX.amazonaws.com/api/

The last few steps involve updating the App in Shopify Dashboard to use your new endpoint as shown here:

Image for post
Image for post

Our app is pretty much ready, copy paste the “Merchant Install link” into your browser and complete the integration.

Image for post
Image for post

At this point you should see the Installed app in your Store Dashboard and you can extend it further to respond to different Shopify events.

Image for post
Image for post
Shopify Store Installed App

Creating and installing a Serverless App into Shopify does not require a lot of coding, as a matter of fact I spent most of my time dealing with configurations.

My complete starter app repo is available here for you to look at and use as a starting point.

You might notice that it’s not a lot of code, part of it is because I’ve not included any code that provides any specific functionality, my goal was to create a starting point that any one can use.


I hope you found this useful, if you get stuck or need help, feel free to reach out.

A huge shout out to Shopify for creating an extendable commerce platform using open standards that anyone can contribute to.

Cheers

The Startup

Medium's largest active publication, followed by +704K people. Follow to join our community.

Naveed Khan

Written by

Director of Software Engineering at Glu Mobile. Occasionally I write about software development at medium and effective-programmer.com

The Startup

Medium's largest active publication, followed by +704K people. Follow to join our community.

Naveed Khan

Written by

Director of Software Engineering at Glu Mobile. Occasionally I write about software development at medium and effective-programmer.com

The Startup

Medium's largest active publication, followed by +704K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store