I have an existing Http POST using urllib2:
data = 'client_id=%s&client_secret=%s&grant_type=authorization_code&code=%s&redirect_uri=%s' % (settings.GOOGLE_CLIENT_ID, settings.GOOGLE_CLIENT_SECRET, code, redirect_uri)
req = urllib2.Request(access_token_url, data=data)
response = urllib2.urlopen(req)
response_content = response.read()
json_response = json.loads(response_content)
I'm trying to convert this to the Requests library instead (http://docs.python-requests.org/) but I'm getting a 400 Invalid Request.
Here's my attempt:
params = {'redirect_uri' : redirect_uri}
params['client_id'] = settings.GOOGLE_CLIENT_ID
params['client_secret'] = settings.GOOGLE_CLIENT_SECRET
params['grant_type'] = 'authorization_code'
params['code'] = code
req = requests.post(access_token_url, data=params)
json_response = req.json()
I tried tweaking it to use params instead of data but I got the same error.
Anything I'm missing?
Make sure the values of the data dict are not already escaped as requests will do that for you. Please notice how your original example does not do any escaping.
Related
I'm trying to GET an URL of the following format using requests.get() in python:
http://api.example.com/export/?format=json&key=site:dummy+type:example+group:wheel
#!/usr/local/bin/python
import requests
print(requests.__versiom__)
url = 'http://api.example.com/export/'
payload = {'format': 'json', 'key': 'site:dummy+type:example+group:wheel'}
r = requests.get(url, params=payload)
print(r.url)
However, the URL gets percent encoded and I don't get the expected response.
2.2.1
http://api.example.com/export/?key=site%3Adummy%2Btype%3Aexample%2Bgroup%3Awheel&format=json
This works if I pass the URL directly:
url = http://api.example.com/export/?format=json&key=site:dummy+type:example+group:wheel
r = requests.get(url)
Is there some way to pass the the parameters in their original form - without percent encoding?
Thanks!
It is not good solution but you can use directly string:
r = requests.get(url, params='format=json&key=site:dummy+type:example+group:wheel')
BTW:
Code which convert payload to this string
payload = {
'format': 'json',
'key': 'site:dummy+type:example+group:wheel'
}
payload_str = "&".join("%s=%s" % (k,v) for k,v in payload.items())
# 'format=json&key=site:dummy+type:example+group:wheel'
r = requests.get(url, params=payload_str)
EDIT (2020):
You can also use urllib.parse.urlencode(...) with parameter safe=':+' to create string without converting chars :+ .
As I know requests also use urllib.parse.urlencode(...) for this but without safe=.
import requests
import urllib.parse
payload = {
'format': 'json',
'key': 'site:dummy+type:example+group:wheel'
}
payload_str = urllib.parse.urlencode(payload, safe=':+')
# 'format=json&key=site:dummy+type:example+group:wheel'
url = 'https://httpbin.org/get'
r = requests.get(url, params=payload_str)
print(r.text)
I used page https://httpbin.org/get to test it.
In case someone else comes across this in the future, you can subclass requests.Session, override the send method, and alter the raw url, to fix percent encodings and the like.
Corrections to the below are welcome.
import requests, urllib
class NoQuotedCommasSession(requests.Session):
def send(self, *a, **kw):
# a[0] is prepared request
a[0].url = a[0].url.replace(urllib.parse.quote(","), ",")
return requests.Session.send(self, *a, **kw)
s = NoQuotedCommasSession()
s.get("http://somesite.com/an,url,with,commas,that,won't,be,encoded.")
The solution, as designed, is to pass the URL directly.
The answers above didn't work for me.
I was trying to do a get request where the parameter contained a pipe, but python requests would also percent encode the pipe. So
instead i used urlopen:
# python3
from urllib.request import urlopen
base_url = 'http://www.example.com/search?'
query = 'date_range=2017-01-01|2017-03-01'
url = base_url + query
response = urlopen(url)
data = response.read()
# response data valid
print(response.url)
# output: 'http://www.example.com/search?date_range=2017-01-01|2017-03-01'
All above solutions don't seem to work anymore from requests version 2.26 on. The suggested solution from the GitHub repo seems to be using a work around with a PreparedRequest.
The following worked for me. Make sure the URL is resolvable, so don't use 'this-is-not-a-domain.com'.
import requests
base_url = 'https://www.example.com/search'
query = '?format=json&key=site:dummy+type:example+group:wheel'
s = requests.Session()
req = requests.Request('GET', base_url)
p = req.prepare()
p.url += query
resp = s.send(p)
print(resp.request.url)
Source: https://github.com/psf/requests/issues/5964#issuecomment-949013046
Please have a look at the 1st option in this github link. You can ignore the urlibpart which means prep.url = url instead of prep.url = url + qry
My response looks like:
[
{"_id":"5f6060d0d279373c0017447d","name":"Faizan","email":"faizan#test.com"}
]
I want to get the name in python. I am tryting:
response = requests.get(url)
data = response.json()
The error I am getting is:
JSONDecodeError at /get/
this might help you
import requests
import json
dburl = 'https://postman-9e13.restdb.io/rest/contact'
headers = {'x-apikey': '7267cbb3c251a01dd8563ca447194e78af67d', 'Content-Type': 'application/json'}
params = {"name":"Faizan","email":"faizan#test.com"}
r = requests.get(dburl, params=params, headers=headers)
print(r.json())
after seeing the result, you can pass to your templates like this
geodata = response.json()
return render(request, 'main/get.html', { 'name': geodata[0]['name'] })
or you can change accordingly.
The snippet you shared is correct, however the problem might be with the URL.
response = requests.get(url)
data = response.json()
Here, .json() only works for the response which is in the JSON format only. If it is showing that error that means your URL returning the HTML document.
I am trying to post some information into an API based on their recommended format. When I use Postman( tool to test APIs), I see that the response has the isSuccess flag set to true. However, when I write the same code in Python using the requests library, I get the isSuccess flag as false
As mentioned about, I verified the headers and the json data object, both are the same yet the results defer
import requests
data = {"AccountNumber":"100007777",
"ActivityID":"78",
"ActivityDT":"2019-08-07 12:00:00",
"ActivityValue":"1"
}
url = "http://<IP>/<API_PATH>"
headers = {
"X-Tenant":"Default",
"Content-Type":"application/json"
}
response = requests.post(url,data=data, headers = headers)
print(response.content)
This code should successfully post the data and I should get a isSuccess:true in my response variable.
Can anyone help me figure out what might be wrong?
Can you try to change;
response = requests.post(url,data=data, headers = headers)
to;
response = requests.post(url,json=data, headers = headers)
or;
response = requests.post(url,body=data, headers = headers)
I am trying to make a POST request in Python 2, using urllib2. My code is currently as follows;
url = 'http://' + server_url + '/playlists/upload?'
data = urllib.urlencode(OrderedDict([("sectionID", section_id), ("path", current_playlist), ("X-Plex-Token", plex_token)]))
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
d = response.read()
print(d)
'url' and 'data' return correctly formatted with the variables, I know this because I can copy their output into Postman for checking and the POST works fine (see example url below)
http://192.168.1.96:32400/playlists/upload?sectionID=11&path=D%3A%5CMedia%5CPPP%5Ctmp%5Cplex%5CAmbient.m3u&X-Plex-Token=XXXXXXXXX
When I run my Python code I get a 401 error returned, presumably meaning the X-Plex-Token parameter was not correctly sent, hence I am not allowed access.
Can anyone tell me where I'm going wrong? Help is greatly appreciated.
Have you tried removing the question mark and not using OrderedDict (no idea why you would need that) ?
url = 'http://' + server_url + '/playlists/upload'
data = urllib.urlencode({"sectionID":section_id), "path":current_playlist,"X-Plex-Token":plex_token})
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
d = response.read()
print(d)
Of course you should be using requests instead anyway:
import requests
r = requests.post('http://{}/playlists/upload'.format(server_url), data = {"sectionID":section_id), "path":current_playlist,"X-Plex-Token":plex_token})
print r.url
print r.text
print r.json
I've ended up switching to Python 3, as I didn't realise that the requests module was included by default. Still no idea why the above wasn't working, but maybe something to do with the lack of headers
headers = {'cache-control': "no-cache"}
edit:
This is what I'm using now, as mentioned above I probably don't need OrderedDict.
import requests
url = 'http://' + server_url + '/playlists/upload'
headers = {'cache-control': "no-cache"}
querystring = urllib.parse.urlencode(OrderedDict([("sectionID", section_id), ("path", current_playlist), ("X-Plex-Token", plex_token)]))
response = requests.request("POST", url, data = "", headers = headers, params = querystring)
print(response.text)
I'm having a bit of trouble. I'm trying to send a POST and trying to follow the documentation, but I can't seem to get it right.
on github: https://github.com/trtmn/Python
Pull requests welcomed!
# Getting documentation from :
#https://docs.python.org/2/howto/urllib2.html
import urllib
import urllib2
url = 'https://hooks.slack.com/services/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'
values = {"username": "webhookbot", "text": "This is posted to #general and comes from a bot named webhookbot.", "icon_emoji": ":ghost:"}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
looks like I needed to stringify it as JSON (which I knew, but didn't know how). Thanks to Tim G. for the assist.
So here's the functional code:
import urllib2
import json
url = 'https://hooks.slack.com/services/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'
values = {"username": "webhookbot", "text": "This is posted to #general and comes from a bot named webhookbot.", "icon_emoji": ":ghost:"}
data = json.dumps(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
Using httplib as an alternative for POST:
*import httplib
conn = httplib.HTTPSConnection(host)
conn.request('POST',urI,request_body, headers)
response = conn.getresponse()
resp_status=response.status
resp_reason=response.reason
resp_body=response.read()
conn.close()*
See if this helps.
Not sure if this solves the problem but if I add a slash to the end of your url I do receive a response when I execute your code.
url = 'https://hooks.slack.com/services/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/'