In this post, we'll use Shopify Admin API to create collections in our store. Before we go on, you are going to need a development store and create a private app where it provides API credentials to interact with store data.
I highly recommend watching the video below to set up a development store in Shopify:
If you already have one, then let's start migrating categories to our Shopify store.
Building Shopify Client
In this part, we are going to build client to interact with Shopify API by sending requests and receiving responses. Simply, we are creating a separate class where it holds all request-response logic and related attributes. That'll make our project more clean and maintainable in the future.
Create an empty directory named client
and inside it add __init__.py
the file which makes it a python package. Next, create another file named shopify_client.py
and start by adding a class named ShopifyClient
:
client/shopify_client.py
import json
import requests
class ShopifyClient:
def __init__(self, api_password: str, shop_url: str, endpoint: str):
self.api_password = api_password
self.shop_url = shop_url
self.endpoint = endpoint
self.headers = {
"Accept": 'application/json',
"Content-Type": 'application/json'
}
The constructor includes the main properties of the client that will be used across functions to interact with Shopify API. For each request, we need the following properties:
api_password
- Password that is given in the private app of Shopify Dev Store.
shop_url
- Shop URL of development store.
endpoint
- Endpoint that will be used to send requests for.
headers
- Header rules to include for each request.
Shopify requires an authorization header, so it knows which particular shop data it should serve. At this point, we'll set only API password as value to header named X-Shopify-Access-Token
. Let's continue by creating a new function named api_request
that will handle all types of requests:
client/shopify_client.py
def api_request(self, *args, **kwargs):
self.headers.update({
"X-Shopify-Access-Token": self.api_password
})
context = {
"method": kwargs.get("method"),
"url": f"{self.shop_url.rstrip('/')}{self.endpoint}",
"timeout": 60,
"headers": self.headers
}
if kwargs.get("method") == "POST":
context["data"] = json.dumps(kwargs.get("data"))
return requests.request(**context).json()
Simply, we're updating the headers to include the authorization header as well. Now, let's see what's inside context:.
method
- It defines the request method type such as GET, POST or DELETE and takes the value from kwargs.
url
- The shop_url concatenated with endpoint to produce an absolute URL where the requests will be sent.
timeout
- Maximum time of waiting for a response.
After that, we're checking if the method
is POST
then insert data
inside context
as well. Once the context
is built the request()
function will send it and return a response as a json
.
Adding Data Models
Now, we need a dummy dataset where it'll migrate to Shopify. To achieve that, we can use factory_boy
package to produce fake data based on the specific model. Create a directory named data and also include __init__.py
file inside it. Let's create the base structure of our model by using dataclass
:
data/entities.py
from dataclasses import dataclass
@dataclass
class Category:
title: str
body_html: str
published: bool
sort_order: str
image: str
Where all these attributes are coming from? The attributes represent required fields of Shopify Collections API.
Currently, we only need the fields above to create a Shopify Collection. The list of belonged products will remain empty for now since we don't have one. Now, it's time to create factories using factory_boy
to produce some data to migrate it later.
data/factories.py
import factory
import factory.fuzzy
from data.entities import Category
class CategoryFactory(factory.Factory):
class Meta:
model = Category
title = factory.Faker('name')
body_html = factory.Faker('sentence')
published = factory.fuzzy.FuzzyChoice([True, True, True, False])
sort_order = "manual"
image = factory.Faker('image_url')
This factory above creates instances of Category
model with fake data based on the attributes we provide by using Faker
. In other words, we are mocking the Category
class to test our functionalities.
Migration of Categories
So, we finished setting up the client and produce some fake data to migrate it later. Now, it's to start creating the base logic which will put everything together and migrate all data to Shopify. Create another file named category.py
in the root level of your directory:
category.py
import logging
from client.shopify_client import ShopifyClient
from data.factories import CategoryFactory
class CategoryMigration:
def __init__(self):
self.log = logging.getLogger(__name__)
logging.basicConfig(level = logging.INFO)
self.client = ShopifyClient(
api_password="YOUR_API_PASSWORD",
shop_url="YOUR_SHOP_URL",
endpoint=ShopifyStoreAdmin.COLLECTION_ENDPOINT.value
)
We are going to use logging
module to print data in the console to see the process in real-time. Also, initializing the Shopify client to make it ready for sending requests.
Next, let's use the factory to produce a list of instances with fake data:
def generate_categories(self):
category_data = CategoryFactory.create_batch(5)
collections_shopify = []
for category in category_data:
collection_row = {
"custom_collection" : {
"title": category.title,
"body_html": category.body_html,
"published": category.published,
"sort_order": category.sort_order,
"image": {"src": category.image }
}
}
collections_shopify.append(collection_row)
return collections_shopify
As you see, we are building the object structure as Shopify requires and appending it into the list. The python dictionary will be converted to actual json
in our client whenever request prepared to be sent.
def migrate(self):
collections_shopify = self.generate_categories()
for collect in collections_shopify:
res = self.client.api_request(
method="POST",
data=collect
)
self.log.info("Response %s", res)
categories_migration = CategoryMigration()
categories_migration.migrate()
Lastly, iterate through generated data and send them to Shopify by using POST the method. The logs will let us know what's going on behind the scenes.
Great! Now you can run the file and watch the migration of data to your development store.
python category.py
Source code available:
PylotStuff / shopify-migration
Migrating data using Shopify API
shopify-migration
Migrating categories data using Shopify API.
This project illustrates migration of source data to Shopify by using Shopify API
and Python
.
Getting Started
Required Python 3+.
Install dependencies:
python3 -m pip install -r requirements.txt
and run:
python category.py
for more information:
Project NFT
Video Explanation with more details
Support 🌏
If you feel like you unlocked new skills, please share them with your friends and subscribe to the youtube channel to not miss any valuable information.
Top comments (1)
Hi, would you like to collaborate with us by making a dedicated article?