REST API example

Describes how to deploy a Decision Optimization model, create and monitor jobs and get solutions using the Watson Machine Learning REST API. The REST API example uses curl, a command line tool and library for transferring data with URL syntax. You can download curl and read more about it at http://curl.haxx.se.

Before you begin

You must have an IBM Cloud account. See https://www.ibm.com/cloud/.

Log in to IBM Cloud. Add a Watson Machine Learning service and obtain the necessary API key, instance id, and URL from the Service Credentials tab. See Service Credentials from IBM Cloud.

About this task

The following steps show you how deploy a Decision Optimization model using the Watson Machine Learning REST API. For more information about the REST APIs relevant for Decision Optimization, see the following sections in the Swagger Documentation:

For Windows users, use ^ instead of \ for the multi-line separator throughout these code examples.

Procedure

  1. Generate an IAM token using your API key obtained from your provisioned Watson Machine Learning instance as follows. Your API key is available on the Service Credentials tab of the IBM Watson Machine Learning service instance:
    curl "https://iam.bluemix.net/identity/token" \
    -d "apikey=YOUR_API_KEY_HERE&grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: Basic Yng6Yng="
    
    Output example:
    {
       "access_token": "**************************************",
       "refresh_token": "**************************************",
       "token_type": "Bearer",
       "expires_in": 3600,
       "expiration": 1554117649,
       "scope": "ibm openid"
    }
  2. Select the runtime that you want to use, as shown in the following code example.
    Use the obtained access token prepended by the word bearer and the ML instance id in the Authorization header and in all API calls. (Make sure that you copy only the access token and not the refresh token.) Your ML instance id is available on the Service Credentials tab of the IBM Watson Machine Learning service instance:
    curl -ik -X GET \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type:application/json" \
    -H "cache-control:no-cache" \
    "https://us-south.ml.cloud.ibm.com/v4/runtimes?runtime.name=do_12.9"
    Output example:
    HTTP/1.1 200 OK
    Server: nginx
    Date: Mon, 15 Apr 2019 12:35:04 GMT
    Content-Type: application/json
    Content-Length: 471
    Connection: keep-alive
    X-Frame-Options: DENY
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1
    Pragma: no-cache
    Cache-Control: private, no-cache, no-store, must-revalidate
    x-global-transaction-id: 19f80ab09b4db07039c8e979731e194a
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    
    {
      "first": {
        "href": "/v4/runtimes?runtime.name=do_12.9"
      },
      "limit": 100,
      "resources": [{
        "metadata": {
          "guid": "do_12.9",
          "href": "/v4/runtimes/do_12.9",
          "created_at": "2019-04-04T09:59:46.236Z"
        },
        "entity": {
          "services": ["Training", "Scoring"],
          "name": "do_12.9",
          "description": "do_12.9",
          "system_defined": true,
          "platform": {
            "name": "do",
            "version": "12.9"
          }
        }
      }]
    }
    
  3. Upload a Decision Optimization model ready for deployment.
    Post a model providing information about its type and the runtime to be used.
    Model types can be:
    • do-opl_12.9 for OPL models
    • do-cplex_12.9 for CPLEX models
    • do-cpo_12.9 for CP models
    • do-docplex_12_9 for Python models

    The runtime is : do_12.9

    For example, this code example uploads a docplex model called Diet with a runtime:
    curl -X POST \https://us-south.ml.cloud.ibm.com/v4/models \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type:application/json" \
    -H "cache-control:no-cache" \
    -d "{\"name\":\"Diet\", \"description\":\"Diet\", \"type\":\"do-docplex_12.9\",\"runtime\": {\"href\":\"/v4/runtimes/do_12.9\"}}"
    A model-id is returned in guid field and a model-URL in the href field in the metadata. The model-URL contains the model-id. Output example:
    {
        "metadata": {
            "guid": "model-id",
            "href": "/v4/models/model-id?rev=********-****-****-****-********",
            "created_at": "2019-03-07T15:37:43.859Z"
        },
    
        "entity": {
            "name": "Diet",
            "description": "Diet",
            "content_status": {
                "state": "no_content"
            },
            "space": {
                "href": "/v4/spaces/117068bc-d891-4bd7-9ccb-a253b8ac1b5d"
            },
            "type": "do-docplex_12.9",
            "runtime": {
                "href": "/v4/runtimes/do_12.9"
            }
        }
    }
    
  4. Zip your model into a (tar,tar.gz,zip) file and upload it to be deployed by the Watson Machine Learning service.
    This code example uploads a model called diet.zip that contains a Python model and no master data:
    curl -X PUT \
    https://us-south.ml.cloud.ibm.com/v4/models/model-id-here/content \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "cache-control: no-cache"
    --data-binary diet.zip
  5. Deploy your model
    Create a reference to your model. Use the model-URL obtained when you created your model ready for deployment. For example:
    curl -X POST \
    https://us-south.ml.cloud.ibm.com/v4/deployments \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type: application/json" \
    -H "cache-control: no-cache"  \
    -d "{\"asset\": { \
         \"href\": \"/v4/models/model-URL-here\"  }, \
        \"batch\": {}}"
    The deployment-id is returned in guid field. Output example:
    {
        "metadata": {
            "parent": {
                "href": ""
            },
            "guid": "deployment-id",
            "modified_at": "",
            "created_at": "2019-03-07T15:41:25+0000",
            "href": "/v4/deployments/deployment-id"
        },
        "entity": {
            "environments": [],
            "name": "",
            "custom": {},
            "online": {},
            "description": "",
            "tags": [],
            "compute": {},
            "batch": {},
            "status": {
                "state": "ready",
                "message": "",
                "virtual_deployment_downloads": []
            },
            "asset": {
                "href": "/v4/models/model-URL"
            },
            "auto_redeploy": false
        }
    }
    
  6. Once deployed, you can monitor your model's deployment state. Use the deployment-id.
    For example:
    curl -X GET \
    https://us-south.ml.cloud.ibm.com/v4/deployments/deployment-id-here \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type: application/json" \
    -H "cache-control: no-cache"  \

    Output example:

    {
      "metadata": {
        "parent": {
          "href": ""
        },
        "guid": "deployment-id",
        "modified_at": "",
        "created_at": "2019-04-15T13:00:30+0000",
        "href": "/v4/deployments/deployment-id-here"
      },
      "entity": {
        "name": "",
        "custom": {
    
        },
        "description": "",
        "batch": {
    
        },
        "status": {
          "state": "ready",
          "message": ""
        },
        "asset": {
          "href": "/v4/models/model-URL"
        },
        "auto_redeploy": false
      }
  7. You can then Submit jobs for your deployed model defining the input data and the output (results of the optimization solve) and the log file.
    For example, the following shows the contents of a file called myjob.json. It contains (inline) input data, some solve parameters, and specifies that the output will be a .csv file.
    {
    		"deployment": {
    			"href":"/v4/deployments/deployment-id-here"
    		},
    		"decision_optimization" : {
    			"solve_parameters" : {
    				"oaas.logAttachmentName":"log.txt",
    				"oaas.logTailEnabled":"true"
    			},
    			"input_data": [
    				{
    					"id":"diet_food.csv",
    					"fields" : ["name","unit_cost","qmin","qmax"],
    					"values" : [
    						["Roasted Chicken", 0.84, 0, 10],
    						["Spaghetti W/ Sauce", 0.78, 0, 10],
    						["Tomato,Red,Ripe,Raw", 0.27, 0, 10],
    						["Apple,Raw,W/Skin", 0.24, 0, 10],
    						["Grapes", 0.32, 0, 10],
    						["Chocolate Chip Cookies", 0.03, 0, 10],
    						["Lowfat Milk", 0.23, 0, 10],
    						["Raisin Brn", 0.34, 0, 10],
    						["Hotdog", 0.31, 0, 10]
    					]
    				},
    				{
    					"id":"diet_food_nutrients.csv",
    					"fields" : ["Food","Calories","Calcium","Iron","Vit_A","Dietary_Fiber","Carbohydrates","Protein"],
    					"values" : [
    						["Spaghetti W/ Sauce", 358.2, 80.2, 2.3, 3055.2, 11.6, 58.3, 8.2],
    						["Roasted Chicken", 277.4, 21.9, 1.8, 77.4, 0, 0, 42.2],
    						["Tomato,Red,Ripe,Raw", 25.8, 6.2, 0.6, 766.3, 1.4, 5.7, 1],
    						["Apple,Raw,W/Skin", 81.4, 9.7, 0.2, 73.1, 3.7, 21, 0.3],
    						["Grapes", 15.1, 3.4, 0.1, 24, 0.2, 4.1, 0.2],
    						["Chocolate Chip Cookies", 78.1, 6.2, 0.4, 101.8, 0, 9.3, 0.9],
    						["Lowfat Milk", 121.2, 296.7, 0.1, 500.2, 0, 11.7, 8.1],
    						["Raisin Brn", 115.1, 12.9, 16.8, 1250.2, 4, 27.9, 4],
    						["Hotdog", 242.1, 23.5, 2.3, 0, 0, 18, 10.4	]
    					]
    				},
    				{
    					"id":"diet_nutrients.csv",
    					"fields" : ["name","qmin","qmax"],
    					"values" : [
    						["Calories", 2000, 2500],
    						["Calcium", 800, 1600],
    						["Iron", 10, 30],
    						["Vit_A", 5000, 50000],
    						["Dietary_Fiber", 25, 100],
    						["Carbohydrates", 0, 300],
    						["Protein", 50, 100]
    					]
    				}
    			],
    			"output_data": [
    				{
    					"id":".*\\.csv"
    				}
    			]
    	}
    }
    
    This code example posts a job that uses this file myjob.json.
    curl -X POST \
    https://us-south.ml.cloud.ibm.com/v4/jobs \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type: application/json" \
    -H "cache-control: no-cache"  \
    -d @myjob.json
    
    A job-id is returned. Output example: (the job is queued)
    {
        "metadata": {
           "parent": {
               "href": ""
           },
           "guid": "job-id",
           "modified_at": "",
           "created_at": "2019-04-11T12:13:16+0000",
           "owner": "",
           "href": "/v4/jobs/job-id"
       },
        "entity": {
            "deployment": {
                "href": "/v4/deployments/deployment-id"
            },
            "decision_optimization": {
                "solve_parameters": {},
                  "input_data": [{
            "id": "diet_food.csv",
            "fields": ["name", "unit_cost", "qmin", "qmax"],
            "values": [["Roasted Chicken", 0.84, 0, 10], ["Spaghetti W/ Sauce", 0.78, 0, 10], ["Tomato,Red,Ripe,Raw", 0.27, 0, 10], ["Apple,Raw,W/Skin", 0.24, 0, 10], ["Grapes", 0.32, 0, 10], ["Chocolate Chip Cookies", 0.03, 0, 10], ["Lowfat Milk", 0.23, 0, 10], ["Raisin Brn", 0.34, 0, 10], ["Hotdog", 0.31, 0, 10]]
          }, {
            "id": "diet_food_nutrients.csv",
            "fields": ["Food", "Calories", "Calcium", "Iron", "Vit_A", "Dietary_Fiber", "Carbohydrates", "Protein"],
            "values": [["Spaghetti W/ Sauce", 358.2, 80.2, 2.3, 3055.2, 11.6, 58.3, 8.2], ["Roasted Chicken", 277.4, 21.9, 1.8, 77.4, 0, 0, 42.2], ["Tomato,Red,Ripe,Raw", 25.8, 6.2, 0.6, 766.3, 1.4, 5.7, 1], ["Apple,Raw,W/Skin", 81.4, 9.7, 0.2, 73.1, 3.7, 21, 0.3], ["Grapes", 15.1, 3.4, 0.1, 24, 0.2, 4.1, 0.2], ["Chocolate Chip Cookies", 78.1, 6.2, 0.4, 101.8, 0, 9.3, 0.9], ["Lowfat Milk", 121.2, 296.7, 0.1, 500.2, 0, 11.7, 8.1], ["Raisin Brn", 115.1, 12.9, 16.8, 1250.2, 4, 27.9, 4], ["Hotdog", 242.1, 23.5, 2.3, 0, 0, 18, 10.4]]
          }, {
            "id": "diet_nutrients.csv",
            "fields": ["name", "qmin", "qmax"],
            "values": [["Calories", 2000, 2500], ["Calcium", 800, 1600], ["Iron", 10, 30], ["Vit_A", 5000, 50000], ["Dietary_Fiber", 25, 100], ["Carbohydrates", 0, 300], ["Protein", 50, 100]]
          }],
          "output_data": [{
            "id": ".*\\.csv"
          }],
                "status": {
                    "state": "queued"
                }
            }
        }
    }
  8. You can also monitor job states. Use the job-id.
    For example:
    curl -X GET \
    https://us-south.ml.cloud.ibm.com/v4/jobs/job-id-here \
    -H "Authorization: bearer IAM-Token-here" \
    -H "ML-Instance-ID:ML-InstanceId-here" \
    -H "Content-Type: application/json" \
    -H "cache-control: no-cache"  \
    
    Output example: (job has completed)
    {
      "metadata": {
        "parent": {
          "href": ""
        },
        "guid": "job-id",
        "modified_at": "",
        "created_at": "2019-04-16T07:38:42+0000",
        "owner": "",
        "href": "/v4/jobs/job-id"
      },
      "entity": {
        "deployment": {
          "href": "/v4/deployments/deployment-id"
        },
        "decision_optimization": {
          "output_data_references": [],
          "solve_parameters": {
            "oaas.logAttachmentName": "log.txt",
            "oaas.logTailEnabled": "true"
          },
          "input_data": [{
            "id": "diet_food.csv",
            "fields": ["name", "unit_cost", "qmin", "qmax"],
            "values": [["Roasted Chicken", 0.84, 0, 10], ["Spaghetti W/ Sauce", 0.78, 0, 10], ["Tomato,Red,Ripe,Raw", 0.27, 0, 10], ["Apple,Raw,W/Skin", 0.24, 0, 10], ["Grapes", 0.32, 0, 10], ["Chocolate Chip Cookies", 0.03, 0, 10], ["Lowfat Milk", 0.23, 0, 10], ["Raisin Brn", 0.34, 0, 10], ["Hotdog", 0.31, 0, 10]]
          }, {
            "id": "diet_food_nutrients.csv",
            "fields": ["Food", "Calories", "Calcium", "Iron", "Vit_A", "Dietary_Fiber", "Carbohydrates", "Protein"],
            "values": [["Spaghetti W/ Sauce", 358.2, 80.2, 2.3, 3055.2, 11.6, 58.3, 8.2], ["Roasted Chicken", 277.4, 21.9, 1.8, 77.4, 0, 0, 42.2], ["Tomato,Red,Ripe,Raw", 25.8, 6.2, 0.6, 766.3, 1.4, 5.7, 1], ["Apple,Raw,W/Skin", 81.4, 9.7, 0.2, 73.1, 3.7, 21, 0.3], ["Grapes", 15.1, 3.4, 0.1, 24, 0.2, 4.1, 0.2], ["Chocolate Chip Cookies", 78.1, 6.2, 0.4, 101.8, 0, 9.3, 0.9], ["Lowfat Milk", 121.2, 296.7, 0.1, 500.2, 0, 11.7, 8.1], ["Raisin Brn", 115.1, 12.9, 16.8, 1250.2, 4, 27.9, 4], ["Hotdog", 242.1, 23.5, 2.3, 0, 0, 18, 10.4]]
          }, {
            "id": "diet_nutrients.csv",
            "fields": ["name", "qmin", "qmax"],
            "values": [["Calories", 2000, 2500], ["Calcium", 800, 1600], ["Iron", 10, 30], ["Vit_A", 5000, 50000], ["Dietary_Fiber", 25, 100], ["Carbohydrates", 0, 300], ["Protein", 50, 100]]
          }],
          "solve_state": {
            "details": {
              "MODEL_DETAIL_NONZEROS": "57",
              "KPI.Total Vit_A": "8518.432542485823",
              "MODEL_DETAIL_TYPE": "LP",
              "KPI.Total Dietary_Fiber": "25.0",
              "KPI.Total Iron": "11.278317739831893",
              "MODEL_DETAIL_CONTINUOUS_VARS": "9",
              "KPI.Total Carbohydrates": "256.80576358904455",
              "KPI.Total Calories": "2000.0000000000002",
              "MODEL_DETAIL_CONSTRAINTS": "7",
              "KPI.Total Calcium": "799.9999999999999",
              "PROGRESS_CURRENT_OBJECTIVE": "2.6904091716962637",
              "MODEL_DETAIL_INTEGER_VARS": "0",
              "KPI.Total Protein": "51.17372234135308",
              "MODEL_DETAIL_KPIS": "[\"Total Calories\", \"Total Calcium\", \"Total Iron\", \"Total Vit_A\", \"Total Dietary_Fiber\", \"Total Carbohydrates\", \"Total Protein\"]",
              "PROGRESS_CURRENT_OBJECTIVE.history": "[[1555414331.72, 2.6904091716962637]]",
              "MODEL_DETAIL_BOOLEAN_VARS": "0"
            },
            "solve_status": "optimal_solution",
            "latest_engine_activity": ["[2019-04-16T11:32:11Z, INFO] Model: diet", "[2019-04-16T11:32:11Z, INFO]  - number of variables: 9", "[2019-04-16T11:32:11Z, INFO]    - binary=0, integer=0, continuous=9", "[2019-04-16T11:32:11Z, INFO]  - number of constraints: 7", "[2019-04-16T11:32:11Z, INFO]    - linear=7", "[2019-04-16T11:32:11Z, INFO]  - parameters: defaults", "[2019-04-16T11:32:11Z, INFO] objective: 2.690", "[2019-04-16T11:32:11Z, INFO]   \"Spaghetti W/ Sauce\"=2.155", "[2019-04-16T11:32:11Z, INFO]   \"Chocolate Chip Cookies\"=10.000", "[2019-04-16T11:32:11Z, INFO]   \"Lowfat Milk\"=1.831", "[2019-04-16T11:32:11Z, INFO]   \"Hotdog\"=0.930", "[2019-04-16T11:32:11Z, INFO] solution.csv"]
          },
          "output_data": [{
            "id": "solution.csv",
            "fields": ["name", "value"],
            "values": [["Spaghetti W/ Sauce", 2.1551724137931036], ["Chocolate Chip Cookies", 10], ["Lowfat Milk", 1.8311671008899093], ["Hotdog", 0.9296975991385928]]
          }, {
            "id": "kpis.csv",
            "fields": ["NAME", "VALUE"],
            "values": [["Total Calories", 2000.0000000000002], ["Total Calcium", 799.9999999999999], ["Total Iron", 11.278317739831893], ["Total Vit_A", 8518.432542485823], ["Total Dietary_Fiber", 25], ["Total Carbohydrates", 256.80576358904455], ["Total Protein", 51.17372234135308]]
          }],
          "status": {
            "state": "completed",
            "running_at": "2019-04-16T11:32:10.958Z",
            "completed_at": "2019-04-16T11:32:11.846Z"
          }
        }
      }
    }

Results

Once your model has been deployed and job executed, the solution results are provided either inline or in the file and location that you specified, for example using an S3 reference. You can post new jobs using the deployment-id without having to redeploy your model.