Start planning with a script

You can run a Calendar Planning task via the API using a Python script. To run the script, call the command python3 script.py request.json.

You need an API key and a secret to work with the Calendar Planning API. To get a secret, contact your client manager or support.

The request signature is calculated automatically based on the request body.

You can send a request for running a task using the requests library. Specify the API key value in the APIKEY field and the secret value in the SECRET field.

#!/usr/bin/env python3

import hashlib
import hmac
import json
import requests
import sys
import time
from urllib.parse import urlencode


APIKEY = '<your API key>'
SECRET = '<your secret>'
SOLVER_URL = 'https://courier.yandex.com'
USER_AGENT = 'RouteQ Support Agent/1.0'
CALENDAR_PLANNING_URI = '/vrs/api/v1/calendar_planning/tasks'


def gen_signature(key, parts):
    HMAC = hmac.new(bytes.fromhex(key), None, digestmod=hashlib.sha256)
    for part in parts:
        HMAC.update(part.encode('utf-8'))
    return HMAC.hexdigest()


def make_request(method, uri, **kwargs):
    body = json.dumps(kwargs['json']) if kwargs.get('json') else ''
    signature = gen_signature(SECRET,[USER_AGENT, method, ' ', uri, body])
    url = SOLVER_URL + uri
    headers = {
        'X-YaCourier-Signature': signature,
        'User-Agent': USER_AGENT,
    }

    print(f"{method} {url}")
    response = requests.request(method, url, verify=False, headers=headers, **kwargs)
    return response


def add_task(task):
    params = {'apikey': APIKEY}
    uri = f"{CALENDAR_PLANNING_URI}?{urlencode(params)}"

    response = make_request('POST', uri, json=task)
    response.raise_for_status()
    j = response.json()

    return j['id']


def get_status(task_id):
    params = {'apikey': APIKEY}
    uri = f"{CALENDAR_PLANNING_URI}/{task_id}/status?{urlencode(params)}"

    response = make_request('GET', uri)
    response.raise_for_status()
    j = response.json()
    print(j)

    return j['status']


def get_result(task_id):
    params = {'apikey': APIKEY}
    uri = f"{CALENDAR_PLANNING_URI}/{task_id}/result?{urlencode(params)}"

    response = make_request('GET', uri)
    response.raise_for_status()
    j = response.json()

    return j


def main():
    with open(sys.argv[1]) as fd:
        task = json.load(fd)

    task_id = add_task(task)

    while get_status(task_id) != 'completed':
        time.sleep(2)

    result = get_result(task_id)
    print(json.dumps(result)[:100])


if __name__ == '__main__':
    main()
Contact support