Отправка запросов с помощью скриптов

Для отправки запросов к API календарного планирования, требующих подпись, можно использовать подготовленные скрипты на Python.

Для работы со скриптами вам потребуется API-ключ и секрет. Чтобы получить секрет, обратитесь к вашему клиентскому менеджеру или напишите в службу поддержки. Подставьте значение API-ключа в поле APIKEY, а секрет — в поле SECRET.

Подпись вычисляется скриптом автоматически на основе данных запроса.

Запрос на запуск задачи отправляется с помощью библиотеки requests.

Запуск планирования с помощью скрипта

Чтобы запустить задачу календарного планирования через API:

  1. Создайте файл request.json и поместите в него тело запроса. Структуру JSON-запроса см. в спецификации.

  2. В той же папке создайте файл script.py и скопируйте в него следующий скрипт на Python:

#!/usr/bin/env python3

import hashlib
import hmac
import json
import requests
import sys
import time
import urllib3
from urllib.parse import urlencode
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


APIKEY = '<ваш API-ключ>'
SECRET = '<ваш secret>'
SOLVER_URL = 'https://courier.yandex.ru'
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()
  1. Запустите скрипт командой python3 script.py request.json.

Получение результата планирования с помощью скрипта

Чтобы получить результат календарного планирования через API:

  1. Создайте файл script.py и скопируйте в него следующий скрипт на Python:
import requests
import hashlib
import hmac
from urllib.parse import urlencode

SECRET = '<ваш secret>'
APIKEY = '<ваш API-ключ>'
TASK_ID = '<идентификатор задачи>'
USER_AGENT = 'RouteQ Support Agent/1.0'
METHOD = 'GET'
BASE_URL = 'https://courier.yandex.ru'
PATH = f'/vrs/api/v1/calendar_planning/tasks/{TASK_ID}/result'
PARAMS = {'apikey': APIKEY}
BODY = ""

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

full_uri_for_signing = f"{PATH}?{urlencode(PARAMS)}"

parts_to_sign = [
    USER_AGENT,
    METHOD,
    " ",
    full_uri_for_signing,
    BODY
]

signature = gen_signature(SECRET, parts_to_sign)


headers = {
    'User-Agent': USER_AGENT,
    'X-YaCourier-Signature': signature
}

print("--- Debug Info ---")
print(f"URL для запроса: {BASE_URL}{PATH}")
print(f"Параметры: {PARAMS}")
print(f"Заголовки: {headers}")
print(f"Строка URI для подписи: {full_uri_for_signing}")
print("------------------\n")

try:
    response = requests.get(
        url=f"{BASE_URL}{PATH}",
        headers=headers,
        params=PARAMS
    )

    print(f"HTTP/1.1 {response.status_code} {response.reason}")
    for header, value in response.headers.items():
        print(f"{header}: {value}")

except requests.exceptions.RequestException as e:
    print(f"Произошла ошибка при выполнении запроса: {e}")
  1. Подставьте идентификатор задачи в поле TASK_ID.
  2. Запустите скрипт командой python3 script.py.
Написать в службу поддержки