Metadata-Version: 2.4
Name: flask-fs2
Version: 0.8.0
Summary: Simple and easy file storages for Flask
Home-page: https://github.com/cgwire/flask-fs2
Author: Axel Haustant
Author-email: noirbizarre@gmail.com
Maintainer: CG Wire
Maintainer-email: support@cg-wire.com
License: MIT
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python
Classifier: Environment :: Web Environment
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: System :: Software Distribution
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.10
Requires-Dist: flask>=2.0.0
Requires-Dist: python-dateutil==2.9.0.post0
Requires-Dist: Werkzeug>=2.0.0
Requires-Dist: cryptography>=39.0.2
Provides-Extra: doc
Requires-Dist: boto3>=1.28.0; extra == "doc"
Requires-Dist: python-swiftclient>=4.4.0; extra == "doc"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "doc"
Requires-Dist: pymongo>=4.5.0; extra == "doc"
Requires-Dist: sphinx==9.1.0; extra == "doc"
Requires-Dist: alabaster==1.0.0; extra == "doc"
Requires-Dist: pillow==12.1.0; extra == "doc"
Provides-Extra: test
Requires-Dist: boto3>=1.28.0; extra == "test"
Requires-Dist: pymongo>=4.5.0; extra == "test"
Requires-Dist: python-swiftclient>=4.4.0; extra == "test"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "test"
Requires-Dist: pytest==9.0.2; extra == "test"
Requires-Dist: pytest-faker==2.0.0; extra == "test"
Requires-Dist: pytest-sugar==1.1.1; extra == "test"
Requires-Dist: pytest-mock==3.15.1; extra == "test"
Requires-Dist: pillow==12.1.0; extra == "test"
Requires-Dist: flask-mongoengine-3==1.1.0; extra == "test"
Requires-Dist: gevent>=24.0.0; extra == "test"
Provides-Extra: s3
Requires-Dist: boto3>=1.28.0; extra == "s3"
Provides-Extra: swift
Requires-Dist: python-swiftclient>=4.4.0; extra == "swift"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "swift"
Provides-Extra: gridfs
Requires-Dist: pymongo>=4.5.0; extra == "gridfs"
Provides-Extra: all
Requires-Dist: boto3>=1.28.0; extra == "all"
Requires-Dist: python-swiftclient>=4.4.0; extra == "all"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "all"
Requires-Dist: pymongo>=4.5.0; extra == "all"
Provides-Extra: qa
Requires-Dist: boto3>=1.28.0; extra == "qa"
Requires-Dist: pymongo>=4.5.0; extra == "qa"
Requires-Dist: python-swiftclient>=4.4.0; extra == "qa"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "qa"
Requires-Dist: pytest==9.0.2; extra == "qa"
Requires-Dist: pytest-faker==2.0.0; extra == "qa"
Requires-Dist: pytest-sugar==1.1.1; extra == "qa"
Requires-Dist: pytest-mock==3.15.1; extra == "qa"
Requires-Dist: pillow==12.1.0; extra == "qa"
Requires-Dist: flask-mongoengine-3==1.1.0; extra == "qa"
Requires-Dist: gevent>=24.0.0; extra == "qa"
Provides-Extra: ci
Requires-Dist: invoke==2.2.0; extra == "ci"
Requires-Dist: coveralls==4.0.2; extra == "ci"
Requires-Dist: pytest-flask==1.3.0; extra == "ci"
Requires-Dist: boto3>=1.28.0; extra == "ci"
Requires-Dist: pymongo>=4.5.0; extra == "ci"
Requires-Dist: python-swiftclient>=4.4.0; extra == "ci"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "ci"
Requires-Dist: pytest==9.0.2; extra == "ci"
Requires-Dist: pytest-faker==2.0.0; extra == "ci"
Requires-Dist: pytest-sugar==1.1.1; extra == "ci"
Requires-Dist: pytest-mock==3.15.1; extra == "ci"
Requires-Dist: pillow==12.1.0; extra == "ci"
Requires-Dist: flask-mongoengine-3==1.1.0; extra == "ci"
Requires-Dist: gevent>=24.0.0; extra == "ci"
Requires-Dist: flake8==7.3.0; extra == "ci"
Requires-Dist: pytest-cov==7.0.0; extra == "ci"
Provides-Extra: dev
Requires-Dist: invoke==2.2.0; extra == "dev"
Requires-Dist: tox==4.34.1; extra == "dev"
Requires-Dist: black==25.12.0; extra == "dev"
Requires-Dist: pre-commit==4.5.1; extra == "dev"
Requires-Dist: autoflake==2.3.1; extra == "dev"
Requires-Dist: setuptools; extra == "dev"
Requires-Dist: boto3>=1.28.0; extra == "dev"
Requires-Dist: pymongo>=4.5.0; extra == "dev"
Requires-Dist: python-swiftclient>=4.4.0; extra == "dev"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "dev"
Requires-Dist: pytest==9.0.2; extra == "dev"
Requires-Dist: pytest-faker==2.0.0; extra == "dev"
Requires-Dist: pytest-sugar==1.1.1; extra == "dev"
Requires-Dist: pytest-mock==3.15.1; extra == "dev"
Requires-Dist: pillow==12.1.0; extra == "dev"
Requires-Dist: flask-mongoengine-3==1.1.0; extra == "dev"
Requires-Dist: gevent>=24.0.0; extra == "dev"
Requires-Dist: boto3>=1.28.0; extra == "dev"
Requires-Dist: python-swiftclient>=4.4.0; extra == "dev"
Requires-Dist: python-keystoneclient>=5.2.0; extra == "dev"
Requires-Dist: pymongo>=4.5.0; extra == "dev"
Requires-Dist: sphinx==9.1.0; extra == "dev"
Requires-Dist: alabaster==1.0.0; extra == "dev"
Requires-Dist: pillow==12.1.0; extra == "dev"
Requires-Dist: flake8==7.3.0; extra == "dev"
Requires-Dist: pytest-cov==7.0.0; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: maintainer
Dynamic: maintainer-email
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

=========
Flask-FS2
=========

Simple and easy file storages for Flask.

|CI badge|


Compatibility
=============

Flask-FS requires Python >= 3.10 and Flask/Werkzeug >= 2.0.0.

Amazon S3 support requires Boto3.

GridFS support requires PyMongo 3+.

OpenStack Swift support requires python-swift-client.


Installation
============

You can install Flask-FS with pip:

.. code-block:: console

    $ pip install flask-fs2
    # or
    $ pip install flask-fs2[s3]  # For Amazon S3 backend support
    $ pip install flask-fs2[swift]  # For OpenStack swift backend support
    $ pip install flask-fs2[gridfs]  # For GridFS backend support
    $ pip install flask-fs2[all]  # To include all dependencies for all backends


Quick start
===========

.. code-block:: python

    from flask import Flask
    import flask_fs as fs

    app = Flask(__name__)
    fs.init_app(app)

    images = fs.Storage('images')


    if __name__ == '__main__':
        app.run(debug=True)


Contributions
=============

All contributions are welcome as long as they respect the `C4
contract <https://rfc.zeromq.org/spec:42/C4>`__.

Code must follow the pep8 convention.

About authors
=============

Flask-FS2 is maintained by CGWire, a company based in France. We help animation
and VFX studios to collaborate better through efficient tooling.
We already work with more than 70 studios around the world.

It's a fork of `this project <https://github.com/noirbizarre/flask-fs>`__.

Visit `cg-wire.com <https://cg-wire.com>`__ for more information.

|CGWire Logo|

.. |CI badge| image:: https://github.com/cgwire/flask-fs2/actions/workflows/ci.yml/badge.svg
   :target: https://github.com/cgwire/flask-fs2/actions/workflows/ci.yml
.. |CGWire Logo| image:: https://zou.cg-wire.com/cgwire.png
   :target: https://cg-wire.com

Changelog
=========

Current
-------

- Swift backend: per-process ``Connection`` pool (``gevent.queue.Queue`` with
  stdlib ``queue.Queue`` fallback) so concurrent greenlets and threads no
  longer share a single ``swiftclient.Connection``. Fixes sporadic 400s,
  ``ConnectionReset`` errors and content corruption observed under
  ``gevent`` workers.
- Swift backend: ``timeout`` and ``retries`` are now passed to every
  ``Connection`` (defaults: 60 s timeout, 5 retries).
- Swift backend: ``write()`` pre-computes ``content_length`` and ``ETag``
  (when content is bytes or a seekable file-like) and verifies the ETag
  returned by Swift; mismatched objects are deleted and the call raises
  ``ClientException`` to prevent silent corruption.
- Swift backend: ``read_chunks()`` releases the borrowed ``Connection``
  back to the pool when the generator is exhausted or ``close()`` is
  called.
- Swift backend: ``list_files()`` uses ``full_listing=True`` so containers
  with more than 10 000 objects are fully enumerated.
- Swift backend: new optional settings ``pool_size`` (default 20),
  ``timeout`` (default 60) and ``retries`` (default 5).

0.7.33 (2026-01-14)
-------------------

- Upgrade GitHub Actions

0.7.32 (2026-01-12)
-------------------

- Drop Python 3.9 support
- Python 3.12 requirements upgrade

0.7.31 (2025-08-19)
-------------------

- Fix CI
- Upgrade requirements

0.7.30 (2025-05-28)
-------------------

- Remove deprecated ``pkg_resources``
- Upgrade requirements

0.7.29 (2025-03-09)
-------------------

- Upgrade requirements
- Update README

0.7.28 (2025-01-10)
-------------------

- Drop support for Python 3.8, add Python 3.13
- Fix Python 3.13 CI
- Fix ``AttributeError: 'GridFS' object has no attribute '_GridFS__collection'``
- Use ``main`` branch in GitHub workflows
- Fix docker compose in GitHub Actions CI
- Run ``autoflake`` and ``black``
- Upgrade requirements

0.7.27 (2024-07-12)
-------------------

- Upgrade requirements

0.7.26 (2024-05-27)
-------------------

- Use wheel of ``flask_mongoengine3`` directly from PyPI
- Fix MongoDB test errors
- Upgrade requirements

0.7.25 (2024-05-07)
-------------------

- Added ``copy()`` method to ``Storage``
- Upgrade requirements

0.7.24 (2024-03-11)
-------------------

- Upgrade requirements

0.7.23 (2023-10-23)
-------------------

- Allow setting multiple backends, encrypted or not
- Added ``create_container``/``create_bucket`` options for Swift and S3
- Ensure server does not serve files outside ``DEBUG`` mode
- Use new ``pytest-flask`` version for CI tests
- Add ``.vscode/settings.json`` for black formatter
- Upgrade Pillow and other requirements

0.7.22 (2023-10-13)
-------------------

- Swift backend refactoring
- Upgrade boto3
- Launch CI build on pull requests and every branch

0.7.21 (2023-10-09)
-------------------

- Allow Flask v3 and newer boto3
- Add Python 3.12 to classifiers and CI matrix
- Use a pytest-flask branch fixing test issues
- Release script exits immediately on non-zero status

0.7.20 (2023-09-28)
-------------------

- Upgrade boto3

0.7.19 (2023-09-18)
-------------------

- Upgrade ``actions/checkout`` to v4
- Disable ``fail-fast`` in CI so jobs finish even on failure
- Cache pip in CI
- Add pre-commit configuration
- Upgrade requirements
- Update README

0.7.18 (2023-09-12)
-------------------

- Switch CI from Travis to GitHub Actions (``ci.yml`` + ``release.yml``)
- Add release script integrated with new workflow
- Add coverage report
- Test against pypy3.10
- Upgrade requirements

0.7.17 (2023-07-25)
-------------------

- Stop encrypting files in memory (stream encryption)
- Upgrade boto3, pymongo and sphinx

0.7.16 (2023-07-13)
-------------------

- Fix tests
- Remove GitHub dependency, add ``python-keystoneclient``

0.7.15 (2023-07-13)
-------------------

- Allow Flask 2.3 in ``setup.cfg``
- Fix Swift tests
- Add tests for ``crypto.py`` and encrypted files in storage
- Upgrade libraries

0.7.14 (2023-05-31)
-------------------

- Fix tests on Flask 2.3
- Fix ``KeyError`` when ``FS_AES256_ENCRYPTED`` is not set
- Fix Travis build

0.7.13 (2023-05-26)
-------------------

- Fix Flask issue with tests

0.7.12 (2023-05-26)
-------------------

- Upgrade libraries

0.7.11 (2023-05-26)
-------------------

- Added file encryption/decryption on put/get (AES256)
- Allow ``cryptography`` from 39.0.2
- Add ``license_file`` in setup
- Add ``launch.json`` for VSCode debugging
- Add issue templates

0.7.10 (2023-03-13)
-------------------

- Create Swift container only if missing
- Fix pip install command for development

0.7.9 (2023-03-03)
------------------

- Added ``read_chunks()`` method on ``Storage``
- Add test ``test_read_chunks``

0.7.8 (2023-03-03)
------------------

- Use Swift ``auth_version`` 3 by default

0.7.7 (2023-02-24)
------------------

- Change options for Swift

0.7.6 (2023-02-09)
------------------

- Use ``app_context()`` when using ``current_app``

0.7.5 (2023-02-06)
------------------

- Fix ``LocalBackend.delete``: use ``self.path`` for destination

0.7.4 (2022-01-24)
------------------

- CGWire will maintain this fork
- Flask-FS2 requires Python 3.7+ and Flask/Werkzeug 2.0.0+
- Remove all code related to Python 2
- Added ``read_chunks()`` operations
- Add region configuration for Swift and S3

0.6.1 (2018-04-19)
------------------

- Fix a race condition on local backend directory creation
- Proper content type handling on GridFS (thanks to @rclement)

0.6.0 (2018-03-27)
------------------

- Added ``copy()`` and ``move()`` operations
- ``delete()`` now supports directories (or prefixes for key/value stores)
- Improve ``metadata()`` ``mime`` handling
- Added explicit ``ImageField.full(external=False)``

0.5.1 (2018-03-12)
------------------

- Fix ``local`` backend ``list_files()`` nested directories handling

0.5.0 (2018-03-12)
------------------

- Added ``metadata`` method to ``Storage`` to retrieve file metadata
- Force ``boto3 >= 1.4.5`` because of API change (lifecycle)
- Drop Python 3.3 support
- Create parent directories when opening a local file in write mode

0.4.1 (2017-06-24)
------------------

- Fix broken packaging for Python 2.7

0.4.0 (2017-06-24)
------------------

- Added backend level configuration ``FS_{BACKEND_NAME}_{KEY}``
- Improved backend documentation
- Use setuptools entry points to register backends.
- Added `NONE` extensions specification
- Added `list_files` to `Storage` to list the current bucket files
- Image optimization preserve file type as much as possible
- Ensure images are not overwritted before rerendering

0.3.0 (2017-03-05)
------------------

- Switch to pytest
- ``ImageField`` optimization/compression.
  Resized images are now compressed.
  Default image can also be optimized on upload with ``FS_IMAGES_OPTIMIZE = True``
  or by specifying `optimize=True` as field parameter.
- ``ImageField`` has now the ability to rerender images with the ``rerender()`` method.

0.2.1 (2017-01-17)
------------------

- Expose Python 3 compatibility

0.2.0 (2016-10-11)
------------------

- Proper github publication
- Initial S3, GridFS and Swift backend implementations
- Python 3 fixes


0.1 (2015-04-07)
----------------

- Initial release

