はじめに
- こんにちはRIN1208です。今回はAWSのSNSとDynamoDBを触れることになり、先ずはローカルでやってみようとのことでDockerComposeで動かしたのですがいろいろあったので(主にSNS)忘れないため、またこれから触る人の参考になればと思いこの記事を書きました。
- また間違っている箇所がありましたら指摘して頂けると幸いです。
実行環境
- macos catalia .ver10.15
- Docker for Mac
使用したコンテナ等
DynamoDB local
Fake SNS
- 今回はPublishするだけだったのでFake SNSというのを使用しました
boto3
DynamoDBにデータを書き込むコード等
- docker-compose.yml
docker-compose.yml
version: "3"
services:
dynamodb:
image: amazon/dynamodb-local
ports:
- 8000:8000
app:
build:
context: .
tty: true
links:
- dynamodb
- Dockerfile
- 今回は使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
- 今回は使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
FROM python:3.6
WORKDIR /
RUN pip install boto3
COPY . /
- pythonのコード
- ここではテーブルの作成、データの書き込み、テーブル一覧の取得をしています
- aws_access_key_idとaws_secret_access_keyはdynamodb local だと適当な文字列で大丈夫です。
- ここではテーブルの作成、データの書き込み、テーブル一覧の取得をしています
main.py
import boto3
resource = boto3.resource(
'dynamodb',
region_name='us-east-1',
endpoint_url="http://dynamodb:8000/",
aws_access_key_id='ACCESS_ID',
aws_secret_access_key='ACCESS_KEY'
)
client = boto3.client(
'dynamodb',
region_name='us-east-1',
endpoint_url="http://dynamodb:8000/",
aws_access_key_id='ACCESS_ID',
aws_secret_access_key='ACCESS_KEY'
)
# 以下の処理はテーブルの作成
tab = resource.create_table(
TableName='atelier',
KeySchema=[
{
'AttributeName': 'id',
'KeyType': 'HASH'
}
],
AttributeDefinitions=[
{
'AttributeName': 'id',
'AttributeType': 'N'
}
],
ProvisionedThroughput={
'ReadCapacityUnits': 1,
'WriteCapacityUnits': 1
}
)
print('Table status:', tab.table_status)
# 以下の処理はデータの書き込み及び、書き込んだデータの取得
table = resource.Table('atelier')
table.put_item(
Item={
"id": 1,
"name": "Ryza",
"job": "Alchemist"
}
)
res = table.get_item(Key={'id': 1})
print(res['Item'])
# 以下の処理はテーブル一覧の取得
tables = client.list_tables()
print('Tables List:', tables['TableNames'])
実行結果
- 実行して以下のように出力されていれば無事処理は成功
実行コマンド
docker-compose up -d --build && docker-compose exec app bash -c "python main.py"
以下のような感じで出力されていれば大丈夫です
Table status: ACTIVE
{'name': 'Ryza', 'job': 'Alchemist', 'id': Decimal('1')}
Tables List: ['test']
詳細はこちらを参照してください。
SNSにPublish
これが一番苦戦しました
docker-compose.yml
docker-compose.yml
version: "3"
services:
sns:
image: s12v/sns
ports:
- 9911:9911
app:
build:
context: .
tty: true
links:
- sns
- Dockerfile
- 今回も使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
- 今回も使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
FROM python:3.6
WORKDIR /
RUN pip install boto3
COPY . /
- pythonのコード
- 今回もaws_access_key_idとaws_secret_access_keyは適当で大丈夫です
main.py
import boto3
sns = boto3.client('sns', region_name='us-east-1',
endpoint_url="http://sns:9911",
aws_access_key_id='foo',
aws_secret_access_key='bar')
res = sns.create_topic(
Name='atelier',
)
print(res['TopicArn'])
listTopic = sns.list_topics(
NextToken=res['TopicArn']
)
print(listTopic)
##-------------------
sns.subscribe(
TopicArn=res['TopicArn'],
Protocol='http',
Endpoint='http',
ReturnSubscriptionArn=True
)
##-------------------
subscriptions = sns.list_subscriptions_by_topic(
TopicArn=res['TopicArn']
)
print(subscriptions)
response = sns.publish(
TopicArn=res['TopicArn'],
Message='hutomomo yabai'
)
print(response)
実行結果
実行コマンド
docker-compose up -d --build && docker-compose exec app bash -c "python main.py"
以下のような感じで出力されていれば大丈夫です
{'Topics': [{'TopicArn': 'arn:aws:sns:us-east-1:123456789012:atelier'}], 'ResponseMetadata': {'RequestId': '3206fffa-b256-4100-b005-7d064c305f35', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '317'}, 'RetryAttempts': 0}}
{'Subscriptions': [{'SubscriptionArn': 'arn:aws:sns:us-east-1:123456789012:atelier:c2e93c42-e7b6-465b-bc71-01ac3b538e2c', 'Owner': '', 'Protocol': 'http', 'Endpoint': 'http', 'TopicArn': 'arn:aws:sns:us-east-1:123456789012:atelier'}], 'ResponseMetadata': {'RequestId': 'e872c714-7152-4233-9ba9-d930ed461ca6', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '563'}, 'RetryAttempts': 0}}
{'MessageId': 'd523ef9c-dca6-4164-8a75-6bf85b0d9c7a', 'ResponseMetadata': {'RequestId': '057296d4-b0b0-4f96-8153-b55224ca6d17', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '270'}, 'RetryAttempts': 0}}
躓いたポイント
上のコードの囲ってある部分で躓いていました
# この部分
sns.subscribe(
TopicArn=res['TopicArn'],
Protocol='http',
Endpoint='http',
ReturnSubscriptionArn=True
)
この部分で何をしているかというとsubscriptionを作成してるだけです。
ちなみに作成していないと以下のエラーがでます
botocore.errorfactory.NotFoundException: An error occurred (NotFound) when calling the Publish operation: Topic not found: arn:aws:sns:us-east-1:123456789012:atelier
Topic上で作ってるのになんでないの!?ってなりました。
このエラーについてはgithubのissueにも上がっていてこれを見るまで気が付きませんでした.
fakesnsはguiもなく記事も全然なくて...
READMEにサンプルコードかsubscriptionの作成が必要と書いて欲しかった...
最後に
- こんにちはRIN1208です。この記事でFakeSNSに触れる人の助けになれば幸いです。
- また、この記事を読んでくださりありがとうございます