Flask-Uploads — Flask-Uploads v0.1 documentation
Flask-Uploads 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.
Mục lục bài viết
Configuration¶
If you’re just deploying an application that uses Flask-Uploads, 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.
However, 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/uploads
is accessible from
http://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
or Lighttpd serve the uploads.
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 save method to save uploaded files and
path and 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 like Zine 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_root
)
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 place this call.
In addition, you can also use patch_request_class to patch your app’s
request_class to have a maximum size for uploads. By default,
there is no limit, so it’s possible for script kiddies to crash your server
by uploading gigantic files. Calling it will install a limit that prevents
it from loading more than a certain amount of data.
patch_request_class
(
app
)
# 16 megabytes
patch_request_class
(
app
,
32
*
1024
*
1024
)
# 32 megabytes
If you need to upload huge files, you may want to look into another solution
like rsync.
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¶
Here are the API docs. These are generated directly from the source code.
Upload Sets¶
- class flaskext.uploads.UploadSet(name=’files’, extensions=(‘txt’, ‘rtf’, ‘odf’, ‘ods’, ‘gnumeric’, ‘abw’, ‘doc’, ‘docx’, ‘xls’, ‘xlsx’, ‘jpg’, ‘jpe’, ‘jpeg’, ‘png’, ‘gif’, ‘svg’, ‘bmp’, ‘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 isDEFAULTS
.
- 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.
- 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.
- storage – The
- path(filename)¶
-
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.
- 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.
- 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.
- name – The name of this upload set. It defaults to
- class flaskext.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 isNone
, Flask-Uploads 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¶
- flaskext.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.Parameters:
- app – The
Flask
instance to get the configuration from.
- upload_sets – The
UploadSet
instances to configure.
- app – The
- flaskext.uploads.patch_request_class(app, size=16777216)¶
-
By default, Flask will accept uploads to an arbitrary size. Unfortunately,
this could lead to a security hole: someone uploads a gigantic file, and
crashes your server when it runs out of memory. Calling this on an
application will patch the app’s request class so that when it hits a
certain size, it will automatically raise an HTTP error.Parameters:
- app – The app to patch the request class of.
- size – The maximum size to accept, in bytes. The default is 16 MiB.
Extension Constants¶
These are some default sets of extensions you can pass to the UploadSet
constructor.
- class flaskext.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
)
- flaskext.uploads.DEFAULTS¶
-
The default allowed extensions – TEXT, DOCUMENTS, DATA, and IMAGES.
- flaskext.uploads.ALL¶
-
This “contains” all items. You can use it to allow all extensions to be
uploaded.
- flaskext.uploads.TEXT¶
-
This just contains plain text files (.txt).
- flaskext.uploads.IMAGES¶
-
This contains basic image types that are viewable from most browsers (.jpg,
.jpe, .jpeg, .png, .gif, .svg, and .bmp).
- flaskext.uploads.AUDIO¶
-
This contains audio file types (.wav, .mp3, .aac, .ogg, .oga, and .flac).
- flaskext.uploads.DOCUMENTS¶
-
This contains various office document formats (.rtf, .odf, .ods, .gnumeric,
.abw, .doc, .docx, .xls, and .xlsx). Note that the macro-enabled versions
of Microsoft Office 2007 files are not included.
- flaskext.uploads.DATA¶
-
This is for structured data files (.csv, .ini, .json, .plist, .xml, .yaml,
and .yml).
- flaskext.uploads.SCRIPTS¶
-
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 php to the DENY setting.
- flaskext.uploads.ARCHIVES¶
-
This contains archive and compression formats (.gz, .bz2, .zip, .tar,
.tgz, .txz, and .7z).
- flaskext.uploads.EXECUTABLES¶
-
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 flaskext.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
.