установка переменной среды в virtualenv

160

У меня есть проект Heroku, который использует переменные среды, чтобы получить его конфигурацию, но я использую virtualenv, чтобы сначала протестировать свое приложение локально.

Есть ли способ установить переменные среды, определенные на удаленном компьютере внутри virtualenv?

Махмуд Ханафи
источник

Ответы:

106

Обновить

По состоянию на 17 мая 2017 года README autoenv утверждает, что direnv , вероятно, является лучшим вариантом и подразумевает, что autoenv больше не поддерживается.

Старый ответ

Я написал autoenv, чтобы сделать именно это:

https://github.com/kennethreitz/autoenv

Кеннет Рейтц
источник
12
Очень забавный GIF: D
chachan
3
Просто к вашему сведению кажется, что .envфайлы bork Heroku строит, по крайней мере, по моему опыту. Так что не включайте это в свой репо. Долгое время пользователь / огромный поклонник autoenv кстати. Привет, Кеннет, да, чувак!
Galarant
Этот ответ остается актуальным после редактирования? Каково Ваше мнение о решении предложенного Nagasaki45 & TheLetterN
замороженное
288

Если вы используете virtualenvwrapper (я настоятельно рекомендую это сделать), вы можете определить различные хуки (преактивировать, постактивировать, предактивировать, постдезактивировать), используя скрипты с одинаковыми именами $VIRTUAL_ENV/bin/. Вам нужен постактивированный крюк.

$ workon myvenv

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
export DJANGO_DEBUG=True
export S3_KEY=mykey
export S3_SECRET=mysecret

$ echo $DJANGO_DEBUG
True

Если вы хотите сохранить эту конфигурацию в каталоге вашего проекта, просто создайте символическую ссылку из каталога вашего проекта на $VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate

Вы даже можете автоматизировать создание символических ссылок каждый раз, когда используете mkvirtualenv .

Очистка при деактивации

Помните, что это не будет убирать за собой. Когда вы деактивируете virtualenv, переменная окружения сохранится. Чтобы очистить симметрично вы можете добавить в $VIRTUAL_ENV/bin/predeactivate.

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
unset DJANGO_DEBUG

$ deactivate

$ echo $DJANGO_DEBUG

Помните, что если использовать это для переменных среды, которые уже могут быть установлены в вашей среде, то неустановленные значения приведут к их полной отмене при выходе из virtualenv. Так что, если это вообще возможно, вы можете записать предыдущее значение где-то временно, а затем прочитать его обратно при деактивации.

Настроить:

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
if [[ -n $SOME_VAR ]]
then
    export SOME_VAR_BACKUP=$SOME_VAR
fi
export SOME_VAR=apple

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
if [[ -n $SOME_VAR_BACKUP ]]
then
    export SOME_VAR=$SOME_VAR_BACKUP
    unset SOME_VAR_BACKUP
else
    unset SOME_VAR
fi

Тест:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Данило Барген
источник
Просто точность: ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivateработа не работает для меня. lnхочет полный путь, поэтому я должен был сделатьln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Zoneur
@Zoneur В какой ты ОС? Под Linux относительные пути работают для ln.
Данило Барген
@DaniloBargen Я использую LinuxMint 3.2.0. Этот ответ сказал, что lnлюбит полные пути, поэтому я попробовал, и это сработало. Когда я попытался catиспользовать символическую ссылку с относительным путем, он сказал No such file or directory.
Zoneur
@dpwrussel, который почти не прошел через рецензию, это хорошее дополнение, но его настолько значительным, что его можно было бы сделать в виде собственного поста (который мог бы принести вам немного репутации). Много хороших ответов - это хорошо :)
Кент Фредрик
2
А источник контроля? Как это переводит других людей, клонирующих и создающих проект, который нуждается в env. var.s?
CpILL
44

Вы можете попробовать:

export ENVVAR=value

в virtualenv_root / bin / activ. По сути, сценарий активации - это то, что выполняется, когда вы начинаете использовать virtualenv, чтобы вы могли поместить туда все свои настройки.

КГР
источник
2
Не уверен, что это достаточно чисто, но определенно работает!
chachan
2
Да, это дешево и противно, но иногда это то, что вам нужно.
Майкл Шепер
1
Я не рекомендую этого, я сделал это, и через некоторое время все сценарии активации (activ, activ.csh, activ.fish) были автоматически перезаписаны, поэтому я потерял свое изменение. Используйте постактивировать и предварительно активировать.
wil93
не используйте пробелы вокруг =
Rik Schoonbeek
Также можно добавить «unset ENVVAR» в deactivateфункцию, определенную virtualenv_root / bin / activ, для настройки и сброса баланса
Лу Зелл,
42

Используя только virtualenv (без virtualenvwrapper ), установить переменные среды легко с помощью activateсценария, который вы используете для активации virtualenv.

Бегать:

nano YOUR_ENV/bin/activate

Добавьте переменные окружения в конец файла следующим образом:

export KEY=VALUE

Вы также можете установить аналогичный хук, чтобы сбросить переменную окружения, как это было предложено Данило Баргеном в его великолепном ответе выше, если вам нужно.

Nagasaki45
источник
9
гораздо более вменяемый подход ИМО. переопределить cdпросто иметь переменные окружения? дрожь
Мишель Мюллер
как насчет очистки после деактивации?
buncis
36

Хотя здесь есть много хороших ответов, я не видел опубликованного решения, которое включает в себя сброс переменных среды при деактивации и не требует дополнительных библиотек virtualenv, поэтому вот мое решение, которое просто включает редактирование / bin / activ с использованием переменные MY_SERVER_NAMEи в MY_DATABASE_URLкачестве примеров:

В сценарии активации должно быть определение деактивации, и вы хотите сбросить переменные в конце его:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}

Затем в конце сценария активации установите переменные:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"

Таким образом, вам не нужно устанавливать что-либо еще, чтобы заставить его работать, и вы не останетесь с переменными, оставшимися, когда станете deactivatevirtualenv.

TheLetterN
источник
3
Мне нравится этот подход, потому что я не хочу внешних библиотек или приложений, но проблема в том, что если вы перестроите среду, вы потеряете все свои настройки.
В.С.Тойков
2
Преимущество такого подхода - скорость настройки и отсутствие магии. Хранение переменных окружения вне контроля исходного кода всегда приведет вас к проблеме потенциального уничтожения ваших секретов / настроек при восстановлении окружения.
Энтони Мэннинг-Франклин
В конечном итоге каталог virtualenv проверяется в хранилище, чтобы это работало? Что делать, если переменные содержат секреты, которые вы не хотите в репо? Как бы вы справились с этим?
fraxture
2
Я не очень понимаю, почему было бы неплохо включить virtualenv в ваш репозиторий, так как они не очень переносимы, но я думаю, что вы можете поместить свои экспорты в отдельный файл вместо сценария активации и получить исходный файл, если он присутствует, и не добавляйте этот файл в свой репозиторий.
TheLetterN
18

Локально внутри virtualenv есть два метода, которые вы можете использовать для проверки этого. Первый - это инструмент, который устанавливается через инструментальный пояс Heroku (https://toolbelt.heroku.com/). Инструмент бригадир. Он будет экспортировать все переменные среды, которые хранятся в файле .env локально, а затем запустить процессы приложения в вашем Procfile.

Второй способ, если вы ищете более легкий подход, - это локально создать файл .env и запустить:

export $(cat .env)
CraigKerstiens
источник
6

Установите autoenv либо

$ pip install autoenv

(или)

$ brew install autoenv

А затем создайте .envфайл в папке вашего проекта virtualenv

$ echo "source bin/activate" > .env

Теперь все работает отлично.

Физер Хан
источник
3

Если вы уже используете Heroku, рассмотрите возможность запуска вашего сервера через Foreman . Он поддерживает .envфайл, представляющий собой просто список строк, KEY=VALкоторые будут экспортированы в ваше приложение до его запуска.

Майкл Миор
источник
3

Другой способ сделать это, который разработан для django, но должен работать в большинстве настроек, это использовать django-dotenv.

  • Оригинал - https://github.com/jacobian/django-dotenv
  • Более полнофункциональный fork- https: //github.com/tedtieken/django-dotenv-rw (я написал это, чтобы иметь возможность устанавливать мои удаленные настройки .env на webfaction из моей локальной командной строки, heroku избаловал меня)
Тед
источник
1

Чтобы активировать virtualenv в envкаталоге и экспортировать переменные среды, хранящиеся в .envиспользовании:

source env/bin/activate && set -a; source .env; set +a
Даниил Машкин
источник
сохранить в псевдонимахecho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Даниил Машкин