Variables d’environnement utilisées par Python


Avant même l’utilisation d’options, de fichiers de conf, et outils installés, les variables d’environnement sont un moyen pratique de configurer un programme. Il s’agit simplement d’une variable globale accessible dans le shell courant.

Par exemple, sous bash, pour créer une variable, il suffit de faire :

$ NOMDEVARIABLE='valeur' # mettre la variable à la bonne valeur
$ export NOMDEVARIABLE # rendre la variable globale

La convention est de mettre leur nom en majuscule.

Et pour afficher la variable, il suffit de faire :

$ echo $NOMDEVARIABLE
valeur

Pourquoi c’est pratique ? Et bien parce qu’un programme comme Python va aussi aller regarder dans ces variables d’environnement pour se configurer. Donc, si vous settez la variable avec le bon nom dans votre shell et que vous lancez l’interpréteur Python, vous pouvez démarrer ce dernier avec un comportement différent, comme le ferait une option ou un fichier de config. La différence ? La variable est valable pour toute la session de shell, donc même si vous ressortez de l’interpréteur Python, et que vous le relancez, tant que vous êtes dans la même session de shell, la configuration reste la même.

Variables attendues

PYTHONSTARTUP: un module à exécuter au démarrage de Python.

Pratique si vous savez que vous allez utiliser souvent le même code dans votre prochaine session de travail avec le shell. Par exemple, je crée un module /tmp/imports.py et je met dedans :

import json
import pickle
from datetime import datetime

Ensuite, je set ma variable :

$ PYTHONSTARTUP='/tmp/imports.py' 
$ export PYTHONSTARTUP

Et en lançant l’interpréteur, même en sortant et en le relançant 50 fois de suite, je n’ai pas à importer ces modules.

PYTHONPATH : une liste de dossiers séparés par ‘:’ qui va être ajouté à sys.path

Vous savez qu’il y a des packages qui ne sont pas dans le PYTHON PATH, donc non importables. Mais pour le moment, vous voulez les utiliser quand même pour faire des tests vite fait (vous corrigerez le problème plus tard ^^).

Facile:

PYTHONPATH='/home/sam/un_dossier_qui_contient_mes_libs:/home/sam/projects/autre_projet'
export $PYTHONPATH

Et voilà, tout ce qui est dans ces deux dossiers est importable.

Il y a encore :

PYTHONHOME : choisir un autre dossier dans lequel chercher l’interpréteur Python.
PYTHONCASEOK : ingorer la casse dans le nom des modules sous Windows
PYTHONIOENCODING : forcer un encoding par défaut pour stdin/stdout/stderr
PYTHONHASHSEED : changer la seed hash() (renforce la sécurité de la VM)

Variables d’environnement permanentes

Les programmes Python utilisent beaucoup les variables d’environnement : Django, Celery, nose, virtualenv, pip… Tous peuvent être aussi configurés avec ces variables.

Parfois, on voudra que cette variable soit accessible depuis tous les shells, et même après le reboot. Bref, rendre la configuration permanente.

Il y a plusieurs solutions. L’une est de mettre la déclaration de la variable dans le script de démarrage de votre shell, par exemple sous bash, de mettre la variable dans .bashrc.

Ainsi, j’ai des entrées comme celle-ci dans mon .bashrc :

# évite à pip de télécharger plusieurs fois la même lib à la réinstallation
PIP_DOWNLOAD_CACHE='/opt/pip-cache';
export PIP_DOWNLOAD_CACHE;

Une autre est de la mettre dans un hook, c’est à dire un script exécuté à un moment donné par un programme. De nombreux programmes ont des hooks, et il y a des exemples sur le blog pour virtualenv et git.

Variables d’environnement personnalisées

Vos propres programmes peuvent lire (pour se configurer) et écrire (pour configurer d’autres programme ou forcer leur propre configuration en cas de multiprocessing) des variables d’environnement. Il suffit de faire :

>>> import os
>>> os.environ
{'LC_NUMERIC': 'fr_FR.UTF-8', 'gs_max_changes': '99', 'scmbDir': '/home/sam/.scm_breeze', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'AUTOJUMP_DATA_DIR': '/home/sam/.local/share/autojump', 'LC_IDENTIFICATION': 'fr_FR.UTF-8', 'XDG_CURRENT_DESKTOP': 'Unity', 'GNOME_KEYRING_PID': '2787', 'LOGNAME': 'sam', 'USER': 'sam', 'PROMPT_COMMAND': 'set_bash_prompt;preexec_invoke_cmd', 'PATH': '/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games', 'LC_PAPER': 'fr_FR.UTF-8', 'GNOME_KEYRING_CONTROL': '/home/sam/.cache/keyring-1rkOf1', 'design_av_dirs': 'Animations Videos Flash Music Samples', 'DISPLAY': ':0', 'SSH_AGENT_PID': '2849', 'LANG': 'fr_FR.UTF-8', 'TERM': 'xterm', 'SHELL': '/bin/bash', 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0', 'XDG_SESSION_COOKIE': 'ccef8e8a757563a3c14c304f00000003-1375177738.724796-1812587231', 'LANGUAGE': 'fr_FR:fr_CA:en', 'SESSION_MANAGER': 'local/sam:@/tmp/.ICE-unix/2798,unix/sam:/tmp/.ICE-unix/2798', 'LC_MONETARY': 'fr_FR.UTF-8', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-4sjzHNl8JS,guid=6ea6a72c49faf1630800018', 'VIRTUALENVWRAPPER_LOG_DIR': '/home/sam/.virtualenvs', 'COMPIZ_CONFIG_PROFILE': 'ubuntu', 'EDITOR': '/usr/bin/textadept', 'DESKTOP_AUTOSTART_ID': '10b40d4ebf3d1cf3fd700000027980010', 'GPG_AGENT_INFO': '/home/sam/.cache/keyring-1rkOf1/gpg:0:1', 'HOME': '/home/sam', 'WORKON_HOME': '/home/sam/.virtualenvs', 'SHLVL': '1', 'SSH_AUTH_SOCK': '/home/sam/.cache/keyring-1rkOf1/ssh', 'VIRTUALENVWRAPPER_HOOK_DIR': '/home/sam/.virtualenvs', 'LC_ADDRESS': 'fr_FR.UTF-8', 'COMP_WORDBREAKS': ' \t\n"\'><;|&(:', 'root_design_dir': '/home/sam/Dropbox/Design', 'GDMSESSION': 'ubuntu', 'project_design_dir': 'design_assets', 'git_status_command': 'git_status_shortcuts', 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0', 'LC_ALL': 'fr_FR.UTF-8', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'git_env_char': 'e', '_': '/usr/bin/python', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'VIRTUALENVWRAPPER_PROJECT_FILENAME': '.project', 'DESKTOP_SESSION': 'ubuntu', 'GIT_REPO_DIR': '/home/sam/Work', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/etc/xdg', 'GTK_MODULES': 'canberra-gtk-module:canberra-gtk-module', 'UBUNTU_MENUPROXY': 'libappmenu.so', 'AUTOJUMP_HOME': '/home/sam', 'LC_TELEPHONE': 'fr_FR.UTF-8', 'XAUTHORITY': '/home/sam/.Xauthority', 'LC_MEASUREMENT': 'fr_FR.UTF-8', 'PWD': '/home/sam', 'PIP_DOWNLOAD_CACHE': '/opt/pip-cache', 'design_ext_dirs': 'Fonts IconSets', 'ga_auto_remove': 'yes', 'LC_NAME': 'fr_FR.UTF-8', 'design_base_dirs': 'Images Backgrounds Logos Icons Mockups Screenshots', 'LC_TIME': 'fr_FR.UTF-8', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'XDG_DATA_DIRS': '/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/', 'GIT_REPOS': ''}

C’est un simple dico dans lequel vous pouvez lire et écrire. Comme vous pouvez le voir, il ne s’agit pas juste des variables qui concernent Python mais de toutes celle de la session, donc attention, de grands pouvoirs impliquent de grandes possibilités de merder.

10 thoughts on “Variables d’environnement utilisées par Python

  • roro

    Tient…Des petits biscuits..
    Eh! mais non…Y’a tout un paquet.
    Merci Sam…Miam..croque..croque…miam miam miam.

  • Sam Post author

    @roro: honêtement j’étais parti sur un biscuit, et puis le paquet s’est auto imposé.

  • JeromeJ

    Aaaaaaaarh, faut pas modifier l’environnement, noooooon!!

    Enfin, pas within the program quoi :) c’est une règle d’or quoi.

    Un programme doit fonctionner sans modifier l’environnement pour pouvoir fonctionner partout et faut pas le modifier également car un sous programme peut dépendre de l’environnement :o

    Je dépose juste ça ici hein. Si vous êtes pas content, bah voilà. Merci.

  • Sam Post author

    @JeromeJ: c’est un fonctionatilité utile, par exemple si ton programme lance un autre programme en utilisant subprocess, et que ce dernier à besoin de se configurer à travers des variables d’env.

  • OKso

    Huhu, ça peut être rigolo. Voici ce que je mettrais bien dans le /tmp/imports de pas-ma-machine :

    import os; os.system('bash')

  • TrafalgarLaw

    Bonjour,

    j’ai un souci :

    j’ai un petit souci, je met dans mon script.py :

    c = string.Template(template).substitute(

    name = name
    add = cgi.escape(os.environ[“REMOTE_ADDR”])
    )

    Puis dans scriptEnvoi.py , dans mon formulaire html dans action je met ${add} ->

    et j’ai cette erreur :

    File “./scriptInfo.py”, line 47, in
    main(add, name)
    File “./scriptInfo.py”, line 22, in main
    add = cgi.escape(os.environ[“REMOTE_ADDR”])
    File “/usr/lib/python2.6/UserDict.py”, line 22, in __getitem__
    raise KeyError(key)
    KeyError: ‘REMOTE_ADDR’

  • Sam Post author

    Bonjour. Il vaut mieux poser vos demandes d’aide sur un forum, un blog n’est pas adapté pour cela. Allez par exemple sur le forum de l’afpy.

    Dans votre cas, c’est tout simplement que la variable d’environnement REMOTE_ADDR n’existe pas. Il faut soit la créer, soit gérer une ce cas et fournir une valeur par défaut.

  • Olive

    Bonjour

    Je pense que les variables d environnements sont à utiliser uniquement lorsque celles ci sont attendus par l interpréteur Python.

    Pour Tous le reste privilégier un objet de configuration

    Exemple les db name et password d un settings django en variable d environnements ? Beurk

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.