Python env
J’utilise python venv dans un environnement archlinux. A chaque fois que j’ajoute un script python, je saisis `python -m venv .venv` . Je suppose que l’environnement venv est identique pour tous les scripts ?
Pas exactement, et c’est un point important à clarifier :
Comment fonctionne un venv
Un venv est lié à un dossier, pas à vos scripts. Quand vous faites :
1
python -m venv .venv
cela crée (ou écrase) le dossier .venv dans le répertoire courant. Deux cas de figure :
1. Vous êtes toujours dans le même dossier projet
Si vous relancez python -m venv .venv à chaque nouveau script dans le même projet, vous réinitialisez l’environnement : les paquets installés via pip install disparaissent (le venv est recréé vierge). Il faut créer le venv une seule fois par projet, pas par script.
2. Un dossier par script
Si chaque script a son propre dossier avec son .venv, alors chaque script a un environnement isolé. C’est le comportement attendu (isolement des dépendances).
Points d’attention sur Arch
- Un venv n’est pas utilisé automatiquement : il faut l’activer (
source .venv/bin/activate) ou appeler directement.venv/bin/python script.py, sinon c’est le Python système qui exécute le script. - Arch met à jour Python système rapidement (ex. 3.12 → 3.13) : les venvs créés avec l’ancienne version cassent après la mise à jour, il faut les recréer. C’est une raison de plus pour ne pas multiplier les venvs inutilement.
python -m venvn’installe paspipdans certaines configs minimales ; utilisezpython -m venv --upgrade-deps .venvou mettez pip à jour juste après.
Alternative moderne
Si vous créez souvent des petits scripts, jetez un œil à uv (disponible dans les dépôts Arch : pacman -S uv) :
1
2
3
uv venv # création quasi instantanée
uv pip install requests
uv run script.py # exécute directement dans le venv, sans activation
Beaucoup plus rapide et gère mieux le cycle de vie des environnements.
En résumé : un venv par projet, créé une fois, et pas un venv par script dans le même projet.
Trois questions
- 1 - un dossier différent pour chaque script avec venv
- 2 - uv ?
- 3 - Comment associer un script python (venv ou uv) à un service utilisateur systemd
1 - Un dossier par script avec venv
C’est une approche valide mais à réserver aux scripts vraiment indépendants :
1
2
3
4
5
6
7
~/scripts/
├── backup/
│ ├── backup.py
│ └── .venv/
├── sync-photos/
│ ├── sync.py
│ └── .venv/
Avantages : isolement total, pas de conflit de versions de paquets.
Inconvénients : duplication (chaque venv refait installer requests, numpy…), plus de maintenance, et sur Arch chaque venv casse à chaque montée de version de Python système.
En pratique, la bonne règle : un venv par projet, pas par script. Si plusieurs scripts partagent des dépendances (ex. tous utilisent requests), regroupez-les dans le même projet/venv. Réservez le venv-par-script aux cas réellement isolés.
2 - uv
uv est un outil écrit en Rust qui remplace pip, venv et pyenv : pacman -S uv.
1
2
3
4
cd ~/scripts/backup
uv venv # crée .venv en quelques millisecondes
uv pip install requests # installation très rapide, avec cache partagé
uv run backup.py # exécute dans le venv, sans activation
Atouts pour votre usage :
- Vite : le cache est partagé entre tous les venvs, donc “un venv par script” coûte beaucoup moins cher en disque et en temps qu’avec venv/pip.
uv run script.pytrouve le.venvdu dossier automatiquement, pas besoin d’activer.uv python install 3.12peut gérer ses propres versions de Python, insensibles aux mises à jour d’Arch.- Alternative encore plus simple pour un script autonome :
uv run --with requests script.pycrée un environnement jetable à la volée, sans venv persistant.
Pour un script avec un fichier requirements.txt : uv venv && uv pip install -r requirements.txt.
3 - Service utilisateur systemd
Le principe : pointez ExecStart directement vers le python du venv, pas le python système. Pas besoin d’activer le venv, l’exécutable .venv/bin/python sait où trouver ses paquets.
Créez ~/.config/systemd/user/backup.service :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Mon script de backup
After=network-online.target
[Service]
Type=simple
# venv : on appelle directement le python du venv
ExecStart=/home/vaden/scripts/backup/.venv/bin/python /home/vaden/scripts/backup/backup.py
WorkingDirectory=/home/vaden/scripts/backup
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
Puis :
1
2
3
4
5
systemctl --user daemon-reload
systemctl --user start backup.service
systemctl --user status backup.service
journalctl --user -u backup.service -f # logs
systemctl --user enable backup.service # démarrage auto
Avec uv, même logique :
1
ExecStart=/home/vaden/scripts/backup/.venv/bin/python backup.py
ou pour un environnement jetable sans venv persistant :
1
ExecStart=/usr/bin/uv run --with requests /home/vaden/scripts/backup/backup.py
Points d’attention :
- Chemin absolu : systemd n’explose pas
~ni les variables, utilisez/home/vaden/.... - Persistance hors session : par défaut, les services user s’arrêtent à la déconnexion. Pour un service qui doit tourner en continu même sans session ouverte :
1
loginctl enable-linger vaden
- Timer : pour une exécution périodique, préférez un timer plutôt qu’une boucle
sleepdans le script. Créezbackup.timer:1 2 3 4 5 6 7 8 9
[Unit] Description=Backup quotidien [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target
1
systemctl --user enable --now backup.timer
(le service reste identique mais sans
WantedBy=default.targetniRestart, et on le lance via le timer). - Environnement : si le script a besoin de variables d’environnement, ajoutez
Environment="MA_VAR=valeur"dans la section[Service]ou un fichierEnvironmentFile=.