Подтвердить что ты не робот

Почему тело запроса HTTP POST должно быть JSON, зарегистрированное в Python?

Я столкнулся с этой проблемой при игре с внешним API. Я отправлял данные своего тела в виде словаря прямо в запрос и получал 400 ошибок:

data = {
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
}

Когда я добавил обертку json.dumps, он работает:

data = json.dumps({
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
})

Я не совсем понимаю, почему это необходимо, поскольку словари и объекты JSON синтаксически идентичны. Может кто-нибудь помочь мне понять, что здесь происходит за кулисами?

Для полноты, вот мои заголовки:

headers = {'API-KEY': 'blerg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*', 'username': 'user', 'password': 'pwd'}

EDIT:

Я не упоминал об этом раньше, но теперь чувствую, что это может быть актуальным. Я использую библиотеку запросов Python, а другая публикация, похоже, предполагает, что вам никогда не придется кодировать параметры для объекта запроса: qaru.site/info/9731/...

"Независимо от того, не нужно ли снова и снова вводить параметры GET/POST, он просто вводит словарь в качестве аргумента и имеет смысл идти".

Кажется, что сериализация не нужна?

Мой объект запроса:

response = requests.post(url, data=data, headers=headers)
4b9b3361

Ответ 1

Очевидно, ваш API требует JSON-кодированных и неформатированных данных. Когда вы передаете dict в качестве параметра data, данные кодируются в форме. Когда вы передаете строку (например, результат json.dumps), данные не закодированы в форме.

Рассмотрим эту цитату из документации запросов:

Как правило, вы хотите отправить некоторые данные, закодированные в форме, - как HTML-форму. Для этого просто передайте словарь в аргумент данных. Ваш словарь данных будет автоматически закодирован в форму при запросе.

     

Существует много раз, когда вы хотите отправить данные, которые не закодированы в форме. Если вы передадите строку вместо dict, эти данные будут опубликованы напрямую.

     

Например, API-интерфейс GitHub v3 принимает данные POST/PATCH с кодировкой JSON:

>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

Refs:

Ответ 2

Хотя они кажутся синтаксическими, существует разница: JSON представляет собой строковое представление сериализованного объекта; в этом случае Python dict. В этом примере вам нужно отправить сериализованные данные в форме строки, и поэтому для выполнения сериализации необходимо использовать json.dumps.

изменить

Как было предложено в комментариях к вопросу, это относится к используемому API, но тем не менее сериализация должна выполняться где-то по пути отправки объекта по проводу.