Переменные окружения для Python проектов
При разработки web-приложения или бота мы часто имеем дело с какой-либо секретной информацией, различными токенами и паролями (API-ключами, секретами веб-форм). "Хардкодить" эту информацию, а тем более сохранять в публично доступной системе контроля версий это очень плохая идея.
# Плохая практика. Не делай так.
API_KEY = 'very_secret_password'
Конфигурационные файлы
Самый простой путь решения данной проблемы, это создание отдельного конфигурационного файла со всей чувствительной информацией и добавление его в .gitignore
. Минус такого подхода в том, что в гит нужно держать ещё и шаблон конфигурационного файла и не забывать его периодически обновлять.
# Уже лучше.
from config import API_KEY
app = Flask(__name__)
app.config['API_KEY'] = API_KEY
Переменные окружения
Более продвинутый подход, это использование переменных окружения. Переменные окружения это именованные переменные, содержащие текстовую информацию, которую могут использовать запускаемые программы. Например, чтобы запустить flask-приложение, вначале нужно указать в переменной окружения FLASK_APP
имя нашего приложения:
$ export FLASK_APP=hello.py
$ flask run
* Running on http://127.0.0.1:5000/
С помощью переменных окружения можно получать различные параметры приложение и секретные ключи:
import os
app.config['API_KEY'] = os.environ.get('API_KEY')
Библиотека python-dotenv
Чтобы не задавать каждый раз вручную переменные окружения при новом запуске терминала, можно воспользоваться пакетом python-dotenv. Он позволяет загружать переменные окружения из файла .env
в корневом каталоге приложения.
Устанавливаем пакет:
pip install python-dotenv
Теперь можно создать файл .env со всеми переменными среды, которые необходимы вашему приложению. Важно, добавьте .env
-файл в .gitignore
, не храните его в системе контроля версий.
import os
from dotenv import load_dotenv
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path)
Этот .env-файл можно использовать для всех переменных конфигурации, но его нельзя использовать для переменных среды FLASK_APP
и FLASK_DEBUG
, так как они необходимы уже в процессе начальной загрузки приложения.
Утилита direnv
Переменные среды могут быть автоматически загружены при входе в папку с проектом, это особенно удобно при работе с несколькими проектами одновременно. Сделать это позволяет утилита direnv. Direnv — это менеджер переменных среды для терминала, поддерживает bash, zsh, tcsh и др. оболочки. Позволяет автоматически загружать и выгружать переменные среды в зависимости от вашего текущего каталога. Это позволяет иметь переменные среды, специфичные для каждого проекта. Перед каждым приглашением проверяется наличие файла .envrc
в текущем и родительском каталогах. Если файл существует, он загружается в подшаблон bash, и все экспортированные переменные затем захватываются direnv, а затем становятся доступными для оболочки.
Установка direnv
sudo apt-get install direnv
Далее необходимо в нести изменения для настройки нашей оболочки, для bash необходимо в конец файла ~/.bashrc
добавить следующее и перезапустить консоль:
eval "$(direnv hook bash)"
Создадим новую папку для проекта:
$ mkdir ~/my-project
$ cd ~/my-project
Покажем, что переменная окружения FLASK_APP не загружена:
$ echo $FLASK_APP
nope
Запишем переменные окружения в файл .envrc
:
$ echo export FLASK_APP=hello.py > .envrc
.envrc is not allowed
Для обеспечения безопасности, после создания или изменения файла .envrc
, нужно выполнить подтверждение с помощью команды direnv allow:
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FLASK_APP
Покажем, что переменная окружения загружена:
$ echo $FLASK_APP
hello.py
При выхода из папки с проектом переменные окружения выгружаются
$ cd ..
direnv: unloading
и становятся снова не заданными
$ echo $FLASK_APP
nope
Работа с виртуальным окружением в direnv
Кроме загрузки переменных окружения, утилита direnv позволяет также работать с виртуальным окружением для Python.
Виртуальное окружение позволяет использовать для отдельные проектов разные версии интерпретатора python и пакетов библиотек. Существует несколько способов создания виртуального окружения для python, здесь мы рассмотрим модуль venv, для другие варианты описаны в документации к direnv.
Чтобы использовать venv для автоматического создания и активирования виртуального окружения, необходимо добавить в файл ~/.config/direnv/direnvrc
следующий код (см. документацию).
Создание виртуального окружения
Если в файл .envrc
добавить строчку
layout python-venv
то при переходе в папку будет direnv создаст виртуальное окружение в папке direnv, например .direnv/python-venv-3.7.3
.
Чтобы создать виртуальное окружение с другим путем, например в более привычной папке venv, надо задать переменную VIRTUAL_ENV
:
export VIRTUAL_ENV=.venv
Таким же способом можно подключать уже созданное виртуальное окружение.
Работа с разными версиями Python
Для установки отличной от системной версии python, нужно использовать команду:
layout python-venv python3.6
Создаем строку приглашения bash (PS1)
В отличие от ручной активации виртуального окружения, в нашем случае строка приглашения bash (PS1) не будет изменена (обычно она выглядит как (venv) user@comp:~$
). Чтобы вернуть показ активации виртуального окружения в консоли нужно в файл ~/.bashrc
добавить следующий код:
show_virtual_env() {
if [[ -n "$VIRTUAL_ENV" && -n "$DIRENV_DIR" ]]; then
echo "($(basename $VIRTUAL_ENV))"
fi
}
export -f show_virtual_env
PS1='$(show_virtual_env)'$PS1
Пример файла настройки файла .envrc
Вот так может выглядеть файл .envrc
настроенный для разработки flask-приложения:
export VIRTUAL_ENV=venv
layout python-venv
export FLASK_APP=app.py
export FLASK_DEBUG=1
Это позволяет автоматически активировать виртуальное окружение и загрузить переменные окружения при входе в папку с проектом.
Автор: Андрей