Python – How to do a basic REST Post with Requests in Python

jsonpostpythonpython-requestsrest

I am having trouble using Requests

The API I am testing indicates the parameter device_info to be POSTED in the message body. It also says that the device_info as a form field. In all the documentation for Requests I cannot find how to add a "name" to the parameter other than slap the name with it's value in json. Here is what I have tried.

import requests
import json

loginPayload = {'device_info':{'app-id':'fc','os-type':'ios'}}
loginHeaders = {'content-type': 'application/json','Authorization':'Basic base64here'}
loginUrl = "http://subdomain.test.com/endpoint/method"
loginPost = requests.post(loginUrl, params=json.dumps(loginPayload), headers=loginHeaders)

print loginPost.text

I have tried changing params= to data= but I've had no luck.

The response back I'm getting is:

{
"response": {
"message": "Parameter 'device_info' has invalid value ()", 
"code": 400, 
"id": "8c4c51e4-9db6-4128-ad1c-31f870654374"
  }
}

EDITED:

Getting somewhere new! I have no modified my code to look as follows:

import requests

login = 'test'
password = 'testtest'
url = "http://subdomain.domain.com/endpoint/method"

authentication = (login,password)
payload = {'device_info': {'device_id': 'id01'}}
request = requests.post(url, data=payload, auth=authentication)

print request.text

Which produces:

{
  "response": {
    "message": "Parameter 'device_info' has invalid value (device_id)", 
    "code": 400, 
    "id": "e2f3c679-5fca-4126-8584-0a0eb64f0db7"
  }
}

What seems to be the the issue? Am I not submitting it in the required format?

EDITED: The solution was changing my parameters to:

{
    "device_info": "{\"app-id\":\"fc\",\"os-type\":\"ios\",\"device_id\":\"myDeviceID1\"}"
}

Best Answer

So there are a few issues here:

  • You don't say that the website you're posting to requires JSON data, in fact in your comment you say that "the encoding that is required is 'application/x-www-form-urlencoded'.
  • params refers to the parameters of the query string. What you need is the data parameter.

So if your application is looking for 'application/x-www-form-urlencoded' data you should NOT be:

  • Setting the Content-Type header
  • Using json.dumps on your payload data

What you should do is the following:

import requests

login_payload = {'device_info': {'app-id': 'fc', 'os-type': 'os'}}
authentication = (login, password)  # Anyone who sees your authorization will be able to get this anyway
url = 'http://example.com/login'
response = requests.post(url, data=login_payload, auth=authentication)

I don't know of a RESTful API that takes x-www-form-urlencoded data, but you could also be describing your issue incorrectly. You haven't given us much to go on and you haven't given me more than the ability to guess. As such, this is my absolute best guess based on everything else you said.