The official Solvice VRP Solver Python SDK is now available on PyPI! Install it today to streamline your route optimization integrations.

Installation

Install the SDK using your preferred Python package manager:
pip install --pre solvice-vrp-solver
The --pre flag is currently required as the package is in pre-release status.

Quick Start

Get up and running with the VRP Solver in minutes:
from solvice_vrp_solver import SolviceVrpSolver

client = SolviceVrpSolver(api_key="your_api_key")

# Solve a simple routing problem
solution = client.vrp.sync_solve({
    "jobs": [
        {
            "name": "delivery-1",
            "location": {"latitude": 51.0500, "longitude": 3.7300},
            "duration": 900  # 15 minutes
        },
        {
            "name": "delivery-2", 
            "location": {"latitude": 51.0543, "longitude": 3.7174},
            "duration": 600  # 10 minutes
        }
    ],
    "resources": [{
        "name": "vehicle-1",
        "shifts": [{
            "from": "2024-01-15T08:00:00Z",
            "to": "2024-01-15T17:00:00Z",
            "start": {"latitude": 51.0543, "longitude": 3.7174}
        }]
    }]
})

print(solution.routes)

Key Features

Type Safety

Full type definitions for all request parameters and response fields

Async Support

Native async/await support with both httpx and optional aiohttp backends

Pythonic Interface

Follows Python conventions with snake_case methods and proper error handling

Auto Retry

Built-in retry logic with configurable attempts for resilient integrations

Configuration

Configure the SDK client with these options:
from solvice_vrp_solver import SolviceVrpSolver

client = SolviceVrpSolver(
    api_key="your_api_key",          # Required: Your API key
    max_retries=2,                   # Optional: Number of retry attempts (default: 2)
    timeout=60.0,                    # Optional: Request timeout in seconds (default: 60.0)
    # Additional configuration options available
)
Never hardcode your API key. Always use environment variables or secure key management systems.

Advanced Usage

Asynchronous Client

For better performance with multiple requests, use the async client:
import asyncio
from solvice_vrp_solver import AsyncSolviceVrpSolver

async def main():
    client = AsyncSolviceVrpSolver(api_key="your_api_key")
    
    # Submit the job asynchronously
    response = await client.vrp.solve({
        "jobs": [...],
        "resources": [...],
        "options": {
            "maxSolvingTime": 300  # 5 minutes
        }
    })
    
    job_id = response.job_id
    
    # Check status
    status = await client.vrp.get_status({"jobId": job_id})
    
    if status.status == "SOLVED":
        # Retrieve solution
        solution = await client.vrp.get_solution({"jobId": job_id})
        print(solution)

# Run the async function
asyncio.run(main())

Error Handling

The SDK provides comprehensive error handling:
from solvice_vrp_solver import SolviceVrpSolver
from solvice_vrp_solver.exceptions import (
    BadRequestError,
    AuthenticationError,
    APIConnectionError
)

client = SolviceVrpSolver(api_key="your_api_key")

try:
    solution = client.vrp.sync_solve({...})
except BadRequestError as e:
    print(f"Invalid request: {e.message}")
    print(f"Details: {e.body}")
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
except APIConnectionError as e:
    print(f"Connection failed: {e.message}")
except Exception as e:
    print(f"Unexpected error: {e}")

Using with Real Road Distances

Enable real-world routing distances instead of straight-line calculations:
solution = client.vrp.sync_solve({
    "jobs": [...],
    "resources": [...],
    "options": {
        "euclidian": False,        # Use real road networks instead of straight-line
        "routingEngine": "OSM",    # OSM, TOMTOM, or GOOGLE
        "traffic": 1.3,           # 30% traffic factor
        "polylines": True         # Include route geometries for mapping
    }
})

Python Version Support

The SDK supports multiple Python versions:
Minimum supported version:
# Compatible with Python 3.8 and above
from solvice_vrp_solver import SolviceVrpSolver

Complete Example

Here’s a comprehensive example showcasing various SDK features:
import asyncio
import os
from solvice_vrp_solver import AsyncSolviceVrpSolver

async def optimize_delivery_routes():
    client = AsyncSolviceVrpSolver(
        api_key=os.environ.get("SOLVICE_API_KEY"),
        max_retries=3,
        timeout=120.0  # 2 minutes
    )
    
    try:
        solution = await client.vrp.sync_solve({
            "resources": [{
                "name": "vehicle-1",
                "shifts": [{
                    "from": "2024-01-15T08:00:00Z",
                    "to": "2024-01-15T17:00:00Z",
                    "start": {"latitude": 51.0543, "longitude": 3.7174},
                    "end": {"latitude": 51.0543, "longitude": 3.7174}
                }],
                "capacity": [100],
                "tags": ["refrigerated"],
                "breaks": [{
                    "duration": 1800,  # 30 minutes
                    "windows": [{
                        "from": "2024-01-15T12:00:00Z",
                        "to": "2024-01-15T13:00:00Z"
                    }]
                }]
            }],
            "jobs": [
                {
                    "name": "customer-123",
                    "location": {"latitude": 51.0500, "longitude": 3.7300},
                    "duration": 900,
                    "load": [20],
                    "priority": 10,
                    "tags": [{"name": "refrigerated", "hard": True}],
                    "windows": [{
                        "from": "2024-01-15T09:00:00Z",
                        "to": "2024-01-15T11:00:00Z"
                    }]
                },
                {
                    "name": "customer-456",
                    "location": {"latitude": 51.0600, "longitude": 3.7400},
                    "duration": 600,
                    "load": [15],
                    "priority": 5,
                    "windows": [{
                        "from": "2024-01-15T14:00:00Z",
                        "to": "2024-01-15T16:00:00Z"
                    }]
                }
            ],
            "options": {
                "euclidian": False,
                "routingEngine": "OSM",
                "traffic": 1.2,
                "maxSolvingTime": 60
            }
        })

        # Process the solution
        for route in solution.routes:
            print(f"Route for {route.resource_name}:")
            for stop in route.stops:
                print(f"- {stop.job_name} at {stop.arrival}")

        # Check for unassigned jobs
        if solution.unassigned:
            print(f"Unassigned jobs: {solution.unassigned}")

    except Exception as error:
        print(f"Optimization failed: {error}")

# Run the optimization
asyncio.run(optimize_delivery_routes())

API Methods

The SDK provides access to all VRP Solver endpoints:

Core Methods

  • sync_solve() - Synchronous solving for smaller problems
  • solve() - Asynchronous solving for larger problems
  • get_status() - Check job status
  • get_solution() - Retrieve solution

Advanced Methods

  • evaluate() - Evaluate an existing solution
  • suggest() - Get improvement suggestions
  • explain() - Get detailed explanations
  • demo() - Get a demo request for testing
For problems with more than 100 jobs or complex constraints, use the asynchronous solve() method to avoid timeouts.

Integration with Data Science Libraries

The Python SDK works seamlessly with popular data science libraries:
import pandas as pd
from solvice_vrp_solver import SolviceVrpSolver

# Load jobs from a CSV file
jobs_df = pd.read_csv('deliveries.csv')

# Convert to VRP format
jobs = jobs_df.to_dict('records')

# Optimize routes
client = SolviceVrpSolver(api_key="your_api_key")
solution = client.vrp.sync_solve({
    "jobs": jobs,
    "resources": [...]
})

# Convert solution back to DataFrame for analysis
routes_df = pd.DataFrame([
    {
        'job_name': stop.job_name,
        'resource_name': route.resource_name,
        'arrival_time': stop.arrival,
        'sequence': i
    }
    for route in solution.routes
    for i, stop in enumerate(route.stops)
])

print(routes_df.head())

Resources