Flask download sometimes not starting in Firefox - flask

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.

Related

Files are being downloaded at pythonanywhere server and user laptop/pc too. How to restrict to write at pythonanywhere server

Problem is i have hosted at pythonanywhere using django.Video is downloaded at pythonanywhere server and user/client system too.Thats why i used os. remove(path).After downloading it removes from server.
Is there any ways files donot write on pyhtonanywhere server. so that i donot use os.remove(path).
How to restrict to write at pythonanywhere server. Only to download at user system.
def fb_download(request):
link = request.GET.get('url')
html= requests.get(link)
try:
url= re.search('hd_src:"(.+?)"',html.text)[1]
except:
url= re.search('sd_src:"(.+?)"',html.text)[1]
path=wget.download(url, 'Video.mp4')
response=FileResponse(open(path, 'rb'), as_attachment=True)
os.remove(path)
return response
If I understand correctly, you're trying to get a request from a browser, which contains a URL. You then access the page at that URL and extract a further URL from it, and then you want to present the contents of that second URL -- a video -- to the browser.
The way you are doing that is to download the file to the server, and then to serve that up as a file attachment to the browser.
If you do it that way, then there is no way to avoid writing the file on the server; indeed, the way you are doing it right now might have problems because you are deleting the file before you've returned the response to the browser, so there may (depending on how the file deletion is processed and whether the FileResponse caches the file's contents) be cases where there is no file to send back to the browser.
But an alternative way to do it that might work would be to send a redirect response to the URL -- the one in your variable url -- like this, without downloading it at all:
def fb_download(request):
link = request.GET.get('url')
html= requests.get(link)
try:
url= re.search('hd_src:"(.+?)"',html.text)[1]
except:
url= re.search('sd_src:"(.+?)"',html.text)[1]
return redirect(url)
By doing that, the download happens on the browser instead of on the server.
I don’t understand javascript really good,
But i think if you download the file to the server
And then you can download the file to the use using JS
And i think you can use

cURL vs Requests (SSL issue?)

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)

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.

Why am I getting different mime types on my flask app on localhost and openshift?

I have a dynamic css file which loads fonts using font-face which is generated by a request and I am setting the content headers explicitly. It's all working well as far as mime types are concerned at localhost(text/css in network tab) except that the fonts are not loaded in chrome but works in firefox. But that's a different issue, so now I put the code on openshift and by magic response has a text/html header. What am I missing here ?
resp = make_response(render_template('webfonts.css', fonts=fonts))
resp.headers.add('content-type', 'text/css')
return resp
heres the flask code.
and heres the url
http://flaskexample-diadara.rhcloud.com/api/webfonts?font=LohitGujarati
I had the same issue (with the Flask built-in server) and also came across your question, I found the following:
While adding the header can be found elsewhere as the recommended solution it actually doesn't set one of the properties in the Response object (which actually makes sense if you think about it) making the server still send out a default text/html header.
The way that I found it to work is this:
response = Response(render_template('css/' + filename), mimetype='text/css')
return response
You should also do
from flask import Response

api request returns json files and not html/xml browser content

I am sending get httpwebrequests to the facebook graph api and all was working fine till I deployed to production server and now module that expects html/xml response is not working and when tested url in internet explorer, the save file dialog pops up and the file needs to be saved.
Other modules also send requests to the facebook graph but just differ in the form of requests so not sure what is going on here.
Any ideas appreciated
Edit:
Let me try and rephrase this. On my production server the httpwebrequest was not returning the correct result. So to Test it I copied the url http://graph.facebook.com/pepsi which is an example, should return the profile info viewable in the browser. The server has internet explorer v8 and I am not sure why it tries to download the file instead of displaying it in the browser. this is what is happening in my code and when I make a request to a different part of the api, then it works in my app but not in the browser
Your question is not very clear. From what I gather, you want the display the JSON response in a browser. Instead, you are being asked to download a file by the browser.
Well, this is normal behaviour. The response you get from Facebook would most likely have a MIME type of application/json. Most newer web browsers display the text in the browser itself. Some browsers, however don't know how to handle this content type and just ask you to download the file.
You mentioned that your module expects an html/xml response. Try changing this to application/json.
You also said that it works in your app but not in your browser. I don't know what you're making, but generally you wouldn't show raw json to the user in a browser, right?