# API Spec¶

## Disclaimer¶

You do not need to read this if you are using the using the Skeleton for your solver. The interface implements this API so you don't have to if you're using Python 3 and the Skeleton. You may want to read this if you don't use the skeleton's interface, or if you are writing your solver in something that is not Python 3.

The API will be reachable from http://guavabot-api.cs170.org/.

## Datastructures¶

The API involves the communication of several datastructures. We detail how to model them in JSON here.

### Cities and Graphs¶

A city, or graph is a triple $G = (n, E, w)$.

• $n$ is a natural number where $n > 0$. It implicitly defines a vertex set $V = \{1, \ldots, n\}$.
• $E \subseteq V \times V$. Self-loops, or edges from the same vertex to itself, are not permitted. Edges [u, v] and [v, u] are considered to be the same (as edges are undirected).
• $w$ is a function that gives positive integer weights to all the edges

We encode $G$ as a JSON map with two fields: n and edges:

• n corresponds directly to $n$ in $G$.
• edges is a list of triples [u, v, w] where u and v are positive numbers with u != v, and w is a positive number corresponding to the weight on the edge. If [u, v, w] exists in edges, then there cannot be any triple of the form [v, u, w'] in edges.

As an example, here is $K_{3, 3}$ with random edge weights:

{
"n": 6,
"edges": [
[1, 4, 10],
[1, 5, 30],
[1, 6, 40],
[2, 4, 50],
[2, 5, 20],
[2, 6, 25],
[3, 4, 15],
[3, 5, 18],
[3, 6, 40]
]
}


We use IDs of the form <name>_<num> to identify a graph, where name is an alphabetical city name and num is a non-negative integer.

### Group Token¶

A group token is an arbitrary-length nonempty string. It is JSON-encoded as a string, always corresponding to field called group_token. Every group will be provided with a group token, which will be unique.

## Rescue¶

A rescue describes a session between group and server starting with a city with bots scattered, terminating with an /end call where hopefully all the bots have been remoted to the home vertex.

Every group may only partake in one active rescue at a time. To start a new rescue, the group calls /start (this can only be done if there are no active rescues).

### Setup¶

The Guavabots live at an unknown set of locations $L$, where $|L|$ is known. The group's goal is to get them all to the home vertex in as little time as possible. In addition, there is a set of $k$ students that make an unknown number of mistakes.

### Score¶

At the end of each rescue, a score is assigned as defined in the problem statement.

## Endpoints¶

The api will be hosted at the root https://guavabot-api.cs170.org/. Prepend this root to all URLs mentioned in the spec after this point. The API takes and consumes JSON.

These are the endpoints called by groups:

• /start - Start a session. Assigns the city instance
• /end - End a session. The score is given
• /scout - Perform a "scout" action
• /remote - Perform a "remote" action
• /score - Get the score

### Authentication¶

Every group will be provided with a group token, which will be unique. The group must provide this token to every API call. The tokens will be assigned and distributed manually, and the API will know of all valid tokens.

There are two possible errors that may occur here:

• If the group does not provide a token, the API responds with 401 Unauthorized with the following body:
{
"error": "No group token",
"documentation_url": "https://guavabot.cs170.org/api/errors/#no-token"
}

• If the group provides a token not known, the API responds with 401 Unauthorized with the following body:
{
"error": "Invalid group token",
"documentation_url": "https://guavabot.cs170.org/api/errors/#invalid-token"
}


### Global Errors¶

If your request body is malformed (i.e. missing expected values or has the wrong type), the API reqspons with 403 Forbidden:

{
"error": "Malformed request",
"documentation_url": "https://guavabot.cs170.org/api/errors/#malformed-request"
}


### Rescue Start and End¶

#### POST /start¶

• Expects body of the form:
{
"group_token": "3d735c94165764ba"
}

• Replies with 200 OK:
{
"city": "toronto_0",
"home": 2,
"k": 10,
"l": 5,
"scout_time": 1,
"time": 0
}

• city describes a city ID, corresponding to a graph.
• home is a vertex in $G$.
• k is a positive natural number. It implicitly defines a set of students $S = \{1, \ldots, k\}$.
• l is a positive natural number. It defines the number of bots on the graph.
• scout_time is a positive natural number. It defines the time taken to scout.
• time is a non-negative integer. It defines the initial wall clock time. It must start at 0.

• If there is an active rescue, responds with 403 Forbidden:

{
"error": "Active rescue",
"documentation_url": "https://guavabot.cs170.org/api/errors/#active-rescue"
}


#### POST /end¶

• Expects body of the form:
{
"group_token": "3d735c94165764ba"
}

• Replies with 200 OK:
{
"score": 5000
}

• If there is no active rescue, responds with 403 Forbidden:
{
"error": "No active rescue",
"documentation_url": "https://guavabot.cs170.org/api/errors/#no-active-rescue"
}


### Actions¶

#### POST /scout¶

• Expects body of the form:
{
"group_token": "3d735c94165764ba",
"vertex": 10,
"students": [3, 5]
}


"students" must be a non-zero-length list of unique elements.

• Replies with 200 OK:
{
"reports": {
"3": true,
"5": false,
},
"time": 1000
}


The time field describes the new time. It has been incremented by $l \cdot s$, where $l$ is the number of students sent to the vertex.

Reports describes all the student reports, whether each student reports a bot there or not.

• If vertex or a student do not exist, or students is not a list or is an empty list, report Malformed scout:
{
"error": "Malformed scout",
"documentation_url": "https://guavabot.cs170.org/api/errors/#malformed-scout"
}

• If the vertex cannot be scouted (e.g. vertex is home), report Scout not allowed:
{
"error": "Scout not allowed",
"documentation_url": "https://guavabot.cs170.org/api/errors/#scout-not-allowed"
}

• If there is no active rescue, report No active rescue:
{
"error": "No active rescue",
"documentation_url": "https://guavabot.cs170.org/api/errors/#no-active-rescue"
}


A vertex cannot be scouted if it was involved in an earlier remote (either as a source or destination).

#### POST /remote¶

• Expects body of the form:
{
"group_token": "3d735c94165764ba",
"from_vertex": 10,
"to_vertex": 11
}

• Replies with 200 OK:
{
"bots_remoted": 3,
"time": 1000
}


The time field describes the new time. bots_remoted describes the number of bots that were at the from_vertex that have now all been moved to the to_vertex.

• If from_vertex == to_vertex, or either vertex is not in the graph, or the edge {from_vertex, to_vertex} is not in the graph, report malformed remote:
{
"error": "Malformed remote",
"documentation_url": "https://guavabot.cs170.org/api/errors/#malformed-remote"
}

• If there is no active rescue, report No active rescue:
{
"error": "No active rescue",
"documentation_url": "https://guavabot.cs170.org/api/errors/#no-active-rescue"
}


### Miscellaneous¶

#### POST /score¶

• Expects body of the form:
{
"group_token": "3d735c94165764ba"
}

• Replies with 200 OK:
{
"submit_token": "3d735c94165764ba3d735c94165764ba",
"completed": 30,
"remaining": 70
}


completed describes how many have been completed, remaining describes how many remaining. submit_token describes the current progress, summarized into a token