如何用flask创建动态文件发送算法

时间:2019-03-30 01:55:28

标签: python flask sendfile

我在使用flask进行文件投放时遇到一些问题。

首先,我的文件树:

processedMain
--processed1
--processed2
--...
--processedN

在每个文件夹中,我有一堆文件,这些文件全部都代表在表中,在该文件中,我将href链接与每个文件的路径放在一起,并通过send_file return的route函数传递。

问题在于,我能够使其工作的唯一方法是为每个硬编码的子文件夹创建@ app.route,如下所示:

@app.route('/' + pathFits1[1] + '<id>', methods=['GET'])
def returnImg1(id):
    return send_file(pathFits1[1] + id, as_attachment=True, attachment_filename=id)

@app.route('/' + pathFits1[2] +'<id>', methods=['GET'])
def returnImg2(id):
    return send_file(pathFits1[2] + id, as_attachment=True, attachment_filename=id)

@app.route('/' + pathFits1[3] + '<id>', methods=['GET'])
def returnImg3(id):
    return send_file(pathFits1[3] + id, as_attachment=True, attachment_filename=id)

其中pathFits1 [i]是子文件夹的路径,当用户单击Web表中的文件时,将传递id。

问题是我有很多子文件夹,并且很累赘为每个文件夹创建@ app.route。 是否有可能为每件事创建一条路线?

P.S。 我对Flask还是很陌生,所以如果我忘了告诉别人,请告诉我,我会填写。

解决方案

实际上,这很尴尬。 正如@ Dan.D所指出的,flask具有捕获的变量的转换器,对我来说,这就是我所需要的,因为我的id变量已经包含文件的完整路径。 因此,现在只有这3行替代了一堆或重复的代码:

@app.route('/<path:id>')
def returnImg(id):
    fileName = id.rsplit('/', 1)[-1]
    return send_file(id, as_attachment=True, attachment_filename=fileName)

id 是文件的完整路径, path:是路径的转换器,而 fileName 是用户将下载的没有路径的文件名在其中(最后一个斜杠之后)

2 个答案:

答案 0 :(得分:1)

您可以在路由表达式中捕获路径。从文档中:

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return 'Subpath %s' % subpath

来自http://flask.pocoo.org/docs/1.0/quickstart/

答案 1 :(得分:0)

据我所知,Flask在@app.route URL中不支持多个变量部分。但是,您可以将文件的完整路径设置为变量部分,然后对其进行解析以提取子文件夹路径和文件ID。

这是一个可行的示例:

pathFits1 = [None] * 3
pathFits1[1] = 'content/images1/'
pathFits1[2] = 'content/images2/'

@app.route('/<path:fullpath>', methods=['GET'])
def returnImg(fullpath):
    global pathFits1
    print("--> GET request: ", fullpath)

    # parse the full path to extract the subpath and ID
    # subpath: get everything until the last slash
    subpath = fullpath.rsplit('/', 1)[:-1][0] + '/'
    # id: get string after the last slash
    id = fullpath.rsplit('/', 1)[-1]

    print("ID:", id, "\tsubpath:", subpath)

    # try to send the file if the subpath is valid
    if subpath in pathFits1:
        print("valid path, attempting to sending file")
        try:
            return send_file(subpath + id, as_attachment=True, attachment_filename=id)
        except Exception as e:
            print(e)
            return "file not found"
    return "invalid path"

但是,更好的实现方法是将文件ID和路径作为GET请求参数(例如http://127.0.0.1:8000/returnimg?id=3&path=content/images1/)发送并像这样检索它们:

from flask import Flask, send_file, request

app = Flask(__name__)

pathFits1 = [None] * 3
pathFits1[1] = 'content/images1/'
pathFits1[2] = 'content/images2/'

@app.route('/returnimg', methods=['GET'])
def returnImg():
    global pathFits1
    id = request.args.get('id')
    path = request.args.get('path')

    print("ID:", id, "\tpath:", path)

    # try to send the file if the subpath is valid
    if path in pathFits1:
        print("valid path, attempting to sending file")
        try:
            return send_file(path + id, as_attachment=True, attachment_filename=id)
        except Exception as e:
            print(e)
            return "file not found"
    return "invalid path"