pengaturan variabel lingkungan di virtualenv

160

Saya memiliki proyek Heroku yang menggunakan variabel lingkungan untuk mendapatkan konfigurasinya, tetapi saya menggunakan virtualenv untuk menguji aplikasi saya secara lokal terlebih dahulu.

Apakah ada cara untuk mengatur variabel lingkungan yang ditentukan pada mesin jarak jauh di dalam virtualenv?

Mahmoud Hanafy
sumber

Jawaban:

106

Memperbarui

Pada 17 Mei 2017 README dari autoenv menyatakan bahwa direnv mungkin merupakan opsi yang lebih baik dan menyiratkan autoenv tidak lagi dipertahankan.

Jawaban lama

Saya menulis autoenv untuk melakukan hal ini:

https://github.com/kennethreitz/autoenv

Kenneth Reitz
sumber
12
Gif sangat lucu: D
chachan
3
Hanya FYI tampaknya .envfile bork Heroku dibangun, setidaknya dalam pengalaman saya. Jadi jangan memasukkannya ke dalam repo Anda. Pengguna lama / penggemar autoenv btw. Hai, Kenneth, Anda laki-laki!
Galarant
Apakah jawaban ini masih relevan setelah diedit? Apa pendapat Anda tentang solusi yang disarankan oleh Nagasaki45 & TheLetterN
dibekukan
288

Jika Anda menggunakan virtualenvwrapper (saya sangat merekomendasikan melakukannya), Anda dapat menentukan kait yang berbeda (preactivate, postactivate, predeactivate, postdeactivate) menggunakan skrip dengan nama yang sama di $VIRTUAL_ENV/bin/. Anda memerlukan pengait postaktivasi.

$ 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

Jika Anda ingin menyimpan konfigurasi ini di direktori proyek Anda, cukup buat symlink dari direktori proyek Anda ke $VIRTUAL_ENV/bin/postactivate.

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

Anda bahkan dapat mengotomatiskan pembuatan symlink setiap kali Anda menggunakan mkvirtualenv .

Membersihkan saat dinonaktifkan

Ingatlah bahwa ini tidak akan bersih setelahnya. Saat Anda menonaktifkan virtualenv, variabel lingkungan akan tetap ada. Untuk membersihkan secara simetris, Anda dapat menambahkan $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

Ingat bahwa jika menggunakan ini untuk variabel lingkungan yang mungkin sudah diatur di lingkungan Anda maka yang tidak disetel akan mengakibatkan mereka benar-benar tidak disetel saat meninggalkan virtualenv. Jadi jika itu kemungkinan Anda bisa mencatat nilai sebelumnya di suatu tempat sementara kemudian membacanya kembali pada nonaktifkan.

Mempersiapkan:

$ 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

Uji:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Danilo Bargen
sumber
Hanya presisi: melakukan ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivatetidak berhasil untuk saya. lningin jalan penuh, jadi saya harus melakukanln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Zoneur
@Zoneur OS apa yang Anda pakai? Di Linux jalan relatif berfungsi untuk ln.
Danilo Bargen
@DaniloBargen Saya menggunakan LinuxMint 3.2.0. Jawaban ini mengatakan bahwa lnmenyukai path lengkap jadi saya mencobanya dan berhasil. Ketika saya mencoba catsymlink dengan path relatif katanya No such file or directory.
Zoneur
@dpwrussel, yang hampir tidak membuatnya melalui ulasan, ini merupakan tambahan yang bagus, tetapi sangat signifikan sehingga bisa dibuat sebagai posnya sendiri (yang akan memberi Anda beberapa perwakilan). Banyak jawaban Baik baik :)
Kent Fredric
2
Dan kontrol sumber? Bagaimana ini diterjemahkan ke orang lain mengkloning dan mengatur proyek yang membutuhkan env. var.s?
CpILL
44

Kamu bisa mencoba:

export ENVVAR=value

di virtualenv_root / bin / aktifkan. Pada dasarnya skrip aktivasi adalah apa yang dijalankan ketika Anda mulai menggunakan virtualenv sehingga Anda dapat menempatkan semua penyesuaian Anda di sana.

kgr
sumber
2
Tidak yakin apakah itu cukup bersih tetapi pasti berfungsi!
chachan
2
Ya, itu murah dan tidak enak, tetapi sesekali itulah yang Anda butuhkan.
Michael Scheper
1
Saya tidak merekomendasikan ini, saya melakukannya dan beberapa saat kemudian semua skrip aktifkan (aktifkan, aktifkan.csh, aktifkan.fish) ditimpa secara otomatis sehingga saya kehilangan uang kembalian. Gunakan postactivate dan predeactivate.
wil93
jangan gunakan spasi di sekitar =
Rik Schoonbeek
Bisa juga menambahkan 'unset ENVVAR' di deactivatefungsi yang didefinisikan virtualenv_root / bin / aktifkan ke pengaturan keseimbangan dan unsetting
Lou Zell
42

Menggunakan hanya virtualenv (tanpa virtualenvwrapper ), pengaturan variabel lingkungan mudah melalui activateskrip yang Anda sumber untuk mengaktifkan virtualenv.

Lari:

nano YOUR_ENV/bin/activate

Tambahkan variabel lingkungan ke akhir file seperti ini:

export KEY=VALUE

Anda juga dapat mengatur pengait serupa untuk menghapus variabel lingkungan seperti yang disarankan oleh Danilo Bargen dalam jawaban besarnya di atas jika perlu.

Nagasaki45
sumber
9
pendekatan yang jauh lebih waras IMO. mengesampingkan cdhanya untuk memiliki variabel lingkungan? shudder
Michel Müller
bagaimana dengan pembersihan setelah dinonaktifkan?
buncis
36

Meskipun ada banyak jawaban yang bagus di sini, saya tidak melihat solusi yang diposting yang keduanya menyertakan variabel lingkungan yang tidak disetel pada penonaktifan dan tidak memerlukan perpustakaan tambahan di luar virtualenv, jadi inilah solusi saya yang hanya melibatkan pengeditan / bin / aktifkan, menggunakan variabel MY_SERVER_NAMEdan MY_DATABASE_URLsebagai contoh:

Seharusnya ada definisi untuk menonaktifkan skrip aktivasi, dan Anda ingin menghapus variabel Anda di akhir skrip:

deactivate () {
    ...

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

Kemudian di akhir skrip aktivasi, atur variabel:

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

Dengan cara ini Anda tidak perlu menginstal apa pun untuk membuatnya berfungsi, dan Anda tidak berakhir dengan variabel yang tersisa ketika Anda deactivatevirtualenv.

TheLetterN
sumber
3
Saya suka pendekatan ini karena saya tidak ingin lib atau aplikasi eksternal tetapi masalah dengan ini adalah bahwa jika Anda membangun kembali lingkungan Anda akan kehilangan semua pengaturan Anda.
VStoykov
2
Keuntungan dari pendekatan ini adalah kecepatan pengaturan dan kurangnya sihir. Menjaga variabel lingkungan di luar kendali sumber akan selalu membawa Anda kembali ke masalah yang berpotensi menghancurkan rahasia / pengaturan Anda saat membangun kembali lingkungan.
Anthony Manning-Franklin
Apakah direktori virtualenv akhirnya diperiksa ke dalam repositori agar berfungsi? Bagaimana jika variabel menyimpan rahasia yang tidak Anda inginkan dalam repo? Bagaimana kamu akan mengatasi ini?
Kelemahan
2
Saya tidak benar-benar melihat mengapa itu akan menjadi ide yang baik untuk memasukkan virtualenv dalam repositori Anda, karena mereka tidak terlalu portabel, tetapi saya membayangkan Anda bisa meletakkan ekspor Anda dalam file terpisah, bukan skrip aktivasi dan sumber file jika itu ada, dan jangan menambahkan file itu ke repositori Anda.
TheLetterN
18

Secara lokal dalam virtualenv ada dua metode yang dapat Anda gunakan untuk menguji ini. Yang pertama adalah alat yang diinstal melalui Heroku toolbelt (https://toolbelt.heroku.com/). Alat itu mandor. Ini akan mengekspor semua variabel lingkungan Anda yang disimpan dalam file .env secara lokal dan kemudian menjalankan proses aplikasi dalam Procfile Anda.

Cara kedua jika Anda mencari pendekatan yang lebih ringan adalah memiliki file .env secara lokal kemudian jalankan:

export $(cat .env)
CraigKerstiens
sumber
6

Instal autoenv baik oleh

$ pip install autoenv

(atau)

$ brew install autoenv

Dan kemudian buat .envfile di folder proyek virtualenv Anda

$ echo "source bin/activate" > .env

Sekarang semuanya bekerja dengan baik.

Fizer Khan
sumber
3

Jika Anda sudah menggunakan Heroku, pertimbangkan untuk menjalankan server Anda melalui Foreman . Ini mendukung .envfile yang hanya berupa daftar baris KEY=VALyang akan diekspor ke aplikasi Anda sebelum dijalankan.

Michael Mior
sumber
1

Untuk mengaktifkan virtualenv di envdirektori dan mengekspor variabel lingkungan yang disimpan .envdigunakan:

source env/bin/activate && set -a; source .env; set +a
Daniil Mashkin
sumber
simpan ke alias denganecho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Daniil Mashkin