Post Bad Request rest api in python - python

I am attempting to post some data through REST API in Python.
data.json
{
"LastModifiedAt": "2020-12-21T20:19:45.335Z",
...
...
}
I am using following code to POST the data.
with open('data.json') as fh:
data = json.load(fh)
headers = {
'Content-Type': 'application/json',
'X-API-Key':'ABC=='
}
response = requests.post('https://myurl.net/api/v1/resource/int_key/endpoint', headers=headers,data=data)
I always get following as response status_code = 400
{
"ModelState": {
"line": [
"Unexpected character encountered while parsing value: L. Path '', line 0, position 0."
]
},
"Message": "The request is invalid."
}
How do I debug this? My URL is correct according to API documentation. Why does it return "Bad Request" status code?

I replaced data with json and it worked.
response = requests.post('https://myurl.net/api/v1/resource/int_key/endpoint', headers=headers,json=data)
I used Postman as suggested by AndroidDev to debug this.

Related

Trying to post data to firestore using requests

im trying to post JSON data to firestore using requests and it keeps returning this error.
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"{\"data\": \"message\"}\": Cannot bind query parameter. Field '{\"data\": \"message\"}' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"{\"data\": \"message\"}\": Cannot bind query parameter. Field '{\"data\": \"message\"}' could not be found in request message."
}
]
}
]
}
}
I've tried different method using different types of JSON Encoding and still returns the same error. i would appreciate if someone could look into this for me. Below is my code
def thestream(self, instance):
app = App.get_running_app()
s = requests.Session()
self.data = {u'data': u'message'}
self.headers = {"authorization": "bearer " + app.idToken}
r = s.post("https://firestore.googleapis.com/v1/projects/*******************************/databases/(default)/documents/messages/TemitayoAdefemi", params=json.dumps(self.data), headers=self.headers)
print(r.ok)
print(r.content.decode())
Try defining a Document resource in your payload:
self.data = {u'fields': {u'data': {u"stringValue": u'message'}}}
In your POST request, try passing the payload in data=self.data instead of param:
r = s.post("https://firestore.googleapis.com/v1/projects/***/databases/(default)/documents/messages/TemitayoAdefemi", data=self.data, headers=self.headers)

How to send rest API (Google Vision's API) request with python?

I guess my question is relatively simple and naive, but I'm new to use REST APIs so I would be grateful for any help or hint.
I'm trying to send a request with urllib (or another Python's library that I no need to install).
Based on their guide, The format is:
POST https://vision.googleapis.com/v1/images:annotate?key=YOUR_API_KEY
and the JSON request format is:
{
"requests":[
{
"image":{
"content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"
},
"features":[
{
"type":"LABEL_DETECTION",
"maxResults":1
}
]
}
]
}
When I try to send the following text (just for test) in the URL line in my browser:
https://vision.googleapis.com/v1/images:{
"requests":[
{
"image":{
"content":"/9j/7QBEUGhvdG9eYxxxzj/Coa6Bax//Z"
},
"features":[
{
"type":"LABEL_DETECTION",
"maxResults":1
}
]
}
]
}?key=my_api_key
I get unfortunately a 404 error.
What should I do? Should I use any library in order to generate the request? Or should I to place the JSON request in another place in the URL?
If you need to send Request Body with the URL you can use CURL. To test REST API's there is a famous software called POSTMAN. By using this you can send requests and receive the response.
CURL,
curl -v -H "Content-Type: application/json" -X POST \
-d '{"image":{"content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"}, "features":[{"type":"LABEL_DETECTION","maxResults":1}]}' https://vision.googleapis.com/v1/images:annotate?key=YOUR_API_KEY
Using POSTMAN you can give these values to it and get results.
Give URL,
https://vision.googleapis.com/v1/images:annotate?key=YOUR_API_KEY
Choose HTTP METHOD as,
POST
And add the REQUEST BODY under the raw field and choose JSON(application/json),
{
"requests":[
{
"image":{
"content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"
},
"features":[
{
"type":"LABEL_DETECTION",
"maxResults":1
}
]
}
]
}
This works for me:
import base64
import requests
import json
URL = "https://vision.googleapis.com/v1/images:annotate?key=YOUR_TOKEN"
#image to base64, which is a long long text
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read())
#make api call
def image_request(image_path):
data = {
"requests":[
{
"image":{
"content":encode_image(image_path)
},
"features":[
{
"type":"LABEL_DETECTION", #other options: LABEL_DETECTION FACE_DETECTION LOGO_DETECTION CROP_HINTS WEB_DETECTION
"maxResults": 10
}
]
}
]
}
r = requests.post(URL, json = data)
return r.text
#arg = path of image
def main(argv):
api_answer = json.loads(image_request(argv[1]))
try:
rows = api_answer['responses'][0]['labelAnnotations']
except:
print(file_to_proccess)
print(api_answer)
data = []
for item in rows:
data.append([item['mid'], item['description'], item['score'], item['topicality']])
# save somewhere the data list...
if __name__ == "__main__":
main(sys.argv)
this was tested and work perfect
import base64
import requests
import json
url = "https://vision.googleapis.com/v1/images:annotate"
querystring = {"key":".........."}
headers = {
'Content-Type': "application/json",
}
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read())
def image_request(image_path):
payload = '{ \"requests\":[ { \"image\":{ \"content\":\"'+encode_image(image_path).decode('utf-8')+'" }, \"features\":[ { \"type\":\"TEXT_DETECTION\" } ] } ]}'
response = requests.request("POST", url, data=payload, headers=headers, params=querystring)
return response.text

Outlook API email attachment issue

I am trying to use Outlook's REST API in my python code to send an email in behalf of a user who already gives me his consent.
I was able to successfully send text emails using their /me/sendmail node with the following payload:
email_payload = {
"Message": {
"Subject": email_subject,
"Body": {
"ContentType": "Text",
"Content": email_body
},
"ToRecipients": [
{
"EmailAddress": {
"Address": to
}
}
]
}
}
However, when trying to add attachments (based on their documentation), I encounter some issues:
email_payload["Message"]["Attachments"] = [
{
"ContentType": "application/pdf",
"Name": "{0}".format("something.pdf"),
"ContentBytes": base64.b64encode(attachment.read())
}
]
Issues consist in 415 response status code with the following content:
{u'error': {u'message': u'A missing or empty content type header was found when trying to read a message. The content type header is required.', u'code': u'RequestBodyRead'}}
Couldn't find anything regarding this in their documentation. Hope somebody can enlighten me :)
For anyone else having such issues, here's the context and fix:
Initially, since I was sending only plain-text emails, my request header looked like this:
request_headers = {
'Authorization': "Bearer {0}".format(token),
}
And the actual request:
api_response = requests.post(
request_url,
json.dumps(body),
headers=request_headers
)
As you might have noticed I wasn't sending any content-type in my headers (not sure why), but everything went well so far up until when I decided to add attachments too.
Seems like if my request_headers would contain Content-Type too, everything would go well:
request_headers = {
'Authorization': 'Bearer {0}'.format(refreshed_token),
'Content-Type': 'application/json'
}

Can not parse JSON share document.\nRequest body:\n\nError:\nnull

I am trying to send a request to Linkedin's rest share api. I have been receiving this error message:
{
"errorCode": 0,
"message": "Can not parse JSON share document.\nRequest body:\n\nError:\nnull",
"requestId": "ETX9XFEI7N",
"status": 400,
"timestamp": 1437910620120
}
The request is send through the following python code:
import requests,json
auth_token = "some auth token"
url = "https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token="+auth_token
headers = {'content-type': 'application/x-www-form-urlencoded','x-li-format':'json'}
data = {
"comment":"Check out developer.linkedin.com!",
"content":{
"title": "LinkedIn Developers Resources",
"description": "Leverage LinkedIn's APIs to maximize engagement",
"submitted-url": "https://developer.linkedin.com",
"submitted-image-url": "https://example.com/logo.png"
},
"visibility":{
"code": "anyone"
}
}
response = requests.post( url , json= data , headers=headers )
return HttpResponse( response )
I made sure that I followed all the instructions in their documentation and can't find the mistake I am making.
Note: i have tried json=data and data=data both are not working
Remove content-type from the headers dictionary.
requests sets the correct Content-Type when using the json keyword argument.
You have three basic problems:
Please read the documentation on oauth2; because you are not passing in the token correctly.
The share URL does not take a oauth2_token argument.
You have the wrong content-type header.

QPX Express API from Python

I am trying to use Google's QPX Express API from python. I keep running into a pair of issues in sending the request. At first what I tried is this:
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=MY_KEY_HERE"
values = {"request": {"passengers": {"kind": "qpxexpress#passengerCounts", "adultCount": 1}, "slice": [{"kind": "qpxexpress#sliceInput", "origin": "RDU", "destination": location, "date": dateGo}]}}
data = json.dumps(values)
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
print(response)
based upon the code from: urllib2 and json
When I run the above code I get the following error message:
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.
I searched for a solution and adapted my code based upon the following question: TypeError: POST data should be bytes or an iterable of bytes. It cannot be str
I changed my code to this:
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=AIzaSyCMp2ZnKI3J91sog7a7m7-Hzcn402FyUZo"
values = {"request": {"passengers": {"kind": "qpxexpress#passengerCounts", "adultCount": 1}, "slice": [{"kind": "qpxexpress#sliceInput", "origin": "RDU", "destination": location, "date": dateGo}]}}
data = json.dumps(values)
data = data.encode("utf-8")
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
print(response)
However, when I run this code I get the following error message:
urllib.error.HTTPError: HTTP Error 400: Bad Request
I also tried changing utf-8 to ascii but I was unsuccessful. How can I get this working properly?
Here is a solution using the excelent requests library.
import json
import requests
api_key = "YOUR API KEY HERE"
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=" + api_key
headers = {'content-type': 'application/json'}
params = {
"request": {
"slice": [
{
"origin": "TXL",
"destination": "LIM",
"date": "2015-01-19"
}
],
"passengers": {
"adultCount": 1
},
"solutions": 2,
"refundable": False
}
}
response = requests.post(url, data=json.dumps(params), headers=headers)
data = response.json()
print data
I am not sure why you request is not working. Maybe it is really the request parameters that were wrong. The date definitely needs to be in the future!
False needs to be in lowercase in JSON, so you need to quote it in Python, like this "refundable" : "false". Otherwise, your query looks good (obviously you'll need to update the date). By the way, it isn't good practice to include your API key in a public forum.

Categories

Resources