IBM Watson Tone Analyzer Invalid JSON Error - json

I must be missing something very simple here. I am following the Example Tutorial Instructions. I already created a free account and I have my API key and the URL. I copied the JSON file as instructed. Here is the command I issued:
curl -X POST -u "apikey:MY-API-KEY" \
--header "Content-Type: application/json" \
--data-binary PATH-TO-FILE \
"MY-URL"
Where MY-API-KEY equals my personal key specified on my Manage page.
Where PATH-TO-FILE equals the path to my local copy of tone.json
Where MY-URL equals the url specified on my Manage page.
Here is the error I am getting:
{"code":400,"sub_code":"C00012","error":"Invalid JSON input at line 1, column 2"}
I copied the JSON exactly from the directions:
{
"text": "Team, I know that times are tough! Product sales have been disappointing for the past three quarters. We have a competitive product, but we need to do a better job of selling it!"
}
I also attempted the following JSON and it received the same error:
{"text":"Hello world"}
What obvious thing am I missing here?

I knew it was going to be something silly.
The directions have this as an example:
curl -X POST -u "apikey:{apikey}" \
--header "Content-Type: application/json" \
--data-binary #{path_to_file}tone.json \
"{url}/v3/tone?version=2017-09-21"
For the path to the file, I had to keep the # symbol in front. so let's assume the full path to the file is /home/joe/Desktop/tone.json, that line has to be:
--data-binary #/home/joe/Desktop/tone.json \

Related

How to GET data of a key in json using curl?

Sorry Pretty noob to json.
Basically I have a simple server where I can upload data in there.
E.g:
curl -vX PUT "http://IP:port/ABC" -H "Content-Type: application/json" -d #"Once Upon a time."
After when I do:
curl -vX GET "http://IP:port/ABC" -H "Content-Type: application/json"
I get:
{"reverse_shell":
{"aliases":{},"mappings":{},"settings":
{"index":{"creation_date":"1561863982371","number_of_shards":"5","number_of_replicas":"1","uuid":"IAWE83rYQqmtKW-9svkBVg","version":{"created":"6040299"},"provided_name":"ABC"}
}
}
}
As you can see there is no where mentioning Once Upon a time, so is there I am missing? or how do I get that data from json using curl?
I am in kali linux env.
It looks like you are trying to post a string as a file.
When you specify a "#" with -d this tells curl to send the data from a file called "Once Upon a time."
If you are trying to put a file then you should do:
my_text_file.txt
Once Upon a time.
curl -vX PUT "http://IP:port/ABC" -H "Content-Type: application/json" -d #./my_text_file.txt https://server/api/path

use curl to POST multipart/form-data, file and lots of key-value pairs

As part of simulating what the front-end of an application will do while I work on the backend, I have been running various curl commands. Was easy to get just a file to be sent as Content-Type:application/octet-stream or just json with Content-Type:application/json
I sent json inline with this:
curl -X POST -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://127.0.0.1:8088
Pulled the json out of a file and sent it like this:
curl -X POST -H "Content-Type: application/json" -H 'Accept: application/json' --data-binary #test.json http://127.0.0.1:8088
(any ideas what the 'Accept' does? does not work without it.., solution from here)
Sent just a file by itself like this:
curl --request POST -H "Content-Type:application/octet-stream" --data-binary "#photo.jpg" http://127.0.0.1:8088
Multipart with json inline and a picture goes very nicely like this:
curl --verbose --request POST --header "Content-Type:multipart/form-data" --form key1=value1 --form upload=#photo.jpg http://127.0.0.1:8088
(solution from here)
The trouble starts when I try to pull both the key-value pairs from a file and the photo, or to paste json into the curl command which also uploads a file. Can curl be convinced to send "Content-Type:multipart/form-data" with key value pairs coming from a file and a file attachment coming from a file?
john.json
{
"surname" : "Doe",
"name" : "John",
"city" : "Manchester",
"address" : "5 Main Street",
"hobbies" : ["painting","lawnbowls"]
}
and
john.jpg
I have tried some things but it just gives me error messages:
Tried inline, pasting in json:
$ curl --verbose --request POST --header "Content-Type:multipart/form-data" --data '{"surname" : "Doe","name" : "John","city" : "Manchester","address" : "5 Main Street", "hobbies" : ["painting","lawnbowls"]}' --form upload=#john.jpg http://127.0.0.1:8088
Warning: You can only select one HTTP request method! You asked for both POST
Warning: (-d, --data) and multipart formpost (-F, --form).
Then I tried to get them both from a file, but it didn't like that either:
$ curl --verbose --request POST --header "Content-Type:multipart/form-data" --form upload#john.json --form upload=#john.jpg http://127.0.0.1:8088
Warning: Illegally formatted input field!
curl: option --form: is badly used here
curl: try 'curl --help' or 'curl --manual' for more information
Any ideas how to make this work?
I think you're on the right track, but taking a look at the curl manual page might get you further.
Some key take aways from the --form option documentation:
The difference between # and < is then that # makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.
So for the JSON use <, but for the picture use #.
I think also you should specify the content type of each section to help the web server know how to parse each section. Although it probably has expectations for each field.
You can also tell curl what Content-Type to use by using 'type=', in a manner similar to:
curl -F "web=#index.html;type=text/html" example.com
You'll have to look up the MIME types for JSON and jpegs.
And then the final piece to keep in mind: This option can be used multiple times.
Most of this is just an echo of what #Tanaike is saying above, but with more explanation from the documentation. I would recommend reading it in further detail.
I think the largest complain curl has with your command is that each part of the form has the key upload. That's sort of ambiguous. Is there one key for JSON and one key for the picture?
It's also really important to know what the webserver expects from each field in the form. There's a wide difference between a file upload and a text field.
With the help from #Breedly and #Tanaike got the following command to work, someone may find it useful one day:
curl --verbose --request POST --header "Content-Type:multipart/form-data" --form "upload1=<john.json" --form "upload2=#john.jpg" http://127.0.0.1:8088
It is happy to have "Content-Type:multipart/form-data" just once to cover both of them in this case. It really however wants the "<" not a "#" for the json.
The following also works:
curl --verbose --request POST --form "upload1=<john.json;type=application/json" --form "upload2=#john.jpg;type=multipart/form-data" http://127.0.0.1:8088

Have an R Plumber API consume JSON on POST

I'm writing and API in R using plumber that ideally will consume the JSON it receives on POST. But I cannot get the endpoint POST example to work that way, so I'm probably missing something obvious.
Using the example URL and Curl I can do the following without issue:
curl -i -X POST http://plumber.tres.tl/append/append -d "val=50"
But the way the example is presented:
POST {val: 50} -> http://plumber.tres.tl/append/append
Suggests that JSON would also be allowed. So I have tried:
curl -H "Content-Type: application/json" -X POST -d '{"val":50}' http://plumber.tres.tl/append/append
And all the variation to ensure UTF-8 encoding, comment out the " and all kinds of other combinations based mostly on what I found here on Stackoverflow about post. For example:
curl -i -X POST -H "Content-Type: application/json" http://plumber.tres.tl/append/append -d '{"val":50}'
curl -i -X POST -H "Accept: application/json" -H "Content-Type: application/json" http://plumber.tres.tl/append/append -d '{\"val\":50}'
curl -i -X POST -H "Content-Type: application/json;charset=UTF-8" http://plumber.tres.tl/append/append -d '{"val":50}'
Also using a file and trying to post it as #my.json did not work.
Maybe it is something on the Plumber side: I would expect that given the toolset to serialize the output, I can also state the expected serialization of the input. But I have not found how to do that.
This turned out to be a relatively simple issue with plumber. The function postBodyFilter calls parseQS that in turn splits on & and = and does not yet check for JSON formats (for example based on an initial { and ending }).
Since jsonlite was already imported by the package I proposed a small change to add basic JSON support in pull request #53.
Following the example in the README, the following will work after adding this patch:
curl --data '{"a":4, "b":5}' http://localhost:8000/sum
Since the call is on jsonlite to parse the content of the querystring, more complex JSON should also be possible, but I have not tested that yet.
Update : This has now been merged into the plumber project and will work for you if you install the version from github using devtools::install_github("trestletech/plumber"), or through a traditional install as soon as version 0.3.1 is available on CRAN.

Why do I get a malformed JSON in request body in this cURL call?

I have been trying to call the CloudFlare API v4, using an example provided in their own documentation.
This is the code of the example
curl -X PUT "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" \ -H "X-Auth-Email: user#example.com" \ -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \ -H "Content-Type: application/json" \ --data '{"id":"372e67954025e0ba6aaa6d586b9e0b59","type":"A","name":"example.com","content":"1.2.3.4","proxiable":true,"proxied":false,"ttl":120,"locked":false,"zone_id":"023e105f4ecef8ad9ca31a8372d0c353","zone_name":"example.com","created_on":"2014-01-01T05:20:00.12345Z","modified_on":"2014-01-01T05:20:00.12345Z","data":{}}'
Which can also be found at
Update DNS Records
Using Windows cmd.exe to run this command, I need to make it single line first, so I removed the "" and reformatted it (twice) making sure I altered no part in the process.
This is the same code in one line:
curl -X PUT "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" -H "X-Auth-Email: user#example.com" -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" -H "Content-Type: application/json" --data '{"id":"372e67954025e0ba6aaa6d586b9e0b59","type":"A","name":"example.com","content":"1.2.3.4","proxiable":true,"proxied":false,"ttl":120,"locked":false,"zone_id":"023e105f4ecef8ad9ca31a8372d0c353","zone_name":"example.com","created_on":"2014-01-01T05:20:00.12345Z","modified_on":"2014-01-01T05:20:00.12345Z","data":{}}'
When I run this single-liner in cmd, it works but I get a malformed JSON in request body, however, a visual check, formatting on Notepad++ and a run through the JSON validator are all positive, this JSON (copied from the CloudFlare documentation) is not malformed.
Error Message
{"success":false,"errors":[{"code":6007,"message":"Malformed JSON in request body"}],"messages":[],"result":null}
Googling this error message or the error code gives me nothing and this same command works on a PC running Linux.
Can someone tell me if this is a known bug, if the JSON really is malformed or if something else comes to mind?
I found the answer in the blog post: "Expecting to find valid JSON in request body..." curl for Windows.
For example, for Purge everything --data value will be:
# On Linux
--data '{"purge_everything":true}'
# On Windows
--data "{\"purge_everything\":true}"
For Windows:
Replace the single quotes with double quotes: ' --> "
Escape the double quotes with a backslash: " --> \"
cmd.exe doesn't support single quotes, to run those commands straight from the docs you can use Bash.
Bash can be enabled in Windows 10 : https://www.laptopmag.com/uk/articles/use-bash-shell-windows-10
or Git Bash comes with Git for windows: https://gitforwindows.org/

Watson API - Retrieve and Rank - Error uploading JSON

I'm following the tutorial at Retrieve and Rank - Get Started, and I'm at the following step:
Issue the following command to upload the cranfield_data.json data to the example_collection collection. Replace {username}, {password}, {solr_cluster_id}, and {/path_to_file} with your information:
$ curl -X POST -H "Content-Type: application/json" -u "{username}":"{password}" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/{solr_cluster_id}/solr/example_collection/update" --data-binary #{/path_to_file}/cranfield_data.json
I'm lobbing the request with the correct username and password, and correct cluster_id and path to the json, but I get the following error:
$ curl -X POST -H "Content-Type: application/json" -u "username":"password" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/cluster_id/solr/example_collection/update" --data-binary #forum_data/parsed_answers.json
Error: WRRCSH006: Error forwarding request [/solr/example_collection/update] for Solr cluster [sc5b47c5e3_bab3_4aff_a818_f0d786d6dece].
Turns out there were characters in the JSON causing it be malformed.
Just verify the JSON "parsed_answers.json", to check for all the punctuations i.e. ";","," to be correctly placed and as per the defined schema, and try to re-upload