Python: преобразование из библиотеки запросов в urllib3

#python #curl #python-requests #urllib3

#python #curl #python-запросы #urllib3

Вопрос:

Мне нужно преобразовать следующую команду CURL в http-запрос на Python:

 curl -X POST https://some/url
-H 'api-key: {api_key}'
-H 'Content-Type: application/json'
-H 'Accept: application/json'
-d '{ "data": { "dirname": "{dirname}", "basename": "{filename}", "contentType": "application/octet-stream" } }'

  

Изначально я успешно реализовал запрос, используя библиотеку запросов Python.

 import requests

url = 'https://some/url'
api_key = ...
dirname = ...
filename = ...

headers = {
    'api-key': f'{api_key}',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
}

payload = json.dumps({
    'data': {
        'dirname': f'{dirname}',
        'basename': f'{filename}',
        'contentType': 'application/octet-stream'
    }
})

response = requests.post(url, headers=headers, data=payload)
  

Позже клиент попросил не использовать pip для установки библиотеки запросов. Для этого я пытаюсь использовать библиотеку urllib3 следующим образом:

 import urllib3

url = 'https://some/url'
api_key = ...
dirname = ...
filename = ...

headers = {
    'api-key': f'{api_key}',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
}

payload = json.dumps({
    'data': {
        'dirname': f'{dirname}',
        'basename': f'{filename}',
        'contentType': 'application/octet-stream'
    }
})

http = urllib3.PoolManager()
response = http.request('POST', url, headers=headers, body=payload)
  

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

Ответ №1:

Попробуйте вызвать .encode('utf-8') on payload перед передачей в качестве параметра.

В качестве альтернативы попробуйте передать полезную нагрузку as fields , не преобразовывая ее вручную в JSON:

 payload = {
  'data': {
    'dirname': f'{dirname}',
    'basename': f'{filename}',
    'contentType': 'application/octet-stream'
  }
}
http = urllib3.PoolManager()
response = http.request('POST', url, headers=headers, fields=payload)
  

Комментарии:

1. Спасибо за ваш ответ, но, к сожалению, я безуспешно перепробовал все ваши предложения («encode (‘utf-8’)» возвращает ту же ошибку 400, а использование «полей» без «json.dumps» возвращает ошибку «требуется байтоподобный объект, а не dict»)

2. Он возвращает вам 400 ответов, но содержит ли он какое-либо сообщение / полезную нагрузку в ответе с подробностями?

3. response.msg равно None, а response.reason — «Плохой запрос»

4. как это было решено?