Webは用いる人のリテラシーで決まる ウェブ運用と開発現場を経験したエンジニアのTIPS
TOP > BLOG > IT記事

PythonとGraphQLでShopifyの在庫を一括更新しよう

早川朋孝 早川朋孝
EC専門のSE

Shopifyの在庫更新をPythonとGraphQLを使ってやってみよう。ShopfiyのAPIにはRESTとGraphQLの2種類のリクエスト方法があるが、両者を比較すると明らかにGraphQLのほうが軽量で扱いやすい。

というのも、RESTの場合、例えば在庫を取得するにしても在庫以外の余計な情報が返ってくる。これはつまりプログラムで余計なメモリを消費することを意味するわけで、明らかにGraphQLのほうがメリットが大きいだろう。

とくに商品数が数万点におよぶなどの場合にGraphQLの恩恵をより感じられるだろう。よほどの事情がない限りShopifyのAPIはGraphQLでリクエストすることを勧める。

在庫更新にはいくつか方法があるが、今回はinventorySetOnHandQuantitiesで更新する方法を紹介する。ShopifyのAPIの認証に必要なのはtokenとshopのurlだが、tokenはすでに発行されているものとする。

inventory_item_idを取得するPythonのコード

Shopifyの場合skuだけで更新できないのが楽天などの他のモールAPIとの違いだろう。skuを軸にして、inventory_item_idを照会しないとならない。また、現時点でShopifyのAPIの一度のリクエストの上限は250なので、その点にも留意する必要がある。ページネーションで次の情報がある場合は、RESTならレスポンスのheaderに情報が含まれているし、GraphQLならレスポンスのなかにhasNextPageという項目があり、ある場合はTrueとある。また、nextPageCursorに必要な情報が格納されている。

import requests
import json

url = '/admin/api/2023-01/graphql.json' #graphQLのエンドポイント
shop_url = 'https://hogehoge.myshopify.com' #利用環境に準ずる
token = 'hogehoge' #利用環境に準ずる
cursor = '' #pagenationの値
limit = 250 #一度のリクエスト上限

headers = { 
             'Content-Type': 'application/json',
             'X-Shopify-Access-Token': token,
}   

data = '{ inventoryItems(first: ' + str(limit) + ',' 
if cursor != None:
    data += 'after: ' + '"' + cursor + '"' 
data += ''') {
              edges {
               #cursor
               node {
                id  
                sku 
               }   
              }   
              pageInfo{
               hasNextPage
               endCursor
              }   
             }   
}'''

url = shop_url + url 
response = requests.post(url, headers=headers, json={'query': data})
if response.status_code == 200:
    json_data = json.loads(response.text)

これは一度のリクエストをするだけなので、取り扱い商品数が250点以上の場合は、必要に応じて繰り返し処理をする。レスポンスのなかにskuとinventory_item_idがある。これでskuを元に関連付けができる。

在庫を更新する

在庫更新に必要なのは以下の情報だ。

  • sku
  • inventory_item_id
  • location_id

location_idはどの店舗のidであるかを示すIDを指す。運営している店舗が1店舗なら1つしかないし、複数ならその数の分だけある。つまりShopifyの在庫に関する仕様は、店舗ごとに個別の在庫を持てるということだ。当たり前といえば当たり前なのだが、この仕様のおかげでAPIの仕様がやや複雑になっている。

#更新したい商品の情報を配列に格納する
items_inventory_info =  [{'quantity': 80, 'inventory_item_id': str,  'locationId': location_id}] 
location_id = 'hogehoge' #利用環境に準ずる

headers = { 
             'Content-Type': 'application/json',
             'X-Shopify-Access-Token': token,
}   
    
query = ''' 
         mutation inventorySetOnHandQuantities($input: InventorySetOnHandQuantitiesInput!) {
          inventorySetOnHandQuantities(input: $input) {
           userErrors {
            field
            message
           }   
           inventoryAdjustmentGroup {
            createdAt
            reason
            changes {
             name
             delta
            }   
           }   
          }   
         }   
''' 
    
url = '/admin/api/2023-01/graphql.json' #graphQLのエンドポイント
url = shop_url + url 

variables = dict({
              "input": {
               "reason": "correction",
               "setQuantities": items_inventory_info
               }
             }
)
res = requests.post(url, headers=headers, json={'query': query, 'variables': variables})
response.append(res)

以上でShopify店舗の在庫更新ができる。

×
このブログを書いてる人
早川 朋孝 EC専門のSE
IT業界歴20年のエンジニアです。ネットショップ勤務で苦労した経験から、EC・ネットショップ事業者に向けて、バックオフィス業務の自動化・効率化を提案するSEをしています。
プロフィール
API連携の相談にのります
趣味は読書、ピアノ、マリノスの応援など
PAGE TOP