JSON_PARSING_ERROR: Unexpected character (r) at position 0 - python

I've been trying for a couple of days to send a notification via FCM using the Python requests package. But I've been struggling with the same issue over and over and I can't figure out what's wrong with my code.
Here's the JSON that I'm trying to send to Firebase:
{"registration_ids":["A token given by Firebase"],"notification": {"title":"1","body":"I'm a test message"}
I might have missed something, but as far as I know, the JSON message is well formatted. I've tried with both notification and message, but to no avail.
Here's the full code I'm using to do this:
import requests
URL = 'https://fcm.googleapis.com/fcm/send'
data = {"registration_ids":["A token from Firebase"],"notification": {"title":"1","body":"I'm a test message"}}
headers = {"Authorization":"key=My server key","Content-Type":"application/json"}
print(data)
r = requests.post(url=URL, data=data, headers=headers)
print(r.text)
It should return a message with a correct status but instead it's returning a 400 OK, JSON_PARSING_ERROR: Unexpected character (r) at position 0.
I'm not completely sure if I'm doing anything wrong. Thanks in advance!

If you want to send data as JSON, you need to actually produce that JSON:
import json
data=json.dumps(data)
requests.post(<...>,data=data)
or use post()'s json argument:
requests.post(<...>,json=data)

Related

Python Post Request Issue, given error 500

body_1 = {"landowner": "asdf#gmail.com","title": report_name,"content": "asdf","project": projectID, }
url_1 = 'http://' + IP + ':8005/projects/notifications/'
response_1 = requests.post(url_1, data=body_1, headers=headers)
For this, I am getting an error 500, when above I have used a similar process to post and it has worked.
I even wrote this code in javascript, and that works but the python equivalent does not.
I tried to add console logs, and everything works up until the response, where it says code 500.
I tried to follow along with javascript as well and try and model it after that too, but that did not work either.
You are getting the error because you are not sending the data as JSON encoded data. When sending an array as data with a request use the json keyword argument. This means your request will look like;
response_1 = requests.post(url_1, json=body_1, headers=headers)
In the example above data= was changed to json=.
By using the json argument the data is encoded to JSON, and the Content-Type header is set to application/json.
Learn more about the json= keyword argument in the requests documentation
If this doesn't fix your issue please add the error output message for the 500 error code.

Python - Spotify API returning Error 400 "Malformed JSON"

Heyo. I'm trying to make a small application in my spare time that uses the Spotify API . I have managed to get my program to use oAuth 2 to let a user authorize my app to manipulate their Spotify, but I have run into a problem with a certain endpoint on the Spotify API.
The endpoint I am having trouble with is https://api.spotify.com/v1/me/player/play (here's a link to their docs for the endpoint https://developer.spotify.com/console/put-play/). Whenever I try to make a put request to the endpoint I receive a 400 status code with the message "Malformed json" I get this message even when I copy/paste their own json from the docs, so I don't think it's a problem with how I am formatting my json, besides I have used json before to call other endpoints and they haven't had a problem with my formatting on those calls.
Here is my code:
headers = {"Authorization":"Bearer {}".format(access_token)}
url = 'https://api.spotify.com/v1/me/player/play'
payload = {"context_uri": "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr"}
r = requests.put(url, headers=headers, data=payload)
print(r)
print(r.text)
To clarify, access_token is the access token that I have gotten from their authorization process, and I am using python-requests to make the http requests (Here is the docs for that: https://requests.kennethreitz.org/en/master/)
I am wondering if the problem is due to the fact that Spotify uses colons int their track IDs and colons are also used in JSON? I saw in another thread on here that I should try to add "Content-Type":"application/json" to my headers but that didn't change the outcome at all.
Any help is greatly appreciated, and if you need any more info please let me know. Thank you!
If your payload is a dict use json kwargs in requests lib. data works for string payload. Here you go:
r = requests.put(url, headers=headers, json=payload)

Python request resulting in blank response

I'm relatively new to Python so would like some help, I've created a script which simply use the request library and basic auth to connect to an API and returns the xml or Json result.
# Imports
import requests
from requests.auth import HTTPBasicAuth
# Set variables
url = "api"
apiuser = 'test'
apipass = 'testpass'
# CALL API
r = requests.get(url, auth=HTTPBasicAuth(apiuser, apipass))
# Print Statuscode
print(r.status_code)
# Print XML
xmlString = str(r.text)
print(xmlString)
if but it returns a blank string.
If I was to use a browser to call the api and enter the cretentials I get the following response.
<Response>
<status>SUCCESS</status>
<callId>99999903219032190321</callId>
<result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Dummy">
<authorFullName>jack jones</authorFullName>
<authorOrderNumber>1</authorOrderNumber>
</result>
</Response>
Can anyone tell me where I'm going wrong.
What API are you connecting to?
Try adding a user-agent to the header:
r = requests.get(url, auth=HTTPBasicAuth(apiuser, apipass), headers={'User-Agent':'test'})
Although this is not an exact answer for the OP, it may solve the issue for someone having a blank response from python-requests.
I was getting a blank response because of the wrong content type. I was expecting an HTML rather than a JSON or a login success. The correct content-type for me was application/x-www-form-urlencoded.
Essentially I had to do the following to make my script work.
data = 'arcDate=2021/01/05'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
r = requests.post('https://www.deccanherald.com/getarchive', data=data, headers=headers)
print(r.status_code)
print(r.text)
Learn more about this in application/x-www-form-urlencoded or multipart/form-data?
Run this and see what responses you get.
import requests
url = "https://google.com"
r = requests.get(url)
print(r.status_code)
print(r.json)
print(r.text)
When you start having to pass things in your GET, PUT, DELETE, OR POST requests, you will add it in the request.
url = "https://google.com"
headers = {'api key': 'blah92382377432432')
r = requests.get(url, headers=headers)
Then you should see the same type of responses. Long story short,
Print(r.text) to see the response, then you once you see the format of the response you get, you can move it around however you want.
I have an empty response only when the authentication failed or is denied.
The HTTP status is still ≤ 400.
However, in the header you can find :
'X-Seraph-LoginReason': 'AUTHENTICATED_FAILED'
or
'X-Seraph-LoginReason': 'AUTHENTICATED_DENIED'
If the request is empty, not even a status code I could suggest waiting some time between printing. Maybe the server is taking time to return the response to you.
import time
time.sleep(5)
Not the nicest thing, but it's worth trying
How can I make a time delay in Python?
I guess there are no errors during execution
EDIT: nvm, you mentioned that you got a status code, I thought you were literally geting nothing.
On the side, if you are using python3 you have to use Print(), it replaced Print

Accessing Elasticsearch with Python 3

I want to use the Python 3 module urllib to access an Elasticsearch database at localhost:9200. My script gets a valid request (generated by Kibana) piped to STDIN in JSON format.
Here is what I did:
import json
import sys
import urllib.parse
import urllib.request
er = json.load(sys.stdin)
data = urllib.parse.urlencode(er)
data = data.encode('ascii')
uri = urllib.request.Request('http://localhost:9200/_search', data)
with urllib.request.urlopen(uri) as repsonse:
response.read()
(I understand that my repsonse.read() doesn't make much sense by itself but I just wanted to keep it simple.)
When I execute the script, I get an
HTTP Error 400: Bad request
I am very sure that the JSON data I'm piping to the script is correct, since I had it printed and fed it via curl to Elasticsearch, and got back the documents I expected to get back.
Any ideas where I went wrong? Am I using urllib correctly? Do I maybe mess up the JSON data in the urlencode line? Am I querying Elasticsearch correctly?
Thanks for your help.
With requests you can do one of two things
1) Either you create the string representation of the json object yourself and send it off like so:
payload = {'param': 'value'}
response = requests.post(url, data=json.dumps(payload))
2) Or you have requests do it for you like so:
payload = {'param': 'value'}
response = requests.post(url, json = payload)
So depending on what actually comes out of the sys.stdin call (probably - as Kibana would be sending that if the target was ElasticSearch - a string representation of a json object == equivalent of doing json.dumps on a dictionary), but you might have to adjust a bit depending on the output of sys.stdin.
My guess is that your code could work by just doing so:
import sys
import requests
payload = sys.stdin
response = requests.post('http://localhost:9200/_search', data=payload)
And if you then want to do some work with it in Python, requests has a built in support for this too. You just call this:
json_response = response.json()
Hope this helps you on the right track. For further reading om json.dumps/loads - this answer has some good stuff on it.
For anyone who doesn't want to use requests (for example if you're using IronPython where its not supported):
import urllib2
import json
req = urllib2.Request(url, json.dumps(data), headers={'Content-Type': 'application/json'})
response = urllib2.urlopen(req)
Where 'url' can be something like this (example below is search in index):
http://<elasticsearch-ip>:9200/<index-name>/_search/

Retrieve access token for Yahoo API using OAuth 2.0 and Python requests

I am trying to retrieve the access token for the Yahoo API, using the explicit grant flow as described in this document:
https://developer.yahoo.com/oauth2/guide/flows_authcode
Everything is fine until Step 4: Exchange authorization code for Access Token
I wrote the following python script to retrieve the code:
import urllib2
import requests
import json
url = 'https://api.login.yahoo.com/oauth2/get_token'
body = "grant_type=authorization_code&redirect_uri=oob&code=************"
headers = {
'Authorization': 'Basic **************',
'Content-Type': 'application/json'
}
r = requests.post(url, data=body, headers=headers)
print r
Note: I replaced sensitive data with "****"
Now, when I execute the script, I only get the "401" error message.
I am 100% sure that the login credentials are fine, so it seems to be related to the way I make the request. It's also the first time that I am using "requests" in python.
Would be great, if you could give me some feedback on the code, and if I am passing the header and body information correctly. I am especially unsure about the passing of the body. The documentation only states the following:
Sample Request Body: grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.example.com&code=abcdef
Change your body variable to a dict, i.e.,
body = {
'grant_type': 'authorization_code',
'redirect_uri': 'oob',
'code': '************',
}
No other changes are needed. Hope it helps.
Tough the problem already solved. But may be other user can still get the same 401 error even if they use correct dict as me. The problem is that the code generated in step 2 in the link can be only use ONCE. And this will get the same 401 error. This took me some time to figure it out. Hope this helps others.

Categories

Resources