Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Making Authenticated Requests

Give Feedback

This lesson reveals you how to authenticate yourself to an API endpoint you want to use. Therefore, the auth parameter provided by each related requests function is used. By default it uses HTTP’s Basic access authentication scheme, but you can use other methods as well. You can even use your own authentication method. This lesson covers even that.

00:00 Welcome to Section 3. We’ll be talking about authentication, SSL Certificate verification, and performance. So, up first—authentication. This is where we’re passing credentials to a server.

00:12 Authentication is passed through the Authorization header. requests uses the parameter auth= and the username and password are passed as a tuple. By default, it will use the HTTP Basic authentication scheme, and I’ve included a link here to the article on Basic access.

00:29 Let’s check it out. So back here in the REPL, let’s make sure—if you haven’t already done it—to make sure that requests is imported, and we’re going to import one additional thing. From the standard library we’ll import getpass.

00:43 getpass will prompt us to enter in a password after we call its function. For this example, we’re going to use GitHub and the /user endpoint, so let’s save that URL to save us some time. To get there, it’s api.github.com/user, and that will normally prompt you for a username and a password.

01:01 Let’s try a simple request to it. Let’s do a get() request, put in our url. For the authorization, I created an account for this.

01:09 If you have a GitHub account, you simply use your username right here, and as a tuple you can enter in the username and the password. In this case, I’m going to have it prompt me to enter in the password. And let me close everything off here. Here’s where it’s going to prompt me.

01:27 And it looks like I must’ve typed something wrong, so let me try it one more time.

01:35 There we go. Successful. As you can see, if I was to type the password wrong, I would get <Response [401]>, which I saw before, which is saying status code Unauthorized. It’d be the same thing if I just simply tried to go to the URL by itself without putting any authorization in. I’d get the same thing—that we’re unauthorized. Again, it’s using the HTTP Basic authentication scheme under the hood.

02:00 You can say explicitly that you want to use that. It would just look a little differently here. We would from requests.auth import HTTPBasicAuth, and we already have getpass imported here.

02:13 We would say requests.get(), and we have the url, and for authorization, we would say HTTPBasicAuth()—and again, we’d make sure we have our username.

02:31 Great. Here it’s going to prompt me for my password again.

02:36 There we go. A 200 status code—successful. requests provides a few other methods of authentication, including HTTPDigestAuth and HTTPProxyAuth.

02:47 You can explore those a little bit further on your own. You can even supply your own authentication mechanism if you want to, but to do that, you first have to create a subclass of AuthBase inside of the requests package, so let’s try it out. We need to create a file.

03:03 So, I’m going to make a new script. I going to call it auth.py. I’ll start with importing requests. From requests.auth I’ll import AuthBase, which is what we’re going to extend.

03:32 So, we’re initting here with our token, and then when we call…

03:43 it will attach an API token to our custom authorization header.

03:52 The header will look like X-TokenAuth, and we’ll set up an f-string here again. Yeah, that requires Python 3.6 or higher. Give myself some room here… and we’ll return r.

04:15 We’ll use the httpbin service again for this example. This time, under auth it will equal our TokenAuth(), and we’ll just put a generic token in here… and just to make sure it ran, we got a responsewe’ll print it out. Let’s save. So again, importing requests, importing AuthBase from the auth portion of requests. And then again, we’re adding this TokenAuth class and after initializing it, for the .__call__() we’re adding this header with this .token.

05:01 Ope, I spelled that wrong. Okay. Let me save. Let’s try running it.

05:15 Oh, I need a request type, get()—that will help. All right, let’s try it again. Great! And we successfully tested our custom authorization. Creating a bad authentication mechanism can create a security vulnerability, so unless a service really requires you to create something custom, it’s usually better to go ahead and use tried and true stuff like Basic auth or OAuth. Next, let’s talk about SSL Certificates.

km on Dec. 9, 2019

Getting below error when i use this example, any help?

SSLError: HTTPSConnectionPool(host='api.github.com', port=443): Max retries exceeded with url: /user (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1045)')))

Chris Bailey RP Team on Dec. 9, 2019

Hi km, Are you using your own credentials to access this url? I’m unsure what is causing the error without knowing what your Python code you used looked like. The error is saying a maximum number of attempts or retries has happened. Are you using the second half of the lesson for this attempt to connect to Github? The second half of this lesson is using the pastebin url. Here is another resource about the types of authorization you can use with requests, with code examples

DaveyD on May 4, 2020

Even if I use a random username and password the response is still 200.

DaveyD on May 4, 2020

Please help. Now what I get is ....local-packages\Python38\site-packages\requests\sessions.py”, line 728, in get_adapter raise InvalidSchema(“No connection adapters were found for {!r}”.format(url)) requests.exceptions.InvalidSchema: No connection adapters were found for ‘hppts://api.github.com/user’

mikesult on May 5, 2020

There’s a typo. Does your code have

‘hppts://api.github.com/user’

it should be

‘https:…”

mikesult on May 5, 2020

question regarding the custom auth example: I understand that it isn’t recommended to write your own auth scheme.

But I’m not confident that I understand what happened with the Custom Auth example. Is it that a new instance of class TokenAuth(token) is created and immediately assigned to the auth param? Then when requests.get() is called it calls the TokenAuth.call() which assigns that token to the response.header, which is where it is needed to create an authenticated response? Alot going on. If so I guess any value passed into TokenAuth() would work. Is this correct?

Chris Bailey RP Team on May 5, 2020

Hi @DaveyD, If you are following along in the REPL part of the lesson, this endpoint/URL ‘api.github.com/user‘ will require an existing Username on GitHub and the password for the account. I tried random things and it would not provide me a Response other than Response [401].

In your second comment you have a typo in your URL. With it starting with ‘hppts:// ....’ instead of ‘https:// …’ That is the reason the InvalidSchema exception appears.

Chris Bailey RP Team on May 5, 2020

Hi @mikesult,

The creation of a custom authentication system would be so much more complex than this example really alludes to. This is a very phony example in that this site, really just a place to test getting responses does not require any authentication. You are right that any value could be passed into TokenAuth() would work, as it will simply put it in the header for your get request. You can see that if you add another print statement or modify the one that is there to print(response.json()). You would see inside the json that comes back,

{... 'headers': {'Accept': ..., 'X-Tokenauth': '12345abcde-token'} ... }

The value would be whatever you put in there.

So a real authentication scheme would have much more going on the host side too. Best to stick with something tried and true, like Basic or OAuth. More info here. Requests:Authentication portion of the docs

Become a Member to join the conversation.