> ## Documentation Index
> Fetch the complete documentation index at: https://docs.solvice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Official Python SDK with full type safety, async support, and Pythonic interface

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

## Installation

Install the SDK using your preferred Python package manager:

<Tabs>
  <Tab title="pip">
    ```bash theme={null}
    pip install --pre solvice-vrp-solver
    ```
  </Tab>

  <Tab title="poetry">
    ```bash theme={null}
    poetry add solvice-vrp-solver --allow-prereleases
    ```
  </Tab>

  <Tab title="pipenv">
    ```bash theme={null}
    pipenv install --pre solvice-vrp-solver
    ```
  </Tab>
</Tabs>

<Note>
  The `--pre` flag is currently required as the package is in pre-release status.
</Note>

## Quick Start

Get up and running with the VRP Solver in minutes:

```python theme={null}
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

<CardGroup cols={2}>
  <Card title="Type Safety" icon="shield-check">
    Full type definitions for all request parameters and response fields
  </Card>

  <Card title="Async Support" icon="bolt">
    Native async/await support with both httpx and optional aiohttp backends
  </Card>

  <Card title="Pythonic Interface" icon="code">
    Follows Python conventions with snake\_case methods and proper error handling
  </Card>

  <Card title="Auto Retry" icon="rotate">
    Built-in retry logic with configurable attempts for resilient integrations
  </Card>
</CardGroup>

## Configuration

Configure the SDK client with these options:

```python theme={null}
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
)
```

<Warning>
  Never hardcode your API key. Always use environment variables or secure key management systems.
</Warning>

## Advanced Usage

### Asynchronous Client

For better performance with multiple requests, use the async client:

```python theme={null}
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:

```python theme={null}
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:

```python theme={null}
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:

<Tabs>
  <Tab title="Python 3.8+">
    Minimum supported version:

    ```python theme={null}
    # Compatible with Python 3.8 and above
    from solvice_vrp_solver import SolviceVrpSolver
    ```
  </Tab>

  <Tab title="Type Hints">
    Full type hint support:

    ```python theme={null}
    from typing import Dict, List, Any
    from solvice_vrp_solver import SolviceVrpSolver

    def optimize_routes(jobs: List[Dict[str, Any]]) -> Dict[str, Any]:
        client = SolviceVrpSolver(api_key="your_api_key")
        return client.vrp.sync_solve({"jobs": jobs, "resources": [...]})
    ```
  </Tab>
</Tabs>

## Complete Example

Here's a comprehensive example showcasing various SDK features:

```python theme={null}
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

<Tip>
  For problems with more than 100 jobs or complex constraints, use the asynchronous `solve()` method to avoid timeouts.
</Tip>

## Integration with Data Science Libraries

The Python SDK works seamlessly with popular data science libraries:

```python theme={null}
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

<CardGroup cols={2}>
  <Card title="PyPI Package" icon="python" href="https://pypi.org/project/solvice-vrp-solver/">
    View on Python Package Index
  </Card>

  <Card title="GitHub Repository" icon="github" href="https://github.com/solvice/vrp-solver-sdk">
    View source code and contribute
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/vrp/introduction">
    Complete API documentation
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:support@solvice.io">
    Get help from our team
  </Card>
</CardGroup>
