cURL vs Requests (SSL issue?) - python-2.7

All, I'm getting some strange behavior trying to use requests for an https call into the gitub api:
print(requests.get('https://api.github.com/gists/bbc56a82f359eccd4bd6').text)
The output looks like printing a binary file (no point in pasting the garbled output here).
An equivalent cURL call ("curl https://api.github.com/gists/bbc56a82f359eccd4bd6") results in the JSON response I'm expecting.
All this started after fixing a pip issue (InsecurePlatformWarning), where a few security-related packages were installed. This fix is required for users of python<2.7.9. I'm on 2.7.3 as it was recommended on some sites not to touch the python build on debian (for dependency-breaking issues).
Note that the issue that i'm having breaks functionality for e.g. github3py python API wrapper, etc.
Is anyone else seeing issues with requests after the upgrade? Any fixes?

This URL clearly responds differently depending on user-agent. I could make the curl command line response differ by simply adding -A moo/1.
You can probably get a curl-like response with Requests from this by using a curl like user-agent.
Or even better: just ask github or read up on their API.

I'm not seeing that behaviour here:
>>> import requests
>>> print(requests.get('https://api.github.com/gists/bbc56a82f359eccd4bd6').text)
Returns a JSON string. You could try debugging this further by changing the User-Agent of your request call to be that of cURL:
headers = {
'User-Agent': 'curl/7.38.0',
}
url = 'https://api.github.com/gists/bbc56a82f359eccd4bd6'
response = requests.get(url, headers=headers)

Related

CSRF Token error when attempting to post from CURL to an API endpoint I control. How do I write the request?

I have not utilized this part of Django before, but I have an endpoint which is giving me a 403 error and is telling me that my request needs a csrf token. I was trying to figure out how best to get this since I was attempting to set up a bunch of curl requests to handle some simple queries to the endpoint. Likewise, I was thinking to also use POSTman, but I was not sure where documentation is to handle these request.
I have seen the cookie csrftoken, but when I was attempting to curl with it, it was still giving me a 403. thought it would looking something like this:
curl -d #profilepicturev2.png -b "csrftoken=Ebfn2OlfhSwFjAEQdoQon7wUjbynFoJqrtHMNPla3cy7ZfCMT9cxZ3OQHsbaedam" http://127.0.0.1:8000/api/files/uploader
Maybe I am mistaken? I am trying to send a photo to the server, so i was thinking that this would be correct and wasnt sure if i needed to add additional params in order to append additional data information.
i need to see your code, but i think you need to install "pillow" to send pictures in django !

Flask download sometimes not starting in Firefox

I am trying to send a file from Flask to the browser, as it can observed from the code below
response = make_response(send_file(os.path.abspath(app.root_path)+server_path,as_attachment=True))
response.mimetype = mimetype # Chosen between "application/zip" and "application/gz"
return response
I am not using send_file directly because I need to add extra headers to the response.
The issue is that in Chrome this works flawlessly but when I move to Firefox the download, sometimes, just hangs in the download manager without starting or the download starts but the page will not refresh.
What could be the cause of this behavior?
Is that the full code example, or are you doing other things to the response? Are there other extra headers are you adding at some point? And are you saying it works on firefox when you try send_file without wrapping it in a make_response first?
Also, depending on which version of flask you're using, send_file supports adding an argument to the method for mimetype, see the documentation: http://flask.pocoo.org/docs/1.0/api/#flask.send_file so there might not be a reason for you to wrap it with the make_response function.

Unity 2017.3 HTTP POST request always empty when it hits web app (Django)

I'm trying to use Unity 2017.3 to send a basic HTTP POST request from Unity scripting. I want to send an image data, which I can access in my script either as file.png or in a byte[]. I am only posting to a local server running Python/Django, and the server does register the POST request coming in - but no matter what I do the request arrives empty of any content, body, files or raw data at my web app.
IEnumerator WriteAndSendPng() {
#extra code that gets bytes from a render texture goes here
#can verify that drawing.png is a valid image for my purposes
System.IO.File.WriteAllBytes("drawing.png", bytes);
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add( new MultipartFormFileSection ("drawing", bytes, "drawing.png", "image/png") );
UnityWebRequest www = UnityWebRequest.Post("http://127.0.0.1:8000/predict/", formData);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) Debug.Log(www.error);
else Debug.Log("Form upload complete!");
}
I'm following the docs and there are a bunch of constructors for MultipartFormFileSection, most of which I feel like I've tried. Also tried UploadHandlers, or the old AddBinaryField WWW API - still the request is always empty when it hits my app... I've read the thorough response to this SO ticket, Sending http requests in C# with Unity. I have tried many of the implementations here but again, Django receives empty requests. Even submitting the simplest possible request from Unity sends empty requests. So weird.
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add (new MultipartFormDataSection ("someVar=something"));
The Python server just sees:
[11/Feb/2018 14:14:12] "POST /predict/ HTTP/1.1" 200 1
>>> print(request.method) # POST
>>> print(request.encoding) # None
>>> print(request.content_type) #multipart/form-data
>>> print(request.POST) # <QueryDict: {}>
>>> print(request.body) # b''
I thought it might be a Django issue, but posting to the same app w/ Postman or from other sources, it sees the incoming data just fine. Anyone done this recently? I thought this would be a piece of cake and many hours into into it I remain stymied. All help appreciated! Thanks, all.
Figured it out courtesy of Unity staffer Aurimas-Cernius on their forums: "The issue most likely is that your Django server does not support HTTP 1.1 chunked transfer. You can either try updating your server, or set chunkedTransfer property on UnityWebRequest to false."
He was right. Setting that flag to false allowed me to start sending simple test case data and receiving it as expected in the Django app - bet I'll be able to get images working in no time. I was also experiencing side effects of using Python 3.5.x (mistakenly assuming I needed to). Upgrading that fixed the chunk issue, too. Cheers!

Django + Wordpress RESTful Api with requests

How can I connect on a Wordpress website (and get it posts) using REST api? What I did:
Installed the REST plugin on Wordpress (https://wordpress.org/plugins/json-rest-api/)
Enabled it
But I can't get the posts. Only if I use CURL (but I would like to use requests)
import requests, json
r = requests.get('http://www.uaigeek.com.br/blog/wp-json/posts', auth=('admin', 'pass'))
print r.status_code
print r.json
Using CURL (curl -I http://www.uaigeek.com.br/blog/wp-json/posts) it works like a charm, but using requests it always get 403 error (sometimes 404).
How can I do that?
Solved! It was a "problem" from Site5 host, they block requests, I've to ask for this permission and it works like a charm now.

Using Request, HttpNtlmAuth to make a system call with authentication

I've got the following snip of code the has the audacity to tell me it is "FAIL to load undefnied" (the nerve...) I'm trying to pass my authenticated session to a system call that uses javascript.
import requests
from requests_ntlm import HttpNtlmAuth
from subprocess import call
# THIS WORKS - 200 returned
s = requests.Session()
r = s.get("http://example.com",auth=HttpNtlmAuth('domain\MyUserName','password'))
call(["phantomjs", "yslow.js", r.url])
The issue is when "calL" gets called - all I get is the following
FAIL to load undefined.
Im guessing that just passing the correct authenticated session should work - but the question is how do I do it such that I can extract the info I want. Out of all the other attempts this has been the most fruitful. Please help - thanks!
There seem to be couple things going on here so I'll address them one-by-one.
The subprocess module in python is meant to be used to call out to the system as if you were using the command line. It knows nothing of "authenticated session"s and the command line (or shell) has no knowledge of how to use a python object, like a session, to work with phantomjs.
phantomjs has python bindings since version 1.8 so I would expect this might be made easier by using them. I have not used them, however, so I can not tell you with certainty that they will be helpful.
I looked at yslow's website and there appears to be no way to pass it the content that you are downloading with requests. Even then, the content would not have everything (for example: any externally hosted javascript that would be loaded by selenium/phantomjs or a browser, is not loaded by requests)
yslow seems as though it normally just downloads the URL for you and performs its analysis. When the website is behind NTLM, however, it first sends the client a 401 response which should indicate to the client that it must authenticate. Further, information is sent to the client that tells it how to authenticate and provides it parameters to use when authenticating for NTLM. This is how requests_ntlm works with requests. The first request is made and generates a 401 response, then the authentication handler generates the proper header(s) and re-sends the request which is why you see the 200 response bound to r.
yslow accepts a JSON representation of the headers you want to send so you can try to use the headers found in r.request.headers but I doubt they will work.
In short, this is not a question that the people who normally follow the requests tag can help you with. And looking at the documentation for yslow it seems that it (technically) does not support authentication of any type. yslow developers might argue though that it supports Basic Authentication because it allows you to specify headers.