Aktivieren Sie eine virtuelle Umgebung mit einem Python-Skript

87

Ich möchte eine virtualenv-Instanz über ein Python-Skript aktivieren.

Ich weiß, dass dies recht einfach ist, aber alle Beispiele, die ich gesehen habe, verwenden es, um Befehle in der Umgebung auszuführen und dann den Unterprozess zu schließen.

Ich möchte einfach die virtuelle Umgebung aktivieren und zur Shell zurückkehren, genau wie bin / enable.

Etwas wie das:

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

Ist das möglich?

Relevant:

virtualenv ›Aufrufen einer Umgebung aus einem Skript

h3.
quelle

Antworten:

85

Wenn Sie einen Python-Unterprozess unter virtualenv ausführen möchten, können Sie dies tun, indem Sie das Skript mit dem Python-Interpreter ausführen, der sich im Verzeichnis / bin / von virtualenv befindet:

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

Wenn Sie jedoch die virtuelle Umgebung unter dem aktuellen Python-Interpreter anstelle eines Unterprozesses aktivieren möchten, können Sie das folgende activate_this.pySkript verwenden:

# 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
quelle
1
//, Sollte diese letzte Zeile im ersten Codeblock dieser Antwort nicht wie folgt lauten : subprocess.Popen([venv_python_file, script_file])?
Nathan Basanese
// Gibt es auch eine Möglichkeit, das script_filevon einem beliebigen Ort aus auszuführen , oder muss es sich im virtualenvVerzeichnis befinden?
Nathan Basanese
Behoben, danke, dass du den Fehler bemerkt hast. Was Ihre zweite Frage script_filebetrifft , muss sich no nicht im Verzeichnis virtualenv befinden, sondern kann sich überall befinden.
Lie Ryan
Wie kann ich die virtuelle Umgebung deaktivieren, wenn ich die zweite Option verwende?
falsePockets
@falsePockets: XY Problem , warum willst du das jemals tun?
Lie Ryan
39

Die einfachste Lösung, um Ihr Skript unter dem Interpreter von virtualenv auszuführen, besteht darin, die Standard-Shebang-Zeile wie am Anfang des Skripts durch den Pfad zum Interpreter Ihres virtualenv zu ersetzen:

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

Machen Sie das Skript ausführbar:

chmod u+x script.py

Führen Sie das Skript aus:

./script.py

Voila!

nafooesi
quelle
1
+1 für Eleganz. Hinweis unter Windows erfordert dies eine Posix-kompatible Umgebung, die Shebang-Linien wie Cygwin oder MSys versteht
Qneill
1
Funktioniert für Python 3.6.3 und Windows 10!
ToonarmyCaptain
Ich glaube, ich hätte die ursprüngliche Frage falsch verstanden. Er möchte die virtuelle Umgebung mit einem Skript aktivieren und mit der aktivierten Umgebung zur Shell zurückkehren. Meine Antwort führt ein Skript in der virtuellen Umgebung aus, aber die zurückgegebene Shell behält die Umgebung nicht bei. Die moderne Lösung ist virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Es ermöglicht das Aktivieren und Umschalten zwischen verschiedenen virtuellen Umgebungen.
Nafooesi
20

Es stellt sich heraus, dass das Problem nicht einfach ist, aber die Lösung.

Zuerst musste ich ein Shell-Skript erstellen, um den Befehl "source" zu verpacken. Das heißt, ich habe das "." stattdessen, weil ich gelesen habe, dass es besser ist, es als Quelle für Bash-Skripte zu verwenden.

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

Dann kann ich mit meinem Python-Skript einfach Folgendes tun:

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

Der ganze Trick liegt im --rcfileArgument.

Wenn der Python-Interpreter beendet wird, bleibt die aktuelle Shell in der aktivierten Umgebung.

Sieg!

h3.
quelle
3
Ich verstehe es wirklich nicht. Warum machst du das nicht einfach so os.system('/bin/bash --rcfile path/to/env/activate') ? Wenn eine Instanz von bash gestartet wird, wird .bashrc als Argument für die Datei --rcfile verwendet. Geben Sie einfach an, dass die RC-Datei Ihre Aktivierungsdatei ist ... Nein?
Depado
@Depado Ich habe gerade Ihre Lösung ausprobiert und dies wird die Shell in Python aktivieren. Zumindest wenn ich es in der Shell versuche. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / enabled') (test) tcraig @ tallis-desktop: ~ $ (test) tcraig @ tallis-desktop: ~ $ ls -l insgesamt 706288
Trenton
Vielleicht funktioniert das aber in einem Skript. Der einzige Nachteil bei dieser Technik ist, dass Sie nicht alle Ihre Aliase und alles, was Sie in Ihrem ~ / .bashrc hatten, erhalten. Aber ich bin damit einverstanden. Zum Beispiel hat der Befehl "ls" keine Farbe. Aber bei mir funktioniert alles. Wenn ich gehen will,
drücke
7
"Wenn der Python-Interpreter beendet wird, bleibt die aktuelle Shell in der aktivierten Umgebung." Was? Es erzeugt eine völlig neue Shell als Unterprozess und wartet, bis es fertig ist.
Kos
Um zu vermeiden, dass mehr neue Dateien in meinem Repository erstellt werden, und um auch die aktuelle Bash-Konfiguration zu replizieren, habe ich cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
Folgendes
14

Um eine andere Python-Umgebung gemäß der offiziellen Virtualenv-Dokumentation auszuführen , können Sie in der Befehlszeile den vollständigen Pfad zur ausführbaren Python-Binärdatei angeben.

/path/to/virtualenv/bin/python

Gleiches gilt, wenn Sie mit Ihrer virtuellen Umgebung ein Skript über die Befehlszeile aufrufen möchten. Sie müssen es vorher nicht aktivieren:

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

Das Gleiche gilt für eine Windows-Umgebung (ob über die Befehlszeile oder über ein Skript):

> \path\to\env\Scripts\python.exe myscript.py
Mariano Ruiz
quelle
2
Die Frage ist: Aktivieren Sie eine virtuelle Umgebung mit einem Python-Skript (NICHT von Shell)
Zaheer
3
Ja, mein Punkt ist, dass Sie die Python-Laufzeit einfach aus einer virtuellen Umgebung aufrufen können, ohne sie vorher aktivieren zu müssen, über die Konsole oder über ein Skript. Ich werde die Antwort klarstellen, danke!
Mariano Ruiz
Oh meine Güte! Ich habe nicht darüber nachgedacht. Dies ist die einzige Lösung, die für mich funktioniert hat :). Wenn ich jetzt Python-Skript von PHP ausführe, verwende ich: "Pfad / zu / virtualenv / bin / Python mypythonscript.py"
Zaheer
6

Nur eine einfache Lösung, die für mich funktioniert. Ich weiß nicht, warum Sie das Bash-Skript benötigen, das im Grunde genommen einen nutzlosen Schritt macht (irre ich mich?)

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

Welches macht im Grunde das, was Sie brauchen:

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

Anstatt die virtuelle Umgebung zu deaktivieren, drücken Sie einfach Ctrl+ Doder beenden Sie das Programm . Ist das eine mögliche Lösung oder wollten Sie das nicht?

Depado
quelle
2

Die untergeordnete Prozessumgebung geht in dem Moment verloren, in dem sie nicht mehr existiert, und das Verschieben des Umgebungsinhalts von dort auf das übergeordnete Element ist etwas schwierig.

Sie müssen wahrscheinlich ein Shell-Skript erzeugen (Sie können eines dynamisch in / tmp generieren), das die Umgebungsvariablen virtualenv in eine Datei ausgibt, die Sie dann im übergeordneten Python-Prozess lesen und in os.environ einfügen.

Oder Sie analysieren einfach das Aktivierungsskript, indem Sie es für die geöffnete Zeile ("bin / enable") verwenden, extrahieren manuell Inhalte und fügen sie in os.environ ein. Es ist schwierig, aber nicht unmöglich.

Mikko Ohtamaa
quelle
2

Die Top-Antwort funktioniert nur für Python 2.x.

Verwenden Sie für Python 3.x Folgendes:

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

Referenz: Was ist eine Alternative zu execfile in Python 3?

Asaad
quelle
1
Was ist activate_this.py
Randy Pen
1
@randyPen, die Datei activate_this.py wird automatisch hinzugefügt, wenn Sie die virtuelle Umgebung in Ihrem Projektverzeichnis erstellen. (dh /project/directory/venv/bin/activate_this.py)
Theoretisch
-2

Sie sollten alle Ihre virtualenvs in einem Ordner erstellen , zvirt .

Angenommen, der Name Ihres virtualenv-Ordners ist virt, wenn Sie ihn nicht ändern

cd
mkdir custom

Kopieren Sie die folgenden Zeilen ...

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

Erstellen Sie eine Shell-Skriptdatei und fügen Sie die obigen Zeilen ein ...

touch custom/vhelper
nano custom/vhelper

Gewähren Sie Ihrer Datei ausführbare Berechtigungen:

sudo chmod +x custom/vhelper

Exportieren Sie nun diesen benutzerdefinierten Ordnerpfad, damit Sie ihn in der Befehlszeile finden können, indem Sie auf die Registerkarte klicken ...

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

Jetzt können Sie es von überall aus verwenden, indem Sie einfach den folgenden Befehl eingeben ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Angenommen, es ist abc dann ...

vhelper abc
SR_Mehta
quelle