0

I have an API I am building out that will allow me to upload media to my WordPress website using their new API. I have searched all over the internet and SO for a solution to this problem, but all of the answers seem to be using an older WordPress API so I have not had much success in finding an answer.

I have the following code written out in a function to send a multipart/form-data request to the API:

img = open(image_path, 'rb')
file_name = os.path.basename(image)

print('Compressing and sending data...')

NEW_HEADER = {
    'Authorization': f'BEARER {WORDPRESS_ACCESS_TOKEN}',
    'Content-Disposition': f'attachment; filename={file_name}',
    'Content-Type': 'multipart/form-data'
}

response = requests.post(
    url=WORDPRESS_MEDIA_URL,
    files={'media': img.read()},
    headers=NEW_HEADER
)

print(response.request)
print(response.text)
return response

Which returns me:

{"media":[],"errors":[]}
<Response [200]>
OK

So, it sends something to the endpoint, but it's return an empty array and empty error box. Again, I can't seem to find any solution for the new WP, so forgive me if the Python seems a little hacky and put-together, I've just been putting together what appears to work.

Further Reading Since Original Posting

I pinged the API with Postman and it returns data as expected:

{"media":[{"id":"xxxx","date":"2022-11-03T20:06:54-05:00","parent":0,"link":"https:mywebsite","title":"mypicture","caption":"","description":"",...}

So, Since the post request seems to not be the issue, I tried to debug my request in Postman and my local console to see what was being sent:

{'User-Agent': 'python-requests/2.28.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'BEARER QnkXS43KhiqO7Oa!9G!zN2gnz90hHhZEribF2ddZu0h8&5V0p5M69^OwDb9E6H%B', 'Content-Type': 'multipart/form-data', 'Content-Length': '6'}
media=

And I see that the media returns empty from my local console. In Postman, the media is returned as undefined (though I'm not sure if that's just Postman being unable to parse the image in a JSON format in the console/debugger.

This leads me to believe that either the way I am accessing/calling the directory with the image is wrong, or the way I am trying to encode it to the request.

Even Further Reading Since Posting

I have since circumnavigated any concerns about directory issues by copying the photos from an external directory to that of one inside the project folder.

Since then, it appears that the current way I am sending the data returns the same response as if I am sending nothing at all:

response = requests.post(
    url=WORDPRESS_MEDIA_URL, # there is no data sent in this request.
    headers=NEW_HEADER
)

Which still returns me:

{"media":[],"errors":[]}
<Response [200]>
OK

This leads me to believe that the way I am sending the data is incorrect, as WordPress is receiving my request, but is not getting the information that it needs.

So, doing some further reading and research, I come across requests-toolbelt, which is to help sending multipart/form-data:

data = MultipartEncoder(fields={'media': (file_name, img, 'image/jpeg')})

new_header = {
    'Authorization': f'BEARER {WORDPRESS_ACCESS_TOKEN}',
    'Content-Type': data.content_type,
    'Content-Disposition': 'form-data; name="media"; filename="%s"' % name_img,
}

response = requests.post(WORDPRESS_MEDIA_URL, data=data, headers=new_header)

Now, when I send a request with this data, I get this response:

{"error":"unsupported_mime_type","message":"File type unknown"}
<Response [400]>
Bad Request

So sending the request with the MultipartEncoder returns an error of an unsupported MIME type. So while it isn't a blank 200 response, it gives me reason to think that perhaps I am using the MultipartEncoder wrong, or I am not making the proper adjustments to the picture I am trying to upload.

Any insight into this would be greatly appreciated.

JCMcRae
  • 245
  • 1
  • 5
  • 11

1 Answers1

0

I figured it out:

payload = {}
files = [('media', ('image-name', img, 'application/octet-stream'))]

new_header = {'Authorization': f'BEARER {WORDPRESS_ACCESS_TOKEN}',}

response = requests.post(WORDPRESS_MEDIA_URL, data=payload, files=files, headers=new_header)

I learned from this SO post how to get the Python requests equivalent of the test request I would send and it made a code snippet very similar to what I have now.

JCMcRae
  • 245
  • 1
  • 5
  • 11