Python + BOX api + 自動認証で 既存のフォルダにアップロード(2020/03/25追記)

やりたいこと

エンタープライズで契約しているBOXの
規定のWEB UIで社員が内容を確認できるフォルダに
自作のアプリから手動の認証なしでファイルをアップロードしたい
言語はPython

日本語のBOX APIの記事は少なめで、該当の例があっても、契約が違うのか画面が変わったのかでやり方が違っていて苦戦したので、平成31年4月1日現在、実現した方法を書いておきます。
いろいろ、もっといい方法がある気がするんですけど、とりあえず実現できた方法です。

令和2年3月25日に追記しました。

 

1.BOXにアプリを作る

認証を自動で行えるのは、JWTアプリです。そうでない方は通常のユーザーアカウントを使うのでユーザーの操作がいります。

下の公式のチュートリアルが画像もついていて、わかりやすいです。
ちなみにPythonはDLした設定ファイルの読み込みに未対応なので、キーをコンソールで作って、コピペしても差し支えないです。
2020/03/25 追記 読み込みに対応していました。

JWTアプリケーションの設定

アプリは以下の設定で作成してしてください。
・アプリケーションアクセス:エンタープライズ
・アプリケーションスコープ:デフォルト(下)
BOXに格納されているすべての〜をON
ユーザーを管理をON
グループを管理をON
エンタープライズのプロパティを管理をON
・高度な機能:デフォルト(どちらもOFF)

2020/03/25 追記
次に、BOXのエンタープライズの管理者が、作成したJWTアプリの使用を許可します。(これはこの記事を新規で書いたときも必要だったかもしれない)

「管理コンソール」>メニュー「アプリ」>タブ「カスタムアプリ」
ボタン「新しいアプリケーションを承認」
クライアントIDに、マイアプリの「構成」>「OAuth 2.0資格情報」>「クライアントID」の値を入力します。

 

2.Pythonのアプリから繋ぐ

これも公式のチュートリアルの下の2つを、Pythonを選んで順番に。チュートリアルがわかりやすいです。
SDKもpipで入るので便利。

SDKのインストール

JWTによる認証(SDK)

各パラメーターは、管理ページの情報や、ローカルのpemファイルのパスなどに書き換えてください。
2020/03/25 追記 pythonでもpemでなく構成ファイルを落として読み込む方式がチュートリアル通りです。詳細は下に

ここまでは充実のサポート体制だったのですが、ここから、既存のフォルダに、アクセスするための設定です。
そのアプリでユーザーを作成するとそのユーザーが管理画面に出てくるので、という記事を読みましたが、今現在、うちの環境ではユーザーを作っても管理画面にアプリユーザーが出なかったのです。

はじめにアップロードするための、適当なファイルを用意する。
ここではphoto.jpgとします。

2020/03/25 追記
上にも書いた通り、pythonでも、上のJWTAuthを書かなくても、ダウンロードした構成ファイルを読み込めるようになっていました。

アプリの「構成」>「公開キーの追加と管理」で「公開/秘密キーペアを作成」をおすと構成ファイルがダウンロードできます。
上のプログラムは、sdkとclientに代入するところを書き換えます。
‘/*******/****_config.json’は構成ファイルのフルパスです。
 sdk = JWTAuth.from_settings_file(‘/*******/****_config.json’)
 client = Client(sdk)
チュートリアルだとconfigという変数名ですね。変数なので何でもいいです。

アップロードはこちらを参考にしています。 https://ja.developer.box.com/docs/work-with-files

client = Client(sdk) までは上のチュートリアルで作ったところです。

folder_idが0だと、このアプリのルートフォルダにファイルがアップロードされます。
上のアプリを作成するときのアプリケーションアクセスの設定をエンタープライズにしないと、アプリ用のユーザーでは、そのアプリ専用の領域のファイルしか操作できないらしいです。この領域はBOXの規定の画面では見られず、アプリの権限でないとアクセスできないそうです。

アップロードに成功すると、戻り値のbox_fileの中身がデバッグとしてずらずらと書き出されます。

その中に、ファイルが何のアカウントでアップロードされたかの情報が含まれていて
AutomationUser_*****_*******@*******.com というメールアドレスの形をしているはずです。

2020/03/25 追記
この戻り値にメールアドレスは含まれなくなりました。ユーザーIDが含まれます。<Box User – 123456789 (MyAppName)> という項目があり、123456789がIDになります。

このIDを手がかりに、ユーザーの情報を取得する関数で調べます。
 user = client.user(user_id).get()
コードだとこんなかんじです。
 from boxsdk 略(上と同じ)
  略
 client=Client(略
 user = client.user(123456789).get() 
この戻り値userを展開すると、メールアドレスの形をした項目が含まれています。

それをメモしておいてください。

(デバッガーのついてる開発環境なら書き出す必要ないですね。今回はシリアル接続したarmのlinuxに直接書いたのでprintしてます)

いつもファイルを見ているBOXのWEB UIから、ファイルをアップロードしたいフォルダーを開いてください。
現在は画面右の「コラボレーション」欄下にある「このフォルダを共有」をクリックし、上でメモをしたメールアドレスに招待メールを送ってください。権限は「編集者」で。

アプリがコラボレーターに追加されます。

フォルダーのURLの最後の数字をメモしておきます。
https://*****.app.box.com/folder/1234567890 ここの1234567890です。

 

3.ファイルをアップロードする

上のソースコードの、下の部分をこんなふうに書き換えます。

先程のフォルダに photo2019-04-01_19:04:01.jpg のようなファイルがアップされているはずです。