Jupyter NotebookのWebAPIを用いたファイルのアップロード/ダウンロード¶
目次
実行例・実装例のフォルダ構成¶
実行例のフォルダ構成を下記に示します。
/ <Jupyter Notebookのルートディレクトリ>
|- test_file
|- test_folder
|- test_folder_file_1.ipynb
|- test_folder_file_2.ipynb
リクエスト送信時に必要な値の取得¶
- <Jupyter NotebookのURL>
AAPF WebUIに表示されている[Access Jupyter Notebook] ボタンからJupyter Notebookにアクセスしてください。 利用しているブラウザのアドレスバーに表示されているURLをコピーし、下記のように
.../jupyterで 終わるように修正した上で使用してください。http://web.example.com/proxy/a2b69b7d848324ee19b25278d29d45b4/jupyter
このURLはAAPF WebAPIを利用して取得することもできます。詳しくは、 AAPF WebAPI Reference を参照してください。
- <アップロード先・ダウンロード元のパス>
Jupyter Notebook上のファイルパスを指定する際は、 Jupyter Notebookのルートディレクトリからの相対パスを指定してください。
下図の矢印が示すディレクトリがJupyter Notebookのルートディレクトリです。
上記の画像の、
test_folder_file_1.ipynbを指定するパスは以下となります。:/api/contents/test_folder/test_folder_file_1.ipynb
- <Jupyter Token>
Jupyter TokenはAAPF WebUIから取得します。使用したいAAClusterの [Access Jupyter Notebook] ボタンをクリックし、 表示されるJupyter Tokenを使用してください。
Jupyter TokenはAAPF WebAPIを利用して取得することもできます。詳しくは、 AAPF WebAPI Reference を参照してください。
Tip
使用方法の実行例には、Jupyter NotebookのWebAPI呼び出しに curl コマンドを使用しています。
curl コマンドのインストールについては、 https://curl.haxx.se/download.html を参照してください。
ファイルのアップロード方法¶
25MB未満のファイルのアップロード¶
25MB未満のファイルは PUT /api/contents/ を使うことでアップロードできます。
ファイルの内容はリクエスト送信時にJSONパラメータの一部としてリクエストボディに入れます。
実行例¶
ここでは bash を用いた実行例を記載しています。
$ curl -X PUT \
-H "Accept: application/json" \
-H "Authorization: Token c1663431be5df1873505524d720f958aa1fecbfd9fc06123" \
-d @- \
"http://web.example.com/proxy/a2b69b7d848324ee19b25278d29d45b4/jupyter/api/contents/test_folder/upload_test.txt" << EOF
{
"content": "$(base64 upload_test.txt)",
"type": "file",
"format": "base64"
}
EOF
リクエストパラメータの指定方法¶
Jupyter Tokenをリクエストヘッダーに設定します。
-H "Authorization: Token <Jupyter Token>" \
リクエストボディとしてJSON形式のデータを送信します。内容は以下の構造で生成してください。
{
"content": "$(base64 <アップロード元のパス>)",
"type": "file",
"format": "base64"
}
- content
- Base64を使用してテキストにエンコードされたファイルの内容を設定します。
この例では、
base64コマンドを使って <アップロード元のパス> にある ファイルの内容をエンコードしています。
アップロード先のパスをURLに含めて指定します。
<Jupyter NotebookのURL>/api/contents/<アップロード先のパス>
Note
アップロード時に存在しないディレクトリにファイルをアップロードすることはできません。 アップロード先のディレクトリは事前に作成してください。
25MB以上のファイルのアップロード¶
データ量が25MB以上のファイルは、1MBごとに分割してアップロードしてください。 また、この方法は25MB以下のファイルでもアップロードができます。
Hint
ディレクトリをまとめてアップロードする場合は、 zip 等で圧縮したファイルをアップロードしてください。
実装例¶
ここではPythonで実装した例を記載しています。
import requests
import base64
import json
import os
import sys
# ファイルアップロード時に必要となる値を入れる変数です
upload_from = 'upload_test.txt'
jupyter_path = 'http://web.example.com/proxy/a2b69b7d848324ee19b25278d29d45b4/jupyter'
jupyter_token = 'c1663431be5df1873505524d720f958aa1fecbfd9fc06123'
upload_to = 'test_folder/upload_test.txt'
with open(upload_from, 'rb') as file:
file_name = os.path.basename(upload_from)
chunk_size = 1024 * 1024
headers = {'Content-Type': 'application/json',
'Authorization': 'token {}'.format(jupyter_token)}
# ファイルを分割して読み込むメソッドです
def divide_file():
chunk = 0
read_data_size = 0
# 読み込んだファイルの容量がファイルサイズと一致するまで処理を実行させます
content_length = os.path.getsize(upload_from)
while read_data_size < content_length:
content = file.read(chunk_size)
encoded_content = base64.b64encode(content).decode('utf-8')
# 読み込んだデータサイズの更新をします
read_data_size = read_data_size + len(content)
# ファイルが最後まで読み込まれた際に、`chunk`は`-1`とします
if read_data_size == content_length:
chunk = -1
else:
chunk += 1
# リクエストのボディとなるように返却します
yield {
'content': encoded_content,
'format': 'base64',
'name': file_name,
'path': upload_to,
'type': 'file',
'chunk': chunk
}
try:
# ファイルを読み終わるまで繰り返す処理とします
for payload in divide_file():
# 作成したリクエストをJupyterに送信します
requests.put('{}/api/contents/{}'.format(jupyter_path, upload_to),
headers=headers, data=json.dumps(payload))
except:
# 例外処理を記載します
print("Unexpected error:", sys.exc_info()[0])
raise
Tip
Jupyter Notebookへリクエストを送信するツールとして、 PyPIで公開されているパッケージの requests を使用しています。
実装内容¶
送信するファイルを分割し、アップロードが可能な状態にします。
- ファイルを1MBごとに読み込みます。
- 1.で読み込んだファイルを
Base64エンコードします。
分割したファイルごとに
PUTリクエストを送信します。リクエストごとに
chunkという番号を1から順につけ、最後のリクエストには-1をつけます。- ヘッダーに以下を設定します。
{ "Content-Type": "application/json", "Authorization": "token <Jupyter Token>" }
- リクエストボディの内容を生成します。
{ "content": <分割したファイルの内容> "format": "base64", "name": <ファイル名>, "path": <アップロード先のパス>, "type": "file", "chunk": <2-1. で付けた番号> }
- 下記のURLへ、
PUTで各リクエストを順に送信します。 <Jupyter NotebookのURL>/api/contents/<アップロード先のパス>
- 下記のURLへ、
ファイルのダウンロード方法¶
ファイルのダウンロードは GET /files/ を使用します。
実行例¶
ここでは、bashを用いてダウンロードしたファイル内容を リダイレクションにてファイル内へ書き込む例を、記載しています。
$ curl -X GET \
-H 'Accept: application/json' \
-H 'X-Response-Encoding: chunked' \
-H "Authorization: Token <Jupyter Token>" \
"<Jupyter NotebookのURL>/files/<ダウンロード元のパス>" \
> <ダウンロード先のパス>
リクエストパラメータ¶
Jupyter Tokenをリクエストヘッダーに設定します。
-H "Authorization: Token <Jupyter Token>" \
ダウンロード元のパスをURLに含めて指定します。
<Jupyter NotebookのURL>/files/<ダウンロード元のパス>
Hint
GET /files/ では Range ヘッダーが使用可能です。このヘッダーを使用することで、 ファイルの一部分をダウンロードしたり、ファイルダウンロードが失敗した際のリジュームを行うことができます。