Aktywuj virtualenv za pomocą skryptu w Pythonie

91

Chcę aktywować instancję virtualenv ze skryptu w języku Python.

Wiem, że jest to całkiem łatwe, ale wszystkie przykłady, które widziałem, używają go do uruchamiania poleceń w środowisku env, a następnie zamykania podprocesu.

Chcę po prostu aktywować virtualenv i wrócić do powłoki, w ten sam sposób, w jaki robi to bin / Activ.

Coś takiego:

$me: my-script.py -d env-name
$(env-name)me:

czy to możliwe?

Istotnych:

virtualenv ›Wywołanie env ze skryptu

h3.
źródło

Odpowiedzi:

88

Jeśli chcesz uruchomić podproces Pythona w virtualenv, możesz to zrobić, uruchamiając skrypt za pomocą interpretera Pythona, który znajduje się w katalogu / bin / virtualenv:

import subprocess

# Path to a Python interpreter that runs any Python script
# under the virtualenv /path/to/virtualenv/
python_bin = "/path/to/virtualenv/bin/python"

# Path to the script that must run under the virtualenv
script_file = "must/run/under/virtualenv/script.py"

subprocess.Popen([python_bin, script_file])

Jeśli jednak chcesz aktywować virtualenv w ramach bieżącego interpretera Pythona zamiast podprocesu, możesz użyć activate_this.pyskryptu:

# Doing execfile() on this file will alter the current interpreter's
# environment so you can import libraries in the virtualenv
activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

execfile(activate_this_file, dict(__file__=activate_this_file))
Lie Ryan
źródło
1
//, Czy ta ostatnia linia w pierwszym bloku kodu w tej odpowiedzi nie powinna wyglądać następująco subprocess.Popen([venv_python_file, script_file]):?
Nathan Basanese
//, Poza tym, czy istnieje sposób na uruchomienie programu script_filez dowolnej lokalizacji, czy też musi on znajdować się w virtualenvkatalogu?
Nathan Basanese
Naprawiono, dziękuję za zauważenie błędu. A jeśli chodzi o drugie pytanie, nie script_file, nie musi znajdować się w katalogu virtualenv, może być wszędzie.
Lie Ryan
Jak mogę dezaktywować wirtualne środowisko env, jeśli używam drugiej opcji?
falsePockets Kwietnia
@falsePockets: Problem XY , dlaczego kiedykolwiek chcesz to zrobić?
Lie Ryan
42

Najprostszym rozwiązaniem do uruchomienia skryptu z interpretera virtualenv jest zastąpienie domyślnej linii shebang ścieżką do interpretera virtualenv, tak jak na początku skryptu:

#!/path/to/project/venv/bin/python

Spraw, aby skrypt był wykonywalny:

chmod u+x script.py

Uruchom skrypt:

./script.py

Voila!

nafooesi
źródło
2
+1 za elegancję. Uwaga w systemie Windows wymaga to środowiska zgodnego z
POSIX,
1
Działa dla Pythona 3.6.3 i Windows 10!
toonarmycaptain
Myślę, że mogłem źle zrozumieć pierwotne pytanie. Chce aktywować środowisko wirtualne skryptem i wrócić do powłoki z aktywowanym środowiskiem. Moja odpowiedź uruchamia skrypt w środowisku wirtualnym, ale zwrócona powłoka nie zachowuje środowiska. Współczesnym rozwiązaniem jest virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Pozwala aktywować i przełączać się między różnymi virtualenvami.
nafooesi
20

Okazuje się, że tak, problem nie jest prosty, ale rozwiązanie jest.

Najpierw musiałem stworzyć skrypt powłoki, aby opakować polecenie „source”. To powiedziawszy, użyłem znaku „.” zamiast tego, ponieważ czytałem, że lepiej go używać niż źródła dla skryptów Bash.

#!/bin/bash
. /path/to/env/bin/activate

Następnie z mojego skryptu Python mogę po prostu zrobić to:

import os
os.system('/bin/bash --rcfile /path/to/myscript.sh')

Cała sztuczka tkwi w --rcfilesporze.

Kiedy interpreter Pythona kończy pracę, pozostawia bieżącą powłokę w aktywowanym środowisku.

Zdobyć!

h3.
źródło
3
Naprawdę tego nie rozumiem. Dlaczego po prostu tego nie zrobisz: os.system('/bin/bash --rcfile path/to/env/activate') wiesz, kiedy uruchamiane jest wystąpienie bash, pobiera on .bashrc jako argument dla --rcfile. Więc po prostu określ, że plik rc jest twoim plikiem aktywacyjnym ... Nie?
Depado
@Depado Właśnie wypróbowałem twoje rozwiązanie i to aktywuje powłokę w Pythonie. przynajmniej gdy spróbuję w muszli. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / Activ') (test) tcraig @ tallis-desktop: ~ $ (test) tcraig @ tallis-desktop: ~ $ ls -l łącznie 706288
Trenton
Może, ale to działa w skrypcie. Jedyną niedogodnością związaną z tą techniką jest to, że nie dostajesz wszystkich swoich aliasów i wszystkiego, co miałeś w swoim ~ / .bashrc. Ale nie przeszkadza mi to. Na przykład polecenie „ls” nie ma koloru. Ale dla mnie wszystko działa. Kiedy chcę wyjść, po prostu
naciskam
7
„Kiedy interpreter Pythona kończy pracę, pozostawia bieżącą powłokę w aktywowanym środowisku” Co? Tworzy zupełnie nową powłokę jako podproces i czeka, aż się zakończy.
Kos
Aby uniknąć tworzenia większej liczby nowych plików w moim repozytorium, a także replikacji bieżącej konfiguracji basha, zrobiłem to:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat
17

Aby uruchomić inne środowisko Pythona zgodnie z oficjalną dokumentacją Virtualenv , w wierszu poleceń możesz określić pełną ścieżkę do wykonywalnego pliku binarnego Pythona, po prostu (nie ma potrzeby wcześniejszego aktywowania virtualenv):

/path/to/virtualenv/bin/python

To samo dotyczy sytuacji, gdy chcesz wywołać skrypt z wiersza poleceń za pomocą virtualenv. Nie musisz go wcześniej aktywować:

me$ /path/to/virtualenv/bin/python myscript.py

To samo dla środowiska Windows (niezależnie od tego, czy pochodzi z wiersza poleceń, czy ze skryptu):

> \path\to\env\Scripts\python.exe myscript.py
Mariano Ruiz
źródło
2
Pytanie brzmi: Aktywuj virtualenv za pomocą skryptu Pythona (NIE z Shell)
Zaheer
3
Tak, chodzi mi o to, że możesz po prostu wywołać środowisko uruchomieniowe Pythona ze środowiska wirtualnego bez konieczności wcześniejszej aktywacji, z konsoli lub ze skryptu. Wyjaśnię odpowiedź, dzięki!
Mariano Ruiz
O mój Boże! Nie myślałem o tym. to jedyne rozwiązanie, które u mnie zadziałało :). Teraz, kiedy wykonuję skrypt Pythona z php, używam: "path / to / virtualenv / bin / python mypythonscript.py"
Zaheer
6

Po prostu proste rozwiązanie, które działa dla mnie. Nie wiem, dlaczego potrzebujesz skryptu Bash, który w zasadzie wykonuje bezużyteczny krok (czy się mylę?)

import os
os.system('/bin/bash  --rcfile flask/bin/activate')

Który w zasadzie robi to, czego potrzebujesz:

[hellsing@silence Foundation]$ python2.7 pythonvenv.py
(flask)[hellsing@silence Foundation]$

Następnie zamiast dezaktywować środowisko wirtualne, po prostu Ctrl+ Dlub zakończ. Czy to możliwe rozwiązanie, czy nie tego chciałeś?

Depado
źródło
2

Środowisko procesu dziecka jest tracone w momencie, gdy przestaje istnieć, a przeniesienie zawartości środowiska z tego środowiska do rodzica jest nieco trudne.

Prawdopodobnie musisz stworzyć skrypt powłoki (możesz wygenerować go dynamicznie do / tmp), który wyprowadzi zmienne środowiskowe virtualenv do pliku, który następnie odczytujesz w nadrzędnym procesie Pythona i umieszczasz w os.environ.

Lub po prostu analizujesz skrypt aktywacyjny, używając polecenia dla linii w open („bin / Activ”), ręcznie wyodrębniasz rzeczy i umieszczasz w os.environ. To trudne, ale nie niemożliwe.

Mikko Ohtamaa
źródło
2
Masz na myśli coś takiego? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1/ ...
h3.
2

Najlepsza odpowiedź działa tylko w Pythonie 2.x.

W przypadku Pythona 3.x użyj tego:

activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))

Odniesienie: Jaka jest alternatywa dla pliku execfile w Pythonie 3?

Asaad
źródło
1
co to jest
activ_this.py
1
@randyPen, plik activ_this.py jest dodawany automatycznie podczas budowania virtualenv w katalogu projektu. (tj. /project/directory/venv/bin/activate_this.py)
Teoretycznie
-2

Powinieneś utworzyć wszystkie swoje virtualenvpliki w jednym folderze, takim jak virt.

Zakładając, że nazwa twojego folderu virtualenv to virt, jeśli nie, zmień ją

cd
mkdir custom

Skopiuj poniższe wiersze ...

#!/usr/bin/env bash
ENV_PATH="$HOME/virt/$1/bin/activate"
bash --rcfile $ENV_PATH -i

Utwórz plik skryptu powłoki i wklej powyższe wiersze ...

touch custom/vhelper
nano custom/vhelper

Przyznaj uprawnienia wykonywalne do swojego pliku:

sudo chmod +x custom/vhelper

Teraz wyeksportuj tę niestandardową ścieżkę folderu, aby można ją było znaleźć w wierszu poleceń, klikając kartę ...

export PATH = $ PATH: "$ HOME / niestandardowe"

Teraz możesz go używać z dowolnego miejsca, po prostu wpisując poniższe polecenie ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Załóżmy, że to abc ...

vhelper abc
SR_Mehta
źródło