1. はじめに
NEQTOでスクリプトを使用したアプリケーションを作成する際、コードを書く、バージョンを管理する、スクリプトをデバイスにロードする、といった作業が発生します。これらの作業は、NEQTO Console(以下、Console)を使用するとすべてブラウザー上で完結することができます。
しかし、「コードを書く時は、使い慣れた自分のエディタで書きたい」「gitでも管理したい」と考え、「でもローカルで開発したコードを一々Consoleのスクリプト欄にコピー&ペーストするのは面倒…」とお悩みの方もいらっしゃるのではないでしょうか。
そこで今回は、NEQTO APIを用いて、コマンドラインからスクリプトの操作を実行するためのコードをご紹介します。
2. NEQTO APIについて
Consoleで扱っているAPIはNEQTO APIとして公開しています。
NEQTO APIは現在以下の4つがあります。
- 認証API
- グローバルAPI
- APリージョンAPI
- NAリージョンAPI
認証API は、NEQTO APIの使用に必要な認証情報を取得するために利用、グローバルAPIは、デバイス、ライセンス、アカウントの管理に利用されます。
リージョンAPIはそれ以外の機能に利用され、スクリプトやノードの管理などが含まれています。物理デバイスに最も近いリージョンが推奨されていますので、 今回はAPリージョンAPI (以下API) を利用します。
詳しくはこちらのドキュメントをご覧ください。
3. 完成したPythonスクリプトのご紹介
はじめに、完成したPythonスクリプトをご紹介します。コマンドラインから実行名を指定すると、対象のAPIが実行されます。
これによって、コマンドラインでスクリプトの実装からアップデート、デバイスへのロードまでを完結することができます。言語はPythonで書きましたが、他の言語でも問題ありません。
% python app.py -h
usage: app.py [-h] {list,read,code-read,upload,download,update,history,revert,node-reload} ...
positional arguments:
{list,read,code-read,upload,download,update,history,revert,node-reload}
sub-command help
list スクリプトのリスト
read スクリプト情報を取得
code-read スクリプトコードを取得
upload スクリプト(file)をアップロード
download スクリプトのダウンロード
update スクリプトのアップデート
history スクリプトのバージョン履歴
revert スクリプトのバージョンの切り替え
node-reload ノードのスクリプトの再ロードコマンドを実行
optional arguments:
-h, --help show this help message and exit
試しに「upload」をアップロードしたいファイルを指定して実行しました。APIのレスポンスのステータスコード(status_code)、ヘッダー(header)、ボディ(text)が出力されるようにしています。
% python app.py upload test.js
status_code 204
header {'Date': 'Wed, 01 Jun 2022 08:51:13 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'POST, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
次の章では、このPythonスクリプトの実装方法についてご紹介していきます。
4. 実装方法
実装は、ログイン方法、スクリプトに関するAPI、コマンドラインインターフェースの3部構成に分けてご紹介します。
言語
- Python3.9
- サードパーティライブラリ
- Requests
ログイン方法
リージョンAPIを使用するためには認証情報が必要となります。認証APIから取得したログイン情報を用いてリージョンAPIにログインします。ドキュメントの情報に従ってログイン関数を以下のように実装します。
import requests
session = requests.Session()
def login():
url = "https://auth.neqto.com/account/api-token-auth"
payload = {
"company_code": COMPANY_CODE,
"email": EMAIL,
"password": PASSWORD
}
headers = {
'content-type': "application/json"
}
response = session.request("POST", url, json=payload, headers=headers)
j_res = response.json()
session.cookies.set("auth_token", j_res["token"])
payload
のログイン情報は各自でセットが必要です。
session.cookies
を使用していますが、他のAPIを使用するときにAuthorizationトークンが必要となるため、requestsライブラリのsession機能を使用しています。
他のAPIでは以下のように使用します。
response = session.request("GET", url, headers=headers)
スクリプトに関するAPI
では、本題の実装に入りましょう。特に難しいことはなく、必要なAPIを関数化していくだけです。APIの仕様はAPIドキュメントに記載の通りです。
今回はスクリプトに関するAPIのみをコマンド化するため、必要な情報は予め取得しておく必要があります。これは例えば、group_idやnode_id、script_idなどです。取得方法としては、以下の方法が挙げられます。
- 対象のNEQTO APIから取得する
- /groups
- /groups/{groups_group_id}/nodes
- /groups/{groups_group_id}/scripts
- ...etc
- Consoleを開き、ブラウザーの「Delveloper Tools」の「Network」から対象APIを探し、「Response」の中からidを探す
- Consoleを開き、図1、図2のように対象のページのURLからidを取得する
基本的にはスクリプトコードの「upload」、スクリプトの情報(名前、環境変数、ライブラリなど)の「update」、ノードのスクリプトの再ロードコマンドを実行する「node-reload」ができるとローカルのみで開発してそれをデバイスで試す事ができるようになるため、その部分のみご説明します。
他のAPIについても同様に実装できますので、このブログの最後に載せる全体のコードをご覧ください。
upload
スクリプトコードをアップロードすることができるコマンドです。ローカルで開発したコードを、NEQTOのスクリプトに反映させることができます。
from urllib.parse import urljoin
import requests
base_url = "https://asia-pacific-1.neqto.com/"
group_id = GROUP_ID
script_id = SCRIPT_ID
@api_response
def script_upload(filename):
with open(filename, "rb") as uploaded_file:
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/upload")
response = session.request("POST", url, files={"file": uploaded_file})
return response
group_id、script_idは各自で設定が必要です。fileのアップロードをするときは、requestのfilesパラメータを使用します。バイナリファイルを開き、files={"file": uploaded_file}
として指定します。filenameはパスを含めて指定する必要があります。filenameが見つからない場合はエラーが起きますので、ご注意ください。
@api_response
については後ほどご説明します。
update
NEQTOのスクリプトの設定を更新することができます。これは、メタデータ、ライブラリ、環境変数などが該当します。
import requests
base_url = "https://asia-pacific-1.neqto.com/"
group_id = GROUP_ID
script_id = SCRIPT_ID
@api_response
def script_partical_update(payload):
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}")
headers = {
'content-type': "application/json"
}
# payload = {
# # "name": "name",
# # "note": "note",
# "lib": ["TYPE/NAME/VERSION"],
# # "env": [
# # {
# # "key": "key",
# # "value": "value",
# # "display": True
# # }
# # ]
# }
response = session.request("PATCH", url, json=payload, headers=headers)
return response
関数の引数のpayloadは、dict型を渡します。session.request
でjson=payload
と指定することで、JSONとしてリクエストボディに渡すことができます。
payloadは執筆時点でのAPIのドキュメントを参考にしています。lib
は、Library usage requirementsのType, Name, Versionを"/"区切りで指定します。PATCHメソッドなので、変更したいパラメータだけを渡します。
node-reload
「upload」, 「update」で更新したものをデバイスに反映させるために、ノードの「スクリプトの再ロード」コマンドを実行することができます。
from urllib.parse import urljoin
import requests
base_url = "https://asia-pacific-1.neqto.com/"
group_id = GROUP_ID
node_id = NODE_ID
@api_response
def node_reload():
url = urljoin(base_url, f"groups/{group_id}/nodes/{node_id}/command:reload")
response = session.request("POST", url)
return response
API Responseの確認
次に、APIの実行状況(レスポンス)を出力して確認します。全ての関数に同じprint文を記述するのは面倒なので、ここではデコレータを使用します。上記の各コードの関数の上にある@api_responseの実装は、以下の通りです。
def api_response(func):
@functools.wraps(func)
def innner(*args, **kwargs):
response = func(*args, **kwargs)
print("status_code", response.status_code)
print("header", response.headers)
print("text", response.text)
return innner
各関数ではsession.request()
のresponse
をそのまま返すようにして、api_response
ではレスポンスのステータスコード、ヘッダー、テキストを出力するようにしています。textとしたのは、レスポンスがJSON形式の場合にも、500エラーなどでHTML形式の場合と同様に文字列形式で出力できるようにするためです。
例えば、script_partical_update関数を実行すると、以下のように出力されます。この時、payloadは以下にしています。
payload = {"note": "test update"}
status_code 200
header {'Date': 'Thu, 02 Jun 2022 06:13:33 GMT', 'Content-Type': 'application/json', 'Content-Length': '191', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text {"id":"<id>","name":"script-auto","note":"test update","updated_at":"2022-06-02T06:13:33.138683Z","created_at":"2022-06-01T07:19:00.460634Z","lib":[],"env":[]}
APIをリクエストする実装の説明については以上です。
ただし、このままだとAPIのリクエストするたびに実行関数を変更するためにコードを書き換える手間が生じます。実行APIをコマンドラインから選択できれば便利になるため、次の章ではコマンドラインインターフェースの原型を作成します。
コマンドラインインターフェース
本章では、コマンドラインからAPIのリクエストの指示ができるように実装します。自作コマンドツール化までできればかっこいいのですが趣旨から外れるため、今回はPythonスクリプトを実行する際に引数を渡すことで、関数を指定できるようにするところまでをご説明します。
まず、ディレクトリ構造は以下のようにしました。
/
|__app.py (メイン)
|__nq/
|__api.py (APIの関数)
|__command_line_args.py (コマンドライン引数)
実装の説明に入りますが、最終的に以下のような物を目指します。
% python app.py upload test.js
status_code 204
header {'Date': 'Wed, 01 Jun 2022 08:51:13 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'POST, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
また、コマンドライン引数を受け取るために、Python標準ライブラリのargparseを使用しています。
python app.py <command> <arguments>
上記のようにcommandを使い分けできるようにするために、Sub-commandsを使用します。パーサーはコマンドラインを解析して情報を保持しますが、パーサーにサブパーサーを登録することで、サブパーサーごとに異なる引数を設定することができます。
例えばpython app.py upload test.js
を実行した場合にscript_upload
関数を実行するためには、以下のように設定します。
command_line_args.py
import argparse
import nq.api as api
def init_parser():
parser = argparse.ArgumentParser()
# parserにsub parsersの登録
subparsers = parser.add_subparsers(dest="sub_name", help="sub-command help")
# sub parserにuploadを登録
parser_upload = subparsers.add_parser('upload', help="スクリプト(file)をアップロード")
# uploadの引数を登録
parser_upload.add_argument('filename', help="アップロードするファイル名")
# uploadを指定したときに実行する関数を指定
parser_upload.set_defaults(func=api.script_upload)
# 引数を受け取る
args = parser.parse_args()
# コマンド指定なしで実行されたらhelpを表示する
if not hasattr(args, "func"):
parser.print_help()
return args
python app.py upload test.js
の時であれば、以下の引数を受け取ります。
args = Namespace(sub_name='upload', filename='test.js', func=<function script_upload at 0x1076c9f70>)
app.pyでは、以下のように呼び出します。コマンドが指定された時(funcが存在する時)のみAPIのリクエストを行うようにします。基本的にはargs.func()
を実行すると、subparser.set_defaults(func=func)
で指定した関数が呼び出されますが、その関数が引数を受け取りたい場合は、場合分けが必要になります。
app.py
from nq.command_line_args import init_parser
import nq.api as api
if __name__ == '__main__':
args = init_parser()
if hasattr(args, "func"):
api.login()
if(args.sub_name == "upload"):
args.func(args.filename)
else:
args.func()
これで「upload」に関してはコマンドラインから指示できるようになりました。
他の場合も同様に設定できるので省略しますが、「update」の時だけ注意点がありますので、ご説明します。リクエストボディをコマンドラインから受け取るように作成するときは、文字列を辞書に変換する必要があります。argparseではtypeで型の指定が可能ですが、dict型を指定してもうまく動作しませんでした。そこで、typeには自作関数を指定できため文字列で受け取り、dictに変換する関数を指定しました。文字列を辞書に変換するときは標準モジュールのastを使います。
command_line_args.py
import ast
def str2dict(payload):
return ast.literal_eval(payload)
init_parser
parser_update = subparsers.add_parser('update', help="スクリプトのアップデート")
parser_update.add_argument('payload', type=str2dict, help="変更するパラメータを辞書形式で指定")
parser_update.set_defaults(func=api.script_partical_update)
今回はpayloadをまとめてコマンドラインから受け取るように作成しましたが、厳格にしたい場合はオプション引数でキーごとに受け取るように作成しても良いでしょう。
5. 実行結果
今回作成したものを実行してみます。全体のコードはブログの最後に載せていますのでそちらをご覧ください。
できること一覧の表示
% python app.py -h
usage: app.py [-h] {list,read,code-read,upload,download,update,history,revert,node-reload} ...
positional arguments:
{list,read,code-read,upload,download,update,history,revert,node-reload}
sub-command help
list スクリプトのリスト
read スクリプト情報を取得
code-read スクリプトコードを取得
upload スクリプト(file)をアップロード
download スクリプトのダウンロード
update スクリプトのアップデート
history スクリプトのバージョン履歴
revert スクリプトのバージョンの切り替え
node-reload ノードのスクリプトの再ロードコマンドを実行
optional arguments:
-h, --help show this help message and exit
スクリプトのリスト
グループに属するスクリプト一覧を取得します。
% python app.py list
script name list ['script-auto']
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:05:07 GMT', 'Content-Type': 'application/json', 'Content-Length': '1611', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, POST, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text {"count":1,"next":null,"previous":null,"results":[{"id":"<script_id>","name":"script-auto","note":"","updated_at":"2022-06-02T07:40:54.065987Z","created_at":"2022-06-01T07:19:00.460634Z","lib":[],"env":[]}]}
スクリプトのアップデート
あるスクリプトIDの情報の一部をアップデートします。
% python app.py update '{"name": "script-auto2", "note": "test-2", "lib": ["I2C/HTS221_V2/latest"], "env": [{"key": "test", "value": "test-2", "display": True}]}'
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:10:37 GMT', 'Content-Type': 'application/json', 'Content-Length': '255', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text {"id":"<script_id>","name":"script-auto2","note":"test-2","updated_at":"2022-06-02T09:10:37.441286Z","created_at":"2022-06-01T07:19:00.460634Z","lib":["I2C/HTS221_V2/latest"],"env":[{"key":"test","value":"test-2","display":true}]}
スクリプト(file)をアップロード
あるスクリプトIDにスクリプトコードをアップロードします。
% python app.py upload test.js
status_code 204
header {'Date': 'Thu, 02 Jun 2022 09:06:58 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'POST, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
スクリプトのバージョン履歴
あるスクリプトIDのスクリプトコードのバージョン履歴を取得します。
% python app.py history
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:13:17 GMT', 'Content-Type': 'application/json', 'Content-Length': '775', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text [{"version_id":"<version_id>","updated_at":"2022-06-02T09:06:58Z"},{"version_id":"<version_id>","updated_at":"2022-06-02T07:20:46Z"}]
スクリプトのバージョンの切り替え
あるスクリプトIDのスクリプトコードのバージョンを指定して切り替えます。
% python app.py revert "<version_id>"
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:14:54 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'POST, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
スクリプトのダウンロード
あるスクリプトIDのスクリプトコードをダウンロード時のファイル名を指定してダウンロードします。APIはバージョンを指定できる仕様ですが今回の実装では現在のスクリプトのみ対応しています。
% python app.py download download.js
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:16:45 GMT', 'Content-Type': 'application/javascript', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Content-Disposition': 'attachment; filename=run.js', 'Allow': 'GET, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
スクリプトコードを取得
あるスクリプトIDのスクリプトコードを取得します。APIはバージョンを指定できる仕様ですが今回の実装では現在のスクリプトコードのみ対応しています。
% python app.py code-read
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:13:46 GMT', 'Content-Type': 'application/json', 'Content-Length': '917', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, POST, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text {"updated_at":"2022-06-02T09:06:58Z","etag":"\"<etag>\"","body":"console.log(\"test\")"}
スクリプト情報を取得
あるスクリプトIDのスクリプト情報を取得します。
% python app.py read
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:12:51 GMT', 'Content-Type': 'application/json', 'Content-Length': '255', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text {"id":"<script_id>","name":"script-auto2","note":"test-2","updated_at":"2022-06-02T09:12:01.074295Z","created_at":"2022-06-01T07:19:00.460634Z","lib":["I2C/HTS221_V2/latest"],"env":[{"key":"test","value":"test-2","display":true}]}
ノードの「スクリプトの再ロード」コマンドを実行
あるスクリプトIDが紐づいたノードに対して、「スクリプトの再ロード」を行います。
% python app.py node-reload
status_code 200
header {'Date': 'Thu, 02 Jun 2022 09:17:17 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Server': 'nginx/1.16.1', 'Allow': 'POST, OPTIONS', 'X-Frame-Options': 'SAMEORIGIN', 'Vary': 'Accept-Language, Origin', 'Content-Language': 'en'}
text
6. 全体のコード
最後に作成したコードの全体を載せます。
app.py
from nq.command_line_args import init_parser
import nq.api as api
if __name__ == '__main__':
args = init_parser()
if hasattr(args, "func"):
api.login()
if(args.sub_name == "upload"):
args.func(args.filename)
elif(args.sub_name == "download"):
args.func(args.filename)
elif(args.sub_name == "update"):
args.func(args.payload)
elif(args.sub_name == "revert"):
args.func(args.version_id)
else:
args.func()
command_line_args.py
import argparse
import ast
import nq.api as api
def str2dict(payload):
return ast.literal_eval(payload)
def init_parser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="sub_name", help="sub-command help")
parser_list = subparsers.add_parser('list', help="スクリプトのリスト")
parser_list.set_defaults(func=api.script_list)
parser_read = subparsers.add_parser('read', help="スクリプト情報を取得")
parser_read.set_defaults(func=api.script_read)
parser_code_read = subparsers.add_parser('code-read', help="スクリプトコードを取得")
parser_code_read.set_defaults(func=api.script_code_read)
parser_upload = subparsers.add_parser('upload', help="スクリプト(file)をアップロード")
parser_upload.add_argument('filename', help="アップロードするファイル名")
parser_upload.set_defaults(func=api.script_upload)
parser_download = subparsers.add_parser('download', help="スクリプトのダウンロード")
parser_download.add_argument('filename', help="ダウンロード時のファイル名")
parser_download.set_defaults(func=api.script_download)
# payloadに渡すパラメータを全て定義しても良い。
parser_update = subparsers.add_parser('update', help="スクリプトのアップデート")
parser_update.add_argument('payload', type=str2dict, help="変更するパラメータを辞書形式で指定")
parser_update.set_defaults(func=api.script_partical_update)
parser_history = subparsers.add_parser('history', help="スクリプトのバージョン履歴")
parser_history.set_defaults(func=api.script_history)
parser_revert = subparsers.add_parser('revert', help="スクリプトのバージョンの切り替え")
parser_revert.add_argument('version_id', type=str, help="version_id")
parser_revert.set_defaults(func=api.script_revert)
parser_reload = subparsers.add_parser('node-reload', help="ノードのスクリプトの再ロードコマンドを実行")
parser_reload.set_defaults(func=api.node_reload)
args = parser.parse_args()
if not hasattr(args, "func"):
parser.print_help()
return args
api.py
from urllib.parse import urljoin
import functools
import requests
base_url = "https://asia-pacific-1.neqto.com/"
group_id = "GROUP_ID"
node_id = "NODE_ID"
script_id = "SCRIPT_ID"
company_code = "COMPANY_CODE"
email = "EMAIL"
password = "PASSWORD"
session = requests.Session()
def login():
url = "https://auth.neqto.com/account/api-token-auth"
payload = {
"company_code": company_code,
"email": email,
"password": password
}
headers = {
'content-type': "application/json"
}
response = session.request("POST", url, json=payload, headers=headers)
j_res = response.json()
session.cookies.set("auth_token", j_res["token"])
def api_response(func):
@functools.wraps(func)
def innner(*args, **kwargs):
response = func(*args, **kwargs)
print("status_code", response.status_code)
print("header", response.headers)
print("text", response.text)
return innner
@api_response
def script_list():
url = urljoin(base_url, f"groups/{group_id}/scripts")
headers = {
'content-type': "application/json"
}
response = session.request("GET", url, headers=headers)
try:
j_res = response.json()
name = [script.get("name", "") for script in j_res.get("results", [])]
print("script name list", name)
except Exception:
pass
return response
@api_response
def script_create():
url = urljoin(base_url, f"groups/{group_id}/scripts")
headers = {
'content-type': "application/json"
}
payload = {
"name": "blog",
"note": "blogで作成",
"lib": ["I2C/HTS221/latest"],
"env": [
{
"key": "GROUP_ID",
"value": "123456789",
"display": True
}
]
}
response = session.request("POST", url, json=payload, headers=headers)
return response
@api_response
def script_read():
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}")
headers = {
'content-type': "application/json"
}
response = session.request("GET", url, headers=headers)
return response
@api_response
def script_partical_update(payload):
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}")
headers = {
'content-type': "application/json"
}
# payload = {
# # "name": "name",
# # "note": "note",
# "lib": ["TYPE/NAME/VERSION"],
# # "env": [
# # {
# # "key": "key",
# # "value": "value",
# # "display": True
# # }
# # ]
# }
response = session.request("PATCH", url, json=payload, headers=headers)
return response
@api_response
def script_code_read():
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/code")
headers = {
'content-type': "application/json"
}
response = session.request("GET", url, headers=headers)
return response
@api_response
def script_code_create():
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/code")
headers = {
'content-type': "application/json"
}
payload = {
"body": "console.log(\"test2\")"
}
response = session.request("POST", url, json=payload, headers=headers)
return response
@api_response
def script_download(filename):
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/download")
headers = {
'content-type': "application/json"
}
response = session.request("GET", url, headers=headers)
with open(filename, mode='wb') as f: # wb でバイト型を書き込める
f.write(response.content)
return response
@api_response
def script_history():
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/history")
headers = {
'content-type': "application/json"
}
response = session.request("GET", url, headers=headers)
return response
@api_response
def script_revert(version_id):
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/revert")
headers = {
'content-type': "application/json"
}
payload = {
"version_id": version_id
}
response = session.request("POST", url, json=payload, headers=headers)
return response
@api_response
def script_upload(filename):
with open(filename, "rb") as uploaded_file:
url = urljoin(base_url, f"groups/{group_id}/scripts/{script_id}/upload")
response = session.request("POST", url, files={"file": uploaded_file})
return response
@api_response
def node_reload():
url = urljoin(base_url, f"groups/{group_id}/nodes/{node_id}/command:reload")
response = session.request("POST", url)
return response
7. まとめ
スクリプトの更新からノードにスクリプトを再ロードさせるまでの手順にフォーカスして、NEQTOリージョンAPIの使い道の一つをご紹介しました。
Pythonスクリプト実行時に引数を渡すだけで簡単にスクリプトに関する操作ができるようになったため、開発が捗ると思います。今回は、グループやノード、スクリプトのIDは固定としていますが、これらも指定できるようにするなど、拡張していくと自由度が上がるでしょう。
これを機に、NEQTO APIの活用法を試してみていただければと思います。