Microsoft Speech API with Python requests? - http-post

I'm trying to use the requests package in Python to make a call to the Microsoft Bing Speech Transcription API. I can make the call work when I use Postman, but this requires manually selecting a file to upload (Postman provides a GUI to select the file), but I'm not sure how this file selection gets mapped onto the actual HTTP request (and by extension the Python requests request). Postman can convert its internal queries into code, and according to Postman the http request it's making is:
POST /recognize?scenarios=smd&appid=[REDACTED]&locale=en-US&device.os=wp7&version=3.0&format=json&form=BCSSTT&instanceid=[REDACTED]&requestid=[REDACTED] HTTP/1.1
Host: speech.platform.bing.com
Authorization: [REDACTED]
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: [REDACTED]
undefined
And the equivalent request if made through the Python requests library would be:
import requests
url = "https://speech.platform.bing.com/recognize"
querystring = {"scenarios":"smd","appid":[REDACTED],"locale":"en-US","device.os":"wp7","version":"3.0","format":"json","form":"BCSSTT","instanceid":[REDACTED],"requestid":[REDACTED]}
headers = {
'authorization': [REDACTED],
'content-type': "application/x-www-form-urlencoded",
'cache-control': "no-cache",
'postman-token': [REDACTED]
}
response = requests.request("POST", url, headers=headers, params=querystring)
print(response.text)
However note that in neither case does the generated code actually pass in the audio file to be transcribed (clearly Postman doesn't know how to display raw audio data), so I'm not sure how to add this crucial information to the request. I assume that in the case of the HTTP request code the audio stream goes in the spot displayed as "undefined". In the Python requests command, from reading the documentation it seems like the response = requests.request(...) line should be replaced by:
response = requests.request("POST", url, headers=headers, params=querystring, files={'file': open('PATH/TO/AUDIO/FILE', 'rb')})
But when I run this query I get "Request timed out (> 14000 ms)". Any idea for how I can successfully call the Microsoft Speech API through Python? Any help would be much appreciated, thanks.

Make this line your post request:
r = requests.post(url, headers=headers, params=querystring, data=open('PATH/TO/WAV/FILE', 'rb').read())
And that should do the trick.
In the Microsoft Documentation, the audio file binary data is the body of the POST request and must be sent using the data parameter of the requests library.

Related

POST request with Content-Type application/x-www-form-urlencoded and

My requirement is very simple.
Call POST request with id and password.
Header has Content-Type = application/x-www-form-urlencoded
and data is also passed as urlencoded like below
Response is coming in xml format.
I tried a lot of examples from everywhere but nothing seems to be working. It gives me back 401 Unauthorized which is an error that target API throws if request is not in proper format.
http://zetcode.com/java/getpostrequest/
Exactly what I needed.
Java HTTP POST request with HttpURLConnection section on the page did the work.

How to POST GZip Request with Apache JMeter

I have a question for using Apach JMeter.
Our project, Android apps post json data with "Gzip Compression" to API server.
The Android apps using "Apache HttpClient" and it's "GzipCompressingEntity" class.
For performance testing of API server, I tryed to recording the request by JMeter's Proxy (="HTTP(S) Test Script Recorder").
But the recorded request body was empty.
What I want to do is to send "Gziped HTTP request data" from Apache JMeter to server.
Is there any way for that?
Following is sample of our Android app's request header.
POST /api/test HTTP/1.1
Content-Type: application/json
Transfer-Encoding: chunked
Content-Encoding: gzip
Host: 192.168.11.11:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.5)
Accept-Encoding: gzip,deflate
RequestBody is Gziped binary data.
What I had done is
Run the "HTTP(S) Test Script Recorder(Proxy Server)" on JMeter.
Set http proxy of Android to use that proxy server.
Execute Android test code of HTTP Client (the post data is compressed by Gzip).
then, that test code finished with failure. (no response from server)
If access directly (without JMeter's Proxy Server), that test succeeded.
Can I send the compressed request data from JMeter just like this?
Add HTTP Header Manager to your test plan and add at least the following headers:
Content-Type: application/json
Content-Encoding: gzip
Add Beanshell PreProcessor as a child of the request which you need to encode and add the following code to it's "Script" area:
import org.apache.commons.io.IOUtils;
import java.util.zip.GZIPOutputStream;
String bodyString = sampler.getArguments().getArgument(0).getValue();
byte [] requestBody = bodyString.getBytes();
ByteArrayOutputStream out = new ByteArrayOutputStream(requestBody.length);
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(requestBody);
gzip.close();
sampler.getArguments().getArgument(0).setValue(out.toString(0));
It will get your request body, compress it and substitute on the fly so the request will be gzipped.
Encoding is wrong, you need to save it in body like this
sampler.getArguments().getArgument(0).setValue(new String(compressedBody, 0));

JMeter HTTP Request: Always Sending GET Method

All,
Every HTTP Request I make to my test REST Service is sent with the method set to GET. Tomcat rejects with a 405 - Unsupported Method. Doesn't matter what I change it to (POST, PUT, etc) Jmeter always sends a GET.
I set up the simplest possible test case by creating a Threadgroup with an HTTP Request Sampler and a View Results Tree. I send a JSON body to the REST Services which just echos back the request along with an ID. Works great with Google's REST Client UI.
Here is the result from the View Results Tree:
Response code: 405
Response message: Method Not Allowed
Response headers:
HTTP/1.1 405 Method Not Allowed
Server: Apache-Coyote/1.1
Allow: POST
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1045
Date: Fri, 18 Jul 2014 21:39:27 GMT
Here is the RequestMapping from my REST Service
#RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
Here are some screenshots from my results. I wonder why there are two URI's below the HTTP Request in the tree? Notice the POST request looks correct.
Since the right answer is not provided yet: It's the "Follow Redirects" Option that causes this behavoir under certain circumstances.
see http://www.sqaforums.com/showflat.php?Cat=0&Number=687068&Main=675937
Try to end the 'Path' value of HTTP Request with '/'. It has to remove the GET result in View Results Tree.
I had the same problem. I tried everything also I read this question and all answers before find the thing that worked for me.
Content-Type should be application/json. It can not be text/html.
Set that in HTTP Header Manager. I assume you have set authentication details correctly.
We need to have three things properly set.
Content type which will be application/json
set the endpoint correctly in the path ,which you can see in soup ui
Check the port number on which the api wil get run on [All this u can first check on soupui and then try running the same in jmeter

RESTserver POST request format

I am developing an API using CodeIgniter and the RestServer for CI (see below). I am also using the Firefox RestClient plugin to test the API.
What I am wondering is how to do the test post (what format).
Tried {"desc":"value"} but it did not work. The API is not "seeing" the incoming post fields.
http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/
the post body doesn't need to have a specific format, but the most convenient is to encode the body in the same way web browsers encode form data, specifically Content-Type: application/x-www-form-urlencoded. In particular, the Host and Content-Length headers are not optional, and the Content-Type header is usually needed to tell the server how to interpret the body. A well formed POST request will look like:
POST /path/to/resource HTTP/1.0
Host: example.com:80
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
key=value&key2=value2
It's still up to the server to recognize the content-type header and parse the body that way.
Note that the data is after all the headers, not as part of the request path (in the first line).
Optionally, you can use Proxy Library which i wrote for CI. With that, you can simulate any of possible call to your API(its works for popular REST API too), with more simple syntax instead using cURL...
// An example call to your API end point using POST, will be simply
$this->load->library('proxy');
$this->proxy->http('POST', 'http://somesite.com/api/users', array('username' => 'foo', 'password' => 'bar'));
You can define whatsoever HTTP header too (like API Key or whatever else).

AJAX HTTP protocol response problem with custom server

I've started to add HTTP support to a custom C# non-webserver application which seems to work fine from Firefox/IE/Chrome when typing in the URL directly to the browser - where I can see a returned text string in the page from my application.
The problem is when I try do the same from a HTTPRequest in JavaScript on a web page I don't get a response with Chrome or Firefox (It's fine in IE) - rather I get a status of zero from the HTTPRequest object. I can however see that my application from its debug output received the request from the browser and provided the response so the browser must not be like the response I send in this case with the exception of IE being less picky.
I've swapped between trying different POST and GET requests to no avail - eg:
request.open('GET', url, true);
request.onreadystatechange = mycallback;
//request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(null); //tried '' as well and other data with a POST
My simplest server reply I have tried is:
HTTP/1.1 200 OK\r\n
Content-Length: 20\r\n
Content-Type: text/plain\r\n
\r\n
...........
I have tried 1.0 instead of 1.1, different headers such as Connection: Close, Accept-ranges and other random stuff as I tried to mimic other such responses I looked at with Wireshark.
Obviously it must be something simple but the magic combination eludes me!
Many thanks in advance.
And on that note I have answered my own question it was the cross domain security feature.
Which I have now fixed by adding the extra response header:
"Access-Control-Allow-Origin: *"
Hopefully that is useful for someone else in the future!

Resources