Skip to content

Commit

Permalink
Merge pull request #2552 from pallets-eco/boto-to-boto3
Browse files Browse the repository at this point in the history
Use boto3 for S3 fileadmin
  • Loading branch information
samuelhwilliams authored Oct 27, 2024
2 parents 6ee0b4d + ad2b8d7 commit ddab93f
Show file tree
Hide file tree
Showing 20 changed files with 778 additions and 130 deletions.
4 changes: 2 additions & 2 deletions doc/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,14 @@ can use it by adding a FileAdmin view to your app::


FileAdmin also has out-of-the-box support for managing files located on a Amazon Simple Storage Service
bucket. To add it to your app::
bucket using a `boto3 client <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.client>`_. To add it to your app::

from flask_admin import Admin
from flask_admin.contrib.fileadmin.s3 import S3FileAdmin

admin = Admin()

admin.add_view(S3FileAdmin('files_bucket', 'us-east-1', 'key_id', 'secret_key')
admin.add_view(S3FileAdmin(boto3.client('s3'), 'files_bucket'))

You can disable uploads, disable file deletion, restrict file uploads to certain types, etc.
Check :mod:`flask_admin.contrib.fileadmin` in the API documentation for more details.
Expand Down
7 changes: 7 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

2.0.0a2
-------

Breaking changes:

* Use of the `boto` library has been replaced by `boto3`. S3FileAdmin and S3Storage now accept an `s3_client` parameter taking a `boto3.client('s3')` instance rather than `aws_access_key_id`, `aws_secret_access_key`, and `region` parameters.

2.0.0a1
-------

Expand Down
23 changes: 23 additions & 0 deletions examples/s3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# S3 Example

Flask-Admin example for an S3 bucket.

To run this example:

1. Clone the repository and navigate to this example::

git clone https://github.com/pallets-eco/flask-admin.git
cd flask-admin/examples/s3

2. Create and activate a virtual environment::

python -m venv venv
source venv/bin/activate

3. Install requirements::

pip install -r requirements.txt

4. Run the application::

python app.py
Empty file added examples/s3/__init__.py
Empty file.
57 changes: 57 additions & 0 deletions examples/s3/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
from io import BytesIO

import boto3
from flask import Flask
from flask_admin import Admin
from flask_admin.contrib.fileadmin.s3 import S3FileAdmin
from flask_babel import Babel
from testcontainers.localstack import LocalStackContainer

app = Flask(__name__)
app.config["SECRET_KEY"] = "secret"
admin = Admin(app)
babel = Babel(app)

if __name__ == "__main__":
with LocalStackContainer(image="localstack/localstack:latest") as localstack:
s3_endpoint = localstack.get_url()
os.environ["AWS_ENDPOINT_OVERRIDE"] = s3_endpoint

# Create S3 client
s3_client = boto3.client(
"s3",
aws_access_key_id="test",
aws_secret_access_key="test",
endpoint_url=s3_endpoint,
)

# Create S3 bucket
bucket_name = "bucket"
s3_client.create_bucket(Bucket=bucket_name)

s3_client.upload_fileobj(BytesIO(b""), "bucket", "some-directory/")

s3_client.upload_fileobj(
BytesIO(b"abcdef"),
"bucket",
"some-file",
ExtraArgs={"ContentType": "text/plain"},
)

s3_client.upload_fileobj(
BytesIO(b"abcdef"),
"bucket",
"some-directory/some-file",
ExtraArgs={"ContentType": "text/plain"},
)

# Add S3FileAdmin view
admin.add_view(
S3FileAdmin(
bucket_name=bucket_name,
s3_client=s3_client,
)
)

app.run(debug=True)
2 changes: 2 additions & 0 deletions examples/s3/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
../..[s3]
testcontainers
4 changes: 0 additions & 4 deletions examples/sqla/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@ def get_locale():
babel = Babel(app, locale_selector=get_locale)


# Initialize babel
babel = Babel(app, locale_selector=get_locale)


import admin.main # noqa: F401, E402
Loading

0 comments on commit ddab93f

Please sign in to comment.