bbengfort bbengfort - 1 month ago 9
Python Question

How can I give input with getpass to a Flask app when deploying with uWSGI?

I have a Flask app that has some cryptographic components. Specifically, there is a key on disk that is encrypted, and must be unencrypted in memory for use during the Flask app processes. In order to unencrypt the key, the user is prompted to enter a passphrase with getpass when the application runs.

This works great with
and a single foreground Flask WSGI server. The problem we're running into is that when deploying with uWSGI, the uWSGI controller does not allow stdin.

Ideally, what we would like to happen is similar to when you restart or start Apache or Nginx with SSL - before the service forks it prompts for a password on stdin.

Any help would be appreciated!


Although we still would prefer to use uWSGI, we have moved to gunicorn because of gunicorn's pre-fork options. This solution is still not ideal, especially because we do not have the ability to add a monitoring service like UPSTART. Essentially, we have a script that we run before that uses
to set the password into an environment variable and pass that environment variable to the gunicorn app.


NAME="baz" # Name of the application
APPDIR=/var/apps/baz # Application project directory
SOCKFILE=/var/apps/baz/gunicorn.sock # Using a socket
BIND="" # Using a port
USER="www-data" # User to run as
GROUP="www-data" # Group to run as
WORKERS=1 # How many worker processes

echo "Starting $NAME"

# Collect the passphrase
read -s -p "Enter $NAME passphrase: " PASSPHRASE
echo ""

# Activate the virtual environment
source /var/venvs/baz/bin/activate
export BAZ_SETTINGS="baz.conf.Config"

# Start Gunicorn
exec gunicorn $NAME:app \
--user $USER --group $GROUP \
--bind $BIND \
--workers $WORKERS \
--chdir $APPDIR \

This is more or less the script used in the tutorial Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL - modified for reading the passphrase and for use with Flask.

We have checked to make sure that the
environment variable does not exist in any environments, but this still feels a little squeaky, so we'd still appreciate any comments, particularly with regards to uWSGI.


Just add --honour-stdin it will disable the remapping of file descriptor 0 to /dev/null

if you call --daemonize you will lose controlling terminal, so you have to postpone daemonization after the input has been read using --daemonize2