# Network Design Example

The following example showcases how to call the API with the Python `requests`
library, using an API key for authentication. To use it:

- Install the Python `requests` library. From your command line: `pip install
  requests`.
- Save the following Python program to your computer, naming it `example.py`.
- Save the [example_request.json](https://developers.google.com/static/optimization/service/shipping/design_shipping_network_request.json) file in the same directory as your program (this is a sample JSON [request](https://developers.google.com/optimization/service/reference/rest/v1/shipping/designShippingNetwork)).
- Create a `credentials.json` file in the same directory as your program, with `{"key": "your_api_key"}`
- Run the example from the command line: `python example.py`.


    # example.py
    import json
    import requests

    def run_example():
        """Calls the OR API to solve a shift scheduling problem."""
        
        # Endpoint for the workforce scheduling solver in the OR API.
        end_point = "https://optimization.googleapis.com/v1/shipping:designShippingNetwork"
        
        # Read the API Key from a JSON file with the format:
        # {"key": "your_api_key"}
        with open("credentials.json") as f:
            credentials = json.load(f)
            api_key = credentials["key"]

        # Load the JSON file with the request.
        with open("example_request.json", "r") as f:
            json_request = json.load(f)

        # Call the API post method.
        response = requests.post(f"{end_point}?key={api_key}", json=json_request)

        # Process the response.
        if response.ok:
            solution = json.loads(response.content)
            with open("example_response.json", "w") as f:
                json.dump(solution, f, indent=2)
            print(solution)
        else:
            error = json.loads(response.content)["error"]
            print(f'Status code {error["code"]}: {error["message"]}')

    if __name__ == "__main__":
        run_example()

## How to set deadlines?

A deadline determines the maximum wall time that a call to the API should take.
A user can set both client and server deadlines. In the context of the OR API, a
server deadline is the more useful one as it informs the backend server of how
much time it has to receive a request, run the underlying solver, and return a
response. In contrast, client deadlines are useful to set the maximum time that
the client application (i.e., the application calling the OR API) is going to
wait for a response, before timing out.

The following code snippet sets both a client and a server deadline in the
session headers of the request. The client deadline is set to 60 seconds. The
server deadline should be less than the client deadline to account for
communication overhead. Here we set the server deadline to be 95% of the client
deadline, but this can vary depending on the application. Notice that the API
key was also moved to the session headers to make the `session.post(...)` call
cleaner.



    # Call the API post method.
    session = requests.Session()
    client_deadline_seconds = 60
    server_deadline_seconds = 0.95 * client_deadline_seconds
    session.headers = {
        "Content-Type": "application/json",
        "Connection": "keep-alive",
        "Keep-Alive": f"timeout={client_deadline_seconds}, max=1",
        "X-Server-Timeout": f"{server_deadline_seconds}",
        "X-Goog-Api-Key": api_key,
    }
    response = session.post(end_point, json=json_request, timeout=client_deadline_seconds)