bad request error 400 while using python requests.post function - python

I'm trying to make a simple post request via the requests library of Python and I get a bad request error (400) while my url is supposedly correct since I can use it to perform a get.
I'm very new in REST requests, I read many tutorials and documentation but I guess there are still things I don't get so my error could be basic. Maybe a lack of understanding on the type of url I'm supposed to send via POST. Here my code :
import requests
v_username = "username"
v_password = "password"
v_headers = {'content-type':'application/rdf+xml'}
url = 'https://my.url'
params = {'param': 'val_param'}
payload = {'data': 'my_data'}
r = requests.post(url, params = params, auth=(v_username, v_password), data=payload, headers=v_headers, verify=False)
print r
I used the example of the requests documentation.

I had a similar problem, i tried changing params to data or with json.dumps():
from json import dumps
r = requests.post(url, params=dumps(params), auth=(v_username, v_password), data=payload, headers=v_headers, verify=False)
or
r = requests.post(url, data=dumps(params), auth=(v_username, v_password), data=payload, headers=v_headers, verify=False)

Related

how to fetch data from API using python

I have to get data from rest api using python. how to send headers to retrieve data from API. is there any module for requesting data from API.
Try requests it has two method get() and post()
Please try:
import requests
import json
res = requests.get('paste your link here')
response = json.loads(res.text)
Previous answers have covered the idea behind how to fetch data from an API using python. Requests library is a natural selection if you want to achieve this.
Documentation and ref: https://requests.readthedocs.io/en/master/
Installation: pip install requests or https://requests.readthedocs.io/en/master/user/install/#install
Coming to the last part - how to send headers to retrieve data from API?
You can pass headers as dictionary to the request.
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
response = requests.get(url, headers=headers)
Now you have the response object in response variable; now it's up to you what you want to achieve. e.g. If you want to see what is the response body as String;
print(response.text)
Yes python has requests lib to make a call to POST and GET methods
e.g.
import requests
url = 'web address'
params = {'key':'value'}
r = requests.get(url = url, params = params)
response = r.json()

How to troubleshoot a Python Requests POST failure when the same POST is working fine in Postman?

I continue to get a very generic, unhelpful error message from python requests when making a POST request that works fine in Postman.
No matter what I try, I continue to receive one of two error messages. And note that the calling python script does not have a line 155, nor does the payload contain the letter "u":
{"error":{"detail":"SyntaxError: Unexpected token: u (sys_script_include.d2426c9ec0a8016501958bf2ac79c775.script; line 155)","message":"Unexpected token: u"},"status":"failure"}
{"error":{"message":"Unexpected token: u","detail":"SyntaxError: Unexpected token: u (sys_script_include.d2426c9ec0a8016501958bf2ac79c775.script; line 155)"},"status":"failure"}
In Postman, the parameters are correctly interpreted and then appended to the url such as:
https://areallylongurl?params={"catalogItem": "Req Name"}
In Python Requests I have tried various combinations of things without luck.
payload = {"params": '{"catalogItem": "Req Name"}'}
response = requests.post(url, headers=headers, json=payload, verify=False)
response = requests.post(url, headers=headers, json=json.dumps(payload), verify=False)
response = requests.post(url, headers=headers, data=payload, verify=False)
response = requests.post(url, headers=headers, data=json.dumps(payload), verify=False)
By using this very helpful SO answer, I was able to further analyze how the Requests library interpreted my provided payload but I am still not sure exactly how to interpret this generic error message, or what the cause may be.
Does anyone have thoughts as to what the underlying issue could be? And note that I can GET from this API without issue from Requests, it's only the POST that's problematic.
Since in postman the parameters are "appended to the url" like https://areallylongurl?params={"catalogItem": "Req Name"}, it means that the request is likely a GET request with JSON passed as a value to the params parameter, rather than a payload to a POST request, in which case you should do this instead:
response = requests.get(url, headers=headers, params={"params": json.dumps(payload)}, verify=False)

Put API Request in Python returning error

I'm fairly new to using API's, so bear with me here. I have searched for other problems like this, but haven't encountered any solutions for one that'll help my problem.
Using Postman, I'm able to make a Put request using JSON and it works fine. When I try to use the same JSON body in Python, I am getting this error:
{'code': 'E.Internal', 'error': 'An internal error has occurred processing your request. Please notify Customer Support for assistance.', 'status': 'error'}
The company's customer support is not too helpful so I wanted to see if someone here could help me instead.
Here is my script:
url = 'https://website.com/rest/site/' + record_id
json_body = (JSON body here, same one that works in Postman)
head = {'Accept':'application/json', 'Content-Type': 'application/json'}
response = requests.put(url, auth=(username, password), json=json_body, headers=head)
data = response.json()
print(data)
If I change the requests.put to requests.get and drop everything after "auth=(username, password)" it works fine and returns the json of the record, so I am able to connect to the API, just not put anything into it with Python. Again, basically the same exact thing works in Postman.
What exactly am I doing wrong and how do I put in the data?
According to the requests documentation you're not filling out the put function correctly. Try it like this?
import json
import requests
url = 'https://website.com/rest/site/' + record_id
headers = {
"Content-Type": "application/json",
'Accept':'application/json'
}
payload = json.dumps({
"data_goes_here": None
})
rv = requests.put(url, data=payload, headers=headers, verify=False)
if rv.status_code > 399:
rv.raise_for_status()
print(json.loads(rv.text))

Python 2.6 json error 400 and 401 when i trying to fetch from Ubiquity Unify API

I am trying to generate a voucher from Ubiquity UNIFY web portal.
It has a API, and there is some ideas to use this with PHP, but I would like to use Python 2.6 to generate.. (I can ofc ourse use other Python versions if this is a must)
My code is:
import urllib, json
import urllib2
import unifi
import os
import requests
def JsonLogin():
payload = {"username" : "myuser","password" : "mypassword"}
r = requests.post("https://ubnt.myserver.com:8443/api/login", data=payload, verify=False)
print r
def JsonApi():
payload = {"cmd":"create-voucher","minutes":1440,"n":1}
r = requests.post("https://ubnt.myserver.com:8443/api/cmd/hotspot", data=payload, verify=False)
print r
JsonLogin();
JsonApi();
My Result is:
<Response [400]>
<Response [401]>
Is there any logic why it returns 400, witch means error...
Is this because I sent invalid JSON or is this because the syntax or JSON tags are wrong?
try this
payload= '{"username" : "myuser","password" : "mypassword", "strict":true}'
r = requests.post("https://ubnt.myserver.com:8443/api/login", data=payload, verify=False)
print r
It should return 200
Then set someway the cookie value that the login returns into a variable
cookies=r.cookies
then
r = requests.post("https://ubnt.myserver.com:8443/api/cmd/hotspot", data=payload, verify=False, cookies=cookies)
I used it with GET and it works

BLS API data using cURL and requests library?

All, I'm trying to implement a curl request to get data from the BLS. Following their example here (they show the curl request), my code looks like this:
import requests
headers = {'Content-type': 'application/json'}
params = {"seriesid":["LEU0254555900", "APU0000701111"],"startyear":"2002", "endyear":"2012"}
p = requests.post('http://api.bls.gov/publicAPI/v1/timeseries/data/', params = params,headers = headers)
print p.url
print p.content
I'm getting the following (error) output:
http://api.bls.gov/publicAPI/v1/timeseries/data/?seriesid=LEU0254555900&seriesid=APU0000701111&endyear=2012&startyear=2002
{"status":"REQUEST_FAILED","responseTime":0,"message":["Sorry, an
internal error occurred. Please check your input parameters and try
your request again."],"Results":null}
Anyone had to deal with the BLS api and python?
Is the requests library the best for this?
You need to send the data as json, not pass it as a params dict. params sets the url parameters, which is not what you want, you need to pass it as data.
This should work:
import requests
import json
headers = {'Content-type': 'application/json'}
data = json.dumps({"seriesid":["LEU0254555900", "APU0000701111"],"startyear":"2002", "endyear":"2012"})
p = requests.post('http://api.bls.gov/publicAPI/v1/timeseries/data/', data=data, headers=headers)
print p.url
print p.content

Categories