Hiding Input
00:00
In the previous lesson, I showed you how to parse the user’s input with the string objects .split() method. In this lesson, I’ll show you how to get input without it being echoed to the screen.
00:11 When you type something in a terminal, it doesn’t have to be shown. In fact, the terminal is doing extra work to show you what you’re typing. This extra work is known as echoing.
00:20
It’s pretty useful as it’s hard to know if you’ve made a typo if you can’t see what you typed. Like with most things on the terminal, input() echoes what the user types, but sometimes you don’t want that.
00:31
What if you’re asking for sensitive information like a password? Python’s getpass() function from the module with the same name works like input() but without the echo.
00:42
Echo. Echo. Yes, I think I’m funny. Let me demonstrate a program that uses getpass(). Here, I’ve written a script called sensitive.py.
00:54
The input() function is built-in, so you don’t have to import anything to use it. By contrast, the getpass() function is in a module, so you have to import it first.
01:03
This line is a little confusing because the module and the function have the same name. Python allows that. This line looks in the module named getpass.
01:12
That’s the from module part, and imports the thing named getpass, which is the second getpass, a function in this case. Since this program is about checking a password, I need the correct password to compare it against.
01:26 This is bad on so many levels. Don’t do this. It keeps the example simple, but storing passwords like this is a bad idea. Remember that, bad idea. I’ll come back to it later.
01:38 In case storing passwords like this wasn’t a bad enough idea, I’ve also chosen a really bad password. Literally. The previous script examples I showed you skipped over a best practice. Here, I’m going to use it. I’ll come back to exactly what that is in a second.
01:53
For now, just know I’m declaring a function which I’ve named main(). It could be named anything, but when your script only does one thing like this one does, main is a common choice.
02:04
This is the heart of the script, and if it looks a lot like calling input(), well there’s a good reason. getpass() pretty much works the same way.
02:11
The user gets prompted with the string argument, and their answer gets returned as a string. The only difference between getpass() and input() is no echo.
02:21 See, I didn’t say it three times. Here, I compare the user’s answer with the bad password, and if it didn’t match, I tell them so. When you import a Python module, any code in the module gets run.
02:34 If your program is a single-file script, that’s no big deal because often that’s exactly what you want it to do. Sometimes though, you want to be able to both run a file and import it somewhere else.
02:44
This line of code is how you tell the difference. Python sets the double underscore __name__ variable automatically. This is also known as dunder name.
02:53
The value in __name__ is the module that this code is running within. If you run this file as a program, the module name gets set to __main__. By putting all of our code in a function, if this file gets imported, nothing gets run.
03:09
You could access the function in another module, or you could access the secret variable as well. To execute the code in main(), you have to explicitly call it, which is what I’m doing here.
03:20
if __name__ contains "__main__":. Like I said before, this is a best practice, so I probably should have been doing it all along.
03:33 There’s the prompt, and now I have to type something,
03:37 and it was the correct password. Note, depending on your operating system and terminal, you might get a little symbol after the prompt. For example, in iTerm on a Mac, you see a little key to indicate that what you’re typing won’t be shown.
03:53 I vaguely recall saying, don’t do that, so let me just reiterate. Don’t do that! You should never store passwords in clear text at all, whether it’s in your program or in a data file.
04:04 You’re just begging for someone to find the password, which completely defeats the purpose of passwords. There are a couple of approaches you can use to solve this problem.
04:13 I’m not going to go into detail, but I figured I’d at least mention them. The first approach is to use an environment variable. Most operating systems support environment variables.
04:22
They’re similar to variables in your program, but available at the OS level. Python’s os module has a function called .getenv(), which allows you to examine these variables.
04:33 You could set an environment variable to contain the correct password. Then your program could find it that way. This is often used with things like Docker containers and AWS servers, where environment variables are set from the outside.
04:47
Another option is to encrypt the password on the hard drive. The hashlib module contains functions for creating cryptographic hashes. These are ways of storing things like passwords, making them unreadable.
04:59 How this works is you store the hashed value of the real password. Then when the user types something in, you hash their response. You compare the two hashed values instead of clear-text ones, and if they match, you let the user in.
05:13
There are a bunch of different ways of hashing with varying degrees of security. Check out the hashlib module if you want to learn more.
05:21 That’s all the content for the course. In the last lesson, I’ll wrap up with a summary and point you at other content you might find interesting.
Become a Member to join the conversation.
