PROJET AUTOBLOG


Sam et Max

source: Sam et Max

⇐ retour index

Comment servir les fichiers statiques avec Django en dev et en prod

mardi 23 octobre 2012 à 00:57

Servir les fichiers CSS, javascript et les images avec Django a toujours été la plus grande source de confusion (heureusement ça s’est bien amélioré avec la 1.4, donc upgradez si vous pouvez). C’est d’autant plus déroutant que la manière de faire est différente selon la version de Django, et selon que l’on est en production ou en développement.

Donc, pour profiter de cet article:

C’est typiquement le cas où il faut comprendre ce qui se passe et pas juste copier/coller du code (ceci est une petite pique à Max qui est en train de décuver comme une loque sur le canap pendant que j’écris cette partie de l’article).

Préparation

Les fichiers statiques se gèrent à base de chemins absolus. Afin de faciliter celà, vous devriez donc toujours avoir ceci tout en haut de votre fichier settings.py:

import os
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))

Si votre fichier de settings n’est pas à la racine du projet (typiquement dans un projet Django 1.4), faites:

import os
SETTINGS_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_DIR = os.path.dirname(SETTINGS_DIR)

Le fichiers de settings étant un fichier Python, on peut mettre tout le code que l’on souhaite dedans, et ce code nous permet d’obtenir de manière dynamique le chemin absolu vers votre dossier de projet. Il servira de base pour tous les chemins vers les fichiers statiques.

__file__ contient le chemin vers le fichier en cours. abspath() permet d’obtenir le chemin absolu. dirname() permet d’obtenir le nom du dossier contenant le fichier.

Notez aussi l’emplacement des fichiers statiques de la Django admin dans un coin (dans la doc de votre site par exemple). Ces fichiers se trouvent dans django/contrib/admin/media, mais si vous galerez pour les trouver, vous pouvez toujours lancer la commande:

python -c "import django, os; print os.path.join(os.path.dirname(django.__file__), 'contrib/admin/media')"

Moi ça donne un truc comme ça:

/home/sam/.virtualenvs/project_env/local/lib/python2.7/site-packages/django/contrib/admin/media

En phase de développement, de la version 1.0 à la version 1.2

Vous êtes sur votre machine, et vous utilisez la commande runserver. C’est donc Django qui va servir vos fichier statiques, et nous allons voir comment, pour chaque version de Django, on peut lui demander de le faire.

C’est une vieille version, servir les fichiers statiques est assez relou, alors on va gruger pour vous faciliter la vie. Non, ce n’est pas la meilleur manière de faire, mais c’est la manière de faire qui vous évitera de retourner sur un forum pour demander pourquoi ça ne marche pas.

Créez un dossier nommé “static” à la racine de votre projet. Mettez tous vos fichiers statiques dedans: js, css, images… Organisez ça en sous-dossier si vous voulez, mais mettez tout dedans, y compris les fichiers statiques des autres apps Django que vous avez installé (et qu’il va falloir copier/coller ou alors faire un lien symbolique). La seule exception est l’admin.

Ce n’est pas particulièrement propre ni pratique, mais ça va marcher. Le surcoût en maintenant sera largement compensé par le fait que ce sera très simple à comprendre et à servir.

Dans votre fichier de settings, pointez MEDIA_ROOT sur ce dossier:

MEDIA_ROOT = os.path.join(PROJECT_DIR, 'static')

Et choissisez un chemin explicite pour MEDIA_URL:

MEDIA_URL = '/static/'

Ne touchez pas à ADMIN_MEDIA_PREFIX. Ne mettez pas MEDIA_URL égale à ADMIN_MEDIA_PREFIX.

Dans le fichier urls.py principal, c’est à dire ce lui est généralement à la racine de votre projet, faites:

# on importe ici tout les trucs nécessaires à urls.py
from django.conf.urls.defaults import *
# on va récupérer MEDIA_ROOT depuis le fichier de settngs
from django.conf import settings
 
# on active l'admin
from django.contrib import admin
admin.autodiscover()
 
# on créé un pattern vide. Cela va nous permettre d'insérer le service
# des fichiers statiques en premier
urlpatterns = patterns('')
 
# On active maintenant le service des fichiers statiques par Django
# mais uniquement en mode DEBUG (pour éviter de l'oublier en prod)
if settings.DEBUG:
    urlpatterns += patterns('',
        (r'%s/(?P<path>.*)$' % settings.MEDIA_URL.strip('/'),
         'django.views.static.serve',
         {'document_root': settings.MEDIA_ROOT}),
    )
 
# Ensuite on déclare nos patterns normalement
# ATTENTION, le signe doit-être "+=", pas "=", sinon vous allez tout écraser
urlpatterns += patterns('',
    # Example:
    (r'^', include('app.urls')),
 
    # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
    # to INSTALLED_APPS to enable admin documentation:
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
 
    # Uncomment the next line to enable the admin:
    (r'^admin/(.*)', admin.site.root),
)

Vous notez que contrairement à ce qu’on voit la doc officielle, on met l’url pour les fichiers statiques en premier. Cela donne une forme étrange à la déclation des urls car on a un urlpatterns vide au début, mais c’est très important: à un moment vous allez déclarer une URl attrape-tout qui court-circuitera tout ce qu’il y a après, et ce jour là vous passerez des heures à chercher pourquoi vos fichiers statiques ne sont pas déclarés.

Le strip() n’est pas obligatoire si vous mettez les slashes correctement partout. Mais ce n’est jamais le cas.

Maintenant, dans votre html, vous pouvez faire ceci:

<link href="/static/chemin/du/fichier/a/relatif/au/dossier/static.css"  rel="stylesheet" />

Et pareil pour le js, les images, etc.

Le chemin est bel et bien écrit en dur dans le templates HTML. Encore une fois, ce n’est pas la meilleure manière de faire, c’est juste celle qui vous garanti que ça marche. Si vous vous sentez à l’aise avec le processus, vous pouvez changer celà en utilisant un context_processor pour ajouter MEDIA_URL à chaque template et remplacer /static/ par {{ MEDIA_URL }}.

Télécharger le projet complet d’exemple

En phase de développement, pour la version 1.3 et 1.4

C’est globalement beaucoup plus facile. Il suffit de mettre tous vos fichiers statiques dans un dossier nommé “static” dans le dossier d’une de vos app pour qu’ils soient trouvés automatiquement quand vous lancerez manage.py runserver.

Voici à quoi ressemblera votre settings.py:

# plus rien à voir avec avant, MEDIA_ROOT et MEDIA_URL designent
# l'endroit où vous voulez que vos utilisateur upload et download des fichiers
# Ce n'est donc plus un paramètre primordial
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
MEDIA_URL = '/media/'
 
# Ce qui s'appelait avant MEDIA_ROOT s'appelle maintenant STATIC_ROOT
# mais il n'est utile pour la prod
# On le met quand même pour plus tard
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
 
# Le settings le plus important: à quelle adresse servir les fichiers statiques
# Utile en dev afin de pouvoir bénéficier des templates tags
STATIC_URL = '/static/'
 
# Les medias de l'admin sont enfin une URL comme une autre qu'on peut
# mettre sous notre propre arborescence
ADMIN_MEDIA_PREFIX = '/static/admin/'
 
# Vous pouvez OPTIONNELLEMENT rajouter ici une liste de chemin vers
# des dossiers de fichiers statiques qui seront ainsi aussi servit automatiquement
# pendant le développement. Par exemple un dossier à la racine
STATICFILES_DIRS = (
    os.path.join(PROJECT_DIR, 'more_static'),
)
# N'utilisez PAS le même dossier que STATIC_ROOT

Il n’y a rien à faire de plus, vos fichiers seront servis automatiquement en dev, pas besoin de toucher aux urls.

Maintenant il faut juste les déclarer vos URLs dans le template.

Pour Django 1.3, vous pouvez ajouter un fichiers statiques ainsi pour éviter d’écrire l’URL en dur:

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
 
<link href="{{ STATIC_PREFIX }}app/css/style.css"  rel="stylesheet" />

Pour django 1.4, c’est encore plus simple:

{% load staticfiles %}
<img src="{% static "app/css/style.css" %}" />

Encore un détail, si vous n’utilisez pas le serveur de dev Django mais un autre serveur de dev (ex: werkzeug), vos fichiers statiques ne seront pas servis automatiquement, mais il est facile d’y remédier. Ajoutez à votre urls.py:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 
urlpatterns += staticfiles_urlpatterns()

Télécharger le projet complet d’exemple

Migration de 1.2 ou moins vers 1.3 ou 1.4

Bouger vos fichiers statiques du répertoire à la racine vers le répertoire nommé “static” d’une de vos apps (ou de plusieurs).

Ajoutez ceci dans votre fichier de config:

STATICFILES_DIRS = (
)
 
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

Et ajoutez django.contrib.sites à vos INSTALLED_APPS.

Remplacez toutes les URls en dur dans le HTML par une version avec les templates tags (voir partie précédente).

Attention, ça ne couvre que la partie pour la gestion des fichiers statiques, il y a d’autres choses à migrer.

En production: toutes versions

Je ne vais pas expliquer ici comment mettre Django en production (c’est un article à lui tout seul, peut être même plusieurs). Ici je vais me concentrer sur comment servir les fichiers statiques, et présupposer DEBUG = False.

Si vous utilisez Djagno 1.2 ou moins, vous n’avez rien à faire côté Django. Si vous utilisez Django 1.3 ou 1.4, vous devez maintenant appeler la commande pyhon manage.py collectstatic. Celle-ci va prendre tous les fichiers statiques de tous les dossiers “static” des apps et ceux listés dans STATICFILES_DIRS et va les copier dans STATIC_ROOT.

Dans tous les cas, vous n’aurez qu’un seul dossier pour le js, le css et les images à servir avec Nginx ou Apache.

Nginx

Si vous avez votre propre serveur, je vous conseil Nginx plutôt qu’Apache pour mettre votre site en prod.

L’idée est de dire dans le fichier de configuration nginx que toutes les URLs qui concernent les fichiers statiques sont servies directement par Nginx, et les autres sont passées à Django:

server {
        listen      8080;
 
        ############################################################
        # la partie qui concerne les fichiers statiques commence ici
        ############################################################
 
        location /favicon.ico {
            # favicon.ico doit être à la racine du dossier img
            root  /chemin/absolu/vers/dossier/img;
        }
 
        # on sert nos fichiers statiques
        # l'url doit correspondre à MEDIA_URL
        location ~* ^/static/ {
            root  /chemin/absolu/vers/dossier/PARENT/du/dossier/statique;
            # on active gzip pour tous les petits fichiers qui contiennent du texte
            # si le navigateur le supporte
            gzip  on;
            gzip_http_version 1.0;
            gzip_vary on;
            gzip_comp_level 6;
            gzip_proxied any;
            gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
            # petite astuce gzip pour les gros fichier
            # voir http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl
            gzip_buffers 16 8k;
 
            # on desactive gzip pour les vieux navigateurs
            gzip_disable ~@~\MSIE [1-6].(?!.*SV1)~@~];
        }
 
       # on fait pareil mais pour l'admin Django
       # l'url doit corresponde à ADMIN_MEDIA_PREFIX
       location ~* ^/media/ {
            root  /chemin/absolu/du/dossier/PARENT/du/dossier/media/de/django;
            gzip  on;
            gzip_http_version 1.0;
            gzip_vary on;
            gzip_comp_level 6;
            gzip_proxied any;
            gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
            gzip_buffers 16 8k;
            gzip_disable ~@~\MSIE [1-6].(?!.*SV1)~@~];
        }
 
        ##############################################################
        # la partie qui concerne les fichiers statiques se termine ici
        ##############################################################
 
        location / {
            proxy_pass http://127.0.0.1:8000;
        }
}

Notez bien que la directive root suppose que vous mettiez le dossier parent du dossier que vous voulez servir, et que le dossier servi a le même nom que le chemin dans l’url.

Par exemple, si vos fichiers statiques sont dans /home/sam/project/static, alors l’url devra être ^/static/ et on passera à l’instruction root le chemin /sam/project.

Apache

Si vous êtes chez un hébergeur qui n’a qu’Apache, voici un manière de servir les fichiers statiques. Je ne connais pas Apache aussi bien que Nginx, donc je ne peux pas m’engager sur la gestion de Gzip.

# TOUS les chemins doivent être accessible pour le user apache (www-data le plus souvent)
# N'oubliez pas les slashes finaux, ils sont importants
 
WSGIPythonPath /chemin/absolu/vers/project/:/chemin/absolu/vers/dossier/parent/du/project/:/chemin/vers/site/package/du/virtualenv/
 
<VirtualHost *:80>
 
    WSGIScriptAlias / "/chemin/absolu/vers/fichier/project.wsgi"
 
    ########################################################
    # Début de la partie qui concerne les fichiers statiques
    ########################################################
 
    # on sert les fichiers statiques du site
    Alias /static/ "/chemin/absolu/vers/dossier/static/"
    Alias /favicon.ico "/chemin/absolu/vers/dossier/static/img/favicon.ico"
 
    # on donne l'autorisation à tous de les lire
    <Directory "/chemin/absolu/vers/dossier/static/">
        Order allow,deny
        Allow from all
    </Directory>
 
    # on sert les fichiers statiques de l'admin
    Alias /media/ "/chemin/absolu/vers/dossier/django/contrib/admin/media/"
    # on donne l'autorisation à tous de les lire
    <Directory "/chemin/absolu/vers/dossier/django/contrib/admin/media/">
        Order allow,deny
        Allow from all
    </Directory>
 
    ######################################################
    # Fin de la partie qui concerne les fichiers statiques
    ######################################################
 
</VirtualHost>

Si vous faites bien gaffe aux droits d’accès des dossiers (récursivement) et que vous avec pas oublié de “/” à la fin d’un chemin, tout ira bien.

Pour Apache, servir les fichiers statiques est généralement la partie facile, c’est faire marcher Django et mod_wsgi qui est difficile: problèmes de droits, mauvaise configuration, Python path qui foine… Mais je m’en branle, puisque c’est pas l’objet de l’article, donc démerdez-vous.

Notes de fin

Jusqu’à la version 1.2, MEDIA_ROOT et MEDIA_URL ne sont que des conventions qui ne servent pas à grand chose à part à être utilisées par des contexts managers et à vous éviter les chemins en durs dans les templates et urls.py.

A partir de Django 1.3, STATIC_ROOT et STATIC_URL sont vraiment utilisées: STATIC_ROOT est là où Django va mettre le resultat de la commande collecstatic et STATIC_URL et l’url que va utiliser la vue staticfiles_urlpatterns.

MEDIA_ROOT et MEDIA_URL existent toujours, mais sont utilisés pour designer le dossier et l’url qui pointent vers les contenus uploadés et downlodés par les utilisateurs. Si vous voulez les servir, il faut faire exactement la même chose à l’époque de Django 1.2 et avant: mettre la route à la main dans urls.py (mais cette fois, il y a un raccourcis pour ça), et rajouter une entrée supplémentaire dans le fichier de conf Nginx ou Apache.

Sinon, vous pouvez aussi vous éviter tout ce merdier en utilisant le middleware qui sert automatiquement tous les fichiers statiques de django_quicky.

Enfin, je n’ai pas abordé les storage backends, tout simplement parce que je n’en utilise pas, donc je ne peux pas vous donner de bons conseils sur la question.

Démasquer les fakes profils sur les réseaux sociaux et sites de rencontres

dimanche 21 octobre 2012 à 21:08

Haaaa c’est bientôt l’hiver, on a envie de trouver une poule pour être au chaud alors on va sur Badoo et on sélectionne les petites les plus chaudes pour commencer, on se dit qu’après quelques rateaux on tapera dans les monstres.
Mais voilà c’est plein de faux profils qui vont tenter de vous vendre un compte en banque rempli de millions de dollars sous condition d’envoyer un Western Union pour débloquer l’avocat enfermé au Congo chargé de valider la transaction… Et bing un trou mais pas au bon endroit…Plutôt dans le compte en banque… Retour case branlette…

Certains profils comme sur Bado sont super bien foutu, il y a même écrit “vérifié” en medaillon histoire de bien noyer le poisson dans la choucroute.

Houuu la bonne petite, tout juste majeure en plus, ça doit craquer...

Un meuf comme ça sur Badoo qui cherche à se faire réalaiser le tuyaux on pourrait se dire que c’est trop beau, mais souvent on tente le coup quand même et le piège se referme sur la proie que vous êtes. Préparez la CB…

Tout ça c’est du passé, grace à tonton Max vous allez pouvoir arrêter de vous faire pigeonner par ces belles poulettes derrière qui se cache certainement un Somalien à qui vous auriez du envoyer DES MILLIERS DE $$$.

Google image est ton ami:

1. Sauvegardez l’image sur votre disque de cette charmante jeune fille (bouton droit, “Enregistrer l’image sous…”)
2. Allez sur Google image et cliquez sur le petit appareil photo, uploadez l’image de la belle et Ho surprise !!!

Notre chère petite “BelleCoeur” de Badoo est en fait la ravissante actrice de boule “ann angel”

Bellecoeur de chez Bado n'est autre que "Ann Angel" , une actrice XXX

Ca ne marche pas à tous les coups mais on a facilement une idée de l’authenticité du profil 4 fois sur 5.

Conclusion:
Ne chauffez que les tromblons, là peut de chance d’avoir de faux profils et elles ont faim ! Faites un bon geste pour la planète que diable !.

On va tous les niquer !

samedi 20 octobre 2012 à 22:07

Je suis ravis qu’il y ait pas trop de réactions comme celle-ci sur ce blog. Mais il faut bien avouer que le politiquement correcte continue de pourrir la journée. Notre cher sebsauvage publie régulièrement des petites piques à destination des peignent cul, et j’avoue que l’article “Nous devons nous autoriser à nous insulter les uns les autre” m’a clairement fait tilté, tellement il est significatif de l’état d’esprit de l’ambiance qui certains veulent nous installer.

Moi je veux vivre dans un monde où on peut publier aussi bien ceci:

Orgie de divinités

Personne n'est mort pour la publication de cette image

 

Que cela:

 

Caricature de Mahomet par Charlie Hebdo

Par contre y a un film récent qui a fait quelques morts

 

Mais si on se fait chahuter en France, j’ai visité beaucoup de pays où on est très loin de pouvoir ne serait-ce qu’en parler tout bas. J’ai vu le résultat, et ça ne me donne pas du tout envie de me retrouver dans cette situation.

Alors petite piqûre de rappel

Arabes, asiatiques et racistes:

Juifs, chinois et allemands:

Flics:

Paranos, sursécuriataires et racistes:

Gay, homophones et metrosexuels:

Noirs:

Et parce qu’il faut bien donner l’exemple par l’auto dérision:

Et on peut continuer sur les gros, les handicapés, les cancereux, les orphelins, etc.

Je hais vos idées, mais je me ferai tuer pour que vous ayez le droit de les exprimer.

Voltaire

Les environnements virtuels Python : virtualenv et virtualenvwrapper

vendredi 19 octobre 2012 à 18:49

Quand on commence à beaucoup programmer, on accumule rapidement plusieurs projets en cours de développement sur sa machine. Certains vieux, certains récents, qui utilisent tous des bibliothèques similaires, mais pas forcément de mêmes versions. Ou parfois des bibliothèques incompatibles. Parfois même, des version différentes de Python: Python 2.6, 2.7, 3.2 ? Et c’est sans compter les mises à jour de l’OS, qui a ses propres besoins en terme de libs et de versions.

Le jour où ça casse, c’est le chaos.

Dans le monde de Python, la solution à ce problème est d’utiliser des environnements virtuels. Ca à l’air d’un gros mot, mais derrière ce terme se cache la notion simple d’avoir des installations de Python isolées de l’OS, et séparées les unes des autres pour chaque projet.

Il existe plusieurs écoles: certains utilisent buildout. C’est une solution puissante, et très compliquée. Python 3.3 vient avec venv, un outil intégré pour gérer les environnements virtuels. Pour les gens comme moi qui veulent quelque chose qui marche partout, tout le temps et facilement, il y a virtualenv.

Installation et usage

Première chose à faire, installer virtualenv:

pip install --user virtualenv

Si vous avez besoin d’un rappel sur pip, c’est par là.

Ensuite, pour chacun de vos projets, créez un environnement virtuel:

virtualenv /path/vers/projet/env_nom_du_projet

Virtualenv va créer un dossier avec un environnement complet dedans: l’interpreteur Python, les libs, des commandes, etc. C’est votre installation isolée.

Pour travailler dans votre installation isolée:

Votre prompt de ligne de commande va changer pour indiquer que vous êtes dans un environnement virtuel:

(env_nom_du_projet) sam $

Si vous installez une bibliothèque avec pip, il l’installera dans cet environnement virtuel, et elle ne sera pas accessible ailleurs. Si vous lancez la commande python, le shell Python aura accès à toutes les libs de cet environnement virtuel.

Vous pouvez sortir de l’environnement virtuel avec la commande deactivate.

Creez autant de virtualenv que vous voulez: un par projet, un pour les tests de nouvelles libs, un pour le plaisir, un pour la route… Ca prend juste de la place, et ce n’est pas ce qui manque sur nos disques durs de nos jours.

Quelques astuces avec virtualenv

Isolation par rapport à l’OS

Vous pouvez choisir que votre env hérite des libs de l’OS, ou non, mais uniquement à la création. Il faut spécifier une option:

Les anciennes versions ont la valeur --system-site-packages activée par défaut, les nouvelles versions de virtualenv ont la valeur --no-site-packages activée par défaut.

Si vous utilisez --system-site-packages, vous pouvez quand même demander à pip freeze de lister uniquement les libs de l’env avec l’option --local.

Choisir une version de Python

Parfois vous voudrez utiliser une version spécifique de Python. Vous pouvez tout à fait créer un env dédié à Python 3.2 et un autre à Python 2.6, il faut juste que les deux versions soient installées sur votre système.

Je ne vais pas détailler commen installer deux versions de Python en parallèle sur chaque OS car je n’ai aucune idée de comment on fait sous Mac ou Windows, mais sous Ubuntu c’est très simple: par défaut on est en Python 2.7, et pour installer Python 3, on fait sudo apt-get install python3. Pour installer Python 2.6, on fait sudo apt-get python2.6.

On a alors 3 executables: /usr/bin/python va déclencher Python 2.7, /usr/bin/python2.6 va appeler Python 2.6, etc. Aucun conflit système, c’est merveilleux.

Il ne reste qu’à construire son environnement virtuel en lui passant en paramètre le chemin vers le Python à utiliser:

virtualenv mon_env -p /usr/bin/python2.6

Et voilà, si on active “mon_env”, la commande python ouvre un shell en Python 2.6, et toutes les libs de l’env sont en 2.6.

Attention: on ne peut pas reconvertir facilement un env d’une version de Python à l’autre. Une fois que c’est créé, c’est fait. Si vous changez d’avis, faite un pip freeze, supprimez l’env, recréé l’env, et faites un pip install -r.

Virtualenv depuis un script extérieur

Si vous êtes dans un script extérieur et que vous voulez appeler un de vos scripts avec ce virtualenv, vous n’avez pas besoin de l’activer pour que ça marche. Il suffit d’appeler le script en le passant en paramètre à l’interpréteur de l’env. Par exemple:

/path/vers/projet/env_nom_du_projet/bin/python mon_script.py

Le script sera alors exécuté dans le cadre du virtualenv.

virtualenvwrapper: ou comment ne pas se faire chier pour passer d’un env à l’autre

Si vous êtes sous Windows, vous pouvez aller boire une bière à la cuisine, ça ne marche pas sous votre OS.

Pour les chanceux qui ont accès à un Unix, il existe un merveilleux logiciel qui va vous éviter le yoyo entre les envs:

pip install --user virtualenvwrapper

Ensuite il faut rajouter quelques lignes dans votre script d’init de shell, par exemple dans ~/.bashrc:

export WORKON_HOME=~/.virtualenvs
mkdir -p $WORKON_HOME
source ~/.local/bin/virtualenvwrapper.sh

Selon où vous avez installé virtualenvwrapper, la dernière ligne peut changer. Moi, mon virtualenv est installé au niveau du système dont le chemin est plutôt /usr/local/bin/virtualenvwrapper.sh.

Ces lignes vont lancer virtualenvwrapper en permanence dans le shell. Relancez le terminal pour l’activer. Le premier lancement va vous afficher un tas de lignes, rassurez-vous, ça n’arrive qu’une fois.

Ensuite, vous avez accès à de nouvelles commandes:

Les options de mkvirtualenv sont les mêmes que pour la commande virtualenv, vous n’avez juste plus à vous souciez de où sont vos envs, ni de où vous êtes.

Ajouter un chemin à la variable d’environnement PATH sous Windows

jeudi 18 octobre 2012 à 22:19

Il y a beaucoup de tutos qui demandent de simplement “ajouter le résultat au PATH”, mais assez peu expliquent pourquoi et comment le faire.

Comme on aime bien faire les choses à l’envers chez Sam et Max, on va d’abord expliquer comment, et ensuite pourquoi.

Modifier le PATH sous Windows 7 et XP

Il faut d’abord ouvrir l’outil d’édition des variables d’environnement.

Sous Windows XP, c’est:

Sous Windows 7, c’est presque pareil:

Dans les deux cas, vous allez vous retrouver avec la fenêtre le plus détestée du monde de Windows, la fameuse fenêtre “Variables d’envionnement”. Toute petite, illisible, est pas redimensionable. Vous ne l’oublierez plus jamais:

Capture d'écran de la fenêtre des variables d'environnement de Windows

Oh mon dieu, il nous fonce dessus !

Dans cette fenêtre, dans la partie “Variables systèmes” (la liste du bas), il faut cliquer sur la ligne qui contient ‘Path’, de telle sorte qu’elle soit sélectionnée (en couleur alors que les autres items de la listes ne le sont pas). Il vous faudra sûrement scroller un peu pour la trouver.

Ensuite il faut cliquer sur le bouton “Modifier…”.

Là s’ouvre une fenêtre avec deux champs, le deuxième, “Valeur de la variable”, est celui qui nous intéresse. Il est absolument chiant à modifier, alors faites plutôt un copier/coller dans un éditeur de texte à part: Ctrl + A pour tout selectioner, Ctrl + C pour tout copier, puis Ctrl + V pour tout coller ailleurs, car je ne suis pas sûr que le clic droit fonctionne dans cette grosse bouse.

Vous devriez avoir un texte qui ressemble à ceci (pas exactement le même, mais proche):

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;

Ne retirez rien de cette valeur si vous ne savez pas ce que vous faites.

Pour ajouter quelque chose au PATH de Windows, il suffit de le mettre tout collé à la fin, suivit d’un ‘;’

Par exemple, pour rajouter le chemin vers l’installation de Python dans le PATH de Windows:

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Python27;

Attention, si vous avez copié/collé le contenu ailleurs, supprimez bien l’ancien contenu en le remplaçant complètement par le nouveau (Ctrl + A, Ctrl + V) sinon vous allez tout péter.

A quoi servent les variables d’environnement et le PATH ?

Sous tous les OS, il y a des variables qui déterminent le fonctionnement de celui-ci (ou plutôt du shell, mais ce n’est pas important). Elles permettent à l’utilisateur, en changeant la variable, de choisir certains comportement primitifs du système.

Par exemple, quand vous tapez une commande dans un terminal, le système va utiliser la variable d’environnement PATH. Il va prendre chaque dossier listé dans PATH, et regarder si il trouve la commande dedans. Si il trouve cette commande, il la lance, et arrête la recherche. Si il ne trouve pas la commande, il va vous dire que la commande n’existe pas.

Ainsi, si vous avez installé Python mais que le shell Python ne se lance pas quand vous entrez la commande python dans un terminal, ajouter C:\Python27; au PATH peut résoudre le problème: Windows va maintenant chercher dans ce dossier également pour voir si la commande existe.