Flask-Reuploaded¶
Flask-Reuploaded allows your application to flexibly and efficiently handle file uploading and serving the uploaded files. You can create different sets of uploads - one for document attachments, one for photos, etc. - and the application can be configured to save them all in different places and to generate different URLs for them.
Configuration¶
If you’re just deploying an application that uses Flask-Reuploaded, you can customize its behavior extensively from the application’s configuration. Check the application’s documentation or source code to see how it loads its configuration.
The settings below apply for a single set of uploads, replacing FILES with the name of the set (i.e. PHOTOS, ATTACHMENTS):
- UPLOADED_FILES_DEST
This indicates the directory uploaded files will be saved to.
- UPLOADED_FILES_URL
If you have a server set up to serve the files in this set, this should be the URL they are publicly accessible from. Include the trailing slash.
- UPLOADED_FILES_ALLOW
This lets you allow file extensions not allowed by the upload set in the code.
- UPLOADED_FILES_DENY
This lets you deny file extensions allowed by the upload set in the code.
To save on configuration time, there are two settings you can provide that apply as “defaults” if you don’t provide the proper settings otherwise.
- UPLOADS_DEFAULT_DEST
If you set this, then if an upload set’s destination isn’t otherwise declared, then its uploads will be stored in a subdirectory of this directory. For example, if you set this to
/var/uploads, then a set named photos will store its uploads in/var/uploads/photos.- UPLOADS_DEFAULT_URL
If you have a server set up to serve from UPLOADS_DEFAULT_DEST, then set the server’s base URL here. Continuing the example above, if
/var/uploadsis accessible fromhttp://localhost:5001, then you would set this tohttp://localhost:5001/and URLs for the photos set would start withhttp://localhost:5001/photos. Include the trailing slash.
However, you don’t have to set any of the _URL settings - if you don’t,
then they will be served internally by Flask. They are just there so if you
have heavy upload traffic, you can have a faster production server like Nginx
serve the uploads.
Since Flask 0.6 you can set MAX_CONTENT_LENGTH to limit the size of uploaded files.
Upload Sets¶
An “upload set” is a single collection of files. You just declare them in the code:
photos = UploadSet('photos', IMAGES)
And then you can use the ~UploadSet.save method to save uploaded files and ~UploadSet.path and ~UploadSet.url to access them. For example:
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST' and 'photo' in request.files:
filename = photos.save(request.files['photo'])
rec = Photo(filename=filename, user=g.user.id)
rec.store()
flash("Photo saved.")
return redirect(url_for('show', id=rec.id))
return render_template('upload.html')
@app.route('/photo/<id>')
def show(id):
photo = Photo.load(id)
if photo is None:
abort(404)
url = photos.url(photo.filename)
return render_template('show.html', url=url, photo=photo)
If you have a “default location” for storing uploads - for example, if your
app has an “instance” directory and uploads should be saved to
the instance directory’s uploads folder - you can pass a default_dest
callable to the set constructor. It takes the application as its argument.
For example:
media = UploadSet('media', default_dest=lambda app: app.instance_path)
This won’t prevent a different destination from being set in the config, though. It’s just to save your users a little configuration time.
App Configuration¶
An upload set’s configuration is stored on an app. That way, you can have upload sets being used by multiple apps at once. You use the configure_uploads function to load the configuration for the upload sets. You pass in the app and all of the upload sets you want configured. Calling configure_uploads more than once is safe.
configure_uploads(app, (photos, media))
If your app has a factory function, that is a good place to call this function.
By default, though, Flask doesn’t put any limits on the size of the uploaded data. To protect your application, you can use patch_request_class. If you call it with None as the second parameter, it will use the MAX_CONTENT_LENGTH setting to determine how large the upload can be.
patch_request_class(app, None)
You can also call it with a number to set an absolute limit, but that only exists for backwards compatibility reasons and is not recommended for production use. In addition, it’s not necessary for Flask 0.6 or greater, so if your application is only intended to run on Flask 0.6, you don’t need it.
File Upload Forms¶
To actually upload the files, you need to properly set up your form. A form
that uploads files needs to have its method set to POST and its enctype
set to multipart/form-data. If it’s set to GET, it won’t work at all, and
if you don’t set the enctype, only the filename will be transferred.
The field itself should be an <input type=file>.
<form method=POST enctype=multipart/form-data action="{{ url_for('upload') }}">
...
<input type=file name=photo>
...
</form>
API Documentation¶
This documentation is generated directly from the source code.
Upload Sets¶
-
class
flask_uploads.UploadSet(name='files', extensions='txt', 'rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'webp', 'csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml', default_dest=None)¶ This represents a single set of uploaded files. Each upload set is independent of the others. This can be reused across multiple application instances, as all configuration is stored on the application object itself and found with flask.current_app.
- Parameters
name – The name of this upload set. It defaults to
files, but you can pick any alphanumeric name you want. (For simplicity, it’s best to use a plural noun.)extensions – The extensions to allow uploading in this set. The easiest way to do this is to add together the extension presets (for example,
TEXT + DOCUMENTS + IMAGES). It can be overridden by the configuration with the UPLOADED_X_ALLOW and UPLOADED_X_DENY configuration parameters. The default is DEFAULTS.default_dest – If given, this should be a callable. If you call it with the app, it should return the default upload destination path for that app.
-
property
config¶ This gets the current configuration. By default, it looks up the current application and gets the configuration from there. But if you don’t want to go to the full effort of setting an application, or it’s otherwise outside of a request context, set the _config attribute to an UploadConfiguration instance, then set it back to None when you’re done.
-
extension_allowed(ext)¶ This determines whether a specific extension is allowed. It is called by file_allowed, so if you override that but still want to check extensions, call back into this.
- Parameters
ext – The extension to check, without the dot.
-
file_allowed(storage, basename)¶ This tells whether a file is allowed. It should return True if the given werkzeug.FileStorage object can be saved with the given basename, and False if it can’t. The default implementation just checks the extension, so you can override this if you want.
- Parameters
storage – The werkzeug.FileStorage to check.
basename – The basename it will be saved under.
-
path(filename, folder=None)¶ This returns the absolute path of a file uploaded to this set. It doesn’t actually check whether said file exists.
- Parameters
filename – The filename to return the path for.
folder – The subfolder within the upload set previously used to save to.
-
resolve_conflict(target_folder, basename)¶ If a file with the selected name already exists in the target folder, this method is called to resolve the conflict. It should return a new basename for the file.
The default implementation splits the name and extension and adds a suffix to the name consisting of an underscore and a number, and tries that until it finds one that doesn’t exist.
- Parameters
target_folder – The absolute path to the target.
basename – The file’s original basename.
-
save(storage, folder=None, name=None)¶ This saves a werkzeug.FileStorage into this upload set. If the upload is not allowed, an UploadNotAllowed error will be raised. Otherwise, the file will be saved and its name (including the folder) will be returned.
- Parameters
storage – The uploaded file to save.
folder – The subfolder within the upload set to save to.
name – The name to save the file as. If it ends with a dot, the file’s extension will be appended to the end. (If you are using name, you can include the folder in the name instead of explicitly using folder, i.e.
uset.save(file, name="someguy/photo_123.")
-
url(filename)¶ This function gets the URL a file uploaded to this set would be accessed at. It doesn’t check whether said file exists.
- Parameters
filename – The filename to return the URL for.
-
class
flask_uploads.UploadConfiguration(destination, base_url=None, allow=(), deny=())¶ This holds the configuration for a single UploadSet. The constructor’s arguments are also the attributes.
- Parameters
destination – The directory to save files to.
base_url – The URL (ending with a /) that files can be downloaded from. If this is None, Flask-Reuploaded will serve the files itself.
allow – A list of extensions to allow, even if they’re not in the UploadSet extensions list.
deny – A list of extensions to deny, even if they are in the UploadSet extensions list.
Application Setup¶
-
flask_uploads.configure_uploads(app, upload_sets)¶ Call this after the app has been configured. It will go through all the upload sets, get their configuration, and store the configuration on the app. It will also register the uploads module if it hasn’t been set. This can be called multiple times with different upload sets.
Changed in version 0.1.3: The uploads module/blueprint will only be registered if it is needed to serve the upload sets.
- Parameters
app – The ~flask.Flask instance to get the configuration from.
upload_sets – The UploadSet instances to configure.
-
flask_uploads.patch_request_class(app, size=67108864)¶ By default, Flask will accept uploads to an arbitrary size. While Werkzeug switches uploads from memory to a temporary file when they hit 500 KiB, it’s still possible for someone to overload your disk space with a gigantic file.
This patches the app’s request class’s ~werkzeug.BaseRequest.max_content_length attribute so that any upload larger than the given size is rejected with an HTTP error.
Note
In Flask 0.6, you can do this by setting the MAX_CONTENT_LENGTH setting, without patching the request class. To emulate this behavior, you can pass None as the size (you must pass it explicitly). That is the best way to call this function, as it won’t break the Flask 0.6 functionality if it exists.
Changed in version 0.1.1.
- Parameters
app – The app to patch the request class of.
size – The maximum size to accept, in bytes. The default is 64 MiB. If it is None, the app’s MAX_CONTENT_LENGTH configuration setting will be used to patch.
Extension Constants¶
These are some default sets of extensions you can pass to the UploadSet constructor.
-
class
flask_uploads.AllExcept(items)¶ This can be used to allow all file types except certain ones. For example, to ban .exe and .iso files, pass:
AllExcept(('exe', 'iso'))
to the UploadSet constructor as extensions. You can use any container, for example:
AllExcept(SCRIPTS + EXECUTABLES)
-
flask_uploads.DEFAULTS= ('txt', 'rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'webp', 'csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml')¶ The default allowed extensions - TEXT, DOCUMENTS, DATA, and IMAGES.
-
flask_uploads.ALL= <flask_uploads.All object>¶ This “contains” all items. You can use it to allow all extensions to be uploaded.
-
flask_uploads.TEXT= ('txt',)¶ This just contains plain text files (.txt).
-
flask_uploads.IMAGES= ('jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'webp')¶ This contains basic image types that are viewable from most browsers (.jpg, .jpe, .jpeg, .png, .gif, .svg, .bmp and .webp).
-
flask_uploads.AUDIO= ('wav', 'mp3', 'aac', 'ogg', 'oga', 'flac')¶ This contains audio file types (.wav, .mp3, .aac, .ogg, .oga, and .flac).
-
flask_uploads.DOCUMENTS= ('rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx', 'pdf')¶ This contains various office document formats (.rtf, .odf, .ods, .gnumeric, .abw, .doc, .docx, .xls, .xlsx and .pdf). Note that the macro-enabled versions of Microsoft Office 2007 files are not included.
-
flask_uploads.DATA= ('csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml')¶ This is for structured data files (.csv, .ini, .json, .plist, .xml, .yaml, and .yml).
-
flask_uploads.SCRIPTS= ('js', 'php', 'pl', 'py', 'rb', 'sh')¶ This contains various types of scripts (.js, .php, .pl, .py .rb, and .sh). If your Web server has PHP installed and set to auto-run, you might want to add
phpto the DENY setting.
-
flask_uploads.ARCHIVES= ('gz', 'bz2', 'zip', 'tar', 'tgz', 'txz', '7z')¶ This contains archive and compression formats (.gz, .bz2, .zip, .tar, .tgz, .txz, and .7z).
-
flask_uploads.EXECUTABLES= ('so', 'exe', 'dll')¶ This contains shared libraries and executable files (.so, .exe and .dll). Most of the time, you will not want to allow this - it’s better suited for use with AllExcept.
Testing Utilities¶
-
class
flask_uploads.TestingFileStorage(stream=None, filename=None, name=None, content_type='application/octet-stream', content_length=- 1, headers=None)¶ This is a helper for testing upload behavior in your application. You can manually create it, and its save method is overloaded to set saved to the name of the file it was saved to. All of these parameters are optional, so only bother setting the ones relevant to your application.
- Parameters
stream – A stream. The default is an empty stream.
filename – The filename uploaded from the client. The default is the stream’s name.
name – The name of the form field it was loaded from. The default is None.
content_type – The content type it was uploaded as. The default is
application/octet-stream.content_length – How long it is. The default is -1.
headers – Multipart headers as a werkzeug.Headers. The default is None.