Getpass: Secure Password Prompt
The strength of Python’s standard library is its size. It includes implementations of so many aspects of a program’s structure that developers can concentrate on what makes their application unique, instead of having to write all the basic pieces over and over again. This series covers some of the more frequently reused building blocks that solve problems common to so many applications. This article would be short and straight forward, compared to the last one i wrote on argpase... Let's just get started.
getpass()
: the function.
Many programs that interact with the user via the terminal need to ask the user for password values without showing what the user types on the screen. The getpass module provides a portable way to handle such password prompts securely. The getpass() function prints a prompt, then reads input from the user until the user presses the enter key. The input is returned as a string to the caller.
import getpass
try:
password: str = getpass.getpass()
except Exception as e:
print('ERROR:', e)
else:
print('You entered:', password)
The result on the terminal:
$ python file.py
Password:
You entered: mypassword
The default prompt is "Password", and the prompt value can be altered by adding a new argument.
import getpass
age = getpass.getpass(prompt="How old are you?")
age: int = int(age) # lets assume the user only inputs an integer value
if age >= 18:
print("logging in...")
else:
print("you cant access this content!")
The result on the terminal:
$ python file.py
How old are you?
logging in...
Changing the stream
By default, getpass() uses sys.stdout
to print the prompt string. For a program that may produce useful output on sys.stdout
, it is frequently a better choice to send the prompt to another stream such as sys.stderr
.
import sys
import getpass
password: str = getpass.getpass(stream=sys.stderr)
print('You entered:', password)
Using sys.stderr
for the prompt means standard output can be redirected (to a pipe or file) without seeing the password prompt. The value entered by the user is not echoed back to the screen.
$ python file.py > /dev/null
Password:
Using getpass without a Terminal
Under Unix, getpass()
always requires a tty it can control via termios , so input echoing can be disabled. With this approach, values will not be read from a non-terminal stream redirected to standard input. Instead, getpass tries to get to the tty for a process, and no error is raised if the function can access it.
$ echo "not secret" | python file.py
Password:
You entered: secret
The caller is responsible for detecting when the input stream is not a tty, and using an alternative method for reading in that case.
import getpass
import sys
if sys.stdin.isatty():
password = getpass.getpass('Using getpass: ')
else:
print('Using readline')
password = sys.stdin.readline().rstrip()
print('Read: ', password)
Output with a tty:
$ python file.py
Using getpass:
Read: secret
For the most basic cases all you'll need is the getpass()
function, but if you find the extra details helpfull, as well as the rest of the article... feel free to follow me on
twitter. and also leave a comment if you have any issues following this tutorial. Happy coding!
NOTE: this article is mostly part of Doug Hellmann's
"The Python3 Standard Library be Example" book.