How to upload files/images through API

I have…

I’m submitting a…

  • [ ] Regression (a behavior that stopped working in a new release)
  • [ ] Bug report
  • [ ] Performance issue
  • [ X ] Documentation issue or request

Current behavior

I’m creating content with no issues with the API but I’m having a hard time trying to figure it out how to upload a file.

This is the python code:

import requests

        url = self.api_url + "/api/apps/atlas/assets/"
        body = open("/path/to/file/head.png", "rb")

        files = {"file" : body}
        payload = {"parentId": "39b46dab-60ee-4bef-ae51-64591d3f5d7f"}

        headers={
        #   'Accept': 'application/json',
        'Content-Type': 'application/json',
        #   'Content-Type': 'multipart/form-data',
          'Authorization': 'Bearer ' + token
        }

        response = requests.request("POST", url, headers=headers, files=files, data = payload, verify=False)

        print(response.json())

Response:

{‘type’: ‘https://tools.ietf.org/html/rfc7231#section-6.5.13’, ‘title’: ‘Unsupported Media Type’, ‘status’: 415, ‘traceId’: ‘00-1ceaa5bd3cbcaf47bba02e20e683d0f6-fe185576eeeb0448-00’}

I’m not sure how to deal with this due that as far as I know from the docs, some fields (like file, parentID, etc) are specified but still does not work.

NOTE: if I remove the “Content-Type” header, the response is this:

{‘message’: ‘Validation error’, ‘traceId’: ‘00-a8af9739f5decc42833a06dc469489af-fd29d1fc671e784b-00’, ‘type’: ‘https://tools.ietf.org/html/rfc7231#section-6.5.1’, ‘details’: [‘File content-type is not defined.’], ‘statusCode’: 400}

So it makes me think that the issue is about setting the right header but I’ve already tried uploading a PNG or JPG image and setting it like “image/png” or “image/jpg” with no success.

NOTE 2: Now, trying with ‘Content-Type’: ‘multipart/form-data’, the response is:

{‘message’: ‘Validation error’, ‘traceId’: ‘00-fd3e84b26ad294428df8319603dacfcd-e3450a4e2b986b4e-00’, ‘type’: ‘https://tools.ietf.org/html/rfc7231#section-6.5.1’, ‘details’: [‘Request body has an invalid format.’], ‘statusCode’: 400}

And my request body is:

b’–6c5d999d51c6052654d631baaffbe3dc\r\nContent-Disposition: form-data; name=“parentId”\r\n\r\n39b46dab-60ee-4bef-ae51-64591d3f5d7f\r\n–6c5d999d51c6052654d631baaffbe3dc\r\nContent-Disposition: form-data; name=“file”; filename=“head.png”\r\n\r\n(BINARY FILE CHUNK)–6c5d999d51c6052654d631baaffbe3dc–\r\n’

Any help will be appreciated. Thanks!

Expected behavior

Minimal reproduction of the problem

Environment

  • [ X ] Self hosted with docker
  • [ ] Self hosted with IIS
  • [ ] Self hosted with other version
  • [ ] Cloud version

Version: [VERSION]

Browser:

  • [ ] Chrome (desktop)
  • [ ] Chrome (Android)
  • [ ] Chrome (iOS)
  • [ ] Firefox
  • [ ] Safari (desktop)
  • [ ] Safari (iOS)
  • [ ] IE
  • [ ] Edge

Others:

I have not idea about python, but here is a sample with javascript: I'm unable to upload assets via the API; 'Can only upload one file" error

or the sample itself: https://jsfiddle.net/1273uf8a/4/

Thanks Sebastian, your work is awesome. Keep it that way!!! :smile:

I finally figured it out. For the record and to help others with the same issue, this is the working code:

import requests

url = self.api_url + "/api/apps/atlas/assets"

file = {("file", ("yo.jpg", open("/path/to/picture/yo.jpg", "rb"), "image/jpeg"))}
# payload = {"folderName": "f184082a-2b96-442f-9c4a-78dbbfb8cf6b"}
payload = {"folderName": "Pictures"}

headers={
          'Authorization': 'Bearer ' + token
        }

response = requests.request("POST", url, headers=headers, files=file, data=payload, verify=False)

print(response.json())

Now I’m struggling how to store that asset under a folder. Could you please give me a hint?

Thanks a lot Sebastian!

You have to create the folder first. Then you should have a folder id which can be attached to the URL as query string ?parentId=<FOLDER_ID>

I forgot to mention that, the folder is already created, that’s why there’s a “folderName” var (previously “parentId”) in the code but still can’t make it work.

Thanks!

Nevermind Sebastian, I’ve added the “parentId” to the url instead of a body parameter in python requests and now it works.

Thanks a lot!!!