PythonでBASEのAPIを叩いて商品を一括更新してみる


今回はPythonでBASEのAPI処理の内、「更新」に関する処理を実装してみます。

APIの解説ページはこちらです。

POST /1/items/edit

処理の流れについては前回紹介した削除と同様、以下の様なものです。

1.ファイル選択のダイアログを開き、処理対象のCSVを選択する。

2.~処理~

3.処理結果が記述されたCSVを出力。

使用するCSVも同じですので、詳細については以下の記事を参照して下さい。


スポンサーリンク

商品情報の更新を行うソースコード

そして今回更新用に作成したコードは以下の通りです。

import os
import requests
import json
import csv
import tkinter, tkinter.filedialog, tkinter.messagebox
from enum import Enum, IntEnum, auto

'''
-----------------------------------------------------------------
 ダイアログで指定したCSVファイルのデータを用い、
 ショップ上の商品データを更新する
-----------------------------------------------------------------
'''
def update_item():
    MSGBOX_TITLE = "商品データ更新処理"

    filepath = get_filepath_dialog(MSGBOX_TITLE)
    if filepath == "":
        return

    with open(filepath, "r", newline="") as f:
        item_list = list(csv.reader(f))
        
    access_token = get_accesstoken()
    header = {
        "Authorization": "Bearer " + access_token,
        }
    param = {}
    cnt = 0

    send_request = False

    result_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "upd_result.csv")
    with open(result_filepath, "w", newline="") as f:
        writer = csv.writer(f)

        # ヘッダ出力
        writer.writerow({"item_id", "title", "result"})

        for idx, item in enumerate(item_list):    
            # 基本データを格納
            param["item_id"] = item[Items.ID]
            param["title"] = item[Items.TITLE]
            param["detail"] = item[Items.DETAIL]
            param["price"] = item[Items.PRICE]
            param["stock"] = item[Items.STOCK]
            param["visible"] = item[Items.VISIBLE]
            param["list_order"] = item[Items.LIST_ORDER]
            param["identifier"] = item[Items.IDENTIFIER]

            # バリエーションデータはリストとしてセット
            if item[Items.VAR_TITLE] != "":
                if "variation_id" in param:
                    param["variation_id"].append(item[Items.VAR_ID])
                    param["variation"].append(item[Items.VAR_TITLE])
                    param["variation_stock"].append(item[Items.VAR_STOCK])
                else:
                    param["variation_id"] = [item[Items.VAR_ID]]
                    param["variation"] = [item[Items.VAR_TITLE]]
                    param["variation_stock"] = [item[Items.VAR_STOCK]]

            # 「最終データ」、
            # または「商品が切り替わる(IDが変わる)」タイミングでAPI送信フラグを立てる
            if idx == len(item_list) - 1:
                send_request = True
            elif item_list[idx][Items.ID] != item_list[idx + 1][Items.ID]:
                send_request = True

            # フラグがONであればAPIを叩いて商品データ更新
            if send_request:
                response = requests.post(APIURL_POST_ITEM_EDIT, params=param, headers=header)
                send_request = False
                param.clear()

                # 結果出力
                result = json.loads(response.text)
                if response.status_code != REQUEST_SUCCESS:
                    writer.writerow({item[Items.ID.value], 
                        item[Items.TITLE.value], "失敗:" + result["error_description"]})

    show_Msgbox(MSGBOX_TITLE, "処理が完了しました。\n結果はupd_result.csvに保存しています。")

さて、上記コードで商品名や商品説明、価格といった一般情報については問題無く更新する事ができるのですが・・・

実はこのままだとバリエーション部分の更新が反映されません。

・・・なんで?

公式のページには「※ variation_idとvariationとvariation_stockは配列で複数登録が可能です。」とありますので、

if "variation_id" in param:
    param["variation_id"].append(item[Items.VAR_ID])
    param["variation"].append(item[Items.VAR_TITLE])
    param["variation_stock"].append(item[Items.VAR_STOCK])
else:
    param["variation_id"] = [item[Items.VAR_ID]]
    param["variation"] = [item[Items.VAR_TITLE]]
    param["variation_stock"] = [item[Items.VAR_STOCK]]

この様な書き方にして初回のデータ作成時は配列として生成。

以降は配列に追加(append)していくという方法で実装しているんですが・・・配列だよなぁ・・・どういう事なんだろう。

商品名などが更新できている時点で構文的にはあっているという事なので、リクエストを送信してもエラーにはなりませんし先ほど書いた通りバリエーション以外の項目は正常に変更されています。

ますます分からない。

仕方無いので反映されないバリエーションの部分は一旦削除して、以下の様な形で実装し直します。

def update_item():
    MSGBOX_TITLE = "商品データ更新処理"

    filepath = get_filepath_dialog(MSGBOX_TITLE)
    if filepath == "":
        return

    with open(filepath, "r", newline="") as f:
        item_list = list(csv.reader(f))
        
    access_token = get_accesstoken()
    header = {
        "Authorization": "Bearer " + access_token,
        }
    param = {}
    cnt = 0

    send_request = False

    result_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "upd_result.csv")
    with open(result_filepath, "w", newline="") as f:
        writer = csv.writer(f)

        # ヘッダ出力
        writer.writerow({"item_id", "title", "result"})

        for idx, item in enumerate(item_list):    
            # 基本データを格納
            param["item_id"] = item[Items.ID]
            param["title"] = item[Items.TITLE]
            param["detail"] = item[Items.DETAIL]
            param["price"] = item[Items.PRICE]
            param["stock"] = item[Items.STOCK]
            param["visible"] = item[Items.VISIBLE]
            param["list_order"] = item[Items.LIST_ORDER]
            param["identifier"] = item[Items.IDENTIFIER]

            response = requests.post(APIURL_POST_ITEM_EDIT, params=param, headers=header)
            send_request = False
            param.clear()

            # 結果出力
            result = json.loads(response.text)
            if response.status_code != REQUEST_SUCCESS:
                writer.writerow({item[Items.ID.value], 
                    item[Items.TITLE.value], "失敗:" + result["error_description"]})

    show_Msgbox(MSGBOX_TITLE, "処理が完了しました。\n結果はupd_result.csvに保存しています。")

スポンサーリンク

バリエーション在庫の更新はできる

バリエーションの更新どうすれば良いんだろう・・・

と、暫く試行錯誤していたのですが、よくよく考えるとタイトルや商品説明、価格なんかはよく修正したりしますが、例えばカラーやサイズバリエーション(「S、M、L」や「レッド、グリーン、ブルー」といった選択肢項目)を追加したり変更するってまず無いですよね。

そう考えると別にバリエーションの更新が出来なくてもあんまり問題無い気がする。

とは言ってもせめてバリエーションの在庫数位は更新したい!

と思う事はあると思いますので、こちらのAPIを使ってみます。

POST /1/items/edit_stock

こちらは「edit_stock」の名の通り「商品情報の在庫数を更新」するためのAPIです。

NameDescription
item_id商品ID (必須)
stock在庫数 (必須 バリエーションの在庫数を更新したい場合は任意)
variation_idバリエーションID (任意 バリエーションの在庫数を更新したい場合は必須)
variation_stockバリエーションの在庫数 (任意 バリエーションの在庫数を更新したい場合は必須)

リクエストパラメーターはシンプルに4つのみ。

バリエーションの場合の配列指定なども無く、これならうまくいくんじゃないかと思い以下のcsvで実験。

そしてこちらが変更前の各在庫数。

こちらが処理後。

 

在庫数の設定が反映されているのが分かりますね。

そしてこちらが在庫更新用のソースコードになります。

'''
-----------------------------------------------------------------
 ダイアログで指定したCSVファイルのデータを用い、
 ショップ上の商品データを更新する
-----------------------------------------------------------------
'''
def update_stock():
    MSGBOX_TITLE = "在庫更新処理"

    filepath = get_filepath_dialog(MSGBOX_TITLE)
    if filepath == "":
        return

    with open(filepath, "r", newline="") as f:
        item_list = list(csv.reader(f))
        
    access_token = get_accesstoken()
    header = {
        "Authorization": "Bearer " + access_token,
        }
    param = {}
    cnt = 0

    send_request = False

    result_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "updstock_result.csv")
    with open(result_filepath, "w", newline="") as f:
        writer = csv.writer(f)

        # ヘッダ出力
        writer.writerow({"item_id", "title", "result"})

        for idx, item in enumerate(item_list):    
            # 基本データを格納
            param["item_id"] = item[Items.ID]
            param["stock"] = item[Items.STOCK]
            param["variation_id"] = item[Items.VAR_ID]
            param["variation_stock"] = item[Items.VAR_STOCK]

            response = requests.post(APIURL_EDIT_STOCK, params=param, headers=header)
            send_request = False
            param.clear()

            # 結果出力
            result = json.loads(response.text)
            if response.status_code != REQUEST_SUCCESS:
                writer.writerow({item[Items.ID.value], 
                    item[Items.TITLE.value], "失敗:" + result["error_description"]})

    show_Msgbox(MSGBOX_TITLE, "処理が完了しました。\n結果はupdstock_result.csvに保存しています。")

まとめ

「items/edit」を使えば商品情報の更新は行えますが、(サイズ/カラー)バリエーションデータの更新についてはいまいちよく分かりませんでした。

しかし、「items/edit_stock」を使えばバリエーションデータの「在庫数」については更新する事が可能という事が分かりました。

他にもAPIは幾つかありますが、大体どれも上で掲載したサンプルコードのパラメータ部分を変えるだけなので特に触れません。

という事でBASEのAPI操作に関してはこれで終了の予定です。

後、今更ですが掲載しているソースコードをそのままコピーしても動きませんのであしからず。

とりあえずPython入れてない方はPython3をインストールして下さい。

そしてrequestsとか一部のライブラリは追加でインストールして、独自関数になっている所は大体過去記事に関数の中身を載せているのでそちらを参照して下さい(適当)。

わからない人はPython勉強しよう!

さすがに投げっぱなし過ぎな気がしたので、GUIフォームの作成練習も兼ねて単体で動かせるものを作ってみようかと思います。完成次第公開する予定です。

さて次の予定ですが、CSVによる一括編集機能が有料オプションなのにAPIは無料で使えるというよく分からないサービスを行っているWowmaを対象に何かやってみたいと思います。

月額1万円のオプションサービスとか高過ぎじゃないですかねぇ・・・金取る所間違ってるんじゃないかと思う。

関連記事と広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする