Flask recommends the Flask-Uploads module for handling uploads. I'd like to reject any file over a certain size. There are a few solutions floating around:
From the docs:
In addition, you can also use patch_request_class to patch your app’s request_class to have a maximum size for uploads.
patch_request_class(app, 32 * 1024 * 1024)
From this SO post:
MAX_CONTENT_LENGTH is the correct way to reject file uploads larger than you want,
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
# save to disk first, then check filesize
request.files['file'].save('/tmp/foo')
size = os.stat('/tmp/foo').st_size
-or-
# save to memory, then check filesize
blob = request.files['file'].read()
size = len(blob)
I don't see MAX_CONTENT_LENGTH
mentioned in the official docs, nor does it even manually check the filesize like the SO post does. Are these two methods ultimately the same, or does there exist a (big/subtle?) difference? Also, does patch_request_class
save the file to disk first to determine total upload size, or does it save to memory?
MAX_CONTENT_LENGTH
is a configuration item for Flask itself, introduced in version 0.6
http://flask.pocoo.org/docs/0.10/patterns/fileuploads/#improving-uploads
By default Flask will happily accept file uploads to an unlimited amount of memory, but you can limit that by setting the MAX_CONTENT_LENGTH config key:
from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
The code above will limited the maximum allowed payload to 16 megabytes. If a larger file is transmitted, Flask will raise an RequestEntityTooLarge exception.
This feature was added in Flask 0.6 but can be achieved in older versions as well by subclassing the request object. For more information on that consult the Werkzeug documentation on file handling.
And from the flask-uploads source: https://bitbucket.org/leafstorm/flask-uploads/src/440e06b851d24811d20f8e06a8eaf5c5bf58c241/flaskext/uploads.py?at=default
def patch_request_class(app, size=64 * 1024 * 1024): """ 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. .. versionchanged:: 0.1.1 :param app: The app to patch the request class of. :param 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. """ if size is None: if isinstance(app.request_class.__dict__['max_content_length'], property): return size = app.config.get('MAX_CONTENT_LENGTH') reqclass = app.request_class patched = type(reqclass.__name__, (reqclass,), {'max_content_length': size}) app.request_class = patched
So I'd say go with:
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
patch_request_class
was just for backwards compatibility.
From Flask 0.6 onwards you should use app.config['MAX_CONTENT_LENGTH']
.
I recently took over as maintainer of the Flask-Uploads project, and one of the first things I did was remove the patch_request_class
in this commit as it does nothing but add confusion for new projects. Any old projects that rely on it should just pin Flask-Uploads==0.1.3
in their requirements.txt
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With