9.2 Synchronous

For the purpose of the tutorial we assume that the problem to be solved is read from a file, and the solutions will be saved to a file, i.e. we don’t go into the logic which sets up the problem and interprets the solution. See file formats for specifications of file formats.

We demonstrate synchronous optimization, see Sec. 7.1 (Synchronous Optimization). Assuming that an HTTP/HTTPS connection to the OptServer was established, we first submit a problem using submit. The file format is passed in the Content-Type header.

Listing 9.5 Submit a problem.
            # POST problem data
            submit = s.post(URL + "/api/v1/submit", 
                            data = probdata,
                            headers = { "Content-Type" : intype },
                            verify = verify )

            if submit.status_code == 200:
                token = submit.headers['X-Mosek-Job-Token']

The response contains a token used to identify the job in future requests. If no errors have occurred, we use solve to request running the solver for the given job token. When requesting the solution we set the Accept header to indicate expected solution format.

Listing 9.6 Starting the solver synchronously.
                # Request the server to solve the problem
                solve = s.get(URL + "/api/v1/solve", 
                              headers = { "X-Mosek-Job-Token" : token,
                                          "Accept": outtype },
                              verify = verify )

The request will return when optimization terminates. If there were no errors, the status codes are available in the headers and the solution in the body of the response.

Listing 9.7 Retrieving results.
                if solve.status_code == 200:
                    if outtype in ["application/json", "application/x-mosek-jtask"]:
                        solution = json.loads(solve.text)
                    else:
                        solution = solve.text
                    res = solve.headers["X-Mosek-Res-Code"]
                    trm = solve.headers["X-Mosek-Trm-Code"]

It is also possible to retrieve the log from the solver (log):

Listing 9.8 Retrieving optimization log.
                    # Obtain the solver log output
                    log = s.get(URL + "/api/v1/log",
                                headers = { "X-Mosek-Job-Token" : token },
                                verify = verify )
                    print(log.text)

The full example is shown below.

Listing 9.9 How to submit a job and solve the problem synchronously. Click here to download.
    # Create a connection
    with requests.Session() as s:
        with open(infile,'rb') as probdata:
            # POST problem data
            submit = s.post(URL + "/api/v1/submit", 
                            data = probdata,
                            headers = { "Content-Type" : intype },
                            verify = verify )

            if submit.status_code == 200:
                token = submit.headers['X-Mosek-Job-Token']
                print("Submit: success")

                # Request the server to solve the problem
                solve = s.get(URL + "/api/v1/solve", 
                              headers = { "X-Mosek-Job-Token" : token,
                                          "Accept": outtype },
                              verify = verify )

                if solve.status_code == 200:
                    if outtype in ["application/json", "application/x-mosek-jtask"]:
                        solution = json.loads(solve.text)
                    else:
                        solution = solve.text
                    res = solve.headers["X-Mosek-Res-Code"]
                    trm = solve.headers["X-Mosek-Trm-Code"]

                    # Obtain the solver log output
                    log = s.get(URL + "/api/v1/log",
                                headers = { "X-Mosek-Job-Token" : token },
                                verify = verify )
                    print(log.text)

                    print(f"Solution: {solution}")
                    print(f"Response code:    {res}")
                    print(f"Termination code: {trm}")
                else:
                    print(f"Error solving the problem, status = {solve.status_code}")
            else:
                print(f"Unexpected status {submit.status_code}")
                print(f"Response: {submit.text}")
                print(f"Headers:  {submit.headers}")