getpass

Prompt the user for a password without echoing

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.

Example

The getpass() function prints a prompt then reads input from the user until they press return. The input is passed back as a string to the caller.

import getpass

p = getpass.getpass()
print 'You entered:', p

The default prompt, if none is specified by the caller, is “Password:”.

$ python getpass_defaults.py
Password:
You entered: sekret

The prompt can be changed to any value your program needs.

import getpass

p = getpass.getpass(prompt='What is your favorite color? ')
if p.lower() == 'blue':
    print 'Right.  Off you go.'
else:
    print 'Auuuuugh!'

I don’t recommend such an insecure authentication scheme, but it illustrates the point.

$ python getpass_prompt.py
What is your favorite color?
Right.  Off you go.
$ python getpass_prompt.py
What is your favorite color?
Auuuuugh!

By default, getpass() uses stdout to print the prompt string. For a program which may produce useful output on sys.stdout, it is frequently better to send the prompt to another stream such as sys.stderr.

import getpass
import sys

p = getpass.getpass(stream=sys.stderr)
print 'You entered:', p

This way standard output can be redirected (to a pipe or file) without seeing the password prompt. The value entered by the user is still not echoed back to the screen.

$ python getpass_stream.py >/dev/null
Password:

Using getpass Without a Terminal

Under Unix, getpass() always requires a tty it can control via termios, so echo can be disabled. This means values will not be read from a non-terminal stream redirected to standard input.

$ echo "sekret" | python getpass_defaults.py
Traceback (most recent call last):
 File "getpass_defaults.py", line 34, in
   p = getpass.getpass()
 File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/getpass.py", line 32, in unix_getpass
   old = termios.tcgetattr(fd)     # a copy to save
termios.error: (25, 'Inappropriate ioctl for device')

It is up to the caller to detect when the input stream is not a tty and use an alternate method for reading in that case.

import getpass
import sys

if sys.stdin.isatty():
    p = getpass.getpass('Using getpass: ')
else:
    print 'Using readline'
    p = sys.stdin.readline().rstrip()

print 'Read: ', p

With a tty:

$ python ./getpass_noterminal.py
Using getpass:
Read:  sekret

Without a tty:

$ echo "sekret" | python ./getpass_noterminal.py
Using readline
Read:  sekret

results matching ""

    No results matching ""