Endpoints ========================================================== *Tarot Routing - Route Optimisation API* Base URL -------- ``https://opt.route.optimiser.app`` Use this URL as the base for all requests on this page. Synchronous Route Optimisation API ---------------------------------- .. http:post:: /v0.40/vrp A synchronous endpoint for Route Optimisation requests :reqheader Authorization: ``Authorization: Token `` The word "Token" followed by a space, followed by your Tarot Routing Token. Don't have one? Contact us info@tarotanalytics.com :reqheader Content-Type: ``Content-Type: application/json`` :reqjson list[Job] jobs: :py:data:`Jobs ` to be considered in the optimisation :reqjson list[Driver] drivers: :py:data:`Drivers ` available to serve those Jobs :reqjson Settings settings: :py:data:`Settings` which govern this optimisation :resjson list[Run] runs: A list of optimised runs. Each :py:data:`Run` has a ":py:data:`driver `" and a list of ":py:data:`jobs `" :resjson list[Job] unserved_jobs: A list of :py:data:`Jobs ` which the optimiser could not serve with the available :py:data:`Drivers ` and Constraints. :statuscode 200: :statuscode 400: Check response body for details :statuscode 401: Misformed or Missing Authorization header :statuscode 403: Invalid or Expired Token .. dropdown:: Example Request :color: light .. literalinclude:: _static/ex1.json :language: json :caption: Request Body ``ex1.json`` .. tabs:: .. tab:: bash .. literalinclude:: _static/optimise_req.sh :language: bash .. tab:: python .. literalinclude:: _static/optimise_req.py :language: python .. dropdown:: Example Response :color: light .. literalinclude:: _static/resp1.json :language: json :caption: Response Body | | Asynchronous Route Optimisation API ----------------------------------- A set of endpoints for asynchronous Route Optimisation :ref:`Learn how it works. ` Start Optimisation ^^^^^^^^^^^^^^^^^^ .. http:post:: /v0.40/polling/vrp Start solving your optimisation problem. Note that the request body is identical to the Synchronous Route Optimisation API :reqheader Authorization: ``Authorization: Token `` The word "Token" followed by a space, followed by your Tarot Routing Token. Don't have one? Contact us info@tarotanalytics.com :reqheader Content-Type: ``Content-Type: application/json`` :reqjson list[Job] jobs: :py:data:`Jobs ` to be considered in the optimisation :reqjson list[Driver] drivers: :py:data:`Drivers ` available to serve those Jobs :reqjson Settings settings: :py:data:`Settings` which govern this optimisation :resjson uid: You will use this unique identifier in subsequent requests to ask for status updates and receive the solution for this optimisation. :resjson status: Make GET requests to this URL to understand how the optimisation is progressing, whether a solution is available, and whether the optimisation is still running. :resjson solution: **After** a status update informs you there is a Solution, make a GET request to this URL to get the Solution. :statuscode 201: Successfully started optimising :statuscode 400: Check response body for details :statuscode 401: Misformed or Missing Authorization header :statuscode 403: Invalid or Expired Token .. dropdown:: Example Request :color: light .. literalinclude:: _static/ex1.json :language: json :caption: Request Body ``ex1.json`` .. tabs:: .. tab:: bash .. code-block:: bash TOKEN=your_tarot_routing_token RESP=$(curl https://opt.route.optimiser.app/v0.40/polling/vrp \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ --data "@ex1.json") VRP_UID=$(echo $RESP | jq -r .uid) echo $VRP_UID # 01GG7AEX026F47CS4NK2JBCE5G .. tab:: python .. code-block:: python import json, requests token = 'Your Tarot Routing Token' with open('ex1.json') as f: body = json.load(f) r = requests.post( url='https://opt.route.optimiser.app/v0.40/polling/vrp', headers={'Content-Type': 'application/json', 'Authorization': 'Token ' + token}, json=body, ) uid = r.json()['uid'] print(uid) # 01GG7AEX026F47CS4NK2JBCE5G .. dropdown:: Example Response :color: light .. literalinclude:: _static/polling_resp.json :language: json :caption: Response Body | | Get Optimisation Status ^^^^^^^^^^^^^^^^^^^^^^^ .. http:get:: /v0.40/polling/vrp/{uid}/status Get the latest status of your optimisation request. :param string uid: The unique identifier for this Optimisation. :resjson string uid: The unique identifier for this Optimisation. :resjson datetime timestamp: The time that this status update was created in `ISO8601 Format `_ :resjson string message: A message to let you know what the optimiser is currently doing (or why it stopped). :resjson bool solving: ``true`` if the optimiser is still solving. ``false`` if it has finished. :resjson int cost: The optimiser has a number which represents how good it's latest solution is. A solution with a lower ``cost`` is better. i.e. it serves more jobs, respects more constraints, has less driving time, etc. The `cost` is dimensionless, and cannot be compared across different optimisations. :resjson datetime next_status_eta: An estimate of the time that the Optimiser will provide its next status, in `ISO8601 Format `_ Instead of polling *regularly* (e.g. every 5 seconds), you should wait until the ``next_status_eta`` to ``GET`` the next status. It is only an estimate, so you should still fallback to a regular poll (e.g. every 5 seconds) in case there's no status update by the ``next_status_eta``. :statuscode 200: :statuscode 400: Check response body for details :statuscode 401: Misformed or Missing Authorization header :statuscode 403: Invalid or Expired Token **Example Request:** .. tabs:: .. tab:: bash .. code-block:: bash TOKEN=your_tarot_routing_token VRP_UID=01GG7AEX026F47CS4NK2JBCE5G RESP=$(curl "https://opt.route.optimiser.app/v0.40/polling/vrp/${VRP_UID}/status" \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json") SOLVING=$(echo $RESP | jq .solving) echo $SOLVING # true .. tab:: python .. code-block:: python import requests token = 'Your Tarot Routing Token' vrp_uid = '01GG7AEX026F47CS4NK2JBCE5G' r = requests.get( url=f'https://opt.route.optimiser.app/v0.40/polling/vrp/{vrp_uid}/status', headers={'Content-Type': 'application/json', 'Authorization': 'Token ' + token}, ) solving = r.json()['solving'] print(solving) # True .. dropdown:: Example Responses :color: light .. literalinclude:: _static/status_started_resp.json :language: json :caption: The first status after the Optimiser starts solving, before it has found a first solution. ``cost=0`` implies no solution has been found yet. .. literalinclude:: _static/status_solving_resp.json :language: json :caption: After a first solution is found, while the optimiser is still solving .. literalinclude:: _static/status_solved_resp.json :language: json :caption: ``solving=false`` indicates the optimiser has finished solving. The message lets you know why it stopped: Time Limit, Improvement Threshold, or Local Minimum if ``quick_opt=true``. | | Get Solution ^^^^^^^^^^^^ .. http:get:: /v0.40/polling/vrp/{uid} Get the (latest) Solution for your Optimisation request :param string uid: The unique identifier for this Optimisation. :resjson list[Run] runs: A list of optimised runs. Each :py:data:`Run` has a ":py:data:`driver `" and a list of ":py:data:`jobs `" :resjson list[Job] unserved_jobs: A list of :py:data:`Jobs ` which the optimiser could not serve with the available :py:data:`Drivers ` and Constraints. :statuscode 200: Succesfully got Solution :statuscode 400: Check response body for details :statuscode 401: Misformed or Missing Authorization header :statuscode 403: Invalid or Expired Token **Example Request:** .. tabs:: .. tab:: bash .. code-block:: bash TOKEN=your_tarot_routing_token VRP_UID=01GG7AEX026F47CS4NK2JBCE5G curl "https://opt.route.optimiser.app/v0.40/polling/vrp/${VRP_UID}" \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" .. tab:: python .. code-block:: python import requests token = 'Your Tarot Routing Token' vrp_uid = '01GG7AEX026F47CS4NK2JBCE5G' r = requests.get( url=f'https://opt.route.optimiser.app/v0.40/polling/vrp/{vrp_uid}', headers={'Content-Type': 'application/json', 'Authorization': 'Token ' + token}, ) .. dropdown:: Example Response :color: light .. literalinclude:: _static/resp1.json :language: json :caption: Response Body | | End to End Polling Optimisation Example ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To make this example work, you will need 1. A Tarot Routing account 2. Your Tarot Routing email and password stored in environment variables ``TAROT_EMAIL`` and ``TAROT_PASSWORD`` 3. A valid :ref:`RoutingProblem` file .. code-block:: bash :caption: Get your email and password into environment variables export TAROT_EMAIL='info@tarotanalytics.com' export TAROT_PASSWORD='my$3cr37P@ssw0rd' .. code-block:: bash :caption: Get an Example RoutingProblem wget https://docs.opt.route.optimiser.app/_static/ex1.json .. code-block:: bash :caption: Get the python example code wget https://docs.opt.route.optimiser.app/_static/solve_polling.py .. code-block:: bash :caption: Run the example pip install requests python optimise_polling.py ex1.json .. tabs:: .. tab:: python .. code-block:: bash :caption: Run the example pip install requests python optimise_polling.py ex1.json .. literalinclude:: _static/optimise_polling.py :language: python :caption: A complete example of how to use the Polling Optimiser. It shows Authentication, Starting the Optimisation, Checking Status, and Getting the Solution.