1. daikumatan

    Posted

    daikumatan
Changes in title
+Rescale API with python Hands-on
Changes in tags
Changes in body
Source | HTML | Preview

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 に返り値も格納されています。

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" を抜き出します。

file_id = res_contents_dict["id"]
print(file_id)

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


[STEP2] ジョブの作成

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

command
python

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

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

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

FileIdの挿入

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

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_mpi",
        "version": "platformmpi-9.1.4"
      },
      "command": "./sample.sh",
      "hardware": {
        "coreType": {
          "code": "hpc-3"
        },
        "coresPerSlot": 2,
        "slots": 1
      }
    }
  ],
  "isLowPriority": "true"
}

ジョブの作成

このAPIはジョブ条件を保存するだけであって、ジョブは実行されません。つまり課金はされません。
(ストレージの容量、データ転送等は除く)

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)

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" を抜き出します。

job_id = res_jobs_dict["id"]
print(job_id)

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

Browserで内容をもう一度確認

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

url = platform + "jobs/" + job_id
print(url)

[STEP3] ジョブの実行

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

command
python

Submit your JOB

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

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

ジョブの状態確認

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)

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
}