Python request gives 415 error while post data - python

I am getting 415 error while posting data to server. This is my code how can i solve this problem. Thanks in advance!
import requests
import json
from requests.auth import HTTPBasicAuth
#headers = {'content-type':'application/javascript'}
#headers={'content-type':'application/json', 'Accept':'application/json'}
url = 'http://IPadress/kaaAdmin/rest/api/sendNotification'
data = {"name": "Value"}
r = requests.post(url, auth=HTTPBasicAuth('shany.ka', 'shanky1213'),json=data)
print(r.status_code)

According to MDN Web Docs,
The HTTP 415 Unsupported Media Type client error response code
indicates that the server refuses to accept the request because the
payload format is in an unsupported format.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
In your case, I think you've missed the headers.
Uncommenting
headers={
'Content-type':'application/json',
'Accept':'application/json'
}
and including headers in your POST request:
r = requests.post(
url,
auth=HTTPBasicAuth('shany.ka', 'shanky1213'),
json=data,
headers=headers
)
should do the trick
import requests
import json
from requests.auth import HTTPBasicAuth
headers = {
'Content-type':'application/json',
'Accept':'application/json'
}
url = 'http://IPadress/kaaAdmin/rest/api/sendNotification'
data = {"name": "Value"}
r = requests.post(
url,
auth=HTTPBasicAuth('shany.ka', 'shanky1213'),
json=data,
headers=headers
)
print(r.status_code)

As a workaround, try hitting your api using Postman. When you can successfully hit the api in postman, generate python code in postman (button is present in the top right corner). You can copy the code in your python project.

Another possible cause is using requests.post when you should be using requests.get or vice versa. I doubt that this is a common problem, but in my case a server that was happy to accept an HTTP GET for a search rejects it with a 415 when HTTP POST is used instead. (Yet another site required that a search be requested using HTTP POST. It was reusing that code that caused my problem.)

Related

How to convert a python post request to a Postman POST request

I have a python post request to a server where my flask app is hosted. It works fine and I am able to get the desired data.
But I want to test the API using POSTMAN. I am unable to do that because I am unfamiliar with POSTMAN to some extent.
Below is the python code that I have.
import requests
import ast
import json
resp1 = {}
url = 'http://myflaskapiurl:port/route'
files = {'file': open(r'file that should be uploaded to the server', 'rb')}
r = requests.post(url, files=files, data={"flag":2})
headers = {
'content-type': "multipart/form-data",
'Content-Type': "application/x-www-form-urlencoded",
'cache-control': "no-cache",
}
resp1 = ast.literal_eval(r.text)
print(resp1)
I am struggling with the question whether the data and file that I am trying to post to the server should be in raw json or form-data or x-www-form-urlencoded section of body. Also what should be the actual structure.
Because every time I POST this data using form-data or x-www-form-urlencoded section of body I get the error saying
werkzeug.exceptions.BadRequestKeyError
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad Request: KeyError: 'file'
This is how it should look like:
The "params" tab should be empty, maybe you're adding a second file parameter there?

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))

Post request using Python urllib

I'm making a request to an api using python3 urllib. This is my code,
headers = {}
headers['Content-Type']='application/x-www-form-urlencoded; charset=UTF-8'
#headers['X-Csrf-Token']= {'mode: cors'}
req = urllib.request.Request(url=URL, headers=headers, method='POST')
res = urllib.request.urlopen(req)
print(res.read())
I get the following response,
urllib.error.HTTPError: HTTP Error 415: Unsupported Media Type
The API endpoint is working fine and I've tested it with Postman. This is the equivalent javascript code which gets the job done,
return fetch(url, { credentials : 'include', method: 'post'})
So I'm assuming I've to find a way to add credentials to the header. Can I do a credentials include parallel in Python or do I have to fetch the specific cookie and set it in the request. Any help appreciated.
The error 415 indicates an issue with 'Content-type'.
'application/x-www-form-urlencoded' does not have any parameters.
https://www.w3.org/TR/html5/iana.html#application/x-www-form-urlencoded
Regarding fetch()'s "credentials", you would need the ability to maintain a session (sending cookies as required).
It is much easier with the requests library's Session
http://docs.python-requests.org/en/master/user/advanced/#session-objects

400 Bad Request With urllib2 for POST

I am struggling from 2 days with a post request to be made only using urllib & urllib2. I have limitations in using curl or requests library, as the machine I would need to deploy my code doesn't support any of these.
The post call would be accompanied with a Header and json Body. I am able to make any get call, but POST with Data & Header throws 400 bad requests. Tried and applied all the options available in google/stackoverflow, but nothing solved!
Below is the sample code:--
import urllib
import urllib2
url = 'https://1.2.3.4/rest/v1/path'
headers = {'X-Auth-Token': '123456789sksksksk111',
'Content-Type': 'application/json'}
body = {'Action': 'myaction',
'PressType': 'Format1', 'Target': '/abc/def'}
data = urllib.urlencode(body)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request, data)
And on setting debug handler, below is the format of the request that can be traced:--
send: 'POST /rest/v1/path HTTP/1.1\r\nAccept-Encoding: identity\r\nContent-Length: 52\r\nHost: 1.2.3.4\r\nUser-Agent: Python-urllib/2.7\r\nConnection: close\r\nX-Auth-Token: 123456789sksksksk111\r\nContent-Type: application/json\r\n\r\nAction=myaction&PressType=Format1&Target=%2Fabc%2Fdef'
reply: 'HTTP/1.1 400 Bad Request\r\n'
Please note, the same post request works perfectly fine with any REST client and with Requests library. In the debug handler output, if we see, the json structure is Content-Type: application/json\r\n\r\nAction=myaction&PressType=Format1&Target=%2Fabc%2Fdef, can that be a problem!
You can dump the json instead of encoding it. I was facing the same and got solved with it!
Remove data = urllib.urlencode(body) and use urllib2.urlopen(req, json.dumps(data))
That should solve.

Django rejects Requests' CSRF Token

I'm writing an Ajax post with python's Request's library to a django backend
Code:
import requests
import json
import sys
URL = 'http://localhost:8000/'
client = requests.session()
client.get(URL)
csrftoken = client.cookies['csrftoken']
data = { 'file': "print \"It works!\"", 'fileName' : "JSONtest", 'fileExt':".py",'eDays':'99','eHours':'1', 'eMinutes':'1' }
headers = {'Content-type': 'application/json', "X-CSRFToken":csrftoken}
r = requests.post(URL+"au", data=json.dumps(data), headers=headers)
Django gives me a 403 error stating that the CSRF token isn't set even though the request.META from csrf_failure() shows it is set. Is there something I'm missing or a stupid mistake I'm not catching?
I asked my friend and he figured out the problem, basically you have to send the cookies that django gives you every time you do a request.
corrected:
cookies = dict(client.cookies)
r = requests.post(URL+"au", data=json.dumps(data), headers=headers,cookies=cookies)
You need to pass the referer to the headers, from the django docs:
In addition, for HTTPS requests, strict referer checking is done by
CsrfViewMiddleware. This is necessary to address a Man-In-The-Middle
attack that is possible under HTTPS when using a session independent
nonce, due to the fact that HTTP ‘Set-Cookie’ headers are
(unfortunately) accepted by clients that are talking to a site under
HTTPS. (Referer checking is not done for HTTP requests because the
presence of the Referer header is not reliable enough under HTTP.)
so change this:
headers = {'Content-type': 'application/json', "X-CSRFToken":csrftoken, "Referer": URL}

Categories