【Python】Amazon SP-APIの利用方法

# 【Python】Amazon SP-APIの利用方法
Amazonの新しいAPI SP-APIの利用方法について、紹介します。


:::note info
2023 年 10 月 2 日以降、SP-API ではAWS Identity and Access Management (IAM) またはAWS 署名バージョン 4を使用する必要がなくなりました。

https://developer-docs.amazon.com/sp-api/changelog/sp-api-will-no-longer-require-aws-iam-or-aws-signature-version-4
:::

:::note info
SP-APIの更新によるAPIの廃止に関しては、下記公式リンクを参照してください。
非推奨のAPIは、削除日を過ぎると、利用できなくなります。

https://developer-docs.amazon.com/sp-api/docs/sp-api-deprecations
:::

SP-APIについての公式サイト

https://developer-docs.amazon.com/sp-api/docs/what-is-the-selling-partner-api

Python SP-APIについては以下の公式サイトを参照。

https://sp-api-docs.saleweaver.com/


:::note info
上記、Python SDKでもAPIは利用可能だが、公式でSDKをリリースしてました。
https://developer-docs.amazon.com/sp-api/docs/tutorial-automate-your-sp-api-calls-using-python-sdk

利用手順(Javaで各APIごとにPython SDKをビルドする必要があります。)
1. SPAPI_Python_SDKフォルダを作成する
1. フォルダへ移動して、下記を実行する
   ```
   git clone https://github.com/amzn/selling-partner-api-models
   wget https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.13/swagger-codegen-cli-2.4.13.jar -O swagger-codegen-cli.jar
   pip install  backoff wheel
   ```
1. Javaをインストールする
   https://www.java.com/ja/download/help/download_options_ja.html
1. 下記を実行する。例）catalogItems APIのPython SDK作成コマンド
   ```
   java -jar swagger-codegen-cli.jar generate -l python -t selling-partner-api-models\clients\sellingpartner-api-aa-python\resources\ -D packageName=swagger_client -o selling-partner-api-models\clients\sellingpartner-api-aa-python -i selling-partner-api-models\models\catalog-items-api-model\catalogItems_2022-04-01.json
   ```
1. 下記ファイル中のパスを変更する
   ```path:selling-partner-api-models\clients\sellingpartner-api-aa-python\spapi\spapiclient.py
   #Update Path
   sys.path.append('SPAPI_Python_SDK/selling-partner-api-models/clients/sellingpartner-api-aa-python')
   from swagger_client.configuration import Configuration
   from swagger_client.api_client import ApiClient
   
   #Update Path
   sys.path.append('SPAPI_Python_SDK/selling-partner-api-models/clients/sellingpartner-api-aa-python')
   from auth.LwaRequest import AccessTokenCache
   ```
   ```path:selling-partner-api-models\clients\sellingpartner-api-aa-python\auth\LwaRequest.py
   #Update path
   sys.path.append("Workfolder/SPAPI_Python_SDK/selling-partner-api-models/clients/sellingpartner-api-aa-python")
   ```
1. sellingpartner-api-aa-python\test.pyを実行する
1. sellingpartner-api-aa-python\setup.pyを実行する
   ```
   python setup.py bdist_wheel
   pip install .\dist\swagger_client-1.0.0-py3-none-any.whl
   ```
:::


公式Youtube動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/AjNII3k6VM4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## 各APIについて

 - AplusContent：商品のA+コンテンツを管理するためのAPI。
 - Authorization：SP-APIのOAuth2.0認証エンドポイント。
 - <font color="Green">Catalog：商品カタログに関する情報を取得するためのAPI。</font>
 - <font color="Green">CatalogItems：商品カタログアイテムに関する情報を取得するためのAPI。</font>
 - FbaInboundEligibility：商品がFBA入庫に対して適格かどうかを確認するためのAPI。
 - FbaSmallAndLight：FBA Small and Lightプログラムに対応する商品を管理するためのAPI。
 - <font color="Green">Feeds：商品、注文、返品などのデータをファイル形式でアップロード、ダウンロードするためのAPI。</font>
 - Finances：セラーのアカウントに関する金銭取引情報を管理するためのAPI。
 - FulfillmentInbound：FBA在庫を納品するためのAPI。
 - FulfillmentOutbound：FBA在庫を出荷するためのAPI。
 - <font color="Green">Inventories：商品の在庫情報を管理するためのAPI。</font>
 - <font color="Green">ListingsItems(※必sellerid)：商品のリストアップやアップデート、削除などのリストアクションを行うためのAPI。</font>
 - <font color="Green">ListingsRestrictions(※必sellerid)：特定の商品に関するリスティング制限に関する情報を取得するためのAPI。</font>
 - MerchantFulfillment：出荷ラベルを印刷し、メール便のラベルを生成するためのAPI。
 - Messaging：バイヤーとのメッセージングに関する情報を取得するためのAPI。
 - Notifications：アクティビティ通知に関する情報を取得するためのAPI。
 - <font color="Green">Orders：注文データに関する情報を取得するためのAPI。</font>
 - Restricted Data Token：リクエストに必要なRestricted Data Tokenを発行するためのAPI。
 - <font color="Green">Product Fees：商品手数料に関する情報を取得するためのAPI。</font>
 - <font color="Green">ProductTypeDefinitions：商品の属性に関する情報を取得するためのAPI。</font>
 - <font color="Green">Products：商品に関する情報を取得するためのAPI。</font>
 - <font color="Green">Reports：商品、注文、財務などのレポートデータをダウンロードするためのAPI。</font>
 - Sales：商品の売上に関する情報を取得するためのAPI。
 - <font color="Green">Sellers：セラーに関する情報を取得するためのAPI。</font>
 - Services：アカウントに関するサービスに関する情報を取得するためのAPI。
 - Shipping：送料に関する情報を取得するためのAPI。
 - Solicitations: Amazonセラーセントラルに表示される顧客からの返信を含む、販売者に対する商品レビューやセラーのフィードバックを管理するためのAPI。
 - Upload: Amazon S3バケットにファイルをアップロードするためのAPI。
 - VendorDirectFulfillmentInventory: ベンダーが直接フルフィルメントする商品の在庫を管理するためのAPI。
 - VendorDirectFulfillmentOrders: ベンダーが直接フルフィルメントする注文を管理するためのAPI。
 - VendorDirectFulfillmentPayments: ベンダーが直接フルフィルメントする商品に関する支払い情報を管理するためのAPI。
 - VendorDirectFulfillmentShipping: ベンダーが直接フルフィルメントする商品の配送情報を管理するためのAPI。
 - VendorDirectFulfillmentTransactions: ベンダーが直接フルフィルメントする商品に関する取引情報を管理するためのAPI。
 - VendorInvoices: ベンダーによって発行された請求書の情報を管理するためのAPI。
 - VendorOrders: ベンダーによって処理される注文に関する情報を管理するためのAPI。
 - VendorShipments: ベンダーが商品を発送するために使用する情報を管理するためのAPI。
 - VendorTransactionStatus: ベンダーが提供する商品に関する取引ステータスを管理するためのAPI。

## アカウント作成

SP-APIの利用には以下の二つのアカウントが必要である
1. セラーセントラルの大口出品者アカウント
1. ~~AWSアカウント~~ ※現在は不要

**各マーケットプレイスで対応するAWSのリージョンが異なるため、セラーセントラルアカウントが認証されたリージョンで、SP-APIのAPIキーを取得する必要がある。** そうしないと悪名高い以下のエラーが吐かれる。

```
"message": "Access to requested resource is denied.",
```

| 出品リージョン| エンドポイント|	AWSリージョン|
|---|---|---|
|北米（カナダ、米国、メキシコ、ブラジルのマーケットプレイス）|	https://sellingpartnerapi-na.amazon.com	|us-east-1|
|ヨーロッパ（スペイン、英国、フランス、オランダ、ドイツ、イタリア、トルコ、アラブ首長国連邦、インドのマーケットプレイス）|	https://sellingpartnerapi-eu.amazon.com|	eu-west-1|
|極東地域（シンガポール、オーストラリア、日本のマーケットプレイス）|https://sellingpartnerapi-fe.amazon.com|	us-west-2|

https://developer-docs.amazon.com/sp-api/docs/what-is-the-selling-partner-api

## 事前準備(IAMユーザーの作成、APIキーの生成)

:::note alert
現在は"1. AWS IAMの設定"は不要になりました。
"2. セラーセントラル設定"のみでSP-API キーが取得・利用可能です。
:::

### 1. AWS IAMの設定 ※不要

<details><summary>設定手順を開く</summary>

#### IAMユーザーの作成
1. https://us-east-1.console.aws.amazon.com/console/home?region=us-east-1 を開く
1. IAM->ユーザー->ユーザーを追加を押す
 ![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/cf6b0659-aade-43f7-fd55-1c41212e6226.png)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/74da18d5-1b2d-a197-3d00-f057ad42cca0.png)
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/b25bde6d-9dde-5174-7578-1d300d8ec727.png)
1. ユーザー名にAWS_IAM_SPAPI_Access_Userを入れる
1. ~~プログラムによるアクセスにチェックを入れる~~
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e043096c-8be7-5aa8-2130-e386969c9f58.png)
1. 次へを押す
1. ポリシーを直接アタッチするを選択する
1. 次へを押す
1. 画面下にあるユーザーの作成を押す
1. 作成したユーザー名を押す
1. セキュリティ認証情報のタブを押す
1. アクセスキーの項目でアクセスキーを作成を押す
1. ローカルコードを選択して、下部のチェックボックスにチェックを入れて、次へを押す
1. アクセスキーを作成を押す
1. csvのダウンロードを押して、アクセスキーとシークレットキーを取得する
![IAM_0308.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9c137f3c-17d6-be42-9fc6-cc18a0f2bef9.png)


#### IAMポリシーの作成
1. IAM->ポリシー->ポリシーを作成を押す
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/7e97aeec-b80f-a70a-aaee-9fc74732883d.png)
2. JSONのタブを選択
3. デフォルトのものを消して、以下をコピペする
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:*:*:*"
        }
    ]
}
```
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/b5380fa9-e223-c243-e4fd-d0dd892afc67.png)
4. 次のステップ：タグを押す
5. この画面はそのままで、次のステップ：確認を押す
6. 名称にAWS_IAM_SPAPI_Policyを入れて、画面下にあるポリシーの作成を押す
7. IAM->ユーザー->先ほど作成したAWS_IAM_SPAPI_Access_Userを押す
![8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/1aa38bfd-ced5-f949-d6df-6cb2e660dd23.png)
8. 許可の追加 -> 許可を追加を押す
9. 既存のポリシーを直接アタッチを押す
10. ポリシーのフィルタで先ほど作成したAWS_IAM_SPAPI_Policyを検索し、チェックを入れる
![9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9c570a6c-b5e4-453e-8548-893335a1c568.png)
11. 次のステップ：確認を押す
12. アクセス権限の追加を押す

#### IAMロールの作成

1. IAM->ロール->AWS_IAM_SPAPI_Access_Userを押す
2. ブラウザでタブを複製する。
3. IAM->ロール->ロールを作成を押す
![10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/3fead41d-d2a9-2de0-e163-55892a116aad.png)
4. カスタム信頼ポリシーを押す
5. 下部の入力画面のテキストを消して、下記に置き換える・
　※**ユーザーのIDはユーザーのARNで確認する**
```
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ユーザーのID:user/AWS_IAM_SPAPI_Access_User"
},
"Action": "sts:AssumeRole"
}
]
}
```
![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/936160eb-17b9-039e-c819-333b6cf206e0.png)
6. 次へを押す
7. トークン作成などの作業過程で作成したポリシー(例、AWS_IAM_SPAPI_Policy)にチェックを入れる
![12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/2f9902ef-9c5a-294b-c688-8ebc232ff792.png)
8. 次へを押す
9. ロール名をAWS_IAM_SPAPI_Access_Roleにして、ロールを作成を押す
10.  作成したロール名をクリックして、信頼関係を押し、信頼されたエンティティに上記で置き換えたテキストが記載されているか確認する。

</details>

### 2. セラーセントラル設定
下記に従い、設定を行う。

1. プライマリーユーザーでセラーセントラルにログインする
2. 左の設定画面から「アプリとサービス」->「アプリの開発」を押す
3. 左上の「プロフィールを表示」を押す。
4. 必要事項を記載していく
5. データアクセスでは、**プライベート開発者：自社をAmazonのサービスAPIと統合するアプリケーションを構築しています。** を選択する
各権限の内容は以下のサイトを参照。
https://developer-docs.amazon.com/sp-api/docs/authorizing-selling-partner-api-applications
6. ロールでは、**赤字で"制限"とあるもの以外すべてにチェックを入れる**
![SP-API_role.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/ff47c3b4-2544-bbc7-c280-c40f8c54c289.png)
各ロールの説明は以下のサイトを参照。
https://developer-docs.amazon.com/sp-api/docs/roles-in-the-selling-partner-api
7. その他必要事項を記載して、登録を押す
7. しばらく(10分~)すると、開発者登録の申請が通る
8. 新しいアプリクライアントを追加を押す
9. アプリ名をSPAPI_Access_Sample_App、APIタイプをSP-APIにする
10. IAM ARNはAWSから取得した**arn:aws:iam::**********:role/AWS_IAM_SPAPI_Access_Role** を入れる
11. ロールは、制限付きロール以外はすべてチェックを入れる
    ![17-1-574x1024 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/6289f97f-add3-0776-45c5-dc2756ae6040.png)
    
これでデベロッパーセントラル画面に登録したアプリケーションが表示されます。
12. 登録したアプリケーション名の横の「LWA認証情報」の”表示”をクリックして、**クライアントIDとクライアント機密情報** を取得する
    ![SP-APIクライアントID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/f3ac9880-2b32-e150-3333-61a03e931498.png)
13. 登録したアプリケーション名の横のアプリの編集->承認を押して、**リフレッシュトークン** を取得する

以上の設定で以下のAPIキーが取得できた

|ENVIRONMENT VARIABLE |DESCRIPTION|
|---|---|
|SP_API_REFRESH_TOKEN |承認によって取得された使用される更新トークン (代わりにクライアントに渡すことができます)|
|LWA_APP_ID |amazon アプリ ID でのログイン|
|LWA_CLIENT_SECRET |Amazon クライアント シークレットを使用したログイン|
|SP_API_ACCESS_KEY |AWS ユーザー アクセス キー|
|SP_API_SECRET_KEY |AWS ユーザー シークレット キー|
|SP_API_ROLE_ARN |ロールの arn (「Assume Role」STS へのアクセス許可が必要です)|

## サンプルコード

```Python
from sp_api.api import Catalog
from sp_api.base import SellingApiException
from sp_api.base.exceptions import SellingApiException
from sp_api.base.marketplaces import Marketplaces

credentials = dict(
    refresh_token='your_refresh_token',  # From Seller central under Authorise -> Refresh Token
    lwa_app_id='your_lwa_app_id',  # From Seller Central, named CLIENT IDENTIFIER on website.
    lwa_client_secret='your_lwa_client_secret',  # From Seller Central, named CLIENT SECRET on website.
    aws_access_key='your_aws_access_key',  # From AWS IAM Setup
    aws_secret_key='your_aws_secret_key',  # From AWS IAM Setup
    role_arn='your_role_arn'  #arn:aws:iam::1234567890:role/SellingPartnerAPIRole
)

def search_products(keyword: str):
    obj = Catalog(marketplace=Marketplaces.JP, credentials=credentials)
    result = obj.list_items(MarketplaceId=Marketplaces.JP.marketplace_id, 
                            Query=keyword, 
                            QueryContextId='All')
    return result()

KeyWord = 'おはよう'
print(search_products(KeyWord))
```

## 【別の方法】セラー向けパブリックアプリケーションのOAuth認証

1. 下記サイトを参照して、OAuth認証URIを作成する
OAuth 承認 URI は、販売パートナー API 承認ワークフローを作成およびテストするための重要なコンポーネントです。OAuth 認証 URI は、ブラウザを Amazon の同意ページにリダイレクトします。このページで、あなたまたは販売パートナーは、アプリケーションに販売パートナー API の呼び出しを行うことに同意することができます。

```
https://sellercentral.amazon.jp/apps/authorize/consent?application_id={your application ID}
https://sellercentral.amazon.jp/apps/authorize/consent?application_id=amzn1.sellerapps.app.0bf296b5-36a6-4942-a13e-EXAMPLEfcd28
```

https://developer-docs.amazon.com/sp-api/docs/authorizing-selling-partner-api-applications#constructing-an-oauth-authorization-uri

2. テスト用URIに変換する
```
https://sellercentral.amazon.jp/apps/authorize/consent?application_id={your application ID}&version=beta
```

3. 販売パートナーのアプリストアから認証を開始する
セラーセントラルにサインインし、販売パートナーのアプリストアに移動します。
アプリケーションの詳細ページを開きます。
[今すぐ認証]を選択します。

4. アプリケーションを承認するための同意
アプリケーションによって要求されたデータ アクセスを確認して受け入れます。
Login to [your application name] now を選択します。
Amazon はログイン URI (アプリケーションの登録時に指定したもの) をブラウザに読み込み、次のクエリ パラメータを追加します。

5. Web サイトにサインインする


6. Amazon から認証情報が送信されます
セラーセントラルは、Amazon がデータへのアクセスを許可していることを示す通知を表示します。このページが表示されている間、次のアクションが実行されます。

Amazon は OAuth リダイレクト URI をブラウザに読み込み、次のクエリ パラメータを追加します。

7. LWA リフレッシュ トークンの LWA 認証コードを交換する
```
POST /auth/o2/token HTTP/l.l
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
grant_type=authorization_code&code=SplxlOexamplebYS6WxSbIA&client_id=foodev&client_secret=Y76SDl2F
```

```json
HTTP/l.l 200 OK
Content-Type: application/json;
charset UTF-8
Cache - Control: no-store
Pragma: no-cache
{
  "access_token": "Atza|IQEBLjAsAexampleHpi0U-Dme37rR6CuUpSR",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "Atzr|IQEBLzAtAhexamplewVz2Nn6f2y-tpJX2DeX"
}
```
アプリケーションは値を保存します。refresh_token



https://developer-docs.amazon.com/sp-api/docs/connecting-to-the-selling-partner-api-using-a-generated-java-sdk


## 出品および価格・在庫更新の方法

:::note info
feed APIによる出品・価格・在庫更新は2025年3月31日に一部利用できなくなります。
https://developer-docs.amazon.com/sp-api/docs/sp-api-deprecations

2025年からは、以下のAPIを利用する必要があります。
・Listings Items API - 個々の商品を出品・価格・在庫更新
・feed API JSON_LISTINGS_FEED - 複数(最大10000件)を一括で出品・価格・在庫更新

以降の詳細は下記公式サイトで確認できる
https://developer-docs.amazon.com/sp-api/docs/migration-workflows-tutorial#migrating-inventory-feeds-workflows
:::

### feed API JSON_LISTINGS_FEEDの使い方

requirements
 - LISTING: 提出されたデータに製品の事実と販売条件が含まれていることを示します。これは、フラット ファイル フィードの「製品テンプレート」に関連します。
 - LISTING_PRODUCT_ONLY: 提出されたデータには製品の事実のみが含まれていることを示します。これは、各行でスキップ オファー機能が選択されたフラット ファイル フィードの「商品テンプレート」に関連付けられます。
 - LISTING_OFFER_ONLY: 送信されたデータに販売条件のみが含まれていることを示します。これは、フラット ファイル フィードの「Listing Loader」テンプレートに関連します。

出品データの送信のために実行する操作
 - "UPDATE" は、アイテム属性の完全なセットが提供され、既存の属性データが提供された属性で置き換えられることを示します。 
 - "PARTIAL_UPDATE" は、指定された項目属性のみが、指定された属性データで更新されることを示します。
   "replace" オペレーションで "PATCH" を使用することと同じです。 
 - "PATCH" は、提供された JSON Patch 操作が該当する属性の更新に使用されることを示します。 
 - "DELETE" は、リスト項目が削除されることを示します。 


:::note info
PARTIAL_UPDATEの時は、LISTING等は指定してはいけない
:::

価格と数量を更新するためのJSON_LISTINGS_FEED
```JSON:JSON
{
  "header": {
    "sellerId": "AXXXXXXXXXXXXX",
    "version": "2.0",
    "issueLocale": "ja_JP"
  },
  "messages": [
    {
      "messageId": 1,
      "sku": "ABC123",
      "operationType": "PATCH",
      "productType": "PRODUCT",
      "patches": [
        {
          "op": "replace",
          "path": "/attributes/purchasable_offer",
          "value": [
            {
              "currency": "JPY",
              "our_price": [
                {
                  "schedule": [
                    {
                      "value_with_tax": 5000.00
                    }
                  ]
                }
              ],
              "minimum_seller_allowed_price": [
                {
                  "schedule": [
                    {
                      "value_with_tax": 1000.00
                    }
                  ]
                }
              ],
              "maximum_seller_allowed_price": [
                {
                  "schedule": [
                    {
                      "value_with_tax": 10000.00
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "op": "replace",
          "path": "/attributes/fulfillment_availability",
          "value": [
            {
              "fulfillment_channel_code": "DEFAULT",
              "quantity": 5,
              "lead_time_to_ship_max_days": 1
            }
          ]
        }
      ]
    },
  ]
}
```



## まとめ
Amazon SP-APIの始め方・使い方を紹介した。