Forums

How does "Static files mappings" affect flask app url route

I found the help page about "static files" here: [https://help.pythonanywhere.com/pages/StaticFiles/]

It seems that there is a nginx/openresty serving static files, after I map '/' to '/home/myname/static', and place a index.html in static folder, even I remove code @app.route('/'), I can also access "http://myname.pythonanywhere.com" since by default it returns 'index.html' to me.

But I also can set static folder in flask app, like:

app = Flask(name, static_url_path='', static_folder='/home/myname/static')

So, how does they co-work if static file server and flask app can both deal with the same route '/'. Further more, I can set @app.route('/img/abc') in flask, while also place a picture 'abc' in '/home/myname/static/img'. As I tried, static file server will pocess them in priority. So, is there some best practice that I can use the static file server to process static files, and flask function 'url_for' still work correctly?

In general, you should not use static_folders within your flask app to serve static files (that will be slower).

For the particular index.html at '/', I would possibly just serve it as a dynamic file instead of a static file (and just setup /static/ url endpoints to serve static files.

And if you are very worried about performance issues on your '/' endpoint, just put cloudflare etc in front of it.

Tnanks for conrad's reply. If I set static files mapping in web page, the static file is return by web server (openresty), however, flask app still set 'static_url_path' and 'static_folder', so I can use 'url_for' function, that's much flexible, What I hope is that the url of static file genereated by 'url_for' is a correct path that openresty in front can process. Is this a feasible method?

I think that if you set up Flask correctly, it should work fine. One thing that Conrad didn't mention which might be of interest -- the system works by checking for static files first, and then delegates to your Python code if there's no file at the appropriate location. An example:

  • Let's say you have a static file mapping on the "Web" page that maps /static/ to /home/yourusername/yoursite/static.
  • If a request comes in for http://yourusername.pythonanywhere.com/static/images/something.png, the system will scan the static file mappings, see the one you've set up, and will then look for a file /home/yourusername/yoursite/static/images/something.png.
  • If it exists, it will serve it.
  • If it does not, it will pass the request on to your Python code.

Thanks for Giles' reply. Now I can make sure for this: 1. Set a static mapping from "/static" to "/home/myname/static". 2. Use code "app = Flask(name, static_folder='/home/myname/static')"

They can work together, <img src="{{ url_for('static', filename='images/something.png') }}" /> will return the picture's url "/static/images/something.png", which will be processed by the delegates web server.

And another method: 1. Set a static mapping from "/" to "/home/myname/static". 2. Use code "app = Flask(name, static_url_path='', static_folder='/home/myname/static')"

Then result of {{ url_for('static', filename='images/something.png') }}" is "/images/something.png", which does not contains string 'static', that seems more clear, but can also be processed by the delegates web server. However, as @conrad had said, It's better serve the url '/' as a dynamic file instead of a static one.

So, which method is better, if I want to omit 'static' prefix (after redirecting, I won't get a /static/index.html), but also want route '/' is dynamically processed by my flask app, seems no perfect way could be found to make it.

I wouldn't use url_for at all, to be honest. If you've set up a route for /static on the web page, then in your templates I'd recommend just doing <img src="/static/images/something.png" />.

https://www.pythonanywhere.com/forums/topic/12195/#id_post_46324

I think that if you set up Flask correctly, it should work fine. One thing that Conrad didn't mention which might be of interest -- the system works by checking for static files first, and then delegates to your Python code if there's no file at the appropriate location. An example:

Is this still true? I'm asking because once I have an endpoint in my flask app serving from a directory, this flask app takes over. It seems static files are then not served through the static path webserver.

This is visible through the headers, as my Flask app uses other headers than the pya static server.

Yes, that's still true. We can take a look at your files and see if we can see any errors, if you like -- we can see your files from our admin interface but we always ask for permission first.

I have similar questions about this. Right now I have some tags in <head> set up like this w/ a Flask template:

<link rel="stylesheet" href="{{ url_for('static', filename='CSS/custom.css') }}">

Where my static folder is a default setup: 'project/app/static'.

It sounds as if I can map from 'project/app/static' to '/static/', and my CSS file will be served from 'https://me.pythonanywhere.com/static/CSS/custom.css'.

Just to be clear I DON'T have to change my {{ url_for(...) }} code?

Although Giles said he would not use it all in his Dec 15, 2017 post above, I think I still need to use "url_for" so my code works when I test updates on a local development server? I am new to Flask so maybe there is some environment configuration piece I am missing?

yes should be fine. (depending on how your url_for('static') is defined)