I'm trying to forward a file upload POST request my Python Flask webservice receives to another API. I already receive the request in a format that the API would accept, however, I was not able to find any way to take the request I received and directly forward it to the API. I had imagined that maybe something like this could exist:
requests.post("url_of_api", request)
Where request is Flask's representation of the received request. Is such a thing possible?
Alternatively, I'm trying to recreate a request with the same data. The problem is that the request contains a file upload (wav specifically). I've tried to create a request with the file data as follows:
requests.post("url_of_api",files={"audio_data":("test.wav",request.files["audio_data"].stream.read())})
I can see in Wireshark that the requests are almost identical in respect to their file representation, however, there are slight differences at the start and end of the bytestream and file in the second request has 46 fewer bytes of data. In addition, it loses its MIME-type. Is there any way to exactly replicate the byte representation of the uploaded file in a new request?
Related
I find this code and I really don't understand it, how is it possible to send data (not query) with GET request
response = requests.get(
check_all_info_url_2, files=multipart_form_data, timeout=30)
and what is files= argument in the get request.
Since requests.get is just a wrapper function this will just call requests.request. Unless requests.session implementes any checking, it will happily send off a GET request with multipart data in it.
Is this valid? Not to my knowledge, although I'm willing to be proven wrong. No api I have ever written would accept file upload on a GET request. But not every server will even check the method, so perhaps this code is interacting with a badly written server which doesn't reject for wrong method, or perhap's it's even interacting with a worse server which expects file upload with GET. There are lots of broken servers out there ;)
In any case, the reason this works with requests is that it just passes keyword arguments through to the underlying session without performing any kind of validation.
Can I send a http response to a specific requestLine outside the function I received the request in it.
As an example I receive the request then pass this request to some functions and I want to send a response to this request, if there is allowed?
If you're going to split the path your program is taking, so it's doing two different things at the same time, then you'll need to utilize control-flow constructs that do this like threads/processes/events/async.
You might want to look at Celery (http://www.celeryproject.org/) and Jobtastic (http://policystat.github.io/jobtastic/).
I am currently trying to implement a HTTP client using python and sockets. It is very simple and the only thing it has to do is to download a file from a webserver and put it into a file supplied by the user.
My code is working fine but I am having a problem of how to exclude the HTTP response header from the file.
The HTTP response header is only at the beginning of the file so I was thinking that I could just dump all the data into the file and then take the header out after. This is a problem though since I/O is very slow.
My next thought was that I could run some Regex on the first response I get from the server, sort away the header and then dump the rest into the file. This seems as a very clunky way to do it though.
Does anyone have any suggestions on how to do this in a smart way?
In the http response, the headers are separated from the body with '\r\n\r\n'. To get only the body, you can try this:
bodyBegin = httpResponse.find('\r\n\r\n') + 4
body = httpResponse[bodyBegin:]
saveToFile(body)
I am writing a web service using Django that will be consumed from a MS SharePoint workflow. In the SP workflow, I created a dictionary with 2 items (id:1, text:'foo'), and used this dictionary as the request content. However, instead of using the dictionary to format a traditional POST parameter list, it sends it as a JSON object in the body of the POST request, so instead of the expected:
id=1&text=foo
in the body of the request, there is this:
{"id":1,"text":"foo"}
which of course, in turn, does not get parsed correctly by Python/Django (I am not sure who exactly does the parsing). How can I either get it to parse JSON, or get SharePoint to send traditionally encoded POST parameters?
EDIT
I saw other posts that explain how to get the raw body and parse the JSON. I was looking for a solution that would either:
Make SharePoint send normal data, or
Get Django to respect the Content-type header that states the data is JSON
There is no need for any parsing at the framework level. The body of the post request is always available in request.body, so you can access it directly:
result = json.loads(request.body)
May be it will help you bit more to handle.
import json
import urlparse
json.dumps(urlparse.parse_qs("id=1&text=foo"))
I have a service to which I need to upload the content and the server starts sending the response after it gets certain amount of data, while my request body is still uploading.
headers = {'Content-Type': 'application/octet-stream', 'Expect': '100-continue', 'Connection' :'keep-alive'}
url = "https://MY_API_URL/WEBSERVICE"
response = requests.put(url, headers=headers,stream=True, data=data_gen(fh))
lines = response.iter_lines()
for line in lines:
print line
data_gen is my generator function which takes a file handle of a very large file that yields 4KB per iteration.
My problem is that I dont get the "response" until the whole file uploads. Any ideas on how I can overcome this.
You cannot accomplish this with requests today. Requests (and the underlying libraries, including httplib/http.client [depending on your version of Python]) all send all of the data before they start reading the response.
One library that may be able to handle this (in fact, I'm fairly certain this should be doable with it) is treq. It uses Twisted which should give you ways to determine when data is received so all you should need to do is register a callback to start accessing that data.