Тип аргумента данных в запросах

#python #json #curl #python-requests

Вопрос:

Рассмотрим (взято из этого документа):

 curl -v POST https://api-m.sandbox.paypal.com/v1/oauth2/token 
  -H "Accept: application/json" 
  -H "Accept-Language: en_US" 
  -u "CLIENT_ID:SECRET" 
  -d "grant_type=client_credentials"
 

Здесь используется знак равенства -d . Конвертер завитков переводит это на Python следующим образом:

 import requests

headers = {
    'Accept': 'application/json',
    'Accept-Language': 'en_US',
}

data = {
  'grant_type': 'client_credentials'
}

response = requests.post('https://api-m.sandbox.paypal.com/v1/oauth2/token', headers=headers, data=data, auth=('CLIENT_ID', 'SECRET'))
 

Обратите внимание, что data это словарь.

С другой стороны, рассмотрите (взято из этого документа):

 curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders 
-H "Content-Type: application/json" 
-H "Authorization: Bearer Access-Token" 
-d '{
  "intent": "CAPTURE",
  "purchase_units": [
    {
      "amount": {
        "currency_code": "USD",
        "value": "100.00"
      }
    }
  ]
}'
 

Конвертер завитков переводит это на Python следующим образом:

 import requests

headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer Access-Token',
}

data = '{n  "intent": "CAPTURE",n  "purchase_units": [n    {n      "amount": {n        "currency_code": "USD",n        "value": "100.00"n      }n    }n  ]n}'

response = requests.post('https://api-m.sandbox.paypal.com/v2/checkout/orders', headers=headers, data=data)
 

В данном случае data это строка.

Я запустил оба кода Python, и они действительно верны. Кроме того, в первом примере, если я построю словарь, он не будет работать. Аналогично, во втором примере, если я попытаюсь использовать словарь, как и в первом, это не сработает.

Почему data в этих двух примерах разные типы (версия Python)? Когда это должен быть словарь, а когда это должна быть строка? Чем знак равенства отличается от двоеточия в завитке?

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

1. Я думаю, что конвертер завитков, должно быть, ошибается. Во втором примере data должен быть объект словаря в моей версии. Насколько мне известно, запросы строят data объект при выполнении запроса к API.

2. Post кодирует словари, переданные data для формирования данных по умолчанию: docs.python-requests.org/en/latest/user/quickstart/. … Для JSON вы передаете словарь как json или, как в вашем примере, сначала строчите его.

3. @rv.кветч Как я написал в вопросе, версия, созданная конвертером, работала, в то время как версия со словарем-нет.

4. @jonrsharpe Как я уже писал в вопросе, первый пример работал только как словарь, а второй-только как строка…

5. Да, я это понимаю. Ссылка выше объясняет, почему. Если вы преобразуете словарь в JSON в первом примере, вы больше не отправляете данные формы , поэтому неудивительно, что это не работает — как минимум, если сервер примет его, вам нужно будет соответствующим образом установить заголовок типа содержимого (как во втором примере). данные могут быть словарем, если вы хотите отправить данные формы, потому что для этого они сериализуются — если вы хотите отправить что-либо еще, включая JSON, вам нужно сериализовать их в строку самостоятельно (вы также можете сериализовать данные для формирования самостоятельно, но зачем беспокоиться).