Help us understand the problem. What is going on with this article?

Rescale API with python Hands-on

More than 1 year has passed since last update.

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
}
daikumatan
2002-2015: Fujixerox, Numerical simulation Engineer 2015-2016: NVIDIA Japan, BD Manager 2016-2020: Rescale Japan, Evangelist 2020-Present: XTREME-D, CTO
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away