【Watson Studioメモ】PCからIBM Cloud Object Storage(COS)にファイルをコピー

# はじめに
Watson Studioで処理をする際、ファイルはCOSにアップロードしたものを使う形になります。
IBM CloudのCOS管理画面から、drag and dropでファイルのアップロードはできるのですが、

・プレフィックス(通常のファイルシステムでディレクトリに相当)付きでアップロードできない
・ファイルが大量にあるときに手間がかかる

などの理由で、プログラムでアップロードしたい場合があります。
Mac PCのJupyter Notebook(Anacondaで導入したもの)でCOSへのアップロードができることを確認しましたので、その手順メモを以下に記載します。

# ドライバの導入
PythonからCOSにアクセスする場合、後ほどのコードに出てくるように、``ibm_botocore``とか``ibm_boto3``といったライブラリを利用します。Watson StudioのJupyterではこれらのライブラリは事前導入済みですぐ使えるのですが、問題はPCの場合これをどうやって導入するかです。
``pip ibm_boto3``とかやっても出てこなかったもので。
これが正解かどうか不明ですが、とりあえず下記の方法でうまくいくことがわかりました。

```
$ git clone https://github.com/ibm/ibm-cos-sdk-python.git
$ cd ibm-cos-sdk-python
$ pip install -r requirements.txt
$ pip install -e .
```

# COS認証情報の取得
下記の手順でCOSの資格情報を取得します。

https://cloud.ibm.com/resources でIBM Cloudのリソース一覧を表示します。
下のような画面になるので、``Cloud Object Storage``のリンクをクリックします。

![スクリーンショット 2019-07-02 9.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/702cff0d-1bea-8cef-e0a4-4c2ff0b14d8c.png)

次のような、COS管理画面になったら
①　画面左の「サービス資格情報」をクリック
②　資格情報のリストから適当なものを選んで「資格情報の表示」をクリック
③　クリップボードアイコンをクリックすると、資格情報全体がクリップボードにコピーされますので、テキストエディタなどにいったん保存します。

![スクリーンショット 2019-07-02 9.38.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/2abc55cf-41e4-c1d7-ed34-8124ae142486.png)

# Pythonコーディング
[notebookダウンロード](https://raw.githubusercontent.com/makaishi2/sample-data/master/notebooks/cos-upload.ipynb)から、notebookファイルをダウンロードし、ローカルのJupyter Notebookに読み込みます。ブラウザからNotebook全体を見たい場合は、以下のリンクを参照して下さい。

https://github.com/makaishi2/sample-data/blob/master/notebooks/cos-upload.ipynb

下の部分のセルは事前入手した資格情報で置き換えます。

![スクリーンショット 2019-07-02 9.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/caaf3ecf-c360-fb6a-dad8-cc7aa22d79e3.png)

コード全体については、以下で簡単に説明します。


### ライブラリのロード
```py3
# ライプラリのロード
# 上のpipコマンドで導入が必要です。
from ibm_botocore.client import Config
import ibm_boto3
```

### COS認証情報の設定
```py3
# COS管理画面から認証情報をコピペして下さい。
cos_credentials = {
  "apikey": "xxxx",
  "endpoints": "https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints",
  "iam_apikey_description": "xxxx",
  "iam_apikey_name": "サービス資格情報-1",
  "iam_role_crn": "crn:v1:bluemix:public:iam::::serviceRole:Writer",
  "iam_serviceid_crn": "xxxx",
  "resource_instance_id": "xxxx"
}
```

### COSオブジェクトの生成
```py3
# COSオブジェクトの生成
auth_endpoint = 'https://iam.bluemix.net/oidc/token'
service_endpoint = 'https://s3-api.us-geo.objectstorage.softlayer.net'
cos = ibm_boto3.client('s3',
                         ibm_api_key_id=cos_credentials['apikey'],
                        ibm_service_instance_id=cos_credentials['resource_instance_id'],
                         ibm_auth_endpoint=auth_endpoint,
                         config=Config(signature_version='oauth'),
                         endpoint_url=service_endpoint)
```

### バケット一覧の取得
動作テストを兼ねてバケットの一覧を取得します。

```py3
# テストを兼ねてバケットリストの取得
for bucket in cos.list_buckets()['Buckets']:
    print(bucket['Name'])
```

こんな感じで結果が返ってくれば成功です。

```
ganpoc-donotdelete-pr-kmbopsuhmnymfs
vincoderecognition-donotdelete-pr-4jyxjcyes5vidt
gan-poc-input01
gan-poc-output01
```

### ファイルアップロード、ダウンロードのサンプルコード
最後にファイルアップロード、ダウンロードのサンプルコードを示します。
特に難しいことはしていないので、コードを見ていただければ何をやっているかはわかると思います。
関数の引数について一つだけ解説すると、``Filename``がPCローカルのファイル名、``Keyname``がCOS内のオブジェクト名を意味しています。``Keyname``の中に``/``の文字を含めると、ディレクトリ同様の扱いができるということになります。

```py3
# ファイルアップロードサンプル
# 前提 元ファイル　ローカルの data/mnist配下
# コピー先 bucketに 'mnist/''のプレフィックス付きで保存

filenames = [
    't10k-labels-idx1-ubyte',
    't10k-images-idx3-ubyte',
    'train-labels-idx1-ubyte',
    'train-images-idx3-ubyte'
]

dirname = 'mnist'
sourcedir = 'data/mnist'
bucket = 'gan-poc-input01'

for filename in filenames:
    to_filename = dirname + "/" + filename
    from_filename = sourcedir + "/" + filename
    print(from_filename, to_filename)
    # ダウンロードサンプル
    #cos.download_file(Bucket=bucket, Key=filename, Filename=filename)
    # アップロードサンプル
    cos.upload_file(Filename=from_filename, Bucket=bucket, Key=to_filename )
```