콘솔워크

네이버 커머스 API 사용해보기 본문

프로그래밍/python

네이버 커머스 API 사용해보기

이휘재123 2022. 12. 7. 15:30
반응형
#!/usr/bin/env python
from http import HTTPStatus
import bcrypt
import pybase64
import http.client
import requests
import json
import time
import os
from common.utils import get_mime_type


class CommerceAPI:
    def __init__(self, client_id, client_secret, account_id=""):

        self.main_url = f"https://api.commerce.naver.com"
        self.client_id = client_id
        self.client_secret = client_secret
        self.account_id = account_id
        self.initData()

    def initData(self):
        self.set_client_secret_sign()
        self.set_token()

    # 전자서명 (self.timestamp, self.client_secret_sign)
    def set_client_secret_sign(self):

        self.timestamp = round(time.time() * 1000)

        # 밑줄로 연결하여 password 생성
        password = self.client_id + "_" + str(self.timestamp)

        # bcrypt 해싱
        hashed = bcrypt.hashpw(password.encode("utf-8"), self.client_secret.encode("utf-8"))

        # base64 인코딩 -> param으로 사용될 것
        self.client_secret_sign = pybase64.standard_b64encode(hashed).decode("utf-8")

    # 토큰 (self.token)
    def set_token(self):
        auth_url = "https://api.commerce.naver.com/external/v1/oauth2/token"
        params = {
            "client_id": self.client_id,  # 제공된 클라이언트 ID
            "timestamp": self.timestamp,  # 전자서명 생성 시 사용된 밀리초(millisecond) 단위의 Unix 시간. 5분간 유효
            "client_secret_sign": self.client_secret_sign,  # 전자서명
            "grant_type": "client_credentials",  # OAuth2 인증 방식 -> client_credentials 고정
            "type": "SELF",
            "account_id": self.account_id,  # type이 SELLER인 경우 입력해야 하는 판매자 ID
        }

        print(params)

        res = requests.post(auth_url, params=params)
        print(res.text)

        if res.status_code == HTTPStatus.OK:
            print("토큰가져오기 성공")
            data = json.loads(str(res.text))
            self.token = data["access_token"]
        else:
            print("토큰 가져오기 실패")

    def get_headers(self):
        return {"Authorization": f"Bearer {self.token}", "content-type": "application/json"}

    def get_headers_multipart(self):
        return {"Authorization": f"Bearer {self.token}"}

    def multi_image_upload(self, img_list: list):
        print("multi_image_upload")

        if len(img_list) > 10:
            print("이미지수", len(img_list))
            print("이미지는 최대 10개까지만 등록가능합니다.")
            return

        api_url = f"https://api.commerce.naver.com/external/v1/product-images/upload"

        files = {}

        for i in range(len(img_list)):
            img_path = img_list[i]
            img_name = os.path.basename(img_path)
            img_type = get_mime_type(img_path)
            img_binary = open(img_path, "rb").read()
            files.update({f"imageFiles[{i}]": (f"{img_name}", img_binary, img_type)})

        headers = self.get_headers_multipart()
        upload_result = requests.post(api_url, headers=headers, files=files)
        print(upload_result.text)

    # Request의 Content-type은 multipart/form-data이어야 합니다.
    # Content-type으로 boundary 구분자를 지정해야 합니다.
    # 각 파일 바이너리간에 boundary 구분자를 포함해주셔야 합니다.
    def img_test(self):
        print("img_test")

        path = "/external/v1/product-images/upload"
        api_url = "https://api.commerce.naver.com{0}".format(path)

        img_path1 = r"D:\img\11357-1.jpg"
        img_path2 = r"D:\img\11357-2.jpg"

        image_binary_1 = open(img_path1, "rb").read()
        image_binary_2 = open(img_path2, "rb").read()

        image_binary_1_type = get_mime_type(img_path1)
        image_binary_2_type = get_mime_type(img_path2)

        files = {
            "imageFiles[0]": ("sample_image_1.jpg", image_binary_1, image_binary_1_type),
            "imageFiles[1]": ("sample_image_2.jpg", image_binary_2, image_binary_2_type),
        }

        # files = {"imageFiles": ("test.png", image_binary, "image/png")}

        headers = self.get_headers_multipart()
        upload_result = requests.post(api_url, headers=headers, files=files)
        print(upload_result)
        print(upload_result.text)
        time.sleep(1)


if __name__ == "__main__":

    # parameter
    client_id = "~~~~~~~~"  # 제공된 클라이언트 ID
    client_secret = "~~~~~~~~"  # API키
    account_id = ""

    cmBot = CommerceAPI(client_id, client_secret, account_id)
    cmBot.img_test()
반응형