Send a POST request with some data, including a file, using Curl - file

How can I include a file in a curl request form my working directory?
Below I've got a POST request that includes data for "first_name" and for "last_name", but now I need to add in the input for file. Theres examples out there where someone is ONLY sending a file along, but I'm trying to send 1 or more files, and other data.
curl
-H "Content-Type: application/json"
-d '{ first_name: "Donny", last_name: "P", my_file: ???? }'
https://sender.blockspring.com/api/blocks/319bfef4aad7f3477745048a2da3ae6a?api_key=2e0ef0c216078d60630d1321e67b243a

This can be only done with a multipart.
Manually building a multipart may be complex, so curl has a built-in -F option.
curl localhost:8000 -F "my_file=#file.ext" -F "name=daniel;last=P" -v
from man curl
-F, --form
(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST
data using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files etc.
To
force the 'content' part to be a file, prefix the file name with an # sign. To just get the content part from a file,
prefix the file name with the symbol <. 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.

Related

Use curl to post file from pipe

How might i take the output from a pipe and use curl to post that as a file?
E.g. the following workds
curl -F 'file=#data/test.csv' -F 'filename=test.csv' https://mydomain#apikey=secret
I'd like to get the file contents from a pipe instead but I can't quite figure out how to specify it as a file input. My first guess is -F 'file=#-' but that's not quite right.
cat data/test.csv | curl -F 'file=#-' -F 'filename=test.csv' https://mydomain#apikey=secret
(Here cat is just a substitute for a more complex sequence of events that would get the data)
Update
The following works:
cat test/data/test.csv | curl -XPOST -H 'Content-Type:multipart/form-data' --form 'file=#-;filename=test.csv' $url
If you add --trace-ascii - to the command line you'll see that curl already uses that Content-Type by default (and -XPOST doesn't help either). It was rather your fixed -F option that did the trick!

Unable to submit Job in Flink using post request via curl request (Request did not match...)

I was trying to send a post request to Flink Job manager running on Kubernetes cluster. While sending post request of /jar/run for a class which doesn't need any command line arguments, it works fine. But while trying to submit a different class in the same jar which requires command line arguments gives following error. -:
{"errors":["Request did not match expected format JarRunRequestBody."]}'
However, while passing command line arguments and submitting job directly like following works -:
./flink run -m localhost:30287 -c com.class.name ~/path/to/jar/1.0-1.0-SNAPSHOT.jar --bootstrap.servers izac-cp-kafka:9092 --group.id test --topic bank_transaction --schema.registry http://mysr-schema-registry:8081 --CepJson """{\"keyId\": \"customer_id\",\"pattern\": [{\"patternName\": \"p1\",\"simpleCondition\":{\"columnName\": \"amount\",\"operator\": \">\",\"value\": \"50\",\"dataType\": \"Int\"}},{\"patternName\":\"p2\",\"simpleCondition\":{\"columnName\":\"amount\",\"operator\":\">\",\"value\":\"30\",\"dataType\":\"Int\"}}],\"connector\":[{\"name\":\"begin\",\"connectorType\":\"next\",\"start\":\"p1\",\"end\":\"p2\"}]}"""
To convert above command to a flink REST based post request I did the following -:
curl -k -v -X POST -H "Content-Type: application/json" --data '{ "entryClass":"com.class.name", "programArgsList": [ "--bootstrap.servers izac-cp-kafka:9092", "--group.id test", "--topic bank_transaction", "--schema.registry http://mysr-schema-registry:8081", "--CepJson """{\"keyId\": \"customer_id\",\"pattern\": [{\"patternName\": \"p1\",\"simpleCondition\":{\"columnName\": \"amount\",\"operator\": \">\",\"value\": \"50\",\"dataType\": \"Int\"}},{\"patternName\":\"p2\",\"simpleCondition\":{\"columnName\":\"amount\",\"operator\":\">\",\"value\":\"30\",\"dataType\":\"Int\"}}],\"connector\":[{\"name\":\"begin\",\"connectorType\":\"next\",\"start\":\"p1\",\"end\":\"p2\"}]}""""]}' http://localhost:30287/jars/2a788e33-c92d-47c4-84af-31e3dff28666_1.0-1.0-SNAPSHOT.jar/run
However, this gave the error as mentioned earlier. I just wanted to convert the above command line job submission to a rest api based submission to flink cluster.
Note -: The post request is for a cluster of flink which already contains the required Jar. I only want to submit a job using a particular class.
I don't think that curl accepts """ as a string interpolation the way scala does so it won't send correct CepJson parameter for sure, so I would start with changing that.
I changed the above curl request to the following and it worked -:
curl -k -v -X POST -H "Content-Type: application/json" --data '{ "entryClass":"com.class.name", "programArgsList": [ "--bootstrap.servers", "izac-cp-kafka:9092", "--group.id"," test", "--topic","bank_transaction", "--schema.registry", "http://mysr-schema-registry:8081", "--CepJson", "{\"keyId\": \"customer_id\",\"pattern\": [{\"patternName\": \"p1\",\"simpleCondition\":{\"columnName\": \"amount\",\"operator\": \">\",\"value\": \"50\",\"dataType\": \"Int\"}},{\"patternName\":\"p2\",\"simpleCondition\":{\"columnName\":\"amount\",\"operator\":\">\",\"value\":\"30\",\"dataType\":\"Int\"}}],\"connector\":[{\"name\":\"begin\",\"connectorType\":\"next\",\"start\":\"p1\",\"end\":\"p2\"}]}"]}' http://localhost:30287/jars/2a788e33-c92d-47c4-84af-31e3dff28666_1.0-1.0-SNAPSHOT.jar/run

Text to Speech 37 byte file returned

The wav file returned by the IBM Watson text to speech service is blank.
I have tried many command line arguments (including,excluding braces) and most return blank wav files of size 37 bytes. My OS is Windows 10.
curl -X POST -u "apikey:{my_key_number_here}" ^
--header "Content-Type: application/json" ^
--header "Accept: audio/wav" ^
--data "{\"text\":\"Hello world.\"}" ^
--output hello_world.wav ^
"https://stream.watsonplatform.net/text-to-speech/api"
I would like to get a "hello world" wav file but instead the wav file I get is blank and only 37 bytes in size.
It looks you don't have the complete URL in your Curl command. You need to use the URL https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize.
The error is probably still an incorrect url, as hinted at by Mike Kistler's answer. The 37 byte file will be an error code and based on your comments its a
{"code":401, "error": "Unauthorized"}
Which means that either you have the wrong key, or you are using the wrong endpoint. To obtain both you need to create an instance of the TTS service in IBM Cloud. Once created you can create credentials for the service. Take a look a the credentials, there will be an IAM Key as well as an endpoint. You need both. Endpoints differ according to the centre you deployed to. For example if you deployed on to the Frankfurt location the endpoint will be https://stream-fra.watsonplatform.net/text-to-speech/api

Sending empty string value for a custom request header using cURL

I am trying to send a HTTP POST custom request header (X-Privet-Token) with value set to "" using cURL on a Linux machine. Following is my command:
curl -k -sI POST -H "X-Privet-Token:" -H "Content-Type: application/json" --trace-ascii --data "action=start&user=xyz#gmail.com" https://127.0.0.1/privet/register
I would like to send an empty string to the server.
Am I missing something?
You can use the following syntax to set a custom header with an empty value
curl -H "X-custom-header;" <some host>
From the man page:
man curl
...
-H, --header <header>
...
If you send the custom header with no-value then its header must be termi-
nated with a semicolon, such as -H "X-Custom-Header;" to send "X-Custom-Header:".
...
I know it is an old question, but I think it is worth to answer it.
I faced a similar issue when calling the privet/info API call in a Java client app, I realized the header was not sent when it was empty. If you want to set an empty header, try to use \"\" (that's what privet documentation states for /privet/info API call):
curl -k -sI POST -H "x-privet-token: \"\"" -H "Content-Type: application/json" --trace-ascii --data "action=start&user=xyz#gmail.com" https://127.0.0.1/privet/register
On the other hand, the privet/register API call requires a valid x-privet-token. Leaving the x-privet-token header empty, 'curl' may be ommiting it.
Having said that, the error you are getting occurs when the endpoint is not advertising /privet/register API, probably because it's already registered. You can check the APIs that the device is exposing examining the /privet/info response.

How to convert multiple documents using the Document Conversion service ina script bash?

How can I convert more than one document using the Document Conversion service.
I have between 50-100 MS Word and PDF documents that I want to convert using the convert_document API method?
For example, can you supply multiple .pdf or *.doc files like this?:
curl -u "username":"password" -X POST
-F "config={\"conversion_target\":\"ANSWER_UNITS\"};type=application/json"
-F "file=#\*.doc;type=application/msword"
"https://gateway.watsonplatform.net/document-conversion-experimental/api/v1/convert_document"
That gives an error unfortunately: curl: (26) couldn't open file "*.doc".
I have also tried "file=#file1.doc,file2.doc,file3.doc" but that gives errors as well.
The service only accept one file at a time, but you can call it multiple time.
#!/bin/bash
USERNAME="<service-username>"
PASSWORD="<service-password>"
URL="https://gateway.watsonplatform.net/document-conversion-experimental/api/v1/convert_document"
DIRECTORY="/path/to/documents"
for doc in *.doc
do
echo "Converting - $doc"
curl -u "$USERNAME:$PASSWORD" \
-F 'config={"conversion_target":"ANSWER_UNITS"};type=application/json' \
-F "file=#$doc;type=application/pdf" "$URL"
done
Document Conversion documentation and API Reference.

Resources