How to Issue JSON POST Request for this API

18 views (last 30 days)
Joseph
Joseph on 4 May 2017
Answered: Juho on 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 Comment
Anudeep Katragadda
Anudeep Katragadda on 8 May 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

Sign in to comment.

Answers (1)

Juho
Juho on 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.

Categories

Find more on Financial Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!