anujkk
anujkk

Reputation: 1353

Flask : How to serve static files from template directory?

I am developing a SAAS application using Flask and I want users to be able to create/upload/use their own custom templates. This is how my directory structure is right now :

/flaskapp
    /application.py
    /static
        /style.css
    /templates (site & admin templates goes here)
        /hello.html
    /userdata
        /user1
            /template1
                 hello.html
            /template2
                 hello.html
        /user2
            /template1
                 hello.html
            /template2
                 hello.html

I am able to serve user specified templates using a solution found through this stackoverflow question : How to dynamically select template directory to be used in flask? but how do I serve static files from template directory. Instead of serving static files from /flaskapp/static/ I want to serve static files using /flaskapp/userdata/<user>/<current-template>/static/ directory where and will be determined dynamically at run time. How to do this?

Upvotes: 5

Views: 2553

Answers (2)

mascarado
mascarado

Reputation: 1

This is what I use to serve files from whatever system directory.

The app searches a specific directory for a specific requested file:

when someone accesses http:/host/where/to/serve/files/example_file.txt the application will try to return example_file.txt as attachment, if the file doesn't exist it will return a 404.

You can adjust this and build the DIRECTORY_TO_SERVE_PATH with your user variables.

You should also validate the files to serve if you have any restrictions because this returns any file that exists in the path.

import os
from flask import abort, send_from_directory


DIRECTORY_TO_SERVE_PATH = '/where/files/are/in/disk/'


@app.route('/where/to/serve/files/<path:filename>')
def download_file(filename):
    if os.path.exists(DIRECTORY_TO_SERVE_PATH + filename):
        return send_from_directory(DIRECTORY_TO_SERVE_PATH, filename, as_attachment=True)
    else:
        abort(404)

Upvotes: 0

djc
djc

Reputation: 11711

Presumably you're using a web server in front of Flask. One way to solve this (which I generally use when using Apache + mod_wsgi for custom WSGI apps) is to just serve the directory straight from disk via the web server. On Apache, I just use an Alias directive for this.

If you want to vary the file served under a given URL per user, you would have to pipe the file through Flask. You'd have to figure out how to properly route the request; after that, you might be able to use wsgi.file_wrapper to send the correct file (though I'm not sure how you'd get at this through Flask).

Upvotes: 1

Related Questions