Как построить команду curl из модуля запросов python?

Запросы на Python - хороший модуль для облегчения программирования доступа к API для REST API, я обычно делаю это ниже

import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}

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

И когда появляется ошибка, я хочу посмотреть, что происходит за ней. Построение команды curl для воспроизведения в командной строке является обычным способом, так как это стандартный способ, который наиболее описан в документе документа RESP

try:
    r = requests.post(url, data=json.dumps(payload), headers=headers)
except Exception as ex:
    print "try to use curl command below to reproduce"
    print curl_request(url,"POST",headers,payload)

Хорошо, что я могу сгенерировать образец команды curl для этого запроса, см. хороший пример в libcloud debug, я не могу найти простой способ построения, ниже - метод, который я хочу создать самостоятельно.

# below code is just pseudo code, not correct 
def curl_request(url,method,headers,payloads):
    # construct curl sample from requests' structure
    # $ curl -v -H "Accept: application/json" -H "Content-type: application/json" 
    # -d '{"some":"data"}' 
    # -X POST https://api.github.com/some/endpoint
    request = "curl -v "
    for header in headers:
        print header
        request = request + '-H "' + header + ": " + headers[header] + '" '
    for payload in payloads:
        request = request + '-d {} "' + payload + ": " + payloads[payload] + '" '         
    request = request + "-X %s %s" % (method,url)
    return request

Также хорошо, если у нас есть метод в requests уже


Ниже приведены окончательные решения, ответы на которые мне помогут. Покажите его здесь для справки

def curl_request(url,method,headers,payloads):
    # construct the curl command from request
    command = "curl -v -H {headers} {data} -X {method} {uri}"
    data = "" 
    if payloads:
        payload_list = ['"{0}":"{1}"'.format(k,v) for k,v in payloads.items()]
        data = " -d '{" + ", ".join(payload_list) + "}'"
    header_list = ['"{0}: {1}"'.format(k, v) for k, v in headers.items()]
    header = " -H ".join(header_list)
    print command.format(method=method, headers=header, data=data, uri=url)    

Ответ 1

Этот метод существовал в запросах один раз, но он далеко не удаленно относится к модулю. Вы можете создать функцию, которая принимает ответ и проверяет его атрибут request.

Атрибут request - это объект PreparedRequest, поэтому он имеет атрибуты headers и body. Тело - это то, что вы проходите, чтобы скручиваться с -d, и заголовки могут быть сгенерированы, как вы это делали выше. Наконец, вы захотите вырвать атрибут url из объекта request и отправить его. Перехватчики не имеют значения для вас, если вы ничего не делаете с помощью специального обработчика проверки подлинности.

req = response.request

command = "curl -X {method} -H {headers} -d '{data}' '{uri}'"
method = req.method
uri = req.url
data = req.body
headers = ['"{0}: {1}"'.format(k, v) for k, v in req.headers.items()]
headers = " -H ".join(headers)
return command.format(method=method, headers=headers, data=data, uri=uri)

Это должно сработать. Ваши данные будут правильно отформатированы, будь то multipart/form-data или что-то еще.

Ответ 2

Вы также можете использовать curlify, чтобы сделать это.

$ pip install curlify
...
import curlify
print(curlify.to_curl(r.request)) // r is the response object from the requests lib