Attiva un virtualenv con uno script Python


91

Voglio attivare un'istanza virtualenv da uno script Python.

So che è abbastanza facile da fare, ma tutti gli esempi che ho visto lo usano per eseguire comandi all'interno di env e quindi chiudere il sottoprocesso.

Voglio semplicemente attivare virtualenv e tornare alla shell, nello stesso modo in cui bin / attivare fa.

Qualcosa come questo:

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

È possibile?

Pertinente:

virtualenv ›Invocare un env da uno script

Risposte:


88

Se vuoi eseguire un sottoprocesso Python sotto virtualenv, puoi farlo eseguendo lo script usando l'interprete Python che risiede nella directory / bin / di 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])

Tuttavia, se vuoi attivare il virtualenv sotto l'attuale interprete Python invece di un sottoprocesso, puoi usare lo activate_this.pyscript:

# 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
//, L'ultima riga nel primo blocco di codice di questa risposta non dovrebbe essere la seguente subprocess.Popen([venv_python_file, script_file]):?
Nathan Basanese

//, Inoltre, c'è un modo per eseguire il script_fileda una posizione arbitraria, o deve essere nella virtualenvdirectory?
Nathan Basanese

Risolto, grazie per aver notato l'errore. Per quanto riguarda la tua seconda domanda, no script_filenon deve essere nella directory virtualenv, può essere ovunque.
Lie Ryan

Come posso disattivare l'ambiente virtuale, se utilizzo la seconda opzione?
false Tasche

@falsePockets: XY Problem , perché mai vuoi farlo?
Lie Ryan

42

La soluzione più semplice per eseguire lo script con l'interprete di virtualenv è sostituire la riga shebang predefinita con il percorso dell'interprete di virtualenv in questo modo all'inizio dello script:

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

Rendi eseguibile lo script:

chmod u+x script.py

Esegui lo script:

./script.py

Ecco!


2
+1 per l'eleganza. Nota su Windows questo richiede un ambiente conforme a posix che capisca le linee shebang come cygwin o msys
qneill

1
Funziona per Python 3.6.3 e Windows 10!
toonarmycaptain

Penso di aver frainteso la domanda originale. Vuole attivare l'ambiente virtuale con uno script e tornare alla shell con l'ambiente attivato. La mia risposta esegue lo script nell'ambiente virtuale ma la shell restituita non mantiene l'ambiente. La soluzione moderna è virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Permette di attivare e passare tra diversi virtualenv.
nafooesi

20

Si scopre che, sì, il problema non è semplice, ma la soluzione lo è.

Per prima cosa ho dovuto creare uno script di shell per racchiudere il comando "source". Detto questo ho usato il "." invece, perché ho letto che è meglio usarlo rispetto ai sorgenti per gli script Bash.

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

Quindi dal mio script Python posso semplicemente fare questo:

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

L'intero trucco sta --rcfilenell'argomento.

Quando l'interprete Python esce lascia la shell corrente nell'ambiente attivato.

Vincere!


3
Non lo capisco davvero. Perché non lo fai: os.system('/bin/bash --rcfile path/to/env/activate') sai, quando viene avviata un'istanza di bash, prende .bashrc come argomento per il --rcfile. Quindi specifica che rcfile è il tuo file di attivazione ... No?
Depado

@ Depado ho appena provato la tua soluzione e questo attiverà la shell all'interno di python. almeno quando lo provo nella shell. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / activation') (test) tcraig @ tallis-desktop: ~ $ (test) tcraig @ tallis-desktop: ~ $ ls -l totale 706288
Trenton

Forse, ma questo funziona in uno script. L'unico inconveniente con questa tecnica è che non ottieni tutti i tuoi alias e tutto ciò che avevi nel tuo ~ / .bashrc. Ma ci sto bene. Ad esempio, il comando "ls" non ha colore. Ma tutto funziona per me. Quando voglio andarmene, basta Ctrl + D
Depado

7
"Quando l'interprete Python esce lascia la shell corrente nell'ambiente attivato" Cosa? Genera una shell completamente nuova come sottoprocesso e attende fino al termine.
Kos

Per evitare di creare più nuovi file sul mio repository e per replicare anche l'attuale configurazione bash, ho fatto questo:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat

17

Per eseguire un altro ambiente Python secondo la documentazione ufficiale di Virtualenv , nella riga di comando è possibile specificare il percorso completo del binario eseguibile Python, solo quello (non è necessario attivare il virtualenv prima):

/path/to/virtualenv/bin/python

Lo stesso vale se vuoi invocare uno script dalla riga di comando con il tuo virtualenv. Non è necessario attivarlo prima:

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

Lo stesso per un ambiente Windows (sia dalla riga di comando che da uno script):

> \path\to\env\Scripts\python.exe myscript.py

2
La domanda è: attiva un virtualenv con uno script python (NON da Shell)
Zaheer

3
Sì, il punto è che puoi semplicemente chiamare il runtime python da un ambiente virtuale senza la necessità di attivarlo prima, dalla console o da uno script. Chiarirò la risposta, grazie!
Mariano Ruiz

Oh mio Dio! Non ci ho pensato. questa è l'unica soluzione che ha funzionato per me :). Ora, quando eseguo lo script Python da php, sto usando: "path / to / virtualenv / bin / python mypythonscript.py"
Zaheer

6

Solo una semplice soluzione che funziona per me. Non so perché hai bisogno dello script Bash che fondamentalmente fa un passaggio inutile (mi sbaglio?)

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

Che fondamentalmente fa quello che ti serve:

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

Quindi invece di disattivare l'ambiente virtuale, basta Ctrl+ Do uscire. È una possibile soluzione o non è quello che volevi?


2

L'ambiente del processo figlio si perde nel momento in cui cessa di esistere e spostare il contenuto dell'ambiente da lì al genitore è alquanto complicato.

Probabilmente è necessario generare uno script di shell (è possibile generarne uno dinamicamente in / tmp) che genererà le variabili di ambiente virtualenv in un file, che verrà quindi letto nel processo Python genitore e inserito in os.environ.

Oppure puoi semplicemente analizzare lo script di attivazione in uso per la riga in open ("bin / activation"), estrarre manualmente le cose e mettere os.environ. È complicato, ma non impossibile.


2
h3.

2

La risposta migliore funziona solo per Python 2.x

Per Python 3.x, usa questo:

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

Riferimento: qual è un'alternativa a execfile in Python 3?


1
cos'è
activ_this.py

1
@randyPen, il file activation_this.py viene aggiunto automaticamente quando crei virtualenv nella directory del tuo progetto. (ovvero /project/directory/venv/bin/activate_this.py)
Teoricamente

-2

Dovresti creare tutti i tuoi messaggi di posta virtualenvelettronica in una cartella, ad esempio virt.

Supponendo che il nome della tua cartella virtualenv sia virt, se non cambiarlo

cd
mkdir custom

Copia le righe seguenti ...

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

Crea un file script di shell e incolla le righe sopra ...

touch custom/vhelper
nano custom/vhelper

Concedi l'autorizzazione eseguibile al tuo file:

sudo chmod +x custom/vhelper

Ora esporta il percorso della cartella personalizzato in modo da poterlo trovare sulla riga di comando facendo clic sulla scheda ...

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

Ora puoi usarlo da qualsiasi luogo semplicemente digitando il comando seguente ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Supponiamo che sia abc allora ...

vhelper abc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.