Как создать алгоритм динамической отправки файла с флягой - PullRequest
1 голос
/ 30 марта 2019

У меня есть некоторые проблемы с подачей файлов с помощью фляги.

Во-первых, мое дерево файлов:

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

В каждой папке у меня есть набор файлов, которые я представляю всем в таблице, гдеЯ поставил ссылку href с путем к каждому из файлов и передал его через функцию маршрута с возвратом send_file.

Проблема в том, что единственный способ, которым я смог заставить его работать, - это создать @ 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] - это путь к подпапке, а идентификатор передается, когда пользователь нажимает на файл в веб-таблице.

Проблема в том, что у меня естьмного подпапок, и это утомительно, чтобы создать @ app.route для каждого.Можно ли создать только один маршрут для каждой вещи?

PS Я совсем новичок в колбе, поэтому, если я забыл что-то сказать, скажите, пожалуйста, что я его заполню.

Решение

На самом деле это было невероятно просто.Как указал @ 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 ]

1 голос
/ 30 марта 2019

Вы можете записать путь в выражении маршрута.Из документации:

@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/

0 голосов
/ 30 марта 2019

Насколько я знаю, Flask не поддерживает несколько переменных разделов в @app.route URL. Однако вы можете указать полный путь к файлу в качестве переменной и затем проанализировать его, чтобы извлечь путь к подпапке и идентификатор файла.

Вот рабочий пример:

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"

Однако, гораздо лучшая реализация - отправить идентификатор файла и путь в виде параметров запроса 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"
...