Активируйте virtualenv с помощью скрипта Python

91

Я хочу активировать экземпляр virtualenv из скрипта Python.

Я знаю, что это довольно просто сделать, но во всех примерах, которые я видел, он используется для запуска команд в env и последующего закрытия подпроцесса.

Я просто хочу активировать virtualenv и вернуться в оболочку, так же, как это делает bin / activate.

Что-то вроде этого:

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

Это возможно?

Соответствующие:

virtualenv ›Вызов env из скрипта

h3.
источник

Ответы:

88

Если вы хотите запустить подпроцесс Python под virtualenv, вы можете сделать это, запустив скрипт с помощью интерпретатора Python, который находится внутри каталога virtualenv / bin /:

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])

Однако, если вы хотите активировать virtualenv в текущем интерпретаторе Python вместо подпроцесса, вы можете использовать activate_this.pyсценарий:

# 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))
Ли Райан
источник
1
//, Разве последняя строка в первом блоке кода этого ответа не должна читаться следующим образом subprocess.Popen([venv_python_file, script_file]):?
Натан Басанезе,
// Кроме того, есть ли способ запустить script_fileиз произвольного места или он должен находиться в virtualenvкаталоге?
Натан Басанезе,
Исправлено, спасибо, что заметили ошибку. Что касается вашего второго вопроса, нет script_fileнеобходимости находиться в каталоге virtualenv, он может быть где угодно.
Ли Райан,
Как я могу деактивировать виртуальную среду, если я использую второй вариант?
falsePockets
@falsePockets: Проблема XY , зачем тебе вообще это нужно?
Ли Райан
42

Самым простым решением для запуска вашего скрипта под интерпретатором virtualenv является замена строки shebang по умолчанию на путь к вашему интерпретатору virtualenv, как в начале скрипта:

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

Сделайте скрипт исполняемым:

chmod u+x script.py

Запускаем скрипт:

./script.py

Вуаля!

нафуэси
источник
2
+1 за элегантность. Обратите внимание на Windows, для этого требуется среда, совместимая с posix, которая понимает строки shebang, такие как cygwin или msys
qneill 01
1
Работает для python 3.6.3 и windows 10!
toonarmycaptain
Думаю, я неправильно понял исходный вопрос. Он хочет активировать виртуальную среду с помощью сценария и вернуться в оболочку с активированной средой. В моем ответе сценарий запускается в виртуальной среде, но возвращенная оболочка не сохраняет среду. Современное решение - virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Это позволяет активировать и переключаться между различными виртуальными машинами.
nafooesi
20

Оказывается, да, проблема не из простых, но решение есть.

Сначала мне пришлось создать сценарий оболочки, чтобы обернуть команду «source». Тем не менее, я использовал "." вместо этого, потому что я читал, что лучше использовать его, чем исходный код для сценариев Bash.

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

Затем из моего скрипта Python я могу просто сделать это:

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

Вся уловка заключается в --rcfileаргументе.

Когда интерпретатор Python завершает свою работу, он оставляет текущую оболочку в активированной среде.

Выиграть!

h3.
источник
3
Я действительно не понимаю. Почему бы вам просто не сделать это: os.system('/bin/bash --rcfile path/to/env/activate') вы знаете, когда экземпляр bash запускается, он принимает .bashrc в качестве аргумента для --rcfile. Так что просто укажите, что rcfile - ваш файл активации ... Нет?
Depado
@Depado Я только что попробовал ваше решение, и это активирует оболочку в python. по крайней мере, когда попробую в оболочке. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / activate') (test) tcraig @ tallis-desktop: ~ $ (test) tcraig @ tallis-desktop: ~ $ ls -l всего 706288
Трентон
Возможно, но это работает в сценарии. Единственное неудобство этой техники заключается в том, что вы не получаете все свои псевдонимы и все, что было в вашем ~ / .bashrc. Но меня это устраивает. Например, команда "ls" не имеет цвета. Но у меня все работает. Когда я хочу уйти, я просто Ctrl + D
Депадо
7
«Когда интерпретатор python завершает свою работу, он оставляет текущую оболочку в активированной среде» Что? Он порождает совершенно новую оболочку как подпроцесс и ожидает его завершения.
Кос,
Чтобы избежать создания новых файлов в моем репозитории, а также для репликации текущей конфигурации bash, я сделал следующее:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat
17

Чтобы запустить другую среду Python в соответствии с официальной документацией Virtualenv , в командной строке вы можете указать полный путь к исполняемому двоичному файлу Python, просто (нет необходимости активировать virtualenv раньше):

/path/to/virtualenv/bin/python

То же самое применимо, если вы хотите вызвать сценарий из командной строки с помощью вашего virtualenv. Вам не нужно активировать его раньше:

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

То же самое для среды Windows (будь то из командной строки или из скрипта):

> \path\to\env\Scripts\python.exe myscript.py
Мариано Руис
источник
2
Вопрос: Активировать virtualenv со скриптом питона (НЕ от Shell)
Захир
3
Да, я хочу сказать, что вы можете просто вызвать среду выполнения python из виртуальной среды без необходимости активировать ее раньше, с консоли или из сценария. Уточню ответ, спасибо!
Мариано Руис,
О боже! Я не думал об этом. это единственное решение, которое сработало для меня :). Теперь, когда я выполняю скрипт python из php, я использую: «путь / к / virtualenv / bin / python mypythonscript.py»
Захир
6

Просто простое решение, которое мне подходит. Я не знаю, зачем вам нужен сценарий Bash, который в основном делает бесполезный шаг (я ошибаюсь?)

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

Что в основном делает то, что вам нужно:

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

Затем вместо деактивации виртуальной среды просто Ctrl+ Dили выйдите. Это возможное решение или не то, что вы хотели?

Депадо
источник
2

Среда дочернего процесса теряется в тот момент, когда она перестает существовать, и перемещение содержимого среды оттуда к родительскому довольно сложно.

Вероятно, вам нужно создать сценарий оболочки (вы можете создать его динамически в / tmp), который будет выводить переменные среды virtualenv в файл, который вы затем читаете в родительском процессе Python и помещаете в os.environ.

Или вы просто анализируете скрипт активации, используя его для строки в open («bin / activate»), извлекаете данные вручную и помещаете в os.environ. Это сложно, но возможно.

Микко Охтамаа
источник
2
Вы имеете в виду что-то вроде этого ? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1/…
h3.
2

Верхний ответ работает только для Python 2.x

Для Python 3.x используйте это:

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))

Ссылка: Какая альтернатива execfile в Python 3?

Асаад
источник
1
что такое activate_this.py
Рэнди Пен
1
@randyPen, файл activate_this.py автоматически добавляется при создании virtualenv в каталоге проекта. (т.е. /project/directory/venv/bin/activate_this.py)
Теоретически
-2

Вы должны создать все свои virtualenvфайлы в одной папке, например virt.

Предполагая, что ваше имя папки virtualenv - virt, если не изменить его

cd
mkdir custom

Скопируйте следующие строки ...

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

Создайте файл сценария оболочки и вставьте приведенные выше строки ...

touch custom/vhelper
nano custom/vhelper

Предоставьте исполняемое разрешение вашему файлу:

sudo chmod +x custom/vhelper

Теперь экспортируйте этот настраиваемый путь к папке, чтобы вы могли найти его в командной строке, щелкнув вкладку ...

экспорт PATH = $ PATH: "$ HOME / custom"

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

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Предположим, это abc, тогда ...

vhelper abc
SR_Mehta
источник