Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask, Keep getting 404 serving static files using send_static_file

Tags:

python

flask

I followed the instructions from How to serve static files in Flask, but still couldn't get it working.

Here's my project structure:

Project_path    |  +--app  |  |  |  +--main.py  +--static     |     +--js        |        +--jquery-1.11.2.min.js 

Here's main.py:

@app.route('/js/<path:path>') def serve_static(path):     root_dir = os.path.dirname(os.getcwd())     print(os.path.join(root_dir, 'static', 'js', path))     return app.send_static_file(os.path.join(root_dir, 'static', 'js', path)) 

Here's index.html:

  ...   <script type="text/javascript" src="/js/jquery-1.11.2.min.js"></script>   ... 

And when I visit /, I could see the correct path of javascript file printed on the screen
which is Project_path/static/js/jquery-1.11.2.min.js.

But still, I got

127.0.0.1 - - [22/Dec/2014 11:26:30] "GET /js/jquery-1.11.2.min.js HTTP/1.1" 404 - 

Any help is appreciated.

EDIT
After stepping through the send_static_file method, I find out what's going on. Basically, I shouldn't use abspath as argument, flask has a judgement in send_static_file:

if os.path.isabs(filename) or \    filename == '..' or \    filename.startswith('../'):     raise NotFound() 

And since the filename I passed into is a abspath, flask raise NotFound().
It seems that what it supposed to be passed in is a relative path to self.static_folder(self is <Flask 'main'>), which, in my project, is Project_name/app/static. However, I didn't set static_folder myself which means flask thinks the static folder should be there.

I'm still trying to figure out what to do.

like image 478
laike9m Avatar asked Dec 22 '14 03:12

laike9m


2 Answers

Finally got it working. use flask.send_from_directory

from flask import send_from_directory  @app.route('/js/<path:filename>') def serve_static(filename):     root_dir = os.path.dirname(os.getcwd())     return send_from_directory(os.path.join(root_dir, 'static', 'js'), filename) 

It is now clear to me that flask really hate people putting app.py or in my case main.py into a subdirectory. Use send_static_file only if your static folder is what flask thinks to be, i.e. a folder with name static in the same directory with app.py.

like image 124
laike9m Avatar answered Oct 05 '22 12:10

laike9m


All you need to do is, pass the static_folder parameter to the initiator:

static_url_path – can be used to specify a different path for the static files on the web. Defaults to the name of the static_folder folder.

static_folder – the folder with static files that should be served at static_url_path. Defaults to the 'static' folder in the root path of the application.

app = Flask(__name__, static_folder=os.path.abspath('/foo/bar/zoo/')) 

Now, flask will look for a directory named static in /foo/bar/zoo from where to serve static files. You only use send_from_directory if you are serving media files which may not be in the same location as static files.

like image 30
Burhan Khalid Avatar answered Oct 05 '22 10:10

Burhan Khalid