REST API 示例 (Decision Optimization)
您可以使用 Watson Machine Learning REST API来部署 Decision Optimization 模型,创建和监视作业以及获取解决方案。
开始之前
- 在Watson Machine Learning 中创建部署空间。 然后查看它并从 "设置" 选项卡复制您的空间标识。 更多信息,请参阅创建部署空间。
- 使用 REST API。 请参阅 使用 REST API 创建部署空间。
关于此任务
对于 Windows 用户,请使用 ^ 而不是 \ 作为多行分隔符和双引号 " 在这些代码示例中。 Windows 用户还需要在标题行中使用至少一个字符空间的缩进。
为了清晰起见,此过程中的一些代码示例已放在 json 文件中,以使命令更易读且更易于使用。
使用 REST API 创建部署后,还可以从 "部署空间 "页面查看部署并向其发送作业。
过程
- 使用主机集群进行认证,如下所示。更多信息,请参阅生成 API 密钥。
- 可选: 如果未如前所述从用户界面获取 SPACE-ID ,那么可以使用 REST API 创建空间,如下所示。 在所有 API 调用中,使用
Authorization头中以词ZenApiKey开头的先前获取的令牌。curl --request POST \ "https://HOST-CLUSTER-HERE/v2/spaces" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json" \ -d "{"name": "SPACE-NAME-HERE","description": "optional description here"}"对于 Windows 用户,将--data-raw命令放在一行上,并将此命令中的所有"替换为\",如下所示:
或者,将数据放在单独的文件中。curl --request POST ^ "https://HOST-CLUSTER-HERE/v2/spaces" ^ -H "Authorization: ZenApiKey <token>" ^ -H "Content-Type: application/json" ^ -d "{\"name\": \"SPACE-NAME-HERE\",\"description\": \"optional description here\"}"SPACE-ID 在metadata部分的id字段中返回。输出示例:
{ "entity": { "compute": [{ "crn": "crn:v1:cpd:private:pm-20:private:a/cpduser:99999999-9999-9999-9999-999999999999::", "guid": "99999999-9999-9999-9999-999999999999", "name": "Watson Machine Learning", "type": "machine_learning" }], "name": "SPACE-NAME", "scope": { "bss_account_id": "cpdaccount" }, "status": { "state": "active" } }, "metadata": { "created_at": "2025-10-30T16:16:44.121Z", "creator_id": "XXXXXXX", "id": "SPACE-ID", "url": "/v2/spaces/SPACE-ID" } }您必须等待直到部署空间状态为
"active",然后才能继续。 您可以按如下所示进行轮询以进行检查。curl --request GET "https://HOST-CLUSTER-HERE/v2/spaces/SPACE-ID-HERE" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json" - 创建 新 Decision Optimization 模型
所有 API 请求都需要采用格式为
version=YYYY-MM-DD的日期的版本参数。 此代码示例发布使用文件create_model.json的模型。 URL 将根据您为机器学习服务选择的地区/位置而有所不同。
create_model.json 文件包含以下代码:curl --request POST \ "https://HOST-CLUSTER-HERE/ml/v4/models?version=2025-08-01" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json" \ -d @create_model.json{ "name": "ModelName", "description": "ModelDescription", "type": "do-docplex_22.1", "software_spec": { "name": "do_22.1" }, "custom": { "decision_optimization": { "oaas.docplex.python": "3.12" } }, "space_id": "SPACE-ID-HERE" }这里的 "
custom块明确说明了Python版本。 这是可选的。 若未指定,您的模型将使用默认版本,当前默认版本为 Python 3.12。 由于默认版本会随着时间的推移而变化,明确说明Python版本可以让您以后轻松更改,或者在默认版本更新时继续使用支持的旧版本。 目前支持 Python、 3.12 以及 3.11 (已弃用)。如果您希望能够 从用户界面运行此模型的作业,而不是仅使用 REST API ,那么必须为输入和输出数据定义 模式 。 如果在创建模型时未定义模式,那么只能使用 REST API 而不是从用户界面运行作业。
您还可以使用为优化模型中的输入和输出指定的模式:
{ "name": "Diet-Model-schema", "description": "Diet", "type": "do-docplex_22.1", "schemas": { "input": [ { "id": "diet_food_nutrients", "fields": [ { "name": "Food", "type": "string" }, { "name": "Calories", "type": "double" }, { "name": "Calcium", "type": "double" }, { "name": "Iron", "type": "double" }, { "name": "Vit_A", "type": "double" }, { "name": "Dietary_Fiber", "type": "double" }, { "name": "Carbohydrates", "type": "double" }, { "name": "Protein", "type": "double" } ] }, { "id": "diet_food", "fields": [ { "name": "name", "type": "string" }, { "name": "unit_cost", "type": "double" }, { "name": "qmin", "type": "double" }, { "name": "qmax", "type": "double" } ] }, { "id": "diet_nutrients", "fields": [ { "name": "name", "type": "string" }, { "name": "qmin", "type": "double" }, { "name": "qmax", "type": "double" } ] } ], "output": [ { "id": "solution", "fields": [ { "name": "name", "type": "string" }, { "name": "value", "type": "double" } ] } ] }, "software_spec": { "name": "do_22.1" }, "space_id": "SPACE-ID-HERE" }发布模型时,提供有关其 模型类型 和要使用的 软件规范 的信息。模型类型 可以是,例如:- OPL 模型的
do-opl_22.1 do-cplex_22.1(对于 CPLEX 模型)- 针对 CP 模型的
do-cpo_22.1 do-docplex_22.1for Python 模型
版本 20.1 也可用于这些模型类型。
对于 软件规范,您可以使用缺省规范的名称
do_22.1或do_20.1(不推荐使用 do_20.1 运行时,并且将很快除去)。 另请参阅 扩展软件规范笔记本 ,其中显示了如何扩展 Decision Optimization 软件规范 (带有 DOcplex 模型的其他 Python 库的运行时)。在
metadata的id字段中返回 MODEL-ID 。输出示例:{ "entity": { "software_spec": { "id": "SOFTWARE-SPEC-ID" }, "type": "do-docplex_22.1" }, "metadata": { "created_at": "2025-07-17T08:37:22.992Z", "description": "ModelDescription", "id": "MODEL-ID", "modified_at": "2025-07-17T08:37:22.992Z", "name": "ModelName", "owner": "***********", "space_id": "SPACE-ID" }, "system": { "warnings": [] }} - OPL 模型的
- 上载可供部署的 Decision Optimization 模型阐述 。首先将模型 压缩 到 (
tar.gz, .zip or .jar) 文件中,然后上载该文件以由 Watson Machine Learning 服务部署。以下代码示例上载名为 diet.zip 的模型,该模型包含 Python 模型并且没有公共数据:curl --request PUT \ "https://HOST-CLUSTER-HERE/ml/v4/models/MODEL-ID-HERE/content?version=2025-08-01&space_id=SPACE-ID-HERE&content_format=native" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/gzip" \ --data-binary "@diet.zip"您可以从 DO-samples下载此示例和其他模型。 选择相关产品和版本子文件夹。 对于 watsonx on-premises,请使用 Cloud Pak for Data v5.2.x 子文件夹中的样本。 - 部署模型创建对模型的引用。 使用 SPACE-ID,在创建可供部署的模型时获取的 MODEL-ID 以及 硬件规范。 例如:
curl --request POST "https://HOST-CLUSTER-HERE/ml/v4/deployments?version=2025-08-01" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json" \ -d @deploy_model.jsonThe deploy_model.json file contains the following code:{ "name": "Test-Diet-deploy", "space_id": "SPACE-ID-HERE", "asset": { "id": "MODEL-ID-HERE" }, "hardware_spec": { "name": "S" }, "batch": {} }DEPLOYMENT-ID 在metadata中的id字段中返回。 输出示例:{ "entity": { "asset": { "id": "MODEL-ID" }, "custom": {}, "description": "", "hardware_spec": { "id": "HARDWARE-SPEC-ID", "name": "S", "num_nodes": 1 }, "name": "Test-Diet-deploy", "space_id": "SPACE-ID", "status": { "state": "ready" } }, "metadata": { "created_at": "2025-07-17T09:10:50.661Z", "description": "", "id": "DEPLOYMENT-ID", "modified_at": "2025-07-17T09:10:50.661Z", "name": "test-Diet-deploy", "owner": "**************", "space_id": "SPACE-ID" } } - 部署后,您可以 监视模型的部署状态。 使用 DEPLOYMENT-ID。例如:
curl --request GET "https://HOST-CLUSTER-HERE/ml/v4/deployments/DEPLOYMENT-ID-HERE?version=2025-08-01&space_id=SPACE-ID-HERE" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json"输出示例:
{ "entity": { "asset": { "id": "MODEL-ID" }, "batch": { }, "custom": { }, "deployed_asset_type": "do", "hardware_spec": { "id": "HARDWARE-SPEC-ID", "name": "S", "num_nodes": 1 }, "name": "Test-Diet-deploy", "space_id": "SPACE-ID", "status": { "state": "ready" } }, "metadata": { "created_at": "2023-10-25T09:44:19.943Z", "id": "DEPLOYMENT-ID", "modified_at": "2023-10-25T09:44:19.943Z", "name": "Test-Diet-deploy", "owner": "**************", "space_id": "SPACE-ID" } } - 然后,您可以针对定义输入数据和输出 (优化求解的结果) 以及日志文件的已部署模型 提交作业 。例如,下面显示了名为
myjob.json的文件的内容。 它包含(内联)输入数据、一些求解参数,并指定输出为 ".csv文件。 有关其他类型输入数据引用的示例,请参阅Decision Optimization批量部署和模型执行。
此代码示例发布使用此文件{ "name":"test-job-diet", "space_id": "SPACE-ID-HERE", "deployment": { "id": "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" } ] } }myjob.json的作业。curl --request POST "https://HOST-CLUSTER-HERE/ml/v4/deployment_jobs?version=2025-08-01&space_id=SPACE-ID-HERE" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json" \ -H "cache-control: no-cache" \ -d @myjob.json返回 JOB-ID 。 输出示例: (作业已排队){ "entity": { "decision_optimization": { "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" } ], "solve_parameters": { "oaas.logAttachmentName": "log.txt", "oaas.logTailEnabled": "true" }, "status": { "state": "queued" } }, "deployment": { "id": "DEPLOYMENT-ID" }, "platform_job": { "job_id": "", "run_id": "" } }, "metadata": { "created_at": "2025-07-17T10:42:42.783Z", "id": "JOB-ID", "name": "test-job-diet", "space_id": "SPACE-ID" } } - 您还可以 监视作业状态。 使用 JOB-ID例如:
curl --request GET \ "https://HOST-CLUSTER-HERE/ml/v4/deployment_jobs/JOB-ID-HERE?version=2025-08-01&space_id=SPACE-ID-HERE" \ -H "Authorization: ZenApiKey <token>" \ -H "Content-Type: application/json"输出示例: (作业已完成){ "entity": { "decision_optimization": { "input_data": [{ "fields": ["name", "unit_cost", "qmin", "qmax"], "id": "diet_food.csv", "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]] }, { "fields": ["Food", "Calories", "Calcium", "Iron", "Vit_A", "Dietary_Fiber", "Carbohydrates", "Protein"], "id": "diet_food_nutrients.csv", "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]] }, { "fields": ["name", "qmin", "qmax"], "id": "diet_nutrients.csv", "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": [{ "fields": ["Name", "Value"], "id": "kpis.csv", "values": [["Total Calories", 2000], ["Total Calcium", 800.0000000000001], ["Total Iron", 11.278317739831891], ["Total Vit_A", 8518.432542485823], ["Total Dietary_Fiber", 25], ["Total Carbohydrates", 256.80576358904455], ["Total Protein", 51.17372234135308], ["Minimal cost", 2.690409171696264]] }, { "fields": ["name", "value"], "id": "solution.csv", "values": [["Spaghetti W/ Sauce", 2.1551724137931036], ["Chocolate Chip Cookies", 10], ["Lowfat Milk", 1.8311671008899097], ["Hotdog", 0.9296975991385925]] }], "output_data_references": [], "solve_parameters": { "oaas.logAttachmentName": "log.txt", "oaas.logTailEnabled": "true" }, "solve_state": { "details": { "KPI.Minimal cost": "2.690409171696264", "KPI.Total Calcium": "800.0000000000001", "KPI.Total Calories": "2000.0", "KPI.Total Carbohydrates": "256.80576358904455", "KPI.Total Dietary_Fiber": "25.0", "KPI.Total Iron": "11.278317739831891", "KPI.Total Protein": "51.17372234135308", "KPI.Total Vit_A": "8518.432542485823", "MODEL_DETAIL_BOOLEAN_VARS": "0", "MODEL_DETAIL_CONSTRAINTS": "7", "MODEL_DETAIL_CONTINUOUS_VARS": "9", "MODEL_DETAIL_INTEGER_VARS": "0", "MODEL_DETAIL_KPIS": "[\"Total Calories\", \"Total Calcium\", \"Total Iron\", \"Total Vit_A\", \"Total Dietary_Fiber\", \"Total Carbohydrates\", \"Total Protein\", \"Minimal cost\"]", "MODEL_DETAIL_NONZEROS": "57", "MODEL_DETAIL_OBJECTIVE_SENSE": "minimize", "MODEL_DETAIL_TYPE": "LP", "PROGRESS_CURRENT_OBJECTIVE": "2.6904091716962637", "STAT.cplex.modelType": "LP", "STAT.cplex.size.booleanVariables": "0", "STAT.cplex.size.constraints": "7", "STAT.cplex.size.continousVariables": "9", "STAT.cplex.size.integerVariables": "0", "STAT.cplex.size.linearConstraints": "7", "STAT.cplex.size.quadraticConstraints": "0", "STAT.cplex.size.variables": "9" }, "latest_engine_activity": ["[2025-04-04T16:34:51Z, INFO] Model: diet", "[2025-04-04T16:34:51Z, INFO] - number of variables: 9", "[2025-04-04T16:34:51Z, INFO] - binary=0, integer=0, continuous=9", "[2025-04-04T16:34:51Z, INFO] - number of constraints: 7", "[2025-04-04T16:34:51Z, INFO] - linear=7", "[2025-04-04T16:34:51Z, INFO] - parameters: defaults", "[2025-04-04T16:34:51Z, INFO] - objective: minimize", "[2025-04-04T16:34:51Z, INFO] - problem type is: LP", "[2025-04-04T16:34:51Z, INFO] Warning: Model: \"diet\" is not a MIP problem, progress listeners are disabled", "[2025-04-04T16:34:51Z, INFO] objective: 2.690", "[2025-04-04T16:34:51Z, INFO] \"Spaghetti W/ Sauce\"=2.155", "[2025-04-04T16:34:51Z, INFO] \"Chocolate Chip Cookies\"=10.000", "[2025-04-04T16:34:51Z, INFO] \"Lowfat Milk\"=1.831", "[2025-04-04T16:34:51Z, INFO] \"Hotdog\"=0.930", "[2025-04-04T16:34:51Z, INFO] solution.csv" ], "solve_status": "optimal_solution" }, "status": { "completed_at": "2025-04-04T16:34:51.796Z", "running_at": "2025-04-04T16:34:50.592Z", "state": "completed" } }, "deployment": { "id": "DEPLOYMENT ID" }, "platform_job": { "job_id": "PLATFORM JOB ID", "run_id": "PLATFORM RUN ID" } }, "metadata": { "created_at": "2025-04-04T16:34:30.603Z", "id": "JOB-ID", "modified_at": "2025-04-04T16:34:51.881Z", "name": "test-job-diet", "space_id": "SPACE-ID" } } - 可选: 您可以 删除作业 ,如下所示:
curl --request DELETE "https://HOST-CLUSTER-HERE/ml/v4/deployment_jobs/JOB-ID-HERE?version=2025-08-01&space_id=SPACE-ID-HERE&hard_delete=true" \ -H "Authorization: ZenApiKey <token>"如果使用 API 删除作业,那么该作业仍将显示在用户界面中。 - 可选: 您可以 删除部署 ,如下所示:
curl --request DELETE "https://HOST-CLUSTER-HERE/ml/v4/deployments/DEPLOYMENT-ID-HERE?version=2025-08-01&space_id=SPACE-ID-HERE" \ -H "Authorization: ZenApiKey <token>"如果使用 API 删除包含作业的部署,那么这些作业仍将显示在用户界面的部署空间中。
结果
部署模型并执行作业后,将以内联方式或在您指定的文件和位置 (例如,使用 S3 引用) 中提供解决方案结果。 您可以使用 deployment-ID 发布新作业,而不必重新部署模型。