Edited at

Rescale API with python Hands-on


Rescale API with PythonによるJobの投入


[STEP0] pre-conditions


rescale で実行する "hellow world" の作成

シェルに以下のコマンドを貼り付けてください。sample.sh が作成されます。


command

uploadFile='sample.sh'

cat << EOF > ${uploadFile}
#!/bin/sh
date
pwd
ls -l
echo "Hello World"
sleep 300
EOF

ファイルができたことを確認します。


command

ls -l



API Key と プラットフォームの設定



  • apikey にはブラウザー上で作成したRescaleAPIをコピーしはりつけます


  • platform は、 USのプラットフォームの場合 https://platform.rescale.com/ 日本の場合 https://platform.rescale.jp/ を入れます

以下 python での操作となります。


command

python


apikey=<'作成したAPI KEY'>

platform="https://platform.rescale.com/"



[STEP1] ファイルのアップロード

もし python を起動していなければ、シェルからpythonを起動してください


command

python



APIを使用したファイルのアップロード 

import requests

my_token = 'Token' + ' ' + apikey
url = platform + "api/v3/files/contents/"

print(my_token)
print(url)

res_contents = requests.post(
url,
headers={'Authorization': my_token},
files={'file': open('./sample.sh', 'rb')}
)
print(res_contents)

<Response [201]> が 返ってきていれば上手くアップロードされています。


返り値の確認 (JSON)

次に返り値を確認します。"201" が返ってきていれば、<変数>.text に返り値も格納されています。


python

import json

res_contents_dict = json.loads(res_contents.text)
json = json.dumps(res_contents_dict, indent=2, separators=(',', ': '))
print(json)

結果例を示します。

下記のような結果が返ってきていることを確認してください。


response

{

"encodedEncryptionKey": "mFau50Xqf0hiakfjYDP+Vw9BheVwyf57E9AJYQwmjig=",
"dateUploaded": "2017-09-10T09:00:30.144586Z",
"viewInBrowser": true,
"decryptedSize": 54,
"downloadUrl": "https://platform.rescale.jp/api/v3/files/BcTKRc/contents/",
"relativePath": "sample.sh",
"pathParts": {
"container": "jpprod-rescale-platform",
"path": "user/user_QbQWc/sample-36bb7981-22fc-4b81-935e-0b95c3c670ca.sh"
},
"isUploaded": true,
"storage": {
"connectionSettings": {
"region": "ap-northeast-1"
},
"encryptionType": "default",
"id": "pCTMk",
"storageType": "S3Storage"
},
"id": "BcTKRc",
"md5": "d6a0dc9d44d56fd476d62e257eeef2f1",
"owner": "daisuke@rescale.com",
"path": "user/user_QbQWc/sample-36bb7981-22fc-4b81-935e-0b95c3c670ca.sh",
"name": "sample.sh",
"typeId": 1,
"isDeleted": false
}


ファイルIDの取得

上記のJSONから "id" を抜き出します。


python

file_id = res_contents_dict["id"]

print(file_id)

"BcTKRc" など ランダムな文字列が返ってきていれば良いです。



[STEP2] ジョブの作成

もし python を起動していなければ、シェルからpythonを起動してください


command

python



ジョブを定義するJSONの作成

ブラウザを操作してジョブ投入条件を設定するかわりにAPIでは、JSONファイルにその条件を記述します。


python

my_job_json = '''

{
"name": "hello_world!!",
"jobanalyses": [
{
"useRescaleLicense": false,
"command": "./sample.sh",
"analysis": {
"code": "user_included_platformmpi",
"version": "platformmpi-9.1.4"
},
"hardware": {
"coresPerSlot": 2,
"slots": 1,
"coreType": {
"code": "hpc-3"
}
}
}
],
"isLowPriority": "true"
}
'''



FileIdの挿入

上記ではファイルIDの情報が不足しているため、先ほどアップロードしたファイルIDをここで挿入してやります。


python

import json

my_job_dict = json.loads(my_job_json)
my_job_dict['jobanalyses'][0]['inputFiles'] = [0]
my_job_dict['jobanalyses'][0]['inputFiles'][0] = {'id': file_id}

json = json.dumps(my_job_dict, indent=2, separators=(',', ': '))
print(json)


下記のようなJSONファイルができあがっていればOKです。


response

{

"name": "hello_world!!",
"jobanalyses": [
{
"useRescaleLicense": false,
"inputFiles": [
{
"id": "BcTKRc"
}
],
"analysis": {
"code": "user_included_platformmpi",
"version": "platformmpi-9.1.4"
},
"command": "./sample.sh",
"hardware": {
"coreType": {
"code": "hpc-3"
},
"coresPerSlot": 2,
"slots": 1
}
}
],
"isLowPriority": "true"
}


ジョブの作成

このAPIはジョブ条件を保存するだけであって、ジョブは実行されません。つまり課金はされません。

(ストレージの容量、データ転送等は除く)


python

import requests

my_token = 'Token' + ' ' + apikey
url = platform + "api/v3/jobs/"

print("Token: ", my_token)
print("url: ", url)
print("expected value: <class 'dict'>): ", type(my_job_dict))

res_jobs = requests.post(
url,
headers = {'Authorization': my_token},
json = my_job_dict
)

print(res_jobs)



返り値の確認 (JSON)


python

import json

res_jobs_dict = json.loads(res_jobs.text)
myjson = json.dumps(res_jobs_dict , indent=2, separators=(',', ': '))
print(myjson)


下記のようなJSONが返ってきていればOKです。


response

{

"isTemplateDryRun": false,
"cidrRule": "0.0.0.0/0",
"jobvariables": [],
"paramFile": null,
"projectId": null,
"monteCarloIterations": null,
"caseFile": null,
"archiveFilters": [],
"remoteVizConfig": null,
"isLowPriority": true,
"sshPort": 22,
"id": "wAXvm",
"cluster": null,
"expectedRuns": null,
"owner": "XXXXXX@XXXX.com",
"name": "hello_world!!",
"includeNominalRun": false,
"resourceFilters": [],
"jobanalyses": [
{
"useRescaleLicense": false,
"flags": {},
"preProcessScript": null,
"onDemandLicenseSeller": null,
"inputFiles": [
{
"decompress": true,
"dateUploaded": "2017-09-10T09:00:30.144586Z",
"viewInBrowser": true,
"decryptedSize": 54,
"downloadUrl": "https://platform.rescale.jp/api/v3/files/BcTKRc/contents/",
"encodedEncryptionKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"relativePath": "sample.sh",
"isUploaded": true,
"storage": {
"connectionSettings": {
"region": "ap-northeast-1"
},
"encryptionType": "default",
"id": "pCTMk",
"storageType": "S3Storage"
},
"id": "BcTKRc",
"md5": "d6a0dc9d44d56fd476d62e257eeef2f1",
"owner": "daisuke@rescale.com",
"path": "user/user_QbQWc/sample-36bb7981-22fc-4b81-935e-0b95c3c670ca.sh",
"name": "sample.sh",
"typeId": 1,
"pathParts": {
"container": "jpprod-rescale-platform",
"path": "user/user_QbQWc/sample-36bb7981-22fc-4b81-935e-0b95c3c670ca.sh"
},
"isDeleted": false
}
],
"command": "./sample.sh",
"envVars": {},
"preProcessScriptCommand": "",
"analysis": {
"name": "Bring Your Own MPI Software",
"versionName": "Platform MPI 9.1.4",
"code": "user_included_mpi",
"version": "platformmpi-9.1.4"
},
"templateTasks": [],
"hardware": {
"coreType": {
"compute": "7.33",
"displayOrder": 1,
"features": [
"ssh",
"cluster_status"
],
"storageIo": "2 GB/s read, 1GB/s write",
"defaultWalltime": null,
"storage": 36,
"mustBeRequested": false,
"color": "#ff4242",
"name": "Onyx",
"remoteVizAllowed": true,
"isDefault": true,
"code": "hpc-3",
"acronym": "O",
"baseClockSpeed": "2.9",
"io": "10 Gb/s",
"processorInfo": "Intel Xeon E5-2666 v3 (Haswell)",
"hasSsd": true,
"description": "HPC++",
"cores": [
1,
2,
4,
8,
18
],
"walltimeRequired": false,
"memory": 3300,
"gpuCounts": [
0,
0,
0,
0,
0
],
"isPrimary": true
},
"coresPerSlot": 2,
"isReusable": false,
"walltime": 750,
"coreSummary": {
"gpusPerNode": 0,
"storagePerNode": 80000,
"numberOfNodes": 1.0,
"memoryPerNode": 7500
},
"type": "compute",
"slots": 1
},
"postProcessScript": null,
"postProcessScriptCommand": ""
}
],
"publicKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}


JOB-ID の取得

上記のJSONから "id" を抜き出します。


python

job_id = res_jobs_dict["id"]

print(job_id)

"wAXvm" のようなランダムな文字列が返ってきていればOKです。


Browserで内容をもう一度確認

下記コマンドを実行して、表示されたURLをブラウザに貼り付けてください。


python

url = platform + "jobs/" + job_id

print(url)



[STEP3] ジョブの実行

もし python を起動していなければ、シェルからpythonを起動してください


command

python



Submit your JOB

このAPIにより、始めてジョブが実行されます。つまり課金が始まります


python

import requests

my_token = 'Token' + ' ' + apikey
url = platform + "api/v3/jobs/" + job_id + "/submit/"

print("Token: ", my_token)
print("url: ", url)

res_submit = requests.post(
url,
headers = {'Authorization': my_token}
)

print(res_submit)


"Response [200]" が返ってきていればOKです。JSONによる返り値はありません



[STEP4] ジョブのモニター

もし python を起動していなければ、シェルからpythonを起動してください


command

python



ジョブの状態確認


python

import requests

my_token = 'Token' + ' ' + apikey
url = platform + "api/v3/jobs/" + job_id + "/statuses/"

print("Token: ", my_token)
print("url: ", url)

res_monitor = requests.get(
url,
headers = {'Authorization': my_token}
)

print(res_monitor)



返り値の確認 (JSON)


python

import json

res_monitor_dict = json.loads(res_monitor.text)
myjson = json.dumps(res_monitor_dict , indent=2, separators=(',', ': '))
print(myjson)


下記のように、"statusReason" に "Completed successfully" があれば、ジョブが完了しています。


response

{

"results": [
{
"statusDate": "2017-09-10T09:22:26.036547Z",
"statusReason": "Completed successfully",
"id": "YZpnm",
"jobId": "wAXvm",
"status": "Completed"
},
{
"statusDate": "2017-09-10T09:17:16.003000Z",
"statusReason": null,
"id": "KxwAa",
"jobId": "wAXvm",
"status": "Executing"
},
{
"statusDate": "2017-09-10T09:13:51.274000Z",
"statusReason": null,
"id": "ikqnm",
"jobId": "wAXvm",
"status": "Validated"
},
{
"statusDate": "2017-09-10T09:13:50.876000Z",
"statusReason": null,
"id": "UHwAa",
"jobId": "wAXvm",
"status": "Started"
},
{
"statusDate": "2017-09-10T09:13:47.069093Z",
"statusReason": null,
"id": "WZpnm",
"jobId": "wAXvm",
"status": "Queued"
},
{
"statusDate": "2017-09-10T09:13:40.149523Z",
"statusReason": null,
"id": "HxwAa",
"jobId": "wAXvm",
"status": "Pending"
}
],
"count": 6,
"previous": null,
"next": null
}