Как передать необработанные данные POST в urllib3?

Попытка использовать urllib3 для публикации данных в формате JSON. Просто хочу, чтобы моя полезная нагрузка POST была необработанной строкой JSON с типом контента application/json. Я просто не вижу, как это сделать.

Документация urllib3 описывает публикацию данных в «полях», т. е. в словарях с парами (ключ, значение), например, как HTML-формы кодируются URL-адресом с URL-адресом. Но я не хочу этого делать.

Самое близкое, что мне удалось получить, это (я просто догадался, куда поместить данные, так как они нигде не задокументированы):

http = urllib3.PoolManager()
headers = urllib3.util.make_headers(basic_auth=key+":")
r = http.request_encode_body('POST', path, json.dumps(payload), headers=headers)

что вызывает эту ошибку urllib3:

File "C:\Python27\lib\site-packages\urllib3-1.7.1-py2.7.egg\urllib3\filepost.py", line 44, in iter_field_objects
yield RequestField.from_tuples(*field)
TypeError: from_tuples() takes exactly 3 arguments (2 given)

Спасибо за любые указатели!


person user2855982    schedule 07.10.2013    source источник
comment
Используйте модуль запросов для Python.   -  person Andreas Jung    schedule 07.10.2013
comment
@ user2799617: модуль запросов предоставляет удобный, но очень узкий интерфейс over urllib3, для некоторых задач, таких как асинхронное программирование, использование запросов нецелесообразно, но использование более явного интерфейса, предоставляемого urllib3, вполне работоспособно. . в любом случае, urllib3 намного удобнее, чем любая из встроенных библиотек Python (httplib или urllib/urllib2).   -  person SingleNegationElimination    schedule 08.10.2013


Ответы (1)


для этого нельзя использовать PoolManager.request, он пытается сам состряпать тело, используйте нижний уровень urlopen:

In [16]: pool = urllib3.PoolManager()

In [17]: print pool.urlopen('POST', 'http://httpbin.org/post', headers={'Content-Type':'application/json'}, body='{"sup":"son"}').data
{
  "data": "{\"sup\":\"son\"}",
  "form": {},
  "json": {
    "sup": "son"
  },
  "origin": "50.74.23.243",
  "args": {},
  "url": "http://httpbin.org/post",
  "files": {},
  "headers": {
    "Host": "httpbin.org",
    "Content-Length": "13",
    "Content-Type": "application/json",
    "Accept-Encoding": "identity",
    "Connection": "close"
  }
}
person SingleNegationElimination    schedule 07.10.2013
comment
^- Это правильно. RequestMethods.request_encode_body(...) слишком высокоуровневый для op, так как он попытается закодировать для вас параметр, похожий на поле dict. Нижний уровень pool.urlopen(..., body=payload) — это именно то, что нужно оператору. Читая документы сейчас, я вижу, что не очевидно, что это то, что происходит. Запрос на вытягивание с улучшенными документами был бы прекрасен. :) - person shazow; 08.10.2013