Open MPishpecki opened 1 year ago
Hey @MPishpecki , I also spend some time trying to fix that because the error messages are less than optimal...
The thing that fixed it for me in the end was adding all the necessary headers from the formdata to the request. Thanks for the post here pointing out that this is needed.
Simple working NodeJS example:
const formData = new FormData();
let productData = {
"identifier": "IDENTIFIER",
"attribute": "main_image",
"scope": null,
"locale": null
}
formData.append("product", JSON.stringify(productData));
const config = {
headers: {
Authorization: "Bearer xxx",
...formData.getHeaders()
}
}
const fileParts = filePath.split("/"); // to get the filename
formData.append("file", fs.readFileSync(filePath), fileParts[fileParts.length - 1]);
await axios.post(`${this.config.url}/api/rest/v1/media-files`, formData, config);
@PhilipKazmeier thank you for the response. In the end we decided not to use this media-files endpoint. Maybe someone else find this thread useful in the future.
Since I came accross this thread while looking for the same thing, after many hours of trying I managed to get this working Python code to create media files on an image attribute (doesn't work for "asset collection" attributes :smiling_face_with_tear:) https://gist.github.com/hildickethan-S73/bdf852d2e73f8fa8ebe2320f45efa787 I post it here for anyone else that stumbles their way here trying to make this endpoint work
this curl was essential for finding my way here, it was from some other issue I can't find right now
curl -X POST -H "Authorization: Bearer {token}" -H "Content-Type: multipart/form-data" -F 'product={"identifier":"123123","attribute":"test_image","scope":null,"locale":null}' -F "file=@/home/x/image.jpeg" "https://domain.com/api/rest/v1/media-files" --trace-ascii /tmp/stdout
You want to use that curl to see how your json is being sent, you need to replicate the "product" with no filename
parameter whatsoever (empty, null or "" does not work) and the "file" one needs filename
and Content-Type
. This needs to be replicated in whatever language you are using
0000: --------------------------d68143a191b92d35
002c: Content-Disposition: form-data; name="product"
005c:
005e: {"identifier":"123123","attribute":"test_image","scope":null
009e: ,"locale":null}
00af: --------------------------d68143a191b92d35
00db: Content-Disposition: form-data; name="file"; filename="image.jpe
011b: g"
011f: Content-Type: image/jpeg
The documentation for
/api/rest/v1/media-files
shows no examples of use. In your Postman collection only Curl example works. Python example does not work. I pasted it below to show you what we get as a return.Is it too much to ask to show us how this call works in any language? No mater how we format the data Akeneo responds with
...You should at least give one of the following properties: \\"product\\" or \\"product_model\\
.PS: Setting up the connection, obtaining an token and pushing products was walk in the park. This endpoint is the opposite.
Examples of not working calls in Python. (hope this saves someones time)
----------------- Not working ---------------------------- headers = {'Authorization': 'Bearer xxx', 'Content-Type': 'multipart/form-data'} files = { 'product': '"{\"identifier\":\"SKU-001\", \"attribute\":\"Product_images\", \"scope\": null,\"locale\":null}"', 'file': open('/images/01.png', 'rb'), } response = requests.post('{url}/api/rest/v1/media-files', headers=headers, files=files) response.text '{"code":422,"message":"You should at least give one of the following properties: \"product\" or \"product_model\"."}'
import requests
headers = {'Authorization': 'Bearer xxx', 'Content-Type': 'multipart/form-data'} files = { 'product': '{"identifier":"SKU-001", "attribute":"picture", "scope": null,"locale":null}', 'file': open('/images/01.png', 'rb'), }
response = requests.post('{url}/api/rest/v1/media-files', headers=headers, files=files) response.text '{"code":422,"message":"You should at least give one of the following properties: \"product\" or \"product_model\"."}'
-------------------------- this is from your Postman given as an example in Python --------------------------------------
import requests url = "{{url}}/api/rest/v1/media-files" payload={'product': '{"identifier":"SKU-001", "attribute":"picture", "scope": null,"locale":null}'} files=[ ('file',('file',open('/path/to/file','rb'),'application/octet-stream')) ] headers = { 'Authorization': 'Bearer {{token}}', 'Content-Type': 'multipart/form-data' } response = requests.request("POST", url, headers=headers, data=payload, files=files) print(response.text) '{"code":422,"message":"You should at least give one of the following properties: \"product\" or \"product_model\"."}'
EDIT: I tried installing your akeneo_cli and pushing images that way. Here is the code and the result:
AKENEO_URL = "url" AKENEO_CLIENT_ID = "xxx" AKENEO_CLIENT_SECRET = "xxx" AKENEO_USERNAME = "xxx" AKENEO_PASSWORD = "xxx"
from akeneo_cli.client import AkeneoClient akeneo_client = AkeneoClient(AKENEO_URL,AKENEO_CLIENT_ID,AKENEO_CLIENT_SECRET)
with akeneo_client.login(AKENEO_USERNAME, AKENEO_PASSWORD) as session: response = session.put_product_file("SKU-001", "Product_images", "/images/01.png", is_model=False, locale=None, scope=None)
response {'headers': {'Server': 'nginx', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Cache-Control': 'no-cache, private', 'Date': 'Fri, 02 Dec 2022 15:46:29 GMT', 'Location': 'https://akeneo.xxx.hypernode.io/api/rest/v1/media-files/6/3/2/3/63233fc4ccf6cdb053e9affb334208c9f63b722b_01.png', 'Content-Security-Policy': "default-src 'self' .akeneo.com 'unsafe-inline'; script-src 'self' 'unsafe-eval' 'nonce-07f41c14e74157aff6fa6296dac0027c13e46705'; img-src 'self' data: .akeneo.com; frame-src ; font-src 'self' data:; connect-src 'self' .akeneo.com", 'X-Content-Security-Policy': "default-src 'self' .akeneo.com 'unsafe-inline'; script-src 'self' 'unsafe-eval' 'nonce-07f41c14e74157aff6fa6296dac0027c13e46705'; img-src 'self' data: .akeneo.com; frame-src ; font-src 'self' data:; connect-src 'self' .akeneo.com", 'X-WebKit-CSP': "default-src 'self' .akeneo.com 'unsafe-inline'; script-src 'self' 'unsafe-eval' 'nonce-07f41c14e74157aff6fa6296dac0027c13e46705'; img-src 'self' data: .akeneo.com; frame-src ; font-src 'self' data:; connect-src 'self' .akeneo.com"}, 'body': '', 'json': {}}