Upload new File

Загрузка файлов¶

Ну да, старая добрая проблема загрузки файлов. Основная мысль загрузки файлов на самом деле очень проста. В общих чертах это работает так:

  1. Тег помечается атрибутом enctype=multipart/form-data , а в форму помещается тег .
  2. Приложение получает доступ к файлу через словарь files в объекте запроса.
  3. Воспользуйтесь методом save() для того, чтобы сохранить временный файл в файловой системе для последующего использования.

Введение¶

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

import os from flask import Flask, request, redirect, url_for from werkzeug.utils import secure_filename UPLOAD_FOLDER = '/path/to/the/uploads' ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) app = Flask(__name__) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER 

Сначала нужно выполнить серию импортов. Большая часть понятна, werkzeug.secure_filename() рассматривается чуть позже. UPLOAD_FOLDER — это путь, куда будут загружаться файлы, а ALLOWED_EXTENSIONS — это набор допустимых расширений. Теперь вручную добавим в приложение правило для URL. Обычно мы так не делаем, но почему мы делаем это сейчас? Причина в том, что мы хотим заставить веб-сервер (или наш сервер приложения) обслуживать эти файлы и поэтому нам нужно генерировать правила для связывания URL с этими файлами.

Почему мы ограничили список допустимых расширений? Наверное вам совсем не хочется, чтобы пользователи могли загружать что угодно, если сервер напрямую отправляет данные клиенту. В таком случае вам нужно быть уверенными в том, что пользователи не загрузят файлы HTML, которые могут вызвать проблему XSS (см. Cross-Site Scripting ( xss ) — межсайтовый скриптинг). Также убедитесь в том, что запрещены файлы с расширением .php , если сервер их выполняет. Правда, кому нужен PHP на сервере? 🙂

Следующая функция проверяет, что расширение файла допустимо, загружает файл и перенаправляет пользователя на URL с загруженным файлом:

def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS @app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': file = request.files['file'] if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return redirect(url_for('uploaded_file', filename=filename)) return '''   

Upload new File

'''

Что делает функция secure_filename() ? Мы исходим из принципа «никогда не доверяй тому, что ввёл пользователь». Это справедливо и для имени загружаемого файла. Все отправленные из формы данные могут быть поддельными и имя файла может представлять опасность. Сейчас главное запомнить: всегда используйте эту функцию для получения безопасного имени файла, если собираетесь поместить файл прямо в файловую систему.

Может быть вам интересно, что делает функция secure_filename() и почему нельзя обойтись без её использования? Просто представьте, что кто-то хочет отправить следующую информацию в ваше приложение в качестве имени файла:

filename = "../../../../home/username/.bashrc" 

Если считать, что ../ — это нормально, то при соединении этого имени с UPLOAD_FOLDER , пользователь может получить возможность изменять на файловой системе сервера те файлы, который он не должен изменять. Нужно немного разбираться в устройстве вашего приложения, но поверьте мне, хакеры настойчивы 🙂

Посмотрим, как отработает функция:

>>> secure_filename('../../../../home/username/.bashrc') 'home_username_.bashrc' 

Осталась последняя вещь: обслуживание загруженных файлов. Начиная с Flask 0.5 для этого можно использовать соответствующую функцию:

from flask import send_from_directory @app.route('/uploads/') def uploaded_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) 

Другая возможность — зарегистрировать uploaded_file с помощью правила build_only и воспользоваться SharedDataMiddleware . Такой вариант будет работать и в более старых версиях Flask:

from werkzeug import SharedDataMiddleware app.add_url_rule('/uploads/', 'uploaded_file', build_only=True) app.wsgi_app = SharedDataMiddleware(app.wsgi_app,  '/uploads': app.config['UPLOAD_FOLDER'] >) 

Теперь, если запустить приложение, всё должно работать как положено.

Улучшение загрузки¶

Как на самом деле Flask обрабатывает загрузку? Если файл достаточно мал, он сохраняется в памяти веб-сервера. В противном случае он помещается во временное место (туда, куда укажет tempfile.gettempdir() ). Но как указать максимальный размер файла, после которого загрузка файла должна быть прервана? По умолчанию Flask не ограничивает размер файла, но вы можете задать лимит настройкой ключа конфигурации MAX_CONTENT_LENGTH :

from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 

Код выше ограничит максимальный размер файла 16 мегабайтами. Если передаваемый файл окажется больше, Flask сгенерирует исключение RequestEntityTooLarge .

Эта функциональность была добавлена во Flask 0.6, но может быть реализована и в более ранних версиях при помощи наследовании от класса request. За более подробной информацией обратитесь к документации Werkzeug об обработке файлов.

Индикаторы процесса загрузки¶

Многие разработчики придумывают считывать файл мелкими частями, сохранять процент загрузки в базу данных и давать возможность JavaScript считывать эти данные из клиента. Короче говоря, клиент спрашивает у сервера каждые 5 секунд, сколько уже было передано. Почувствовали иронию ситуации? Клиент спрашивает у сервера о том, что уже и так знает.

Сейчас существуют способы получше, которые работают быстрее и более надёжны. В последнее время в вебе многое изменилось и теперь можно использовать HTML5, Java, Silverlight или Flash, чтобы сделать загрузку удобнее со стороны клиента. Посмотрите на следующие библиотеки, предназначенные именно для этого:

Простейшее решение¶

Поскольку общая процедура загрузки файлов остаётся неизменной для всех приложений, занимающихся загрузкой файлов, для Flask есть расширение под названием Flask-Uploads, которое реализует полностью самостоятельный механизм загрузки с белым и чёрным списком расширений и т.п.

Источник

Python flask загрузка файлов на сервер – пример

Загрузка файлов — это процесс передачи двоичных или обычных файлов на сервер, Flask позволяет нам легко загружать их. Все, что нам нужно, это иметь HTML-форму с шифрованием, установленным на multipart/form-data.

Сценарий flask на стороне сервера извлекает файл из объекта запроса, используя объект request.files[]. После успешной загрузки файл сохраняется в нужном месте на сервере.

Загруженный файл сохраняется во временном каталоге сервера на некоторое время, прежде чем он будет сохранен в нужном месте. Имя целевого файла можно получить, используя следующий синтаксис.

name = request.files['file'].filename

Однако мы можем указать путь к папке, в которую файл должен быть загружен на сервере, и максимальный размер загружаемого файла. Все это можно сделать в настройках конфигурации объекта flask.

Синтаксис Описание
1 app.config[‘UPLOAD_FOLDER’] Он используется для упоминания папки загрузки.
2 app.config[‘MAX_CONTENT-PATH’] Он используется для указания максимального размера загружаемого файла.

Рассмотрим следующий пример загрузки файла из локальной файловой системы на сервер.

Пример

В этом примере мы предоставим пользователю селектор файлов (file_upload_form.html), где пользователь может выбрать файл из файловой системы и отправить его на сервер.

Файл извлекается с помощью объекта request.files[‘file’] и сохраняется на сервере.

Поскольку мы используем сервер разработки на том же устройстве, файл будет загружен в каталог, из которого выполняется flask скрипт upload.py.

from flask import * app = Flask(__name__) @app.route('/') def upload(): return render_template("file_upload_form.html") @app.route('/success', methods = ['POST']) def success(): if request.method == 'POST': f = request.files['file'] f.save(f.filename) return render_template("success.html", name = f.filename) if __name__ == '__main__': app.run(debug = True)
    

File uploaded successfully

File Name: >

Пользователю отображается HTML-форма, чтобы он мог просматривать файловую систему в поисках файла, который будет загружен на сервер разработки.

Загрузка файла Flask

Здесь пользователь выбрал файл с именем galexy.jpg, который будет загружен на сервер.

Загрузка файла с именем galexy.jpg

Приведенный ниже снимок создается для URL-адреса localhost:5000/success. При успешной загрузке файла пользователю отображается сообщение об успешном выполнении с именем загруженного файла.

Сообщение об успешном выполнении

Мы можем подтвердить это, зайдя в каталог, где находится upload.py, как показано на изображении ниже.

Источник

Читайте также:  Php date last monday
Оцените статью