Skip to main content

Flexible and efficient upload handling for Flask

Project description

CI Status https://coveralls.io/repos/github/jugmac00/flask-reuploaded/badge.svg?branch=main PyPI PyPI - Python Version https://img.shields.io/pypi/l/flask-reuploaded

Flask-Reuploaded

Flask-Reuploaded provides file uploads for Flask.

Notes on this package

This is an independently maintained version of Flask-Uploads based on the 0.2.1 version of the original, but also including four years of unreleased changes, at least not released to PyPI.

Noteworthy is the fix for the Werkzeug API change.

Goals

  • provide a stable drop-in replacement for Flask-Uploads

  • regain momentum for this widely used package

  • provide working PyPI packages

Migration guide from Flask-Uploads

Incompatibilities between Flask-Reuploaded and Flask-Uploads

As already mentioned, staying compatible with Flask-Uploads is one of this project’s goals.

Nevertheless, there are the following known incompatibilities:

  • the patch_request_class helper function has been removed; the function was only necessary for Flask 0.6 and earlier. Since then you can use Flask’s own MAX_CONTENT_LENGTH environment variable, so you don’t read more than this many bytes from the incoming request data.

  • autoserve of uploaded images now has been deactivated; this was a poorly documented “feature”, which even could have lead to unwanted data disclosure; if you want to activate the feature again, you need to set UPLOADS_AUTOSERVE=True

Uninstall and install

If you have used Flask-Uploads and want to migrate to Flask-Reuploaded, you only have to install Flask-Reuploaded instead of Flask-Uploads.

That’s all!

So, if you use pip to install your packages, instead of …

$ pip install `Flask-Uploads`  # don't do this! package is broken

… just do …

$ pip install `Flask-Reuploaded`

Flask-Reuploaded is a drop-in replacement.

This means you do not have to change a single line of code.

Installation

$ pip install Flask-Reuploaded

Getting started

create an UploadSet

from flask_uploads import IMAGES

photos = UploadSet("photos", IMAGES)

configure your Flask app and this extension

app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)

use photos in your view function

photos.save(request.files['photo'])

See below for a complete example.

Documentation

You can find the documentation at:

https://flask-reuploaded.readthedocs.io/en/latest/

You can generate the documentation locally:

tox -e docs

You can update the dependencies for documentation generation:

tox -e upgradedocs

Minimal example application

Application code, e.g. main.py

import os

from flask import Flask, flash, render_template, request
# please note the import from `flask_uploads` - not `flask_reuploaded`!!
# this is done on purpose to stay compatible with `Flask-Uploads`
from flask_uploads import IMAGES, UploadSet, configure_uploads

app = Flask(__name__)
photos = UploadSet("photos", IMAGES)
app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)


@app.route("/", methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        photos.save(request.files['photo'])
        flash("Photo saved successfully.")
        return render_template('upload.html')
    return render_template('upload.html')

HTML code for upload.html

<!doctype html>
<html lang=en>
<head>
    <meta charset=utf-8>
    <title>Flask-Reuploaded Example</title>
</head>
<body>
    {% with messages = get_flashed_messages() %}
    {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
        <li>{{ message }}</li>
    {% endfor %}
    </ul>
    {% endif %}
    {% endwith %}

<form method=POST enctype=multipart/form-data action="{{ url_for('upload') }}">
    <input type=file name=photo>
    <button type="submit">Submit</button>
</form>
</body>
</html>

Project structure

The project structure would look as following…

 tree -I "__*|h*"
.
├── main.py
├── static
   └── img
└── templates
    └── upload.html

Running the example application

In order to run the application, you have to enter the following commands…

 export FLASK_APP=main.py

 flask run

Then point your browser to http://127.0.0.1:5000/.

Contributing

Contributions are more than welcome.

Please have a look at the open issues.

There is also a short contributing guide.

Changelog

1.6.0 (2026.06.06)

  • SECURITY FIX: Ensure overridden file names are normalized via lowercase_ext() prior to extension validation checking and writing to disk.

1.5.0 (2026.02.21)

  • drop support for Python 3.8 and 3.9

  • add support for Python 3.13

  • migrate from setup.py to pyproject.toml configuration

  • fix doc building on read the docs

  • SECURITY FIX: Fix critical path traversal and extension bypass vulnerability (CVE pending, CVSS 9.8)

    • Apply secure_filename() to the name parameter to prevent path traversal attacks

    • Re-validate file extension after name override to prevent extension bypass

    • Add path containment check to ensure files are saved within the upload directory

    • Sanitize folder component when extracted from name parameter

    Impact: This vulnerability allowed remote attackers to write files to arbitrary locations on the filesystem and bypass extension restrictions, potentially leading to remote code execution via Server-Side Template Injection (SSTI) in Flask applications.

    Credit: Jaron Cabral (Cal Poly Humboldt) for discovery and reporting

    Recommendation: All users should upgrade to this version immediately. Do not pass user-controlled input to the name parameter in older versions.

1.4.0 (2023.10.03)

  • fix deprecation warning for pytest

  • drop support for Python 3.6 / 3.7

  • add support for Python 3.12

  • upgrade dependencies for building docs

1.3.0 (2022.12.20)

  • improve documentation (#133)

  • drop support for Python 3.6

  • add support for Python 3.11

  • update dependencies for building documentation

1.2.0 (2021.11.07)

  • add contexts to coverage report

  • pin documentation dependencies to prevent future breakage

  • fix typing errors (mypy) with recently released Flask 2.0.1

  • add support for Python 3.10

1.1.0 (2021.05.09)

  • make type checkers aware that this library is using type annotations

1.0.0 (2021.04.07)

  • raise test coverage to 100%

  • use official Pallets theme for the documentation

  • remove deprecated patch_request_class helper function; use MAX_CONTENT_LENGTH instead.

  • autoserve now has been deactivated by default and needs explicit activation via the setting UPLOADS_AUTOSERVE=True

0.5.0

  • improve documentation of example app

  • document surprising autoserve feature

  • issue a warning when using autoserve without explicit configuration

0.4.0

  • add type annotations

  • drop support for Python 2 and Python 3.5 (#8)

  • deprecate patch_request_class (#43)

  • use a src directory for source code (#21)

  • add tox env for check-python-versions (#20)

  • add flake8-bugbear

  • add short contribution guide (#6)

  • add getting started (#59)

  • delete broken example and add minimal example to README (#15)

  • add support for Python 3.9

  • use gh actions instead of Travis CI

0.3.2

  • documentation update (#5)

    • update docs/index.rst

    • use blue ReadTheDocs theme

    • update sphinx configuration

    • add documentation link to setup.py, so it shows on PyPi

    • add note about documentation in the README file

    • delete old theme files

  • configure isort to force single line imports

0.3.1

  • add badges to README (# 31)

  • add migration guide from Flask-Uploads to Flask-Reuploaded (#11)

  • add packaging guide (#28)

  • update installation instruction in README

0.3

Besides including four years of unreleased changes from the original package, most notable the fix for the Werkzeug API change, the following changes happened since forking the original package.

  • rename package from Flask-Uploads to Flask-Reuploaded (#10)

  • update setup.py (#12)

  • start using pre-commit.com (#4)

  • update README (#14)

  • setup CI (Travis) (#3)

  • fix broken tests (#13)

  • make use of pytest instead of the no longer maintained nose (#2)

  • add a changelog and start tracking changes (#1)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_reuploaded-1.6.0.tar.gz (35.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flask_reuploaded-1.6.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file flask_reuploaded-1.6.0.tar.gz.

File metadata

  • Download URL: flask_reuploaded-1.6.0.tar.gz
  • Upload date:
  • Size: 35.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for flask_reuploaded-1.6.0.tar.gz
Algorithm Hash digest
SHA256 c18910646384281fbcaa2ee7325f3dc68c3278d33ff4cf1f6053716b580954ac
MD5 91db9ba641f6782a25f2208a23d74d99
BLAKE2b-256 130fca570c1223d2f30e883c7e1a13c90e49b5c7b158439917a7cf03f5db1e7f

See more details on using hashes here.

File details

Details for the file flask_reuploaded-1.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for flask_reuploaded-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0858f79b82c1e5c75965b8bcc886c5abc2119b459fe5e150c4b302413e15cbf2
MD5 00d32c1accbd4993acfd49f03ae547ef
BLAKE2b-256 b3ddcf2491d72f3e10bb1ec290494e989cb0bf2aebabbabf5aa72a05a242aaac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page