$npx -y skills add NVIDIA/skills --skill cuopt-server-api-pythoncuOpt REST server — start server, endpoints, Python/curl client examples. Use when the user is deploying or calling the REST API.
| 1 | # cuOpt Server — Deploy and client (Python/curl) |
| 2 | |
| 3 | This skill covers **starting the server** and **client examples** (curl, Python). Server has no separate C API (clients can be any language). |
| 4 | |
| 5 | ## Problem types supported |
| 6 | |
| 7 | | Problem type | Supported | |
| 8 | |--------------|:---------:| |
| 9 | | Routing | ✓ | |
| 10 | | LP | ✓ | |
| 11 | | MILP | ✓ | |
| 12 | | QP | ✗ | |
| 13 | |
| 14 | ## Required questions |
| 15 | |
| 16 | Ask these if not already clear: |
| 17 | |
| 18 | 1. **Problem type** — Routing or LP/MILP? (QP not available via REST.) |
| 19 | 2. **Deployment** — Local, Docker, Kubernetes, or cloud? |
| 20 | 3. **Client** — Which language or tool will call the API (e.g. Python, curl, another service)? |
| 21 | |
| 22 | ## Start server |
| 23 | |
| 24 | ```bash |
| 25 | # Development |
| 26 | python -m cuopt_server.cuopt_service --ip 0.0.0.0 --port 8000 |
| 27 | |
| 28 | # Docker |
| 29 | docker run --gpus all -d -p 8000:8000 -e CUOPT_SERVER_PORT=8000 \ |
| 30 | nvidia/cuopt:latest-cuda12.9-py3.13 |
| 31 | ``` |
| 32 | |
| 33 | ## Verify |
| 34 | |
| 35 | ```bash |
| 36 | curl http://localhost:8000/cuopt/health |
| 37 | ``` |
| 38 | |
| 39 | ## Workflow |
| 40 | |
| 41 | 1. POST to `/cuopt/request` → get `reqId` |
| 42 | 2. Poll `/cuopt/solution/{reqId}` until solution ready |
| 43 | 3. Parse response |
| 44 | |
| 45 | ## Python client (routing) |
| 46 | |
| 47 | ```python |
| 48 | import requests, time |
| 49 | SERVER = "http://localhost:8000" |
| 50 | HEADERS = {"Content-Type": "application/json", "CLIENT-VERSION": "custom"} |
| 51 | payload = { |
| 52 | "cost_matrix_data": {"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}}, |
| 53 | "travel_time_matrix_data": {"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}}, |
| 54 | "task_data": {"task_locations": [1, 2], "demand": [[10, 20]], "task_time_windows": [[0,100],[0,100]], "service_times": [5, 5]}, |
| 55 | "fleet_data": {"vehicle_locations": [[0, 0]], "capacities": [[50]], "vehicle_time_windows": [[0, 200]]}, |
| 56 | "solver_config": {"time_limit": 5} |
| 57 | } |
| 58 | r = requests.post(f"{SERVER}/cuopt/request", json=payload, headers=HEADERS) |
| 59 | req_id = r.json()["reqId"] |
| 60 | # Poll: GET /cuopt/solution/{req_id} |
| 61 | ``` |
| 62 | |
| 63 | ## Terminology: REST vs Python API |
| 64 | |
| 65 | | Python API | REST | |
| 66 | |------------|------| |
| 67 | | order_locations | task_locations | |
| 68 | | set_order_time_windows() | task_time_windows | |
| 69 | | service_times | service_times | |
| 70 | |
| 71 | Use `travel_time_matrix_data` (not transit_time_matrix_data). Capacities: `[[50, 50]]` not `[[50], [50]]`. |
| 72 | |
| 73 | ## Debugging (422 / payload) |
| 74 | |
| 75 | **Validation errors:** Check field names against OpenAPI (`/cuopt.yaml`). Common mistakes: `transit_time_matrix_data` → `travel_time_matrix_data`; capacities per dimension `[[50, 50]]` not per vehicle `[[50], [50]]`. Capture `reqId` and response body for failed requests. |
| 76 | |
| 77 | ## Runnable assets |
| 78 | |
| 79 | Run from each asset directory (server must be running; scripts exit 0 if server unreachable). All use Python `requests`: |
| 80 | |
| 81 | - [assets/vrp_simple/](assets/vrp_simple/) — Basic VRP (no time windows) |
| 82 | - [assets/vrp_basic/](assets/vrp_basic/) — VRP with time windows |
| 83 | - [assets/pdp_basic/](assets/pdp_basic/) — Pickup and delivery |
| 84 | - [assets/lp_basic/](assets/lp_basic/) — LP via REST (CSR format) |
| 85 | - [assets/milp_basic/](assets/milp_basic/) — MILP via REST |
| 86 | |
| 87 | See [assets/README.md](assets/README.md) for overview. |
| 88 | |
| 89 | ## Escalate |
| 90 | |
| 91 | For contribution or build-from-source, see the developer skill. |