Etsy API file upload function doesn't work

737 views Asked by At

I am trying to work with Etsy API, to create a listing, upload images and download files (for digital product).

I have a working functions for listing creation and image upload, but I have some problems with file upload. By documentation (https://developers.etsy.com/documentation/reference/#operation/uploadListingFile) it seems very similar to image upload, however it doesn't work for me.

The function I am using is this:

def upload_file(keystring,token,shop_id,listing_id,file):
  
    headers = {
        "Accept": "application/json",
        "x-api-key": keystring,
        "Authorization" : f"Bearer {token}"
              }
    
    url = f"https://openapi.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/files"
    
    files = {'file': ('10.png', open(file,'rb'))}
    

    response = requests.post(
        url=url,
        headers=headers,
        files=files
    )

    if response.status_code == 200:
        print(response.json())
    else:
        print('Upload failed with status code:', response.status_code) 
        print(response.json()) 

And as a response, I get 400:

'A valid name must be provided with a new file.'

Maybe someone has any ideas or have a working function for this task.

2

There are 2 answers

1
Jānis Š On

OK, got everything working.

For others interested, you need to pass data in this format:

files = {'file': ('10.png', open(fileto, 'rb'), 'multipart/form-data')} 
data = {'name': '10.png'}

replacing 10.png to real file name

0
Mark OB On

For anyone still struggling with this, the culprit for me was having 'multipart/form-data' in the headers. This is my working method now for uploading on V3 of the Etsy API

def upload_images(self, keystring, shop_id, listing_id, image_file_path, image_rank):

    # Upload the primary image
    image_endpoint = f'/shops/{shop_id}/listings/{listing_id}/images'
    image_url = self.base_url + image_endpoint

    headers = {
        "Authorization": f"Bearer {self.token['access_token']}", 
        "x-api-key": keystring
    }

    extras = {
        "client_id": keystring
    }

    etsy_auth = OAuth2Session(
        keystring, 
        token=self.token, 
        auto_refresh_url=self.refresh_url, 
        auto_refresh_kwargs=extras, 
        token_updater=self.token_update
    )

    with open(image_file_path, 'rb') as image_file:
        file_data = image_file.read()
        file_name = os.path.basename(image_file_path)
        
        data = {
            "name": file_name,
            "rank": image_rank
        }

        files = {
            "image": file_data,
            "name": file_name
        }
        r = json.loads(etsy_auth.post(image_url, files=files, headers=headers, data=data).text)

    return r