Où va le code personnalisé dans une virtualenv?

107

Quelle sorte de structure de répertoire doit-on suivre lors de l'utilisation virtualenv? Par exemple, si je construisais une application WSGI et créais un virtualenv appelé, foobarje commencerais par une structure de répertoires comme:

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

Une fois cet environnement créé, où placerait-on le leur:

  • fichiers python?
  • fichiers statiques (images / etc)?
  • des forfaits "personnalisés", comme ceux disponibles en ligne mais introuvables dans la fromagerie?

par rapport aux virtualenvrépertoires?

(Supposons que je sache déjà où les répertoires virtualenv eux-mêmes devraient aller .)

Phillip B Oldham
la source
8
@jkp: Je ne suis pas d'accord. La façon dont vous mettez en page une application Python est différente de la façon dont vous localisez cette application dans un virtualenv à des fins de développement. C'est lié, mais pas le même. Veuillez ne pas fermer en double.
jcdyer

Réponses:

90

virtualenvfournit une instance d'interpréteur python, pas une instance d'application. Vous ne créeriez normalement pas vos fichiers d'application dans les répertoires contenant le Python par défaut d'un système, de même qu'il n'est pas nécessaire de localiser votre application dans un répertoire virtualenv.

Par exemple, vous pouvez avoir un projet dans lequel vous avez plusieurs applications utilisant le même virtualenv. Ou, vous testez peut-être une application avec un virtualenv qui sera ensuite déployé avec un système Python. Ou, vous pouvez créer une application autonome dans laquelle il peut être judicieux de placer le répertoire virtualenv quelque part dans le répertoire de l'application lui-même.

Donc, en général, je ne pense pas qu'il y ait une seule bonne réponse à la question. Et, une bonne chose à ce sujet virtualenvest qu'il prend en charge de nombreux cas d'utilisation différents: il n'est pas nécessaire qu'il y ait un seul bon moyen.

Ned Deily
la source
8
D'accord. J'utilise virtualenv pour tout ce que je fais et je ne place jamais de fichiers dans le répertoire virtualenv. Virtualenv n'a aucun impact sur la structure de votre projet; activez simplement le virtualenv (ou utilisez son bin / python), et travaillez sur vos fichiers où que vous les ayez de toute façon.
Carl Meyer
Je suis également tout à fait d’accord. La seule fois où je jamais toucher tous les fichiers dans mon virtualenv (je utiliser virtualenvwrapper) est quand je veux modifier les postactivateet postdeactivatecrochets.
Thane Brimhall
La question serait mieux servie avec des exemples concrets et pratiques de différentes options, y compris des compromis comme on le voit dans d'autres réponses à cette question.
andyfeller
2
Il est plus propre de garder votre projet séparé du virtualenvrépertoire, mais la comparaison virtualenvavec le système python n'est pas utile, car le but de virtualenvest de corriger les dépendances brisées et d'isoler les projets afin qu'ils puissent utiliser différentes versions de package et même des versions python (je me rends compte que cela a été écrit avant -python3). Permettre aux applications de partager un virtualenvutilise virtualenvcomme s'il s'agissait de python système, laissant les applications vulnérables aux mêmes problèmes que virtualenv est conçu pour résoudre. There should be one obvious way to do it; logiquement, cela devrait être 1: 1
Davos
@Ned: Vous essayez d'acquérir des bonnes pratiques, mais cela reste incertain: si vous avez des dizaines de projets, chacun avec sa propre virtualenv, comment savoir quel projet est utilisé avec quel virtualenv? Ajouter de minuscules scripts shell à la racine de chaque dossier avec le nom du virtualenv avec lequel vous l'utilisez?
ccpizza
57

Si vous n'avez que quelques projets de temps en temps, rien ne vous empêche de créer une nouvelle virtualenv pour chacun et de placer vos packages directement à l'intérieur:

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

L'avantage de cette approche est que vous pouvez toujours être sûr de trouver le script d'activation qui appartient au projet à l'intérieur.

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

Si vous décidez d'être un peu plus organisé, vous devriez envisager de mettre tous vos virtualenv dans un seul dossier et de nommer chacun d'eux d'après le projet sur lequel vous travaillez.

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

De cette façon, vous pouvez toujours recommencer avec une nouvelle virtualenv lorsque les choses tournent mal, et vos fichiers de projet restent en sécurité.

Un autre avantage est que plusieurs de vos projets peuvent utiliser le même virtualenv, vous n'avez donc pas à refaire la même installation encore et encore si vous avez beaucoup de dépendances.

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

Pour les utilisateurs qui doivent régulièrement configurer et supprimer des virtualenvs, il serait logique de regarder virtualenvwrapper.

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

Avec virtualenvwrapper, vous pouvez

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Vous n'avez plus à vous soucier de la localisation de vos virtualenvs lorsque vous travaillez sur les projets "foo" et "bar":

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

Voici comment vous commencez à travailler sur le projet "foo":

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

Ensuite, passer au projet "bar" est aussi simple que ceci:

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

Assez bien, n'est-ce pas?

Maik Röder
la source
Je suis tout à fait d' accord avec cette réponse sur l'utilisation virtualenvwrapper. Il fait abstraction du virtualenv tout en vous offrant tous les avantages.
Thane Brimhall
5
Mais pas du tout d' accord sur le fait de JAMAIS mettre votre code dans l'environnement virtuel. Si vous le voulez "près" du projet sur le système de fichiers, placez un venv/répertoire au même niveau que celui du projet BASE_DIR.
Rob Grant
30

Étant donné que les virtualenv ne sont pas déplaçables, à mon avis, il est déconseillé de placer vos fichiers de projet dans un répertoire virtualenv. Le virtualenv lui-même est un artefact de développement / déploiement généré (un peu comme un fichier .pyc), qui ne fait pas partie du projet; il devrait être facile de le souffler et de le recréer à tout moment, ou d'en créer un nouveau sur un nouvel hôte de déploiement, etc.

Beaucoup de gens utilisent en fait virtualenvwrapper , qui supprime presque complètement les virtualenvs réels de votre conscience, les plaçant tous côte à côte dans $ HOME / .virtualenvs par défaut.

Carl Meyer
la source
Tout à fait d'accord, c'est une mauvaise pratique, il est bon de souligner qu'il devrait être facile de souffler et de recréer, en particulier pour tester les déploiements et réduire les packages d'exigences inutiles. Je veux juste ajouter que virtualenv est possible de se déplacer en utilisant, par exemple, virtualenv --relocatable myvenvvoir stackoverflow.com/a/6628642/1335793 simplement parce que vous pouvez ne pas dire que vous devriez cependant.
Davos
2

Si vous attribuez un a à votre projet setup.py, pip peut l'importer directement depuis le contrôle de version.

Faites quelque chose comme ceci:

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

Le -emettra le projet dans myproject/src, mais le liera myproject/lib/pythonX.X/site-packages/, donc toutes les modifications que vous apportez seront immédiatement prises en compte dans les modules qui l'importent depuis votre fichier local site-packages. Le #eggbit indique à pip le nom que vous voulez donner au paquet d'œufs qu'il crée pour vous.

Si vous ne l'utilisez pas --no-site-packages, veillez à spécifier que vous souhaitez que pip s'installe dans le virtualenv avec l' -Eoption

jcdyer
la source