How to Issue JSON POST Request for this API

6 vues (au cours des 30 derniers jours)
Joseph
Joseph le 4 Mai 2017
Réponse apportée : Juho le 22 Jan 2020
I am trying to pass file data to a JSON API but can't seem to get the webwrite data formatted properly.
The API in question is this one here: http://astrometry.net/doc/net/api.html
I can do the first step including getting the session key. Code is:
options = weboptions('MediaType','application/x-www-form-urlencoded','RequestMethod','post');
url = 'http://nova.astrometry.net/api/login';
apikey = 'XXXXXXXXXXXXX';%I've removed my key here for posting this question
json_command = ['request-json={"apikey": "', apikey, '"}'];
response = webwrite(url,json_command,options);
So I get a good response here with the result:
response = '{"status": "success", "message": "authenticated user: ########@gmail.com", "session": "azpl2in6ti45yso2dph2r7bejck7s7gv"}'
Now what I want to do is submit file data, instead of a URL. The instruction are here:
So what I do is simply build the string, but I think that this is not sufficient and perhaps I need to set more parameters in weboptions?
For what it's worth, the code is:
inds = find(response == '"');
session = response(inds(end-1)+1:inds(end)-1);
scale_est = 0.416;%arcsec per pixel
scale_err = 2;% percent
center_ra = 180.1083432;
center_dec = -45.5434345;
radius = 0.3;
tweak_order = 0;%for SIP distotion polynomial https://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf
parity = 2;
image_width = 4096;
image_height = 4096;
positional_error = 1;
url = 'http://nova.astrometry.net/api/upload';
json_command = [];
json_command = ['{"session": "', session,'", '];
json_command = [json_command, '"url": "', url,'", '];
json_command = [json_command, '"allow_commercial_use": ', '"n','", '];
json_command = [json_command, '"allow_modifications": ', '"n','", '];
json_command = [json_command, '"publicly_visible": ', '"n','", '];
json_command = [json_command, '"scale_units": ', '"arcsecperpix','", '];
json_command = [json_command, '"scale_type": ', '"ev','", '];
json_command = [json_command, '"scale_est": ', num2str(scale_est,4),', '];
json_command = [json_command, '"scale_err": ', num2str(scale_err,3),', '];
json_command = [json_command, '"center_ra": ', num2str(center_ra,8),', '];
json_command = [json_command, '"center_dec": ', num2str(center_dec,8),', '];
json_command = [json_command, '"radius": ', num2str(radius,5),', '];
json_command = [json_command, '"tweak_order": ', num2str(tweak_order),', '];
json_command = [json_command, '"parity": ', num2str(parity),', '];
json_command = [json_command, '"image_width": ', num2str(image_width),', '];
json_command = [json_command, '"image_height": ', num2str(image_height),', '];
json_command = [json_command, '"positional_error": ', num2str(positional_error),', '];
json_command(end-1:end) = [];
json_command = [json_command, '}'];
uploadfilePOST = sprintf(['--===============2521702492343980833==\nContent-Type: text/plain\nMIME-Version: 1.0\nContent-disposition: form-data; name="request-json"\n\n' ,json_command]);
uploadfilePOST = sprintf([uploadfilePOST, '\n--===============2521702492343980833==\nContent-Type: application/octet-stream\nMIME-Version: 1.0\n']);
filename = 'test.txt';
uploadfilePOST = sprintf([uploadfilePOST, 'Content-disposition: form-data; name="file"; filename="', filename, '"\n']);
positions = round(rand(20,2)*4000,4);
for i = 1: length(positions)
uploadfilePOST = sprintf([uploadfilePOST, '\n', num2str(positions(i,1)), ' ', num2str(positions(i,2))]);
end
uploadfilePOST = sprintf([uploadfilePOST, '\n\n--===============2521702492343980833==--']);
response = webwrite(url,uploadfilePOST,options);
The result of response is:
response = '{"status": "error", "errormessage": "no json"}'
So, I'm not sure what to actually do here, is the problem. How would one use Matlab's webwrite to satisfy's this API's file data submission procedure? The URL submission is as easy as getting the session key, but I would like to be able to submit a data table.
  1 commentaire
Anudeep Katragadda
Anudeep Katragadda le 8 Mai 2017
Unfortunately, at the moment, you cannot upload a file in multipart/form-data format from MATLAB to a Web Service.
Possible workarounds:
1. If you can change the web protocol take file data from a JSON packet - you could load your file as a character vector, base64 encode the text, and send it in JSON. Ex: { ..., "file" : base64data }. You would need to convert from character data back into your binary file format on the server.
2.If you are sending data to an existing server - Use the MATLAB HTTP interface to create your own multi-part form. This solution will not be as simple:
>> header = matlab.net.http.field.ContentTypeField(matlab.net.http.MediaType('multipart/form-data','boundary','randomchars'));
>> data = (created multipart content as above)
>> req = matlab.net.http.RequestMessage('POST',header,data);
>> uri = matlab.net.URI(uri,token,token,filename,filename,);
>> resp = req.send(uri);
You would need to format your data to follow the standards of multipart mesage by following the standards here: https://tools.ietf.org/html/rfc2046

Connectez-vous pour commenter.

Réponses (1)

Juho
Juho le 22 Jan 2020
Did you find solution for your problem? Since Matlab 2018a, there is container provider for files which could help you https://se.mathworks.com/help/matlab/ref/matlab.net.http.io.fileprovider-class.html.

Catégories

En savoir plus sur Call Web Services from MATLAB Using HTTP dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by