Автоматически загружать virtualenv при запуске script
У меня есть python script, который нуждается в зависимостях от virtualenv. Мне было интересно, если бы я мог добавить его на свой путь и автоматически запустить его virtualenv, запустить, а затем вернуться к системному python.
Я пытаюсь поиграть с autoenv и .env
, но это не похоже на то, что я ищу. Я также думал об изменении шабанга, чтобы указать на виртуальный путь, но это кажется хрупким.
Ответы
Ответ 1
Есть два способа сделать это:
-
Поместите имя виртуального env python в первую строку script. Как этот
#!/Ваш/виртуальный/окр/путь/bin/питон
-
Добавьте каталоги виртуальной среды в sys.path. Обратите внимание, что вам нужно импортировать библиотеку sys. Как этот
import sys
sys.path.append( '/путь/к/виртуальным/ENV/Библиотека')
Если вы перейдете ко второму варианту, вам может потребоваться добавить несколько путей на sys.path(сайт и т.д.). Лучший способ получить это - запустить ваш виртуальный интерпретатор python на env и выкинуть значение sys.path. Вот так:
/your/virtual/env/bin/python
Python blah blah blah
> import sys
> print sys.path
[ 'blah', 'blah' , 'blah' ]
Скопируйте значение sys.path в приведенный выше фрагмент.
Ответ 2
Я удивлен, что об этом никто еще не упомянул, но вот почему в каталоге virtualenv bin есть файл с именем activate_this.py
. Вы можете передать это execfile()
, чтобы изменить путь поиска модуля для текущего интерпретатора.
# 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))
Вы можете поместить этот файл в начало вашего script, чтобы заставить script всегда запускаться в этом виртуальном пространстве. В отличие от модификации hashbang, вы можете использовать относительный путь с помощью:
script_directory = os.path.dirname(os.path.abspath(__file__))
activate_this_file = os.path.join(script_directory, '../../relative/path/to/env/bin/activate_this.py')
Ответ 3
Из документа virtualenv :
Если вы непосредственно запускаете script или интерпретатор python из virtualenvs bin/directory (например, путь/в/env/bin/pip или /path/to/env/bin/python script.py) нет необходимости в активации.
Итак, если вы просто вызываете исполняемый файл python в свой virtualenv, ваш virtualenv будет "активным". Таким образом, вы можете создать script следующим образом:
#!/bin/bash
PATH_TO_MY_VENV=/opt/django/ev_scraper/venv/bin
$PATH_TO_MY_VENV/python -c 'import sys; print(sys.version_info)'
python -c 'import sys; print(sys.version_info)'
Когда я запускаю этот script в моей системе, два вызова python распечатывают то, что вы видите ниже. (Python 3.2.3 находится в моем virtualenv, а 2.7.3 - моя система Python.)
sys.version_info(major=3, minor=2, micro=3, releaselevel='final', serial=0)
sys.version_info(major=2, minor=7, micro=3, releaselevel='final', serial=0)
Таким образом, любые библиотеки, которые вы установили в своем виртуальном каталоге, будут доступны, когда вы вызываете $PATH_TO_MY_VENV/python
. Звонки в вашу обычную систему python
, конечно, не будут знать о том, что находится в виртуальном пространстве.
Ответ 4
Я думаю, лучший ответ здесь - создать простой script и установить его внутри вашего виртуального. Затем вы можете напрямую использовать script или создать символическую ссылку или что-то еще.
Вот пример:
$ mkdir my-tool
$ cd my-tool
$ mkdir scripts
$ touch setup.py
$ mkdir scripts
$ touch scripts/crunchy-frog
$ chmod +x scripts/crunchy-frog
хрустящие-лягушки
#!/usr/bin/env python
print("Constable Parrot ate one of those!")
setup.py
from setuptools import setup
setup(name="my-cool-tool",
scripts=['scripts/crunchy-frog'],
)
Сейчас:
$ source /path/to/my/env/bin/activate
(env) $ python setup.py develop
(env) $ deactivate
$ cd ~
$ ln -s /path/to/my/env/bin/crunchy-frog crunchy-frog
$ ./crunchy-frog
Constable Parrot ate one of those!
Когда вы устанавливаете script (через setup.py install
или setup.py develop
), он заменит первую строку scripts
строкой shebang для env python (которую вы можете проверить с помощью $ head /path/to/my/env/bin/crunchy-frog
), Поэтому всякий раз, когда вы запускаете этот конкретный script, он будет использовать этот определенный Python env.
Ответ 5
Помогает ли это?
import site
site.addsitedir('/path/to/virtualenv/lib/python2.7/site-packages/')
Ответ 6
У меня была эта проблема раньше, и я сделал простой script, чтобы искать виртуальную папку, рекурсивно просто импортируя и вызывая функцию:
script_autoenv.py
# -*- coding:utf-8 -*-
import os, site
def locate_env(path, env_name):
"""search for a env directory name in each directory in the path"""
if os.path.isdir(path + "/env"):
env_26_path = '%s/%s/lib/python2.6/site-packages/' % (path, env_name)
env_27_path = '%s/%s/lib/python2.7/site-packages/' % (path, env_name)
if os.path.isdir(env_26_path):
site.addsitedir(env_26_path)
print "Virtualenv 2.6 founding"
elif os.path.isdir(env_27_path):
site.addsitedir(env_27_path)
print "Virtualenv 2.7 founding"
else:
new_path, old_dir = os.path.split(path)
if old_dir:
locate_env(new_path, env_name)
else:
print "No envs found"
Вам просто нужно указать каталог script, а папку имени env и script сделать остальные:
test.py
# -*- coding:utf-8 -*-
import os
import script_autoenv
script_autoenv.locate_env(os.path.realpath(__file__), 'env')
import django
print django.VERSION
Я надеюсь, что это сработает для вас.