python flask browsing through directory with files

A path converter (docs link) in the url structure is better than hardcoding all the different possible path structures.

os.path.exists can be used to check if the path is valid and os.path.isfile and os.path.isdir for checking if the path is a file or a directory, respectively.

Endpoint:

@app.route('/', defaults={'req_path': ''})
@app.route('/<path:req_path>')
def dir_listing(req_path):
    BASE_DIR = '/Users/vivek/Desktop'

    # Joining the base and the requested path
    abs_path = os.path.join(BASE_DIR, req_path)

    # Return 404 if path doesn't exist
    if not os.path.exists(abs_path):
        return abort(404)

    # Check if path is a file and serve
    if os.path.isfile(abs_path):
        return send_file(abs_path)

    # Show directory contents
    files = os.listdir(abs_path)
    return render_template('files.html', files=files)

Template (Now with directory browsing :) ):

<ul>
    {% for file in files %}
    <li>
        <a href="{{ (request.path + '/' if request.path != '/' else '') + file }}">
            {{ (request.path + '/' if request.path != '/' else '') + file }}
        </a>
    </li>
    {% endfor %}
</ul>

Note: abort and send_file functions were imported from flask.


Here is a working example.

# app.py
from flask import Flask 
from flask_autoindex import AutoIndex

app = Flask(__name__)

ppath = "/" # update your own parent directory here

app = Flask(__name__)
AutoIndex(app, browse_root=ppath)    

if __name__ == "__main__":
    app.run()

Here is a working repo

  • https://github.com/MrAmbiG/folderview

I created this function for my project ... it is working perfectly ... it start browsing at this folder /home/myuser/myfolder

@app.route('/myfolder/<path:folders>')
@app.route('/myfolder/')
def mybrowser(folders=''):
    environ = flask.request.environ
    path = environ.get('PATH_INFO')
    path = path.lower()
    #if path=='/myfolder': return flask.redirect(path+'/',code=307)
    os_path = '/home/myuser'+path.rstrip('/')
    if path.endswith('/'):
        HTML_HEADER = """<html><head><title>Index of {path_title}</title></head><body bgcolor="white"><h1>Index of {path_title}</h1><hr><pre><a href="../">../</a>\n"""
        HTML_FOOTER = "</pre><hr></body></html>"
        path_title = os_path.split('myuser')[1]+'/'
        html = HTML_HEADER.format(path_title=path_title)
        import os,time
        files = os.listdir(os_path)
        for file in files:
            path = os_path+'/'+file
            size = str(os.path.getsize(path))
            date = os.path.getmtime(path)
            date = time.gmtime(date)
            date = time.strftime('%d-%b-%Y %H:%M',date)
            spaces1 = ' '*(50-len(file))
            spaces2 = ' '*(20-len(size))
            if os.path.isdir(path): html += '<a href="' + file + '/">' + file + '/</a>'+spaces1+date+spaces2+'   -\n'
            else: html += '<a href="' + file + '">' + file + '</a>'+spaces1+' '+date+spaces2+size+'\n'
        html += HTML_FOOTER
        #open(os_path+'/index.html','w').write(html)
        response_headers = {'Content-Type':'text/html','Content-Length':str(len(html))}
        status = '200 OK'
        response = flask.Response(html,status=status,headers=response_headers)
    else:
        response = flask.send_file(os_path,conditional=True)
    return response

Tags:

Python

Flask