python requests.post is always giving 400 bad request - python

We are trying to upload screenshots to a server from mac machine big sur(11.4 kernel 20.5 version) using python. But the response is always shows 400 Bad request, but the same is working fine from the postman. Any help is appreciated.
token = 'Bearer {}'.format(auth_token)
url = "{}/screenshot".format(base_url)
payload = {'date': date}
try:
files = {'imagefile': ('imagefile', open(
image_path, 'rb'), 'image/jpeg')}
log.debug("file : {0}".format(files))
except Exception as e:
log.error("file ERROR: {0}".format(e))
headers = {'Authorization': token}
try:
response = requests.post(
url, headers=headers, data=payload, files=files, timeout=30)
except Exception as e:
log.error("Response ERROR: {0}".format(e))

The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)
This means your headers are malformed, or your format is wrong.

Related

Python requests keeps returning 401 client error

I have some python test code that is requesting web pages from a embedded controller. For general .htm pages it works but when I request a .txt file stored on it I get a
"401 Client Error: Unauthorized for url: http://192.168.61.30/fs/work/sys/crashdump/log0.txt"
HTTP error
The code is as follows:-
for url in ['http://192.168.61.30/get_version.htm']:
try:
cookies = {'Auth': access_token}
response = requests.get(url, cookies=cookies)
# If the response was successful, no Exception will be raised
response.raise_for_status()
except HTTPError as http_err:
print(f'HTTP error occurred: {http_err}') # Python 3.6
except Exception as err:
print(f'Other error occurred: {err}') # Python 3.6
else:
print("*****Access obtained******")
print(response.content);
print('Success!')
for url in ['http://192.168.61.30/fs/work/sys/crashdump/log0.txt']:
try:
cookies = {'Auth': access_token}
response = requests.get(url, cookies=cookies)
# If the response was successful, no Exception will be raised
response.raise_for_status()
except HTTPError as http_err:
print(f'HTTP error occurred: {http_err}') # Python 3.6
except Exception as err:
print(f'Other error occurred: {err}') # Python 3.6
else:
print("*****Access obtained******")
print(response.content);
print('Success!')
The 1st one works fine, however the 2nd one always fails with 401 client error and as far as I can work out never gets as far as the web server. Looking at the returned headers I don't see any authorisation requests. I have also disabled the proxies.
If I send the same request via a web browser I get no problems
The headers response is
{'Server': 'HPCi Controller Web server', 'Connection': 'close', 'X-Frame-Options': 'SAMEORIGIN', 'Content-Type': 'text/html'}
I have tried adding WWW-Authentication: Basic to the headers, but no success

Connecting to API works using Shell but w/ Python requests lib throws 400 Client Error: Bad Request for url

I'm trying to connect to the Fluctuo (mobility data) GraphQL API with my access token. It works perfectly well using the curl Shell script, but it throws a 400 Client Error: Bad Request for url when trying the same using the Python requests library.
This is the curl script that works:
curl --request POST \
--url https://flow-api.fluctuo.com/v1?access_token=MY_ACCESS_TOKEN \
--header 'content-type: application/json' \
--data '{"query":"query ($lat: Float!, $lng: Float!) {\n vehicles(lat: $lat, lng: $lng) {\n\t\tid\n }\n}","variables":{"lat":48.856614,"lng":2.352222}}'
This is the Python code that throws the error:
url = "https://flow-api.fluctuo.com/v1?access_token=" + MY_ACCESS_TOKEN
head = {'content-type': 'application/json'}
query='''
query ($lat: Float!, $lng: Float!) {\n vehicles(lat: $lat, lng: $lng) {\n\t\tid\n }\n}","variables":{"lat":48.856614,"lng":2.352222}'''
try:
r = requests.post(url, json={'query': query},headers=head)
r.raise_for_status()
except requests.exceptions.HTTPError as err:
raise SystemExit(err)
Any ideas about what could go wrong is much appreciated.
I found the solution in the meantime: the POST data needed to be JSON-encoded. I dumped the query into JSON and this solved the issue. See code below.
import requests
import json
url = "https://flow-api.fluctuo.com/v1?access_token=" + MY_ACCESS_TOKEN
head = {'content-type': 'application/json'}
data = {"query":"query ($lat: Float!, $lng: Float!) {\n vehicles(lat: $lat, lng: $lng) {\n\t\tid\n }\n}","variables":{"lat":48.856614,"lng":2.352222}}
try:
r = requests.post(url, data=json.dumps(data), headers=head)
r.raise_for_status()
except requests.exceptions.HTTPError as err:
raise SystemExit(err)
r.status_code

Microsoft Emotion API for video with Python

I'm using the following code to send my video and apparently I got no error. But the response is coming blank. How can I read the response?
########### Python 2.7 #############
import httplib, urllib, base64, json
headers = {
# Request headers
'Ocp-Apim-Subscription-Key': 'xxxxxxxxxxxxxxxxxxxx',
'Content-Type': 'application/json'
}
video_filename = {"url":"https://fsarquivoeastus.blob.core.windows.net/public0/WhatsApp-Video-20160727.mp4"}
params = urllib.urlencode({})
try:
conn = httplib.HTTPSConnection('api.projectoxford.ai')
conn.request("POST", "/emotion/v1.0/recognizeinvideo?%s" % params, json.dumps(video_filename), headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
The Cognitive Service Video APIs, including Emotion, operate asynchronously, and by design return an empty response body when the POST succeeds. What you must do instead is retrieve the operation URL from the headers, as shown here:
response = conn.getresponse()
location = response.getheader('operation-location');
print(location);
You call GET on that location URL to check on the status of the operation. More on that here.
#FelipeSouzaLima, To getting the operation result from Emotion Recognition in Video, you need to do two steps as below.
Call the REST API for Emotion Recognition in Video, then you will get the blank response body and the operation-location header which will be called at the next step as #cthrash said.
Call the url of the value of operation-location header above with the same Ocp-Apim-Subscription-Key as request header, then you can get the json response body which includes the recognition job status. If the value of status field in the json response is Succeeded, you will get the operation result as processingResult field in the json result, please refer to the REST API of Get Recognition in Video Operation Result.

Get variable outside exception Python

I am calling an API with the urllib. When something is not as expected, the API throws an error at the user (E.G. HTTP Error 415: Unsupported Media Type). But next to that, the API returns a JSON with more information. I would like to pass that json to the exception and parse it there, so I can give information to the user about the error.
Is that possible? And if, how is it done?
Extra info:
Error: HTTPError
--EDIT--
On request, here is some code (I want to read resp in the exception):
def _sendpost(url, data=None, filetype=None):
try:
global _auth
req = urllib.request.Request(url, data)
req.add_header('User-Agent', _useragent)
req.add_header('Authorization', 'Bearer ' + _auth['access_token'])
if filetype is not None:
req.add_header('Content-Type', filetype)
resp = urllib.request.urlopen(req, data)
data = json.loads(resp.read().decode('utf-8'), object_pairs_hook=OrderedDict)
except urllib.error.HTTPError as e:
print(e)
return data
--EDIT 2--
I do not want to use extra library's/modules. As I do not control the target machines.
Code
import urllib.request
import urllib.error
try:
request = urllib.request.urlopen('https://api.gutefrage.net')
response = urllib.urlopen(request)
except urllib.error.HTTPError as e:
error_message = e.read()
print(error_message)
Output
b'{"error":{"message":"X-Api-Key header is missing or invalid","type":"API_REQUEST_FORBIDDEN"}}'
Not asked but with module json you could convert it to dict via
import json
json.loads(error_message.decode("utf-8"))
Which gives you the dict out of the byte string.
If you're stuck with using urllib, then you can use the error to read the text of the response, and load that into JSON.
from urllib import request, error
import json
try:
req = urllib.request.Request(url, data)
req.add_header('User-Agent', _useragent)
req.add_header('Authorization', 'Bearer ' + _auth['access_token'])
if filetype is not None:
req.add_header('Content-Type', filetype)
resp = urllib.request.urlopen(req, data)
data = json.loads(resp.read().decode('utf-8'), object_pairs_hook=OrderedDict)
except error.HTTPError as e:
json_response = json.loads(e.read().decode('utf-8'))
If you're not stuck to urllib, I would highly recommend you use the requests module instead of urllib. With that, you can have something like this instead:
response = requests.get("http://www.example.com/api/action")
if response.status_code == 415:
response_json = response.json()
requests doesn't throw an exception when it encounters a non-2xx series response code; instead it returns the response anyway with the status code added.
You can also add headers and parameters to these requests:
headers = {
'User-Agent': _useragent,
'Authorization': 'Bearer ' + _auth['access_token']
}
response = requests.get("http://www.example.com/api/action", headers=headers)

Getting error headers with urllib2

I need to send a PUT request to a web service and get some data out of error headers that is the expected result of the request. The code goes like this:
Request = urllib2.Request(destination_url, headers=headers)
Request.get_method = lambda: 'PUT'
try:
Response = urllib2.urlopen(Request)
except urllib2.HTTPError, e:
print 'Error code: ', e.code
print e.read()
I get Error 308 but response is empty and I'm not getting any data out of HTTPError. Is there a way to get HTTP headers while getting an HTTP error?
e has undocumented headers and hdrs properties that contains the HTTP headers sent by the server.
By the way, 308 is not a valid HTTP status code.

Categories

Resources