はじめに
JupyterNotebookはブラウザで操作できるので、普通はRESTで操作できる必要はないです。
個人用の備忘録なのですが、こんなのが役に立つのは、Jupyterを使ったシステムを作っているか、
それらの保守等で、自動構築やテスト自動化などが必要な人たちですね。
なんて、マニアックなんだ。
前提
まず、Jupyter Notebook の バージョンは 5.7.2 となる。
色々試してみたが、どうにもパスワード認証がうまくいかなくて、token で動かすとうまくいった。
トークンを取ってくる
token とは、Security in the Jupyter notebook serverのページに登場する token=
の後に続く文字列の事です。
[I 11:59:16.597 NotebookApp] The Jupyter Notebook is running at:
http://localhost:8888/?token=c8de56fa4deed24899803e93c227592aef6538f93025fe01
ファイルの一覧
token指定の所が肝。
この指定ができれば、あとはAPIの流儀に従ってパラメータやパス指定するだけ、とても簡単です。
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import json
import requests
def main():
"""main."""
parser = argparse.ArgumentParser()
parser.add_argument('base_url', help='base_url')
parser.add_argument('token', help='token')
parser.add_argument('relpath', nargs='?', default='/', help='relative path')
args = parser.parse_args()
headers = {
'Authorization': 'token %s' % args.token,
'Content-Type': 'application/json'
}
resp = requests.get(
'{}/api/contents{}'.format(args.base_url, args.relpath),
headers=headers
)
print("{}".format(json.dumps(resp.json(), indent=4)))
if __name__ == '__main__':
main()
ちなみに、パスワードを使おうとして 'Authorization': 'Basic %' … みたくやったのですが、
403 地獄から逃れられず、レスポンスは json でなくて html のページに飛ばされた。
アップロード
- XSRF のエラーが出る場合は、requests でセションで cookie とか持ちまわるように小細工が必要。
- 画像とかを送りたいときは、 base64 で埋め込んでやれば良い
- URLの相対パス指定が肝でファイルやディレクトリがないと失敗する
そういう意味で、パラメータ側の name とか path の存在意義がいまいちわからず
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import json
import requests
def main():
"""main."""
parser = argparse.ArgumentParser()
parser.add_argument('base_url', help='token')
parser.add_argument('token', help='token')
parser.add_argument('relpath', help='relative path ... ex. /foo/bar.txt')
args = parser.parse_args()
api_url = '{}/api/contents{}'.format(args.base_url, args.relpath)
headers = {
'Authorization': 'token %s' % args.token,
'Content-Type': 'application/json'
}
req_body = {
'name': 'bar.txt',
'path': '.',
'type': 'file',
'format': 'text',
'content': 'foo'
}
resp = requests.put(
api_url,
json.dumps(req_body).encode("utf-8"),
headers=headers
)
if resp.headers.get('Content-Type').startswith('application/json'):
print("{}".format(json.dumps(resp.json(), indent=4)))
print("")
if __name__ == '__main__':
main()
参考
-
Security in the Jupyter notebook server — Jupyter Notebook 5.7.4
token の取り方とか。 - API
-
Jupyter Notebook Server API
The schema is here
と書かれているあたりをみれば何となく分かる。もし、自由に好きなパッケージをインストールできる状況下にあれば、 requests を使わなくても、Swagger (Open API)で生成してクライアントI/Fを配備しても良いですけどね。 - Contents API
-
Jupyter Notebook Server API
-
Cookie passing for Jupyter Notebook APIs #1431
バージョンや環境によっては、X-XSRF-Token
をいれないと弾かれることがある。クロスサイト リクエスト フォージェリ (CSRF/XSRF) の対策で、クロスサイトかどうかを判別するトークンをいれないといけないとか何とか。