Python Request Post with param data - python

This is the raw request for an API call:
POST http://192.168.3.45:8080/api/v2/event/log?sessionKey=b299d17b896417a7b18f46544d40adb734240cc2&format=json HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json
Content-Length: 86
Host: 192.168.3.45:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
{"eventType":"AAS_PORTAL_START","data":{"uid":"hfe3hf45huf33545","aid":"1","vid":"1"}}
This request returns a success (2xx) response.
Now I am trying to post this request using requests:
import requests
headers = {'content-type' : 'application/json'}
data ={"eventType" : "AAS_PORTAL_START",
"data" : {"uid": "hfe3hf45huf33545",
"aid": "1",
"vid": "1"}
}
url = ("http://192.168.3.45:8080/api/v2/event/log?"
"sessionKey=9ebbd0b25760557393a43064a92bae539d962103&"
"format=xml&"
"platformId=1")
requests.post(url, params=data, headers=headers)
The response from this request is
<Response [400]>
Everything looks fine to me and I am not quite sure what I posting wrong to get a 400 response.

params is for GET-style URL parameters, data is for POST-style body information. It is perfectly legal to provide both types of information in a request, and your request does so too, but you encoded the URL parameters into the URL already.
Your raw post contains JSON data though. requests can handle JSON encoding for you, and it'll set the correct Content-Type header too; all you need to do is pass in the Python object to be encoded as JSON into the json keyword argument.
You could split out the URL parameters as well:
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
then post your data with:
import requests
url = 'http://192.168.3.45:8080/api/v2/event/log'
data = {"eventType": "AAS_PORTAL_START", "data": {"uid": "hfe3hf45huf33545", "aid": "1", "vid": "1"}}
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
requests.post(url, params=params, json=data)
The json keyword is new in requests version 2.4.2; if you still have to use an older version, encode the JSON manually using the json module and post the encoded result as the data key; you will have to explicitly set the Content-Type header in that case:
import requests
import json
headers = {'content-type': 'application/json'}
url = 'http://192.168.3.45:8080/api/v2/event/log'
data = {"eventType": "AAS_PORTAL_START", "data": {"uid": "hfe3hf45huf33545", "aid": "1", "vid": "1"}}
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
requests.post(url, params=params, data=json.dumps(data), headers=headers)

Assign the response to a value and test the attributes of it. These should tell you something useful.
response = requests.post(url,params=data,headers=headers)
response.status_code
response.text
status_code should just reconfirm the code you were given before, of course

Set data to this:
data ={"eventType":"AAS_PORTAL_START","data":{"uid":"hfe3hf45huf33545","aid":"1","vid":"1"}}

Related

Letterboxd api Bad Request (400) for no apparent reason python

I'm trying to access the Letterboxd api to get an authentification token but I keep getting Bad Request feedback. Here's my code:
import requests
import urllib
import json
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
}
url = 'https://api.letterboxd.com/api/v0/auth/token'
body = {
'grant_type': 'password',
'username': 'myname',
'password': 'mypassword'
}
response = requests.post(
url+urllib.parse.urlencode(headers), data=json.dumps(body))
print('\n')
print(response.text)
Any idea what I did wrong? The response is just an HTTP document with no info besides the Error message "400 Bad Request". Heres the documentation if it helps https://api-docs.letterboxd.com/#auth
First: I can't test if all code works.
You send headers in url but you should send it as part of headers=.
And when you use module requests then you can use json=body instead of data=json.dumps(body)
response = requests.post(url, headers=headers, json=body)
But header 'Content-Type': 'application/x-www-form-urlencoded' suggests that you will send data as form data, not json data - which needs data=body without converting to json
response = requests.post(url, headers=headers, data=body)
EDIT:
In your link to documentation I see link to python module (in part "Example implementations") - so maybe you should use it instead of writing own code because documentation mentionts something about "All API requests must be signed" (in part "Request signing") - and this may need extra code to create it.

REST API post request results in successful request but not creation

I've been trying to make a Post Request to my CRM API. The CRM API is very vague:
"You can use POST request when you wish to create records. You POST a JSON encoded string to the servers and it will return a single instance of the record."
POST /{object_name}
Example:
Request URL (POST):
/accounts
Request Body (JSON):
{
"name": "testing API"
}
I've had plenty of success making GET requests regularly, but POST is not working out so easily.
url = "https://apiv4.reallysimplesystems.com/accounts?<KEY>"
payload = {"name":"Ziggy","owner":"XYZ","addresscounty/state":"Awe","source":"Space"}
headers = {
'Content-Type': 'application/json',
'Cookie': 'XSRF-TOKEN=<TOK>; really_simple_systems_session=<KEY>'
}
response = requests.post(url, headers=headers, data=payload)
I get a status code 200 when I run this, but I'm really looking for that 201. The only clue that I've got to follow at this point is that when I run:
response.json()
I get the error:
JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I've tried switching the response parameters to json:
response = requests.post(url, headers=headers, json=payload)
I've tried ensuring that my payload is json by using json.dumps():
payload = {"name":"Ziggy","owner":"XYZ","addresscounty/state":"Awe","source":"Space"}
payload = json.dumps(payload)
And I've tried all sorts of other shenanigans that I can't even recall at this point. Does anyone have any idea where I'm going wrong here? The 200 status code makes me feel painfully close.
Replace <AUTH_TOKEN> with your auth token
url = "https://apiv4.reallysimplesystems.com/accounts/"
payload = {"name":"Ziggy"}
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer <AUTH_TOKEN>',
}
response = requests.post(url, headers=headers, data=payload)
Problem solved:
import json
import requests
url = "https://apiv4.reallysimplesystems.com/accounts"
payload = {"name":"RSS Test Joe Bloggs","addresscounty/state":"Maryland","source":"Word of Mouth"}
payload = json.dumps(payload)
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer <AUTH KEY>'
}
response = requests.post(url, headers=headers, data=payload)
Rather than using Postman's code which included the in the URL and used :
'Cookie': 'XSRF-TOKEN=<TOK>; really_simple_systems_session=<KEY>'
I replaced it with a standard Authorization header. Secondly, I found that using json.dumps(payload) and json = payload was resulting in a Bad Request.

How to proceed multipart/form-data or application/x-www-form-urlencoded request using requests module in python?

Our API clients support only multipart/form-data and application/x-www-form-urlencoded format. So, when I try to access their API:
import requests
import json
url = "http://api.client.com/admin/offer"
headers = {"Content-Type": "multipart/form-data", "API-Key": "ffffffffffffffffffffffffffffffffffffffff"}
data = {"Content-Type": "multipart/form-data", "title": "Demo offer", "advertiser": "f4a89a7h1aq", "url": "http://demo.com/", "url_preview": "http://demo.com/", "description": "Bla bla bla", "freshness": "fresh", "total": "2.0", "revenue": "1.8"}
r = requests.post(url, headers=headers, data=json.dumps(data))
print r.text
I get this:
{"status":2,"error":"Submitted wrong data. Check Content-Type header"}
How to overcome this issue?
Thanks!
Our API clients support only multipart/form-data and
application/x-www-form-urlencoded format
Yet you are setting the Content-type header to application/json, which is not multipart/form-data nor application/x-www-form-urlencoded.
Setting the content type in the body of the HTTP request will not help.
It appears that the server does not support JSON. You should try posting the data as a standard form like this:
import requests
import json
url = "http://api.client.com/admin/offer"
headers = {"API-Key": "ffffffffffffffffffffffffffffffffffffffff"}
data = {"title": "Demo offer", "advertiser": "f4a89a7h1aq", "url": "http://demo.com/", "url_preview": "http://demo.com/", "description": "Bla bla bla", "freshness": "fresh", "total": "2.0", "revenue": "1.8"}
r = requests.post(url, headers=headers, data=data)
print r.text
By default requests.post will set the Content-type header to application/x-www-form-urlencoded and will "urlencode" the data in the body of the request. This should work because you state that the server supports application/x-www-form-urlencoded.

python POST request and null value

I'm using the following code , to do POST request on application level
url = 'http://www.webdev.com/web/POST'
headers = {'content-type': 'application/json'}
payload = {'name': 'name', 'status': 'success', 'newname': 'name'}
r = requests.post(url, data=json.dumps(payload), headers=headers)
r.text
r.status_code
r.connection.close()
from Python logs
send: 'POST /web/POST HTTP/1.1\r\nHost: www.webdev.com\r\nContent-Length: 189\r\nUser-Agent: python-requests/2.8.1\r\nConnection: keep-alive\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\n\r\n'
send: '{"name": "test1", "status": "sucsses", "newname": "name23"}'
reply: 'HTTP/1.1 200 OK\r\n'
but on the application level, it gives null value for the 3 vars.
The application is expecting the following format:
http://www.webdev.com/web/POST?name=test1&status=sucsses&newname=name23
I used curl command to do the post and application got the right value
You aren't passing your params as part of url and sending them in POST body, but server is waiting for GET params.
To pass your payload as GET parameters use params keyword argument:
r = requests.post(url, params=payload, headers=headers)
According to your url format you should ignore passing data, simply pass params.
Good luck!

Python Requests Code 141 Error

I'm trying to use requests in python to post a json dictionary to a url. I need to get a string back from the url but I keep getting a code 141 error -{"code":141,"error":"Missing a github repository link"}. I'm using this website(http://docs.python-requests.org/en/latest/user/quickstart/) to do requests.
Any ideas on why I keep getting that error? Code is below.
import requests
import json
payload = { "email" : "jade#gmail.com", "github" : "https://github.com/"}
headers = {'content-type': 'application/json', "Accept": 'application/json'}
r = requests.post("http://challenge.code2040.org/api/register", params = payload, headers = headers)
print(r.url)
print r.text
Update: The suggestion worked but now I'm getting an{"code":141,"error":"success/error was not called"} error when I try to save the response I recieve from the url into a variable and then post it back to a different url.
#Store the token into a variable
token = r.text
payload = { "token" : token}
headers = {'content-type': 'application/json', "Accept": 'application/json'}
r = requests.post("http://challenge.code2040.org/api/getstring", json = payload, headers = headers)
print r.text
Since you are making a POST request and you need to provide a JSON in the request body, use json argument, not params:
r = requests.post("http://challenge.code2040.org/api/register",
json=payload,
headers=headers)
(tested - got back a token)
Note that json argument was introduced in requests 2.4.2.

Categories

Resources