Via the JSON:API I'm creating and updating content entities on Drupal 9.5.8 - for content, taxonomies, relationships it's working fine.
But I can't get images to upload - they seem to be corrupted. I've tried this sort of script: https://www.drupal.org/project/drupal/issues/3079384#comment-13250753
import requests
import os
from requests.auth import HTTPBasicAuth
def upload_image(image_path):
api_url = 'https://example.com/jsonapi/node/event/a8ef729b-1fd6-4233-979a-fa0f81132dde/field_image' #?_format=json
auth = HTTPBasicAuth('Username', 'Password')
image_filename = os.path.basename(image_path)
headers = {'Content-Type': 'application/octet-stream',
'Content-Disposition': 'file; filename="{}"'.format(image_filename.replace('images/', ''))}
multipart_form_data = {'file': (image_filename, open(image_path, 'rb'))}
print(api_url)
print(auth)
print(image_filename)
print(headers)
response = requests.post(api_url, files=multipart_form_data, headers=headers, auth=auth)
print(response.json())
return None
upload_image('images/test.jpg')
And I've tried and errored with a few other / similar approaches like:
def upload_image2(image_path):
api_url = 'https://example.com/jsonapi/node/event/a8ef729b-1fd6-4233-979a-fa0f81132dde/field_image' #?_format=json
auth = HTTPBasicAuth('Username', 'Password')
image_filename = os.path.basename(image_path)
headers = {'Accept': 'application/vnd.api+json',
'Content-Type': 'application/octet-stream',
'Content-Disposition': f'file; filename="{image_filename}"'
}
with open('images/test.jpg', 'rb') as f:
response = requests.post(api_url, headers=headers, auth=auth, files={'test.jpg': f})
print(response.json())
return None
Strange enough: Adding #?_format=json
to the upload_image2 doesn't change anything. But adding it to upload_image, I receive an error:
{'message': 'No route found for the specified format json. Supported formats: api_json.'}
The image that I'm uploading is 11.1 kB (just trying to upload this screenshot)
What I see on the website / edit form seems to be broken:
The uploaded image is 11.3 kB - which I can't upload here, since it's a broken image, as it seems.
According to that comment, I'm not trying to base64 encode the image.
There is a CURL and Node.js example - but I wasn't able to transfer it to Python, as it seems.
And in this ticket, it seems as if BasicAuth can be used as well to upload files, so that might not be the issue as well.
What am I doing wrong?
After much fiddling around, I was able to get it working via this Code: https://www.drupal.org/node/3024331#comment-13248319
It seems like
data = bytearray(data)
was the missing piece.