Serve static files from drawings without URL prefix

For development, I would like to use static files from the static project folder. However, I do not want to download all files through the drawing url prefix. Is it possible to configure the flask, so it looks in all the static folders and returns the first file found? The reason for this is that when you deploy the application, the build process pulls out all the files from our drawings and puts them in a separate folder (similar to the collection of Django collections).

In other words, I have 2 drawings: foo and bar :

 app +--- foo | +--- assets | | +--- css | | | | | +--- js | + | | | +--- __init__.py: foo_blueprint = Blueprint('foo', __name__, static_folder='assets') | +--- bar + | +--- __init__.py: bar_blueprint = Blueprint('bar', __name__, static_folder='assets') 

I want all js files in specific js subfolders to be accessible from url /static/js/file.js . Is it possible?

+1
python flask static-files
source share
1 answer

You cannot use the default flask mechanism.

In your example, you will create 3 rules for a static forlder:

 Rule "/assets/<path:filename>" for "static" endpoint Rule "/assets/<path:filename>" for "foo.static" endpoint Rule "/assets/<path:filename>" for "bar.static" endpoint 

When the flask matches your URL, you must first transfer it and return it. In this case, it returns the endpoint rule static . After the function is sent for this endpoint, for example. one folder.

PS. I'm not sure if the static final endpoint, better check out the Map.update method.

But you can always write your own request descriptor, which will look in folders with blue prints:

 class MyApp(Flask): def static_dispatchers(self): yield super(MyApp, self).send_static_file for blueprint in self.blueprints.values(): yield blueprint.send_static_file def send_static_file(self, filename): last_exception = None for static_dispatcher in self.static_dispatchers(): try: return static_dispatcher(filename) except NotFound as e: last_exception = e raise last_exception 

PS. This example does not include the drawing registration sequence, as it is stored in a dict.

But if you have two files with the same name, then the first file will be processed. For example, if you have the following structure:

 /static /static/app.js "console.log('app');" /foo/static/app.js "console.log('foo app');" /foo/static/blue.js "console.log('foo blue');" /foo/static/foo.js "console.log('foo self');" /bar/static/app.js "console.log('bar app');" /bar/static/blue.js "console.log('foo blue');" /bar/static/bar.js "console.log('bar self');" 

And include the scripts on the page:

 <script src="{{ url_for('static', filename='app.js') }}"></script> <script src="{{ url_for('foo.static', filename='app.js') }}"></script> <script src="{{ url_for('bar.static', filename='app.js') }}"></script> <script src="{{ url_for('foo.static', filename='blue.js') }}"></script> <script src="{{ url_for('bar.static', filename='blue.js') }}"></script> <script src="{{ url_for('foo.static', filename='foo.js') }}"></script> <script src="{{ url_for('bar.static', filename='bar.js') }}"></script> 

You will have the following result:

 app app app foo blue (or bar blue) foo blue (or bar blue) foo self bar self 

For js and css, you can combine files with the same path, but cannot do this for images.

However, I prefer to use a unique URL prefix for each plan because it is simple with url_for .

+2
source share

All Articles