I'm working with Dropbox's python API, trying to convert the following curl command to Python Requests:
curl -X POST https://content.dropboxapi.com/2/files/download \
--header "Authorization: Bearer <ACCESS_TOKEN>" \
--header "Dropbox-API-Arg: {\"path\": \"/Homework/math/Prime_Numbers.txt\"}"
My translation so far:
downloadHeader={"Authorization: " + authorization}
downloadURL = "https://content.dropboxapi.com/2/files/download"
downloadPayload = {"Dropbox-API-Arg": {"path": "/" + dbPATH}}
downloadResponse = requests.post(downloadURL, data=json.dumps(downloadPayload), headers=downloadHeader)
However, when I run this I get the following error:
for header in headers.items():
AttributeError: 'set' object has no attribute 'items'
Can anyone give me some feedback? I'm confident about my authorization value because it's working in a separate request which I'm copy and pasting below:
MDlink = "https://api.dropboxapi.com/2/sharing/get_shared_link_metadata"
authorization = "Bearer " + ACCESS_TOKEN
headers={"Content-Type":"application/json", "Authorization": authorization}
payload = {"url": imageLink}
response = requests.request("POST", MDlink, data=json.dumps(payload), headers=headers)
Thank you very much!
You want this
downloadHeader={"Authorization: " + authorization}
To be
downloadHeader={"Authorization": authorization}
Or more precisely
downloadHeader={"Authorization": "Bearer <ACCESS_TOKEN>"}
Explanation:
{1} # this is a set. It has no .items()
{1: 1} # this is a dict. You can call .items()
Related
I do not coding a this situation.
I can create a repository in python using a request.post(), but I can not delete a this repository.
Here is the code:
def deleteRepository(self, repo, name):
headers = {'Accept': 'application/vnd.github.v3+json',
'Authorization': 'token {}'.format(self.token)}
response = requests.delete(self.api_url + '/repos/' + name + repo, headers = headers)
return response.json()
+ name + repo seems strange.
Consider this implementation for instance
def deleteRepository(self,name,username):
response = requests.delete(self.api_url+'/repos/' + username + '/'+name+'?access_token='+self.token)
print(response.status_code)
Note the '/repos/' + username + '/'+name+' part: separators are important for your path segments.
Update June 2021: as explained in "
Deprecating API authentication through query parameters "
If you're currently making an API call similar to
curl "https://api.github.com/user/repos?access_token=my_access_token"
Instead, you should send the token in the header:
curl -H 'Authorization: token my_access_token' https://api.github.com/user/repos
So:
def deleteRepository(self,name,username):
response = requests.delete(self.api_url+'/repos/' + username + '/'+name+', headers={'Authorization': 'token self.token'})
print(response.status_code)
I've been trying to connect to an oauth2 API. I've managed to write a code that delivers a token, so the token is not a problem.
I've checked that with curl. The following works:
curl -X GET \
https://api.website.pl/sale/delivery-methods \
-H 'Authorization: Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA' \
-H 'accept: application/vnd.website.public.v1+json'
<- This returns the data I need.
However, I simply can't make it work in python.
headers = {}
headers['Authorization'] = 'Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA'
headers['Accept'] = 'application/vnd.website.public.v1+json'
get_url = 'https://api.website.pl/sale/delivery-methods'
requests.get(get_url, headers)
The response is <Response [406]>, incorrect data, which I'm interpreting as a signal I didn't pass all the relevant authorization headers.
Any ideas how to fix that?
try this:
headers = {}
headers['Authorization'] = 'Bearer eyJhbGciOiJSUzBmF1BWKBjk3GiA'
headers['Accept'] = 'application/vnd.website.public.v1+json'
get_url = 'https://api.website.pl/sale/delivery-methods'
response = requests.get(get_url, headers=headers)
When trying out the digitalocean v2 api I come across the following behaviour:
curl -X POST "https://api.digitalocean.com/v2/droplets" \
-d'{"name":"t002","region":"ams3","size":"512mb","image":"debian-7-0-x64","ssh_keys":[123]}' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
Works fine and the droplet gets created.
Now when I do call it from python with:
json_values = {'name': 's002', 'region': 'ams3', 'size': '512mb', 'image': 'debian-7-0-x64', 'ssh_keys': [123]}
data = urllib.parse.urlencode(json_values)
data = data.encode("utf-8")
try:
req = urllib.request.Request(create_droplets_url, data)
req.add_header("User-Agent", uagent) # set custom user agent
req.add_header("Authorization", BearerToken) # set custom user agent
response = urllib.request.urlopen(req)
I get back: HTTP Error 422: Unprocessable Entity with no further information. Am i doing something wrong on the python side? Thx
Additional Info:
I figured out that the problem must be with ssh_keys. If I remove that element everything works fine.
Why are you url-encoding the data? That's not what the curl version is doing. Dump it to JSON instead:
data = json.dumps(json_values)
req = urllib.request.Request(create_droplets_url, data)
I have received the same error and realized it has occurred due to the server side validation failed with your post data.
Solution:
use requests.post instead of urllib.request.Request then you could get the accurate error message for that serverside 422 error code.
Sample code:
import requests
API_URL = "***"
TOKEN = "***"
HEADERS = {
"User-Agent": "Python API Sample",
"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"
}
data = {
"user_id": "***",
"project_id": "***"
}
json_data = json.dumps(data).encode('utf8')
response = requests.post(url=API_URL, headers=HEADERS, data=json_data)
print(json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": ")))
Thanks :)
There are lot of questions posted how to consume the REST services with python, but none of them worked for me,
currently with the below curl cli i can get the authentication token.
curl cli
curl -v --user username:pass1234 -H "content-type: application/json" -X POST -d "" https://mywebsite/api/v1/auth/token-services --insecure
when i execute the above cli i get the json response as below :
output snip from above curl cli
< HTTP/1.1 200 OK
< Server: nginx/1.4.2
< Date: Mon, 14 Apr 2014 23:22:41 GMT
< Content-Type: application/json
< Content-Length: 201
< Connection: keep-alive
Connection #0 to host <ipaddress> left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
{"kind": "object#auth-token", "expiry-time": "Mon Apr 14 23:37:41 2014", "token-id": "l3CvWcEr5rKvooOaCymFvy2qp3cY18XCs4JrW4EvPww=", "link": "https://mywebsite/api/v1/auth/token-services/1634484805"}
NOW MY QUESTION is, how to achieve this using python. WHAT libraries i should use? i need to extract the token-id from the json response. so that i will use that token for further request to consume REST services.
if some one can post the PYTHON code snippet for this that would be great.
Have a look at the following HOWTO of the python documentation: HOWTO Fetch Internet Resources Using urllib2. There you also find a section with an code example for Basic authentication. The HOWTO describes how you can use the module urllib2.
Other useful libraries:
requests
mechanize
I got the solution for what i am looking for...
Complete Sample code ...
import requests
from requests.auth import HTTPBasicAuth
import json
token = ""
def get_token(username, password, url):
global token
#verify=False will not verify the ssl
resp = requests.post(url, auth=HTTPBasicAuth(username, password), verify=False)
print "\n", dir(resp)
print "Status Code:", resp.status_code, "\n"
print "text:", resp.text, "\n"
print "json:", resp.json(), "\n"
print "Content:", resp.content, "\n"
print "Headers:", resp.headers, "\n"
print "Header(Content-type:)", resp.headers.get('content-type'), "\n"
print "Header(Content-length:)", resp.headers.get('content-length'), "\n"
print "OK:", resp.ok, "\n"
print "json dump:", json.dumps(resp.json())
json_dict = json.loads(resp.text)
token = json_dict['token-id']
print "\ntoken-id:", json_dict['token-id']
for key, value in json_dict.items():
print key, "=>", value
return token
def get_global_users(token):
print "\nexecuting get_global_users.."
print "Token", token
url = 'https://xxx.xxx.xxx.xxx/api/v1/global/users'
headers_dict = {'content-type': 'application/json', 'Accept': 'application/json', 'X-Auth-Token': token}
resp = requests.get(url, headers=headers_dict, verify=False)
print "Status Code:", resp.status_code, "\n"
print "text:", resp.text, "\n"
print "json:", resp.json(), "\n"
json_users = json.loads(resp.text)
print "all users:\n", json_users['users']
print "\n"
for users in json_users['users']:
for key, value in users.items():
print key, "=>", value
def post_global_user(token):
print "\nexecuting post_global_users.."
print "Token:", token
url = 'https://xxx.xxx.xxx.xxx/api/v1/global/users'
headers_dict = {'content-type': 'application/json', 'Accept': 'application/json', 'X-Auth-Token': token}
payload = {'username': 'myuser', 'password': 'pas1234', 'pw-type': 0, 'privilege': 15}
resp = requests.post(url, data=json.dumps(payload), headers=headers_dict, verify=False)
print "Status Code:", resp.status_code, "\n"
To emulate the curl command:
$ curl -v --user username:pass1234 -H "accept: application/json" \
-X POST -d "" https://mywebsite/api/v1/auth/token-services --insecure
in Python using only stdlib:
#!/usr/bin/env python
import base64
import json
from urllib2 import urlopen, Request
credentials = base64.b64encode(b'username:pass1234')
headers={'Authorization': b'Basic ' + credentials,
'Accept': 'application/json'}
response = urlopen(Request("https://example.com/post", b"", headers))
data = json.load(response)
token_id = data["token-id"]
If you want to see what is sent to/received from a server for https requests; enable debugging:
import urllib2
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPSHandler(debuglevel=1)))
I'm trying to integrate PayPal REST API in my website. As a first step, I'm trying to translate cURL commands into Python and I'm getting an Exception Value: HTTP Error 400.
The code I'm using (is based on https://stackoverflow.com/a/2003832/2675537):
def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()
req = urllib2.Request("https://api.sandbox.paypal.com/v1/oauth2/token",
headers = {
"Authorization": basic_authorization("EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM", "EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM"),
"Accept": "application/json",
"Accept": "*/*",
"User-Agent": "my-python-app/1",
},
data = '{"message":{"body":' + 'grant_type=client_credentials' + '}}' )
f = urllib2.urlopen(req)
return HttpResponse(f)
which is the equivalent (I guess) to:
curl https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-u "EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM:EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM" \
-d "grant_type=client_credentials"
And the traceback is here: (Edit: Broken Link)
According to PayPal I should get a response like this:
{"scope":"https://api.paypal.com/v1/payments/.* https://api.paypal.com/v1/vault/credit-card https://api.paypal.com/v1/vault/credit-card/.* https://api.paypal.com/v1/developer/.*","access_token":"OABI8rm75u.5EIuK7.JrI2sLhnv3rhDgLElKAwTfyys","token_type":"Bearer","app_id":"APP-2EJ531395M785864S","expires_in":28800}
Is there an error in my code? Is there a better way to do it?
First of all, I would suggest you not to post your keys in clear text in your code examples.
The error your getting "HTTP Error 400: Bad Request", is due to a badly formed request.
From the docs the format for a request is:
urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])
data may be a string specifying additional data to send to the server,
or None if no such data is needed.
headers should be a dictionary, and will be treated as if add_header()
was called with each key and value as arguments.
So your data field is passing a dict instead of string, and it would be a lot more readable
if you separated the fields outside of the Request class. When you have multiple header
fields to fill in, I find it better to use the add_header method as shown below.
import urllib, urllib2
def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()
url = "https://api.sandbox.paypal.com/v1/oauth2/token"
params = { "grant_type": client_credentials}
data = urllib.urlencode(params)
req = urllib2.Request(url, data)
req.add_header("Authorization",basic_authorization("XXX"))
req.add_header("Accept", "application/json")
req.add_header("User-Agent", "my-python-app/1")
response = urllib2.urlopen(req)