## 経緯 [[LocalStack]]がユーザーアカウントとトークン利用必須となり、商用利用には有償になったので代替を探していたところ、[[Moto]]がいいのではというのを見かけたので試してみる。 目的はテストのモック化ではなく、ローカルでの起動。登録は[[🦉Jumeaux]]([[Python]])、参照は[[🧊Miroir CLI]]([[Go]])のツールで実施する。 ## 起動 [[Docker]]を使う。[[Docker Compose]]のファイル。 `docker-compose.yml` ```yaml services: motoserver: image: motoserver/moto:latest ports: - "3456:3000" environment: - MOTO_PORT=3000 ``` ```console docker compose up -d ``` ## 動作確認 [[DynamoDB]]のテーブルと、[[S3]]のバケットを作成する。 ```console export AWS_ACCESS_KEY_ID=test export AWS_SECRET_ACCESS_KEY=test export AWS_DEFAULT_REGION=ap-northeast-1 export AWS_ENDPOINT_URL=http://localhost:3456 aws dynamodb create-table \ --table-name miroir \ --attribute-definitions AttributeName=hashkey,AttributeType=S \ --key-schema AttributeName=hashkey,KeyType=HASH \ --billing-mode PAY_PER_REQUEST aws s3api create-bucket \ --create-bucket-configuration LocationConstraint=ap-northeast-1 \ --bucket mamansoft-miroir ``` いくつか動作確認する。 ### [[DynamoDB]] ```console # テーブル一覧 $ aws dynamodb list-tables { "TableNames": [ "miroir" ] } ``` ```console # 登録 aws dynamodb put-item --table-name miroir --item '{ "hashkey": {"S":"sample-001"}, "title": {"S":"sample title"}, "same_count": {"N":"10"}, "different_count": {"N":"2"}, "check_status": {"S":"todo"} }' ``` ```console # 取得 aws dynamodb get-item --table-name miroir --key '{ "hashkey": {"S":"sample-001"} }' # 全件取得 aws dynamodb scan --table-name miroir ``` ```console # 更新 aws dynamodb update-item \ --table-name miroir \ --key '{"hashkey":{"S":"sample-001"}}' \ --update-expression 'SET check_status = :s' \ --expression-attribute-values '{":s":{"S":"done"}}' ``` ```console # 削除 aws dynamodb delete-item \ --table-name miroir \ --key '{"hashkey":{"S":"sample-001"}}' ``` ```console # テーブル削除 aws dynamodb delete-table \ --table-name miroir ``` ### S3 ```console # バケット一覧 aws s3api list-buckets ``` ```console # ファイルのアップロード echo '{"hello":"world"}' > sample.json aws s3api put-object \ --bucket mamansoft-miroir \ --key results/sample-001/report.json \ --body sample.json ``` ```console # オブジェクト一覧取得 aws s3api list-objects-v2 \ --bucket mamansoft-miroir ``` ```console # オブジェクト取得 aws s3api get-object \ --bucket mamansoft-miroir \ --key results/sample-001/report.json \ downloaded.json ``` ```console # メタデータ確認 aws s3api head-object \ --bucket mamansoft-miroir \ --key results/sample-001/report.json ``` ```console # オブジェクト削除 aws s3api delete-object \ --bucket mamansoft-miroir \ --key results/sample-001/report.json ``` ```console # 再帰的にすべてのオブジェクトを削除 aws s3 rm s3://mamansoft-miroir \ --recursive ``` ```console # バケット削除 aws s3api delete-bucket \ --bucket mamansoft-miroir ``` ## [[🦉Jumeaux]]で動かす ### バケットとテーブルの初期化 さっきと同じ流れをもう一度。 ```console export AWS_ACCESS_KEY_ID=test export AWS_SECRET_ACCESS_KEY=test export AWS_DEFAULT_REGION=ap-northeast-1 export AWS_ENDPOINT_URL=http://localhost:3456 aws dynamodb create-table \ --table-name miroir \ --attribute-definitions AttributeName=hashkey,AttributeType=S \ --key-schema AttributeName=hashkey,KeyType=HASH \ --billing-mode PAY_PER_REQUEST aws s3api create-bucket \ --create-bucket-configuration LocationConstraint=ap-northeast-1 \ --bucket mamansoft-miroir ``` ```console $ aws dynamodb list-tables { "TableNames": [ "miroir" ] } $ aws s3api list-buckets { "Buckets": [ { "Name": "mamansoft-miroir", "CreationDate": "2026-03-11T04:33:01+00:00" } ], "Owner": { "DisplayName": "webfile", "ID": "bcaf1ffd86f41161ca5fb16fd081034f" }, "Prefix": null } ``` ### Jumeauxプロジェクトの準備 `config.yml` `requests/` `api/` の作成。 ```console uv run python jumeaux/main.py init ignore ``` 設定変更。`final` の部分だけ。 `config.yml` ```yaml final: - name: json - name: viewer - name: miroir config: table: miroir bucket: mamansoft-miroir cache_max_age: 120 # 追加 endpoints: dynamodb: http://localhost:3456 s3: http://localhost:3456 ``` APIサーバー起動。 ```console make server ``` ### 実行 ```console export AWS_ACCESS_KEY_ID=test export AWS_SECRET_ACCESS_KEY=test export AWS_DEFAULT_REGION=ap-northeast-1 uv run python jumeaux/main.py run requests ```