muenzpraeger / salesforce-einstein-vision-apex

Apache License 2.0
30 stars 24 forks source link

EinsteinVision_PredictionService.createExample gives error #5

Closed FishOfPrey closed 7 years ago

FishOfPrey commented 7 years ago

Hi, I'm trying to take a PNG blob from a ContentVersion and pass it into createExample().

I keep getting the response message:

Response finished with Error: The 'name', 'labelId', and 'data' parameters are required to create an example.

Anonymous Apex code:

VisionController vc = new VisionController();
EinsteinVision_PredictionService ps = new EinsteinVision_PredictionService(vc.accessToken);

long datasetId = 1001419;
long labelId = 8588;
Id exampleId = '069o0000002CXDS'; // Rover.PNG

Blob fileBlob = [Select VersionData from ContentVersion where ContentDocumentId = :exampleId order by VersionNumber desc limit 1].VersionData;
EinsteinVision_Example ex = ps.createExample(datasetId, 'firstExample.png', labelId, fileBlob);
System.assertNotEquals(null, ex);

I've checked that the dataSetId and labelId are correct.

I was able to manually create the example using Postman in Chrome. https://www.dropbox.com/s/5lcwfw4wjeomf51/Postman.PNG?dl=0

Any ideas?

Maybe the body part for the image data needs a Content-Type header and the filename on the Content-Disposition?

The postman preview showed it as:

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="data"; filename="rover.png"
Content-Type: image/png

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="labelId"

8588
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="name"

rover.png
----WebKitFormBoundaryE19zNvXGzXaLvS5C

Thanks, Daniel

FishOfPrey commented 7 years ago

Well, that was some interesting learning about base64 encoding and appending a file when using multipart/form-data.

The problem is largely covered in POST Mutipart/form-data with HttpRequest. The short version is if you aren't really careful the last few bytes of the file can get corrupted as part of the base64 encoded.

I needed to swap out the EinsteinVision_HttpBodyPart.WriteBodyParameter method with a new one when used by EinsteinVision_HttpBodyPartExample to encode the example blob data.

I'll see if I can put this together in a pull request.

muenzpraeger commented 7 years ago

LMK if I should jump on that.

I've taken that part of the wrappers directly from the MetaMind repo, so we should let them know too.

FishOfPrey commented 7 years ago

I've had a go at addressing it in the patch request. It isn't complete as the mimetype is hard coded to PNG. Would also benefit from some apex test cases.

It did work in the one test I completed.