pip: Python
`pip install requests` is een van de meest getypte regels in een terminal, en tegelijk een van de meest betwiste.
Want zodra je op een Debian- of Ubuntu-server werkt, krijg je te horen dat je pip niet moet gebruiken. Op een Raspberry Pi met een verouderde Python werkt het juist wel, tot het niet meer werkt. En in een container is het weer volstrekt normaal. De vraag is nooit of pip goed is, maar waar je het loslaat op een systeem dat je niet volledig in de hand hebt.
Laten we eerst vaststellen wat pip doet. Het haalt pakketten op van PyPI, de publieke repository met honderdduizenden Python-pakketten, en zet ze in je Python-omgeving. Dat kan `requests` zijn, dat kan een interne tool zijn die nog nergens staat, dat kan een ontwikkelversie rechtstreeks uit een Git-repository.
Het lost daarbij de afhankelijkheden op. Als pakket A pakket B nodig heeft en B op zijn beurt C, dan regelt pip dat. Dat is precies waar vroeger de "dependency hell" zat: handmatig versies uitzoeken die met elkaar overweg konden. pip doet dat nu voor je, en breekt de hele installatie af als er ergens iets misgaat. Geen half geïnstalleerde rommel.
Dat is de basis. De keuzes zitten ergens anders.
Het eerste wat je moet beslissen: waar staat je Python?
Op moderne systemen heb je `pip` en `pip3`. Ze doen hetzelfde, maar `pip` kan op oudere configuraties naar Python 2 wijzen. Python 2 is sinds 2020 einde verhaal, dus in de praktijk gebruik je `pip3` als je zeker wilt weten dat je Python 3 raakt. Op een schone installatie maakt het niet uit. Op een server waar iemand ooit iets heeft achtergelaten, wel.
Dan de systeemvraag. Op Debian en Ubuntu beheert `apt` de Python-pakketten die bij het systeem horen. Die zijn getest, gepatcht en passen bij de rest van de distributie. Ze zijn ook ouder. Soms veel ouder. pip geeft je de actuele versie van PyPI, maar buiten het beheer van `apt` om. Dat is de ruil: recenter tegen minder systeemintegratie.
Op een productieserver waar stabiliteit zwaarder weegt dan de nieuwste versie, is `apt` vaak de betere keuze. Op een ontwikkelmachine waar je een specifieke versie nodig hebt, wint pip. Er is geen regel die voor beide geldt.
De echte vraag: waarom zou je pip systeemwijd draaien?
Het antwoord is meestal: dat wil je niet.
Een virtuele omgeving, gemaakt met `venv` of `virtualenv`, isoleert je pakketten per project. Project A kan `django==4.2` gebruiken, project B `django==5.0`, en ze weten niets van elkaar. Zonder die isolatie overschrijft de een de ander, en dan zoek je op een vrijdagmiddag waarom je tests ineens omvallen.
pip maakt zelf geen virtuele omgevingen aan. Het werkt er wel mee samen. Activeer een omgeving en pip installeert lokaal, niet in het systeem. Dat is de standaardwerkwijze in professionele ontwikkeling, en het is de reden dat de waarschuwing "externally-managed-environment" bestaat: moderne distributies willen voorkomen dat je per ongeluk het systeem-Python om zeep helpt.
De kosten zijn reëel. Je moet per project een omgeving aanmaken, activeren, en de dependencies bijhouden. Wie één script draait op een wegwerpmachine heeft daar niets aan. Wie tien projecten naast elkaar onderhoudt, kan niet zonder.
Wat pip niet doet
pip beheert geen systeembibliotheken. Als een Python-pakket een C-bibliotheek nodig heeft, moet die via `apt` of een andere systeempakketbeheerder komen. pip installeert alleen Python-spullen.
pip kan ook niet netjes terugrollen. Een upgrade terugdraaien betekent handmatig de oude versie installeren. Voor complexere situaties bestaan `pip-tools`, `poetry` en `conda`, die elk een hoger niveau van beheer bieden — en elk hun eigen leercurve en eigenaardigheden meebrengen. Soms is dat de moeite. Soms is het een extra laag die je op zondagavond staat te debuggen.
Wat pip wel goed doet: reproduceren. Met `pip freeze` exporteer je alle geïnstalleerde pakketten met exacte versienummers naar een `requirements.txt`. Iemand anders draait `pip install -r requirements.txt` en krijgt dezelfde omgeving. Dat is de basis van reproduceerbare builds en continue integratie, en het is een van de weinige dingen waar de hele Python-wereld het over eens is.
Offline en achter een firewall
In netwerken zonder internettoegang — denk aan overheidsomgevingen of streng afgeschermde bedrijven — kun je pakketten vooraf downloaden als `.whl`- of `.tar.gz`-bestand en lokaal installeren. pip ondersteunt dat zonder morren. Ook pakketten direct uit een Git-repository halen werkt, wat handig is voor interne tools die nooit op PyPI komen.
Beide scenario's vragen wel dat je weet wat je doet. Een lokale installatie uit een `.whl` werkt alleen als alle afhankelijkheden ook aanwezig zijn. pip lost niets op wat er niet is.
Dus wat kies je?
Systeemwijd pip draaien op Debian is vragen om problemen, tenzij je precies weet wat je doet en waarom. `apt` is dan de rustigere route, met oudere pakketten als prijs. Virtuele omgevingen met pip zijn de standaard voor ontwikkeling, maar kosten je de moeite van het opzetten en bijhouden per project. Containers maken het weer anders: daar is pip in de image juist volstrekt normaal, want de isolatie zit al in de container zelf.
Wat je kiest hangt af van hoeveel projecten je naast elkaar draait, hoe streng je omgeving is, en of je iemand kunt bellen als het misgaat. Op een laptop met één script is dat antwoord anders dan op een productieserver met tien services. pip is in beide gevallen hetzelfde gereedschap. De vraag is alleen of jij degene bent die het vasthoudt, of het systeem dat om je heen is gebouwd.