LoginSignup
1
1

【データ可視化/Streamlit】S3バケットの画像を署名付きURL機能を使ってStreamlit上に表示する方法

Posted at

前置き

こんにちは、データエンジニアの山口です!

現在業務で、Streamlitでデータ可視化アプリを作成しており、
今後アプリ上にS3バケット内の画像を表示できるようにもしたいなと考えております。
なので、今回はその練習をしてみることにしました!

実装する手順の目次

以下のような流れで、実施テストを行いました。

  1. S3に画像をアップロード
  2. アクセスキーの取得
    • IAMユーザーを作成する
    • S3のアクセス権限を持たせる
    • アクセスキーを作成する
  3. Streamlitでアプリを作る
    • コードの作成をする
    • $ streamlit runコマンドを実行する

実装に取り掛かります!

それでは、実装する手順に記載した手順で実装を進めていきます!

1. S3に画像をアップロード

まずは、Streamlitに表示したい画像をS3バケット内に用意をします!

Streamlitに表示したい適当な画像を用意して、
yamaguchi-streamlit-testバケットへアップロードします。

image.png

2. アクセスキーの取得

AWSのアクセスキーを使ってStreamlitからS3へのアクセスを可能にしていきます!
今回はIAMユーザーを作成して、そのユーザーにS3へのアクセス権限を渡し、そこからアクセスキーを取得します。

2-1. IAMユーザーを作成する

AWSのコンソール画面のIAM > ユーザー > ユーザーの作成からIAMユーザーの作成をします。
今回はyamaguchi-streamlit-testというユーザーを作成します。
image.png

2-2. S3FullAccessを持たせる

IAMユーザーにS3のアクセス権限(ポリシー)を持たせます。
今回はAmazonS3FullAccessを持たせることにします。
image.png

2-3. アクセスキーを作成する

作成したIAMユーザーのアクセスキーを取得していきます。
IAM > ユーザー > [作成したIAMユーザー名]から、セキュリティ認証情報タブをクリックして、
アクセスキーを作成をクリックします。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3838333537332f61623035623162642d336339622d383565322d613132662d6661656635633338383738342e706e67.png

今回はStreamlitをローカルで動かすので、ユースケースをローカルコードとしてアクセスキーを作成してみます。

AWS上にアプリをデプロイしてアプリを動かしたい場合は、
AWSコンピューティングサービスで実行されるアプリケーションを選択するのか、
またはアクセスキーを使うべきなのか要検討だなと思いました。

image.png

これで一通り設定が終わりなので、アクセスキーを作成をクリックします!
image.png

以下のような画像が表示されるので、アクセスキーシークレットアクセスキーをメモしておきます。
後ほどここで取得した情報を/.streamlit/secrets.tomlに記載します。
スクリーンショット 2024-02-24 9.34.10.png

3.Streamlitでアプリを作る

3-1. コードの作成をする

まずはこのようなディレクトリの構成を作ります。

├── yamaguchi-streamlit-test/
│   └── .streamlit/
│       └── secrets.toml
└── yamaguchi-streamlit-test.py

そして、各ファイルには以下のようなコードを書きます。

.streamlit.secrets.toml
[aws_credentials]
aws_access_key_id = "[上記で取得したアクセスキー]"
aws_secret_access_key = "[上記で取得したシークレットアクセスキー]"
region_name = "[S3バケットがあるリージョン名]"
yamaguchi-streamlit-test.py
import os
import boto3
import streamlit as st

# AWSの認証情報を取得する関数
def get_aws_config():
    if os.path.exists('./.streamlit/secrets.toml'):
        aws_connection_params = {
            "aws_access_key_id": st.secrets["aws_credentials"]["aws_access_key_id"],
            "aws_secret_access_key": st.secrets["aws_credentials"]["aws_secret_access_key"],
            "region_name": st.secrets["aws_credentials"]["region_name"]
        }
    return aws_connection_params


# 署名付きURLを生成する関数
def generate_presigned_url(bucket_name, object_name, expiration=3600):
    response = s3_client.generate_presigned_url('get_object',
                                                Params={'Bucket': bucket_name,
                                                        'Key': object_name},
                                                ExpiresIn=expiration)
    return response

# S3のバケット名
bucket_name = 'yamaguchi-streamlit-test'
# S3のクライアントを生成
aws_config = get_aws_config()
s3_client = boto3.client('s3',
                         aws_access_key_id=aws_config['aws_access_key_id'],
                         aws_secret_access_key=aws_config['aws_secret_access_key'],
                         region_name=aws_config['region_name'])


# S3バケット内の画像の一覧の署名付きURLを生成
image_url1 = generate_presigned_url(bucket_name, 'bear1.jpg')
image_url2 = generate_presigned_url(bucket_name, 'bear2.jpg')


# Streamlitで画像を横並びで表示
st.title('S3 Image Viewer')
col1, col2 = st.columns(2)
with col1:
    st.image(image_url1, caption='Bear1', use_column_width=True)
with col2:
    st.image(image_url2, caption='Bear2', use_column_width=True)

3-2. $ streamlit runコマンドを実行する

最後にyamaguchi-streamlit-testディレクトリにて、
$ streamlit run yamaguchi-streamlit-test.pyコマンドを実行すると画像を表示することができました!
image.png

まとめ

無事問題なく実装することができました!

今回は画像2枚だけを表示するだけで済みましたが、
業務で実装する場合は大量に画像を表示する必要があるので、そのためのコードも考えていかなきゃなと思いました。

GENDAデータチームではプロダクトのデータ解析や機械学習プロジェクトを推進できるデータサイエンティストを募集しています。
興味を持っていただけましたら、是非ご連絡いただけると幸いです!

参考記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1