Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flask server ( eventlet ) issue #222

Closed
jackmullen opened this issue Feb 3, 2016 · 8 comments
Closed

Flask server ( eventlet ) issue #222

jackmullen opened this issue Feb 3, 2016 · 8 comments
Assignees

Comments

@jackmullen
Copy link

Dear Miquel:

I have been struggling with this issue for some time. If you can think of a better forum to ask please let me know.

I have a flask application (which works nicely) that benefits from real time feedback via flask-socketio (2.0). My problem involves the server. First

  1. How can I be sure eventlet is actually serving files and not the testing server that ships with flash.. At the command line I see this after starting, and debug=False. "wsgi starting up on http://0.0.0.0/"

for the record I have installed eventlet
( pip freeze |grep eventlet == > eventlet==0.17.4 )
flask version .10.1
flask-serverio version 2.0

I am starting the app using the following code :
if name == 'main':
flask_options = dict(
host='0.0.0.0',
port=80,
)
socketio.run(app, **flask_options)

The real issue is this: I am attempting to serve media files, for download not streaming. I have been using flask.send_from_directory() and using the appropriate headers to cause down load in the browser and for the most part that works -- but there is something different between the eventlet (and the flask out of the box testing server) server and most others including nginx hosting an app designed to just serve media files from flask for download. ( I have tested the result using straight apache and no flask with positive results -- as described below the apache server mimics the nginx server)

When using the eventlet server -- If I try to open the a link to a file on a Quick time player (apple) or other player like vlc -- It plays the file with the notation of "Live Broadcast" rather than download the file and play after enough data has arrived. This is an important problem for the concept of my app. The usefulness of the having the file quickly downloaded is what I am looking for.

I have checked the request headers from the server setup with eventlet and compared them to a nginx server version -- serving the same file from the same site -- and, with the exception of the addition of etags and no 'server' header being produced by the eventlet server, they are nearly identical.

Both servers, for example, show content-type as 'audio/mpeg' and I have even set up a wrapper around send_file() to produce 'accept-range' header.. But the behavior of the end results are not the same.

The nginx served file will cause the quick time player to download the file and then play -- the flask with eventlet ( I assume ) .. will cause the quicktime player to play as a stream leading to restarts of the stream with a loss of data (say on a cell phone) ---

My questions are how can I be sure eventlet is serving the file -- and if it is -- why do you suppose it is different response from the application calling for the file ?

If I want to use nginx as the proxy server :

In your example in the docs you mention how to use nginx as a proxy -- does that require the uwsgi server to also be configured for the connection to the socket ? for example downloading and installing uwsgi and then configuring uwsgi as a proxy between flask and nginx ?

Is there any further information on how to use nginx ?

Thank you,

Jack Mullen

@jackmullen
Copy link
Author

I was able to use the nginx proxy example you provided and it revealed something new. It must be a Flask issue that prevents the full read of the data file or apparently is not passing the data to the server for download -- it is measured out as a mpeg streaming server might -- (say icecast) .. (although changing the content-type header to 'application/octet-stream' or 'force download' makes no difference.

Here is what I learned -- if you set up Flask and uwsgi and let nginx start the flask application it will allow the data to be downloaded by the client while playing -- If I start the flask application using a flask.app.run() or socketio.run() and let nginx connect via port 5000 the data is only available as a stream .. As you have mentioned there is no way at this time to serve the data via uwsgi and nginx .. is that correct ?

@jackmullen
Copy link
Author

Oh and the results are the same with flask-socketio or without as I have set a separate file server flask app that does not use flask-socketio and it also will not properly provide the data when running standalone on port 5000 and nginx proxied.

@miguelgrinberg
Copy link
Owner

Pretty sure you can force a file to be saved instead of opened with the Content-Disposition header in the response. Are you setting that? If you are, please compare the values from nginx and flask.

@jackmullen
Copy link
Author

yes -- It will not work in the situations I described above -- I can use content-disposition in the parameters of send_from_directory() and it will cause a download box in a browser -- but has no affect on the mobile apps and the media apps like quicktime .. they will still stream the data rather than download -- but if I let nginx start the app using uwsgi the proper behavior is observed wherein the content is downloaded by the mobile apps as they play it .. I can give real examples if you are interested .. but I have determined it has nothing to do with socketio .. except that I wish i could get socketio to work in a situation where I had the download behavior I am looking for and real time communications. .. :) thank you ..

@miguelgrinberg
Copy link
Owner

Have you considered using the <video> tag to get your video clips to play back while downloading?

@jackmullen
Copy link
Author

No but I will ...

@jackmullen
Copy link
Author

I have found a solution to the issue I have identified above .. I have added another location definition to the proxy config file you created

location /static {
alias /var/www/html/testserver/static;
autoindex on;
expires max;
}
After this the nginx server will serve the file in the expected way.

maybe you could add this to your nginx proxy example -- also maybe there is a similar solution available for the eventlet server -- not sure.

@miguelgrinberg
Copy link
Owner

Configuring nginx to serve static files directly without passing through Flask is always a good idea, as nginx can serve files much more efficiently than Flask. If the video files you are serving are not generated dynamically, then this is a great solution.

I agree it is a good idea to include this in the documentation, to avoid people from blindly copy/pasting the example config. I have to think about how to represent the static file location, which can vary for different applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants