Запрос к API с использованием Python urllib

Добрый день.
Подскажите пожалуйста, как выполнить POST запрок с API iTop, используя только стандартную библиотеку Python3 без requests?
При отправке запроса мне возвращается ошибка, что auth_user не указан. Как делаю:

  1. Формирую словарь {“auth_user”: user, “auth_pwd”: password, “json_data”: {…}}
  2. Перевожу его в строку json.dumps() + encode(‘utf-8’)
  3. Получившуюся последовательность прикрепляю к объекту Request вместе с заголовком ‘Content-Type: application/x-www-form-urlencoded’
  4. Ошибка: Missing parameter auth_user

Привет!
Про python не скажу, но такая ошибка возникает тогда, когда айтоп не может выбрать auth_user/auth_pwd из запроса. Попробуй auth_user и auth_pwd передать в url (не json, а именно query параметрами вслед за version: http://itop/webservices/rest.php?version=1.3&auth_user=admin&auth_pwd=password). Либо используй Basic авторизацию. При этом в конфиге должны быть включены соответствующие login_mode.

Я так и думал сделать, но всё же интересно как правильно сформировать body в urllib.
С requests таких проблем нет, но я не знаю как он точно передаёт тело запроса.

Думаю, тут проблема в том, что ты переводишь в urlencoded весь json {“auth_user”: user, “auth_pwd”: password, “json_data”: {…}}, а надо переводить только значение json_data. В твоем случае тело получается:

%7B%22auth_user%22%3A%22admin%22%2C%22auth_pwd%22%3A%22password%22%2C%22json_data%22%3A%7B%22param%22%3A%22val%22%7D%7D

А должно быть:

auth_user=admin&auth_pwd=password&json_data=%7B%22param%22%3A%22val%22%7D

Я бы мог закодировать только часть JSON, но весь body должен иметь тип bytes.
Можно передать auth_user/auth_pwd в качестве аргументов URL, да, тогда начинает ругаться на отсутствующий json_data. =)

Всё тело POST-запроса c Content-Type: application/x-www-form-urlencoded с должно выглядеть так:

То есть названия параметров и “=” не должны перекодироваться в urlencoded.