The following is a complete example, using the *Python API*, of solving a graph
created with Seattle road network data for a shortest path problem via the
/solve/graph endpoint. For more information on
Network Graphs & Solvers, see Network Graphs & Solvers Concepts.

The prerequisites for running the shortest path solve graph example are listed below:

- Kinetica (v.
`7.0`

or later) - Graph server enabled
- Python API
`Solve graph script`

`Seattle road network CSV file`

The native *Kinetica Python API* is accessible through the following means:

- For development on the
*Kinetica*server: - For development not on the
*Kinetica*server:

In default *Kinetica* installations, the native *Python* API is located in the
`/opt/gpudb/api/python`

directory. The
`/opt/gpudb/bin/gpudb_python`

wrapper script is provided, which sets the
execution environment appropriately.

Test the installation:

```
/opt/gpudb/bin/gpudb_python /opt/gpudb/api/python/examples/example.py
```

Important

When developing on the *Kinetica* server, use
**/opt/gpudb/bin/gpudb_python** to run *Python* programs and
**/opt/gpudb/bin/gpudb_pip** to install dependent libraries.

In the desired directory, run the following but be sure to replace

`<kinetica-version>`

with the name of the installed Kinetica version, e.g.,`v7.0`

:git clone -b release/<kinetica-version> --single-branch https://github.com/kineticadb/kinetica-api-python.git

Change directory into the newly downloaded repository:

`cd kinetica-api-python`

In the root directory of the unzipped repository, install the Kinetica API:

sudo python setup.py install

Test the installation (

*Python*2.7 (or greater) is necessary for running the API example):python examples/example.py

The *Python* package manager, **pip**, is required to install the API
from *PyPI*.

Install the API:

pip install gpudb --upgrade

Test the installation:

python -c "import gpudb;print('Import Successful')"

If

*Import Successful*is displayed, the API has been installed as is ready for use.

The example script makes reference to a `road_weights.csv`

data file
in the current directory. This can be updated to point to a valid path on the
host where the file will be located, or the script can be run with the data
file in the current directory.

```
CSV = "road_weights.csv"
```

This example is going to demonstrate solving (both individual and batch solve) for the shortest path between source points and several destination points located within a road network in Seattle.

Several constants are defined at the beginning of the script:

`HOST`

/`PORT`

-- host and port values for the database`OPTION_NO_ERROR`

-- reference to a /clear/table option for ease of use and repeatability`TABLE_SRN`

-- the name of the table into which the Seattle road network dataset is loaded`GRAPH_S`

-- the Seattle road network graph`GRAPH_S_SPSOLVED`

/`GRAPH_S_SPSOLVED2`

/`GRAPH_S_SPSOLVED3`

-- the Seattle road network graph shortest path solution tables

```
HOST = "127.0.0.1"
PORT = "9191"
OPTION_NO_ERROR = {"no_error_if_not_exists": "true"}
TABLE_SRN = "seattle_road_network"
GRAPH_S = TABLE_SRN + "_graph"
GRAPH_S_SPSOLVED = GRAPH_S + "_shortest_path_solved"
GRAPH_S_SPSOLVED2 = GRAPH_S + "_shortest_path_solved2"
GRAPH_S_SPSOLVED3 = GRAPH_S + "_shortest_path_solved3"
```

One graph is used for the shortest path solve graph example utilized in the
script: `seattle_road_network_graph`

, a graph based on the `road_weights`

dataset (the CSV file mentioned in Prerequisites).

The `GRAPH_S`

graph is created with the following characteristics:

- It is directed because the roads in the graph have directionality (one-way and two-way roads)
- It has no explicitly defined
`nodes`

because the example relies on implicit nodes attached to the defined edges - The
`edges`

are represented using WKT LINESTRINGs in the`WKTLINE`

column of the`seattle_road_network`

table (`EDGE_WKTLINE`

). The road segments' directionality is derived from the`TwoWay`

column of the`seattle_road_network`

table (`EDGE_DIRECTION`

). - The
`weights`

are represented using the time taken to travel the segment found in the`time`

column of the`seattle_road_network`

table (`WEIGHTS_VALUESPECIFIED`

). The weights are matched to the edges using the same`WKTLINE`

column as edges (`WEIGHTS_EDGE_WKTLINE`

) and the same`TwoWay`

column as the edge direction (`WEIGHTS_EDGE_DIRECTION`

). - It has no inherent
`restrictions`

for any of the nodes or edges in the graph - It will be replaced with this instance of the graph if a graph of the same
name exists (
`recreate`

)

```
print("Creating {}".format(GRAPH_S))
create_s_graph_response = kinetica.create_graph(
graph_name=GRAPH_S,
directed_graph=True,
nodes=[],
edges=[
TABLE_SRN + ".WKTLINE AS EDGE_WKTLINE",
TABLE_SRN + ".TwoWay AS EDGE_DIRECTION"
],
weights=[
TABLE_SRN + ".WKTLINE AS WEIGHTS_EDGE_WKTLINE",
TABLE_SRN + ".TwoWay AS WEIGHTS_EDGE_DIRECTION",
TABLE_SRN + ".time AS WEIGHTS_VALUESPECIFIED"
],
restrictions=[],
options={
"recreate": "true",
"enable_graph_draw": "true",
"graph_table": "seattle_graph_debug"
}
)
```

The first example illustrates a simple shortest path solve from a single source node to a single destination node. First, the source node and destination node are defined.

```
source_nodes = ["POINT(-122.1792501 47.2113606)"]
destination_nodes = ["POINT(-122.2221 47.5707)"]
```

Next, the `seattle_road_network_graph`

graph is solved with the solve results
being exported to the response:

```
solve_s_spgraph_response = kinetica.solve_graph(
graph_name=GRAPH_S,
solver_type="SHORTEST_PATH",
source_nodes=source_nodes,
destination_nodes=destination_nodes,
solution_table=GRAPH_S_SPSOLVED,
options={"export_solve_results": "true"}
)["result_per_destination_node"]
```

The cost for the source node to visit the destination node is represented as time in minutes:

```
Cost per destination node when source node = ['POINT(-122.1792501 47.2113606)']:
+--------------------------+---------------------+
| Destination Node | Cost (in minutes) |
+==========================+=====================+
| POINT(-122.2221 47.5707) | 40.6214 |
+--------------------------+---------------------+
```

The solution output to WMS:

The second example illustrates a shortest path solve from a single source node to many destination nodes. First, the source node and destination nodes are defined. When one source node and many destination nodes are provided, the graph solver will calculate a shortest path solve for each destination node.

```
source_nodes = ["POINT(-122.1792501 47.2113606)"]
destination_nodes = [
"POINT(-122.2221 47.5707)",
"POINT(-122.541017 47.809121)",
"POINT(-122.520440 47.624725)",
"POINT(-122.467915 47.427280)"
]
```

Next, the `seattle_road_network_graph`

graph is solved with the solve results
being exported to the response

```
solve_s_spgraph_response2 = kinetica.solve_graph(
graph_name=GRAPH_S,
solver_type="SHORTEST_PATH",
source_nodes=source_nodes,
destination_nodes=destination_nodes,
solution_table=GRAPH_S_SPSOLVED2,
options={"export_solve_results": "true"}
)["result_per_destination_node"]
```

The cost for the source node to visit each of the destination nodes separately is represented as time in minutes:

```
Cost per destination node when source node = ['POINT(-122.1792501 47.2113606)']:
+------------------------------+---------------------+
| Destination Node | Cost (in minutes) |
+==============================+=====================+
| POINT(-122.2221 47.5707) | 40.6214 |
+------------------------------+---------------------+
| POINT(-122.541017 47.809121) | 90.2934 |
+------------------------------+---------------------+
| POINT(-122.520440 47.624725) | 79.7342 |
+------------------------------+---------------------+
| POINT(-122.467915 47.427280) | 69.0357 |
+------------------------------+---------------------+
```

The solutions output to WMS:

The third example illustrates a shortest path solve from a many source nodes
to many destination nodes. First, the source node and destination nodes are
defined. If many source node and many destination nodes are provided, the graph
solver will pair the source and destination node by list index and calculate a
shortest path solve for each pair. For this example, there are two starting
points (`POINT(-122.1792501 47.2113606)`

and
`POINT(-122.375180125237 47.8122103214264)`

) and paths will be calculated from
the first source to two different destinations and from the second source to two
other destinations.

Important

Calculations from multiple unique sources are faster and more efficient than calculations with one unique source, but results may differ slightly between multiple unique source calculations and single unique source calculations (less than ~1% variance).

```
source_nodes = [
"POINT(-122.1792501 47.2113606)",
"POINT(-122.1792501 47.2113606)",
"POINT(-122.375180125237 47.8122103214264)",
"POINT(-122.375180125237 47.8122103214264)"
]
destination_nodes = [
"POINT(-122.2221 47.5707)",
"POINT(-122.541017 47.809121)",
"POINT(-122.520440 47.624725)",
"POINT(-122.467915 47.427280)"
]
```

Next, the `seattle_road_network_graph`

graph is solved with the solve results
being exported to the response:

```
solve_s_spgraph_response3 = kinetica.solve_graph(
graph_name=GRAPH_S,
solver_type="SHORTEST_PATH",
source_nodes=source_nodes,
destination_nodes=destination_nodes,
solution_table=GRAPH_S_SPSOLVED3,
options={"export_solve_results": "true"}
)["result_per_destination_node"]
```

The cost for the source node to visit each of the destination nodes separately is represented as time in minutes:

```
Cost per destination node:
+-------------------------------------------+------------------------------+---------------------+
| Source Node | Destination Node | Cost (in minutes) |
+===========================================+==============================+=====================+
| POINT(-122.1792501 47.2113606) | POINT(-122.2221 47.5707) | 40.6723 |
+-------------------------------------------+------------------------------+---------------------+
| POINT(-122.1792501 47.2113606) | POINT(-122.541017 47.809121) | 90.2636 |
+-------------------------------------------+------------------------------+---------------------+
| POINT(-122.375180125237 47.8122103214264) | POINT(-122.520440 47.624725) | 51.1153 |
+-------------------------------------------+------------------------------+---------------------+
| POINT(-122.375180125237 47.8122103214264) | POINT(-122.467915 47.427280) | 59.9621 |
+-------------------------------------------+------------------------------+---------------------+
```

The solutions output to WMS:

Included below is a complete example containing all the above requests, the data files, and output.

To run the complete sample, ensure the
`solve_graph_seattle_shortest_path.py`

and `road_weights.csv`

files are in the same directory (assuming the locations were not changed in the
`solve_graph_seattle_shortest_path.py`

script); then switch to that
directory and do the following:

If on the Kinetica host:

/opt/gpudb/bin/gpudb_python solve_graph_seattle_shortest_path.py

If running after using PyPI or GitHub to install the Python API:

python solve_graph_seattle_shortest_path.py