Onde em um virtualenv vai o código customizado?

107

Que tipo de estrutura de diretório deve-se seguir ao usar virtualenv? Por exemplo, se eu estivesse construindo um aplicativo WSGI e criasse um virtualenv chamado foobar, começaria com uma estrutura de diretório como:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}

Depois de criar esse ambiente, onde alguém colocaria o seu próprio:

  • arquivos python?
  • arquivos estáticos (imagens / etc)?
  • Pacotes "personalizados", como os disponíveis online mas não encontrados na loja de queijos?

em relação aos virtualenvdiretórios?

(Suponha que eu já saiba para onde os próprios diretórios virtualenv devem ir .)

Phillip B Oldham
fonte
8
@jkp: Eu discordo. O modo como você faz o layout de um aplicativo Python é diferente de como você localiza esse aplicativo em um virtualenv para fins de desenvolvimento. Está relacionado, mas não é o mesmo. Não feche como duplicado.
jcdyer

Respostas:

90

virtualenvfornece uma instância do interpretador Python, não uma instância do aplicativo. Normalmente, você não criaria seus arquivos de aplicativo nos diretórios que contêm o Python padrão de um sistema, da mesma forma, não há necessidade de localizar seu aplicativo em um diretório virtualenv.

Por exemplo, você pode ter um projeto em que vários aplicativos usam o mesmo virtualenv. Ou você pode estar testando um aplicativo com um virtualenv que mais tarde será implantado com um sistema Python. Ou você pode estar empacotando um aplicativo autônomo em que faça sentido ter o diretório virtualenv localizado em algum lugar dentro do próprio diretório do aplicativo.

Portanto, em geral, não acho que haja uma resposta certa para a pergunta. E, uma coisa boa virtualenvé que ele oferece suporte a muitos casos de uso diferentes: não precisa haver um caminho certo.

Ned Deily
fonte
8
Acordado. Eu uso o virtualenv para tudo que faço e nunca coloco arquivos dentro do diretório virtualenv. O Virtualenv não precisa ter nenhum impacto na estrutura do projeto; apenas ative o virtualenv (ou use seu bin / python) e trabalhe em seus arquivos onde quer que você os tenha.
Carl Meyer
Eu também concordo de todo o coração. A única vez que eu nunca tocar todos os arquivos dentro da minha virtualenv (uso I virtualenvwrapper) é quando eu quero editar o postactivatee postdeactivateganchos.
Thane Brimhall
A questão seria mais bem respondida com exemplos práticos e concretos de diferentes opções, incluindo compensações, conforme visto em outras respostas nesta questão.
andyfeller
2
É mais limpo manter seu projeto separado do virtualenvdiretório, mas comparar virtualenvcom o sistema python é inútil, porque o objetivo virtualenvé consertar dependências quebradas e isolar projetos para que eles possam usar diferentes versões de pacote e até mesmo versões de python (eu percebo que isso foi escrito antes -python3). Permitir que os aplicativos compartilhem um virtualenvé usar virtualenvcomo se fosse python do sistema, deixando os aplicativos vulneráveis ​​aos mesmos problemas que o virtualenv foi projetado para resolver. There should be one obvious way to do it; logicamente, deve ser 1: 1
Davos
@Ned: Tentando adquirir algumas das melhores práticas, mas ainda não está claro: se você tem dezenas de projetos, cada um com seu próprio virtualenv, como você mantém o controle de qual projeto é usado com qual virtualenv? Adicionar pequenos scripts de shell na raiz de cada pasta com o nome do virtualenv com o qual você os usa?
ccpizza
57

Se você tem apenas alguns projetos de vez em quando, nada o impede de criar um novo virtualenv para cada um e colocar seus pacotes dentro:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}
  /mypackage1
    __init__.py
  /mypackage2
    __init__.py

A vantagem dessa abordagem é que você sempre pode ter certeza de encontrar o script de ativação que pertence ao projeto.

$ cd /foobar
$ source bin/activate
$ python 
>>> import mypackage1
>>>

Se você decidir ser um pouco mais organizado, deve considerar colocar todos os seus virtuaisenvs em uma pasta e nomear cada um deles com o nome do projeto em que está trabalhando.

  /virtualenvs
    /foobar
      /bin
        {activate, activate.py, easy_install, python}
      /include
        {python2.6/...}
      /lib
        {python2.6/...}
  /foobar
    /mypackage1
      __init__.py
    /mypackage2
      __init__.py

Dessa forma, você sempre pode recomeçar com um novo virtualenv quando algo der errado e seus arquivos de projeto permanecerem seguros.

Outra vantagem é que vários de seus projetos podem usar o mesmo virtualenv, portanto, você não precisa fazer a mesma instalação repetidamente se tiver muitas dependências.

$ cd /foobar
$ source ../virtualenvs/foobar/bin/activate
$ python 
>>> import mypackage2
>>>

Para usuários que regularmente precisam configurar e desmontar o virtualenvs, faria sentido examinar o virtualenvwrapper.

http://pypi.python.org/pypi/virtualenvwrapper

Com o virtualenvwrapper você pode

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Você não precisa mais se preocupar com a localização do seu virtualenvs ao trabalhar nos projetos "foo" e "bar":

  /foo
    /mypackage1
      __init__.py
  /bar
    /mypackage2
      __init__.py

É assim que você começa a trabalhar no projeto "foo":

$ cd foo
$ workon
bar
foo
$ workon foo
(foo)$ python
>>> import mypackage1
>>>

Então, mudar para o projeto "bar" é tão simples quanto isto:

$ cd ../bar
$ workon bar
(bar)$ python
>>> import mypackage2
>>>

Muito legal, não é?

Maik Röder
fonte
Eu concordo totalmente com esta resposta sobre o uso virtualenvwrapper. Ele abstrai perfeitamente o virtualenv, ao mesmo tempo que oferece todos os benefícios.
Thane Brimhall
5
Mas discordo fortemente sobre SEMPRE colocar seu código dentro do ambiente virtual. Se você quiser "perto" do projeto no sistema de arquivos, coloque um venv/diretório no mesmo nível do projeto BASE_DIR.
Rob Grant de
30

Como os virtuaisenvs não são realocáveis, na minha opinião é uma prática ruim colocar os arquivos do projeto dentro de um diretório virtualenv. O virtualenv em si é um artefato de desenvolvimento / implantação gerado (como um arquivo .pyc), não faz parte do projeto; deve ser fácil explodi-lo e recriá-lo a qualquer momento ou criar um novo em um novo host de implantação, etc.

Na verdade, muitas pessoas usam o virtualenvwrapper , que remove o virtualenvs real de sua consciência quase completamente, colocando-os lado a lado em $ HOME / .virtualenvs por padrão.

Carl Meyer
fonte
Concordo totalmente que é uma prática ruim, ótimo salientar que deve ser fácil explodir e recriar, especialmente para testar implantações e reduzir pacotes de requisitos desnecessários. Só quero acrescentar que virtualenv é possível realocar usando, por exemplo, virtualenv --relocatable myvenvconsulte stackoverflow.com/a/6628642/1335793 só porque você pode, não significa que deveria.
Davos
2

Se você der ao seu projeto um setup.py, pip pode importá-lo diretamente do controle de versão.

Faça algo assim:

$ virtualenv --no-site-packages myproject
$ . myproject/bin/activate
$ easy_install pip
$ pip install -e hg+http://bitbucket.org/owner/myproject#egg=proj

O -eirá colocar o projeto myproject/src, mas vinculá-lo a myproject/lib/pythonX.X/site-packages/, portanto, quaisquer alterações feitas serão coletadas imediatamente nos módulos que o importam de seu local site-packages. O #eggbit diz a pip qual nome você deseja dar ao pacote de ovos que ele cria para você.

Se você não usar --no-site-packages, tenha o cuidado de especificar que deseja que o pip seja instalado no virtualenv com a -Eopção

Jcdyer
fonte