小ネタ: 最新のWatson SDKでは認証情報(Credentials)をファイルに外出しできます


![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108535/bac1ca97-327d-5192-9520-6103bbe62c14.png)

# 要は(TL;DR)

- 2019/3月にWatson SDKが新しくなりました（V4)
- パッケージの名前がwatson-developer-cloudからibm-watsonに代わってます
- V4では認証情報をファイルに外だしできるのでプログラムのコードをシンプルにできます
- 他にも様々な機能追加がありますがV3とは非互換部分もあるので、ご利用は計画的に


# はじめに ～ Watson SDK v4(ibm-watson)　ご利用は計画的に

こんにちわ！石田です。遅ればせながら、ではありますが2019/3末にWatson SDKが新しいものになってます。最新版はバージョンがv4に変わり機能強化してますがパッケージの名前やAPIも変わってます。よって**何も考えないで環境を無理矢理にアップデートしてしまうと、既存のアプリが動かずに死にます**。（あ、ちなみにv4では名前もwatson-developer-cloudから**ibm-watson**に変わってますので、意図的にpip install ibm-watson[^1]とか**新しい名前を指定しないかぎり、勝手に新しいモジュールが導入されてしまうことはありません**ので、ご安心ください。)　まあ様々な機能がアップしてるので、「今すぐ」でなくても**長期的には最新版のご利用をお勧めします**。要は「ご利用は計画的に」ってことで。

[^1]: pythonの場合。他の言語でも新しい名前を使わなければ大丈夫。

新SDK紹介のブログ記事 :newspaper: [IBM Watson SDK Major Releases March 2019](https://medium.com/ibm-watson/ibm-watson-sdk-major-releases-march-2019-e57c8a66201e)
:octocat: Github上の [IBM Watson SDK](https://github.com/watson-developer-cloud)

# v4ではサービスの認証情報はibm-credentials.envに書いておけばいい

Watsonの様々なサービスの認証情報は昔はuserid/password、IAMに移行した現在は**apikey**を指定していますが、新しいV4のSDKからはアプリ内でいちいち指定せずとも、**ibm-credentials.env**というファイルに所定の形式で書いておけばオッケーになりました。

- **これはオプション**であり、従来の方法でももちろんいいです
- この機能はnode-sdk, python, java, unity, dotnetのWatson SDKで利用できます。**モバイルのswift SDKでは利用できません**


下記は[node-sdkのREADME](https://github.com/watson-developer-cloud/node-sdk)での記述の抜粋です。
![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108535/6af2464c-1bce-33b3-4a22-e177ebea705e.png)


この節の記述を訳すとこんな感じ

# 【翻訳】認証情報(クリデンシャル)の指定
> SDKで前節のような認証を行うには、２つの方法があります。
> **クリデンシャル・ファイル（こっちが簡単！）**
>クリデンシャル・ファイルを使う場合は、所定の場所にファイルを置いておくだけで、SDKが内容をパースして認証の処理を行ってくれます。クリデンシャル・ファイルは利用するサービス・インスタンスの「管理(Manage)」タブで表示される認証情報の「ダウンロード」ボタンで入手できます。
ダウンロードしたファイルは**ibm-credentials.env**という名前になります。SDKは後述する「ファイルパス」を構成で指定しない限り、この名前の付いたファイルを探します。SDKがibm-credentials.envを以下の順番で探します。

> - 環境変数　IBM_CREDENTIALS_FILEで指定されたディレクトリー
> - システムのホーム・ディレクトリー
>- 現在のカレント・ワーキング・ディレクトリー(Nodeが実行されたディレクトリー)

>環境を正しくセットアップしたなら、プログラミング・コードの中で認証について気にする必要はなくなります。例えば、もしDiscovery用にクリデンシャル・ファイルをダウンロードしたなら、以下の処理だけで済みます。

>```
> const DiscoveryV1 = require('ibm-watson/discovery/v1');
>const discovery = new DiscoveryV1({ version: '2019-02-01' });
>```
>たったこれだけです！

>コード中で一度に複数のサービスを使っているために異なるibm-credentials.envファイルが複数できてしまう場合は、単純にそれらの内容を１つのibm-credentials.envに書いておけば、SDKが適切なサービスの認証情報の割り当てをハンドリングしてくれます。

>もしクリデンシャル・ファイルの置き場所や名前を変更したければ、**IBM_CREDENTIALS_FILE**という環境変数でセットできます。この設定は先ほど述べたファイルの探索場所に優先します。このように指定します。
>```
>export IBM_CREDENTIALS_FILE="<path>"
>```
>ここで<path>は/home/user/Downloads/<file_name>.envのような感じです。もしディレクトリー名を指定した場合は、そのディレクトリー中でibm-credentials.envという名前のファイルを探します。

# 例

各サービスの「管理」－「ダウンロード」で所定の場所にダウンロードすればいいだけです

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108535/daae6cc7-b775-1462-6be1-73024dbe7481.png)

**ibm-credentials.env**の例。サービスが複数ある場合は単純にマージすればよいです。

```text
ASSISTANT_IAM_APIKEY=OcrHggzp-tlvjaz5gL_f009uLgXXXXXXXXYXJkAPVvvh
ASSISTANT_URL=https://gateway.watsonplatform.net/assistant/api
SPEECH_TO_TEXT_IAM_APIKEY=w-BbPMow_ED3hc3lL-9LYs4iQBTCKxEn5D1bXXXXXXXX
SPEECH_TO_TEXT_URL=https://stream.watsonplatform.net/speech-to-text/api
TEXT_TO_SPEECH_IAM_APIKEY=PYYsI8h18Yx7I0iwFhLS63i6PfJgkAIUvWKZXXXXXXXX
TEXT_TO_SPEECH_URL=https://stream.watsonplatform.net/text-to-speech/api
```

左が今まで、右がV4です。プログラム的にコード量が「劇的に減る」わけではありませんが、「コード内で認証を意識せずに済む」のはありがたいです。（左は今は認証情報べた書きしてますが、環境変数や.envで外部から与えるならさらに面倒になるわけで。。）

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108535/15f98b20-828e-2e87-fdde-af44183e80a8.png)

以上、小ネタでした。