よろしくお願いしまっす!

この記事は…

集え、初老丸達よ。初老丸達による世界に向けた技術的(又はそれに関連する)な物語を綴るカレンダーです。我こそ初老丸という方、初老丸予備軍の方も奮ってご参加下さい。ジーク・初老丸!

qiita.com

初老丸 Advent Calendar 2017 1 日目の記事になる予定です。

やりたいこと

  • 任意の S3 バケット内に任意のキーが存在しているかを確認したい
  • 関数として呼び出して、戻り値としてオブジェクトが存在していたら True を返して、存在していなければ False を返すようにしたい

諸々

bash

AWS CLI の s3_api head-object を利用する。

aws s3api head-object --bucket ${_BUCKET} --key ${_KEY}

関数にすると以下のような感じにすると良さそう。

#!/usr/bin/env bash

function s3_key_exists?(){
  _KEY=${1}
  aws s3api head-object --bucket ${_BUCKET} --key ${_KEY} > /dev/null 2>&1
  if [ $? == 0 ];then
    true
  else
    false
  fi
}

このファンクションを以下のように呼べばちょっとカッコイイかも。

#!/usr/bin/env bash

if s3_key_exists? $_KEY ;then
  echo "存在しています."
else
  echo "存在していません."
fi

Ruby

$ ruby --version
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]

Aws::S3::Resource を使えば、シンプルに書けるのが嬉しい。

require 'aws-sdk'

s3_bucket = Aws::S3::Resource.new(:region => 'ap-northeast-1',
                                  :profile => 'xxxxxx').bucket('bucket_name')

s3_bucket.object('key_name').exists?

実際に利用する場合には以下のような感じになるかなと。

#!/usr/bin/env ruby

require 'aws-sdk'

s3_bucket = Aws::S3::Resource.new(:region => 'ap-northeast-1',
                                  :profile => 'xxxxxx').bucket('bucket_name')

if s3_bucket.object('key_name').exists? then
  puts "存在しています."
else
  puts "存在していません."
end

Python

$ python -V
Python 3.6.2

こちらの記事を参考に head_objectを使うパターンを採用。

import boto3
from botocore.errorfactory import ClientError

s3 = boto3.client('s3')
try:
    s3.head_object(Bucket='bucket_name', Key='key_name')
except ClientError:
    pass

利用する場合には以下のような感じかな…

#!/usr/bin/env python

import boto3
from boto3.session import Session
from botocore.errorfactory import ClientError

session = Session(profile_name='my-profile')
s3 = session.client('s3')

def check_s3_key_exists(key):
    try:
        s3.head_object(Bucket='bucket_name', Key=key)
        return True
    except ClientError:
        return False


if check_s3_key_exists('key_name'):
    print('オブジェクトは存在しています.')
else:
    print('オブジェクトは存在していません.')

Go

$ go version
go version go1.8.3 darwin/amd64

func (*S3) HeadObject を使うパターン。

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/s3"
)

...

    input := &s3.HeadObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
    }

    _, err := s3Svc.HeadObject(input)

    _, err := s3Svc.HeadObject(input)
    if err != nil {
        // 全てのエラーを false として返すという強引な対応
        return false
    } else {
        return true
    }
...

利用する場合には以下のような感じかな…

package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/service/s3"
)

var (
    aws_profile = "my-profile"
    aws_region = "ap-northeast-1"
)

func s3Svc(profile string, region string) *s3.S3 {
    var config aws.Config
    creds := credentials.NewSharedCredentials("", profile)
    config = aws.Config{Region: aws.String(region), Credentials: creds}
    sess := session.New(&config)
    s3Svc := s3.New(sess)
    return s3Svc
}

func checkS3KeyExists(bucket string, key string) bool {
    s3Svc := s3Svc(aws_profile, aws_region)
    input := &s3.HeadObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
    }

    _, err := s3Svc.HeadObject(input)
    if err != nil {
        // 全てのエラーを false として返すという強引な対応
        return false
    } else {
        return true
    }
}

func main() {
    if checkS3KeyExists("bucket_name", "key_name") {
        fmt.Println("オブジェクトは存在しています.")
    } else {
        fmt.Println("オブジェクトは存在していません.")
    }
}

PHP

$ php --version
PHP 7.1.5 (cli) (built: May 23 2017 13:40:11) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.5, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.5.3, Copyright (c) 2002-2017, by Derick Rethans

doesObjectExist という素敵なメソッドがあるのでこれを使う。

<?php
...
$s3 = new Aws\S3\S3Client([
    'profile' => AWS_PROFILE,
    'region' => AWS_REGION,
    'version' => 'latest'
]);

$result = $s3->doesObjectExist('bucket_name', 'key_name');
...

利用する場合には以下のような感じかな…

<?php

require 'vendor/autoload.php';

define('AWS_PROFILE', 'my-profile');
define('AWS_REGION', 'ap-northeast-1');

$s3 = new Aws\S3\S3Client([
    'profile' => AWS_PROFILE,
    'region' => AWS_REGION,
    'version' => 'latest'
]);

if ($s3->doesObjectExist('bucket_name', 'key_name')) {
    echo 'オブジェクトは存在しています.' . PHP_EOL;
} else {
    echo 'オブジェクトは存在していません.' . PHP_EOL;
}

doesObjectExist メソッドが素敵過ぎる。

以上

メモでした。

元記事はこちら

言語別 S3 バケットに任意のキーが存在しているかを確認するコード片