128

I am trying to use an API query in Python. From the command line I can use curl like so:

curl --header "Authorization:access_token myToken" https://website.example/id

This gives some JSON output. myToken is a hexadecimal variable that remains constant throughout.

I would like to make this call from python so that I can loop through different ids and analyze the output. Before authentication was needed I had done that with urllib2. I have also taken a look at the requests module but couldn't figure out how to authenticate with it.

1

8 Answers 8

198

The requests package has a very nice API for HTTP requests, adding a custom header works like this (source: official docs):

>>> import requests
>>> response = requests.get(
... 'https://website.example/id', headers={'Authorization': 'access_token myToken'})

If you don't want to use an external dependency, the same thing using urllib2 of the Python 2 standard library looks like this (source: official docs):

>>> import urllib2
>>> response = urllib2.urlopen(
... urllib2.Request('https://website.example/id', headers={'Authorization': 'access_token myToken'})

For Python 3, simply use urllib instead of urllib2

9
  • 1
    Strange. What bugs me a little is the colon in the header... ah! Maybe I (or we both ;) just read that wrong. The header might be named "Authorization" and its value then would be "access_token long_hexadecimal_string". Want to give that a spin?
    – wosc
    Commented Dec 12, 2012 at 6:56
  • 1
    This solution is deprecated or otherwise not working in default Anaconda install. Commented May 5, 2018 at 0:50
  • 1
    What is access_token myToken? From where and how can I get it? @wosc
    – Deep Jadia
    Commented Aug 5, 2019 at 2:53
  • 1
    It is an authentication token that the server uses to verify you are authorized to have access to the API. You need to obtain client credentials (username, password, API key) for the API you want to access and then send them (for example, via a get request) to the authentication server. The server returns a string that could be JSON-encoded to your client and you then use that as a token in your API calls. Search for JWT or OAuth to do some more reading and view some examples. Commented Aug 29, 2019 at 14:27
  • 1
    As @Sowmiya Ragu pointed below, sometimes it's not 'access_token' but 'Bearer'. response = requests.get( 'https://website.com/id', headers={'Authorization': 'Bearer myToken'}) . Not sure if this is a version or specific sever's config isuue.
    – SwissNavy
    Commented Jan 28, 2020 at 11:10
46

I had the same problem when trying to use a token with Github.

The only syntax that has worked for me with Python 3 is:

import requests

myToken = '<token>'
myUrl = '<website>'
head = {'Authorization': 'token {}'.format(myToken)}
response = requests.get(myUrl, headers=head)
1
  • What would be the token here? Or how to get authentication token?
    – Deep Jadia
    Commented Aug 5, 2019 at 2:13
29
>>> import requests
>>> response = requests.get('https://website.com/id', headers={'Authorization': 'access_token myToken'})

If the above doesnt work , try this:

>>> import requests
>>> response = requests.get('https://api.buildkite.com/v2/organizations/orgName/pipelines/pipelineName/builds/1230', headers={ 'Authorization': 'Bearer <your_token>' })
>>> print response.json()
4
  • 2
    I had the same issue this week and what ended up working for me was the Authorization bearer option. Not sure why there's a difference, but thanks for providing that option for me to try and successfully get working! Commented Jan 31, 2020 at 13:05
  • 1
    @SowmiyaRagu the second part works for me Bearer <my_token> while the first doesn't because the response is as if the request is not authenticated.
    – hydradon
    Commented Feb 5, 2020 at 17:46
  • JULY 2022 : OPTION 2 WORKS ON PYTHON REQUESTS = 2.28.1
    – Koops
    Commented Jul 18, 2022 at 5:50
  • access_token does not work because it is deprecated in python3 Commented Sep 20, 2022 at 21:29
13

A lot of good answers already, but I didn't see this option yet:

If you're using requests, you could also specify a custom authentication class, similar to HTTPBasicAuth. For example:

from requests.auth import AuthBase


class TokenAuth(AuthBase):
    def __init__(self, token, auth_scheme='Bearer'):
        self.token = token
        self.auth_scheme = auth_scheme

    def __call__(self, request):
        request.headers['Authorization'] = f'{self.auth_scheme} {self.token}'
        return request

This could be used as follows (using the custom auth_scheme from the example):

response = requests.get(
    url='https://example.com', 
    auth=TokenAuth(token='abcde', auth_scheme='access_token'),
)

This may look like a more complicated way to set the Request.headers attribute, but it can be advantageous if you want to support multiple types of authentication. Note this allows us to use the auth argument instead of the headers argument.

1
  • 2
    Useful because you don't have to merge headers manually
    – Kiruahxh
    Commented Jul 21, 2022 at 8:43
12
import requests

BASE_URL = 'http://localhost:8080/v3/getPlan'
token = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImR"

headers = {'Authorization': "Bearer {}".format(token)}
auth_response = requests.get(BASE_URL, headers=headers)

print(auth_response.json())

Output :

{
"plans": [
    {
        "field": false,
        "description": "plan 12",
        "enabled": true
    }
  ]
}
7

Have you tried the uncurl package (https://github.com/spulec/uncurl)? You can install it via pip, pip install uncurl. Your curl request returns:

>>> uncurl "curl --header \"Authorization:access_token myToken\" https://website.com/id"

requests.get("https://website.com/id",
    headers={
        "Authorization": "access_token myToken"
    },
    cookies={},
)
3

I'll add a bit hint: it seems what you pass as the key value of a header depends on your authorization type, in my case that was PRIVATE-TOKEN

header = {'PRIVATE-TOKEN': 'my_token'}
response = requests.get(myUrl, headers=header)
3

One of the option used in python to retrieve below:

import requests

token="abcd" < retrieved based>
headers = {'Authorization': "Bearer {}".format(token)}
response = requests.get(
    'https://<url api>',
    headers=headers,
    verify="root ca certificate"
)

print(response.content)

If you get hostname mismatch error then additional SANs need to be configured in the server with the hostnames.

Hope this helps.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.