De AI-engineer track, en ontwikkelomgevingen met uv
Python installeren, waarom uv in plaats van pip, en een geïsoleerde, reproduceerbare omgeving voor elk project met uv init, uv add en uv run — plus de juiste interpreter in je editor.
Hoe wil je leren?
Het probleem dat we oplossen
Een nieuwe AI-engineer komt bij een team. De eerste taak is simpel: het project draaien op de eigen laptop. De README zegt "voer python main.py uit". Dat doet de collega, en dan krijgt die ModuleNotFoundError: No module named 'httpx'. Op de machine van de persoon die het project schreef, werkt hetzelfde commando perfect.
Als je er dieper induikt, blijkt dat er al twee jaar elk pakket in dezelfde Python terechtkomt dat ooit door een project op de machine van de auteur nodig was. Welke pakketten dit project nodig heeft, staat nergens opgeschreven — er is alleen "het werkt op mijn machine". De nieuwe collega besteedt een halve dag aan het zoeken en installeren van pakketten, één voor één, en aan het eind is één ervan een andere versie, dus de resultaten verschillen ook.
Professionele teams hebben één antwoord hierop: elk project krijgt zijn eigen geïsoleerde omgeving, en wat die omgeving bevat, staat in een bestand. Zo kan iedereen met één commando exact dezelfde omgeving bouwen. Dat bouwen we in dit hoofdstuk — met uv — en dat gebruiken we de rest van de cursus.
Aan het einde van dit hoofdstuk kun je
- Python installeren met de gewone installer én met
uv python install, en uitleggen hoe die twee verschillen - Uitleggen wat
pipis en waarom deze cursusuvgebruikt - Een geïsoleerde projectomgeving maken en draaien met
uv init,uv add,uv runenuv venv - Met een voorbeeld laten zien waarom projecten niet op de systeem-Python moeten draaien
- De eigen interpreter van het project kiezen in VS Code of PyCharm
Wat je eerst nodig hebt: van map kunnen wisselen in een terminal (met cd) en een commando kunnen uitvoeren. Dit is het eerste hoofdstuk van de cursus, dus verder is niets nodig.
Hoe deze track werkt
Deze cursus is een career track. Elk hoofdstuk is als één les, en elk eindigt met een opdracht die je op je eigen machine uitvoert. De eerste hoofdstukken leggen de basis van professioneel werk — omgevingen, Git, projectstructuur, configuratie. Daarna volgen zuivere Python, testen, API's, databases, RAG, beveiliging en deployment.
Eén ding is goed om van tevoren te zeggen: bij een bedrijf wordt de code van een AI-engineer niet geaccepteerd omdat hij "draait". Of iemand anders hem op zijn of haar machine kan draaien, of iemand hem kan reviewen, of iemand hem over zes maanden nog begrijpt — dat hoort er ook bij. Daarom is elke praktijkopdracht in deze cursus opgezet alsof de code in de repository van een echt team terechtkomt. En de eerste stap van die werkwijze is de omgeving.
Python installeren: twee routes
Route één — de gewone installer. Download de 3.12-installer van python.org en voer hem uit. Op Windows vink je op het allereerste scherm Add python.exe to PATH aan; zonder dat herkent de terminal het commando python niet. Op macOS is het .pkg-bestand van python.org voldoende. Op Linux is python3 meestal al aanwezig — en daarover volgt hieronder een waarschuwing.
Om te controleren:
python --version
Python 3.12.0Op macOS en Linux is het commando vaak python3 --version.
Route twee — met uv. uv is één tool die Python-versies, projectomgevingen en pakketten beheert. Installeer eerst uv. Op macOS en Linux:
curl -LsSf https://astral.sh/uv/install.sh | shIn Windows PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Open daarna een nieuwe terminal:
uv --version
uv 0.9.1 (9887ef5bd 2025-10-09)Jouw versienummer kan anders zijn. Nu Python:
uv python install 3.12
Installed Python 3.12.11 in 27.42s
+ cpython-3.12.11-windows-x86_64-none (python3.12.exe)De tijd en de platformnaam aan het eind zijn op jouw machine anders. Let erop dat de Python die uv installeert in een eigen map staat: die raakt de hoofd-Python van de machine niet aan, en verandert PATH niet.
De twee routes kunnen naast elkaar bestaan, en beide werken voor deze cursus. Het verschil: de gewone installer geeft je één Python voor de hele computer; uv python install geeft je Pythons die projecten kiezen naar behoefte. Het ene project wil 3.12, het andere 3.13 — geen van beide komt de ander in de weg.
Wat pip is, en waarom we uv gebruiken
Externe pakketten voor Python — httpx, pydantic, fastapi — staan in een repository die PyPI heet. Het traditionele hulpmiddel om ze op te halen is pip, dat bij Python zit. Bijna elke tutorial op internet gebruikt pip install ....
pip werkt goed, maar het doet maar één ding: pakketten installeren. En het installeert ze in de Python waarmee het is gestart. Voor een professioneel project was al het andere een apart hulpmiddel nodig:
- de juiste Python-versie krijgen — een apart hulpmiddel
- een geïsoleerde omgeving maken en activeren —
python -m venv, en daarna met de handactivate - bijhouden wat het project nodig heeft — met de hand, in een bestand, en dat wordt vaak vergeten
- precies vastleggen welke versie van elk pakket is gebruikt (een lockfile) — weer een ander hulpmiddel
uv doet alle vier in één tool, en veel sneller. Het belangrijkste: als je met uv add iets toevoegt, wordt het automatisch in het bestand van het project geschreven. "Ik heb het geïnstalleerd, maar vergeten op te schrijven" — de oorzaak van de problemen van de nieuwe collega hierboven — kan zo niet gebeuren.
Dus waar in deze cursus pakketten of omgevingen aan bod komen, is het uv. Als je ergens anders pip install ziet, is de uv-variant bijna altijd uv add.
Waarom de systeem-Python niet de plek is voor projecten
De "systeem-Python" is de Python die direct op de computer is geïnstalleerd — degene die start als je python typt in een terminal zonder een omgeving te activeren. Pakketten van een project daarin installeren geeft drie problemen:
- Iedereen deelt één kamer. Het ene project heeft
pydantic1 nodig, het andere 2. De systeem-Python kan er maar één bevatten, dus als je het ene project repareert, breek je het andere. - Afhankelijkheden worden onzichtbaar. Het pakket was al geïnstalleerd voor een oud project, dus het nieuwe project draait — maar nergens in het project staat dat het dat pakket nodig heeft. Op jouw machine verschijnt geen foutmelding; de fout verschijnt op de machine van een collega, of op de server.
- Het besturingssysteem gebruikt hem. Op macOS en Linux draaien sommige systeemprogramma's op die Python. Als je de pakketten ervan verandert, kunnen die stuk gaan — daarom blokkeren recente Linux-versies het direct installeren in de systeem-Python.
Het tweede probleem is het gevaarlijkst, omdat het stil is. De systeem-Python op de machine waarop dit hoofdstuk is geschreven heeft nog httpx, pydantic en rich over van oud werk. Elk script "draait" daar dus — en precies daarom kun je op die manier niet zien wat een script echt nodig heeft.
De misvatting is: "Het draait op mijn machine, dus het is in orde." Een script dat op de systeem-Python draait, bewijst alleen dat het pakket op een bepaald moment op jouw machine is geïnstalleerd. Wat het project zelf nodig heeft, bewijs je pas als alles vanuit het eigen bestand van het project in een lege omgeving is geïnstalleerd, en het script daarna draait.
Een eerste project met uv
Vanuit je werkmap:
uv init hello-ai --python 3.12
Initialized project `hello-ai` at `D:\ai-lab\hello-ai`(Het pad aan het eind is jouw eigen map; de voorbeelduitvoer in dit hoofdstuk verkort paden.) uv init maakt een nieuwe map aan, en daarin staat:
hello-ai/
├── .git/
├── .gitignore
├── .python-version
├── README.md
├── main.py
└── pyproject.tomlHet belangrijkste hiervan is pyproject.toml — de identiteitskaart van het project:
[project]
name = "hello-ai"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []dependencies = [] — het project heeft nog geen pakketten van buiten nodig. .python-version bevat alleen 3.12: welke Python dit project gebruikt. En uv init heeft een Git-repository en een .gitignore voor je aangemaakt — die komen in het volgende hoofdstuk aan bod.
Nu draaien:
cd hello-ai
uv run main.py
Using CPython 3.12.11
Creating virtual environment at: .venv
Hello from hello-ai!Bij de eerste keer maakte uv run zelf een map .venv aan — dat is de geïsoleerde omgeving van het project — en draaide daarna main.py met de Python van die omgeving. Je hoefde niets te activeren.
uv add: een pakket toevoegen, en het opschrijven
Bijna elk project waar een AI-engineer aan werkt, roept een API aan. Het eerste pakket is dus de HTTP-client httpx, plus python-dotenv om .env-bestanden te lezen:
uv add httpx python-dotenv
Resolved 9 packages in 119ms
Installed 8 packages in 92ms
+ anyio==4.15.1
+ certifi==2026.7.22
+ h11==0.16.0
+ httpcore==1.0.9
+ httpx==0.28.1
+ idna==3.20
+ python-dotenv==1.2.3
+ typing-extensions==4.16.0Je vroeg om twee pakketten en kreeg er acht — de rest zijn de eigen afhankelijkheden van httpx, die uv zelf heeft uitgezocht. De versienummers kunnen nieuwer zijn wanneer jij dit doet.
Kijk nu eens in pyproject.toml:
[project]
name = "hello-ai"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"httpx>=0.28.1",
"python-dotenv>=1.2.3",
]Eén commando deed drie dingen: de pakketten werden in .venv geïnstalleerd, pyproject.toml legt nu vast dat het project ze nodig heeft, en er verscheen een nieuw bestand uv.lock dat de exacte versie van alle acht pakketten vastlegt. Lockfiles komen verderop in de cursus uitgebreid aan bod; voor nu is het genoeg om te weten dat een collega die de repository kloont en uv sync draait precies deze acht versies krijgt.
Om iets te verwijderen gebruik je uv remove:
uv remove python-dotenv
Resolved 8 packages in 21ms
Uninstalled 1 package in 11ms
- python-dotenv==1.2.3Ook dit werkt op beide plekken: het pakket verdwijnt uit .venv en wordt uit pyproject.toml gehaald.
uv venv, en met de hand activeren
uv run maakt en gebruikt de omgeving voor je, dus in deze cursus is dat bijna altijd genoeg. Soms heb je alleen een lege omgeving nodig — bijvoorbeeld in een oud project dat nog geen pyproject.toml heeft. Dan:
uv venv --python 3.12
Using CPython 3.12.11
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activateDie laatste regel komt uit Windows PowerShell. Hier verschillen de besturingssystemen:
# Windows (PowerShell)
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activateEenmaal actief begint de prompt met (hello-ai) of (.venv), en een gewoon python-commando draait de Python van die omgeving. Om te stoppen: deactivate. Onthoud dat je met uv run niets van dit alles nodig hebt — dat is het voordeel. uv run in de README van een team is de veilige keuze, omdat je niet kunt vergeten te activeren.
De editor naar de Python van het project laten wijzen
Het programma draait in de terminal, maar de editor zet een rode streep onder import httpx — dat betekent bijna altijd dat de editor naar een andere Python kijkt.
VS Code: installeer de Python-extensie van Microsoft. Open daarna de projectmap, druk op Ctrl + Shift + P (Cmd + Shift + P op macOS) → Python: Select Interpreter → kies de Python in .venv. Staat hij niet in de lijst, gebruik dan Enter interpreter path en wijs ernaar: .venv\Scripts\python.exe op Windows, .venv/bin/python op macOS/Linux.
PyCharm: Settings → Project → Python Interpreter → Add Interpreter → Add Local Interpreter → kies een bestaande omgeving en geef hetzelfde pad. Recente versies bieden ook direct een uv-omgevingstype aan.
De makkelijkste manier om zeker te weten welke Python de editor gebruikt, is dit uitvoeren in de ingebouwde terminal van de editor:
import sys
print(sys.executable)Het pad moet eindigen in de .venv van je project — bijvoorbeeld ...\hello-ai\.venv\Scripts\python.exe. Het begin van het pad hangt af van je map, dus de volledige uitvoer staat hier niet.
Een compleet voorbeeld
Maak in het project hello-ai een bestand aan dat env_check.py heet. Het is een kleine "omgevingscontrole" — wanneer iemand nieuw in een team komt, bevestigt zoiets als dit eerst dat alles staat waar het hoort:
import sys
from importlib.metadata import version
from pathlib import Path
def main() -> None:
in_venv = sys.prefix != sys.base_prefix
print(f"Python : {sys.version_info.major}.{sys.version_info.minor}")
print(f"In a venv : {in_venv}")
print(f"Env folder : {Path(sys.prefix).name}")
import httpx # installed with `uv add httpx`
print(f"httpx : {version('httpx')}")
print(f"Client ready: {httpx.Client is not None}")
print("Hello, AI engineer.")
if __name__ == "__main__":
main()Draai het vanuit het project:
uv run env_check.pyPython : 3.12
In a venv : True
Env folder : .venv
httpx : 0.28.1
Client ready: True
Hello, AI engineer.Nu draaien we hetzelfde bestand in een lege omgeving. Het bestand is naar een andere map gekopieerd, daar is met uv venv --python 3.12 een omgeving aangemaakt, en het bestand is direct gedraaid met de Python van die omgeving (.venv\Scripts\python env_check.py op Windows, .venv/bin/python env_check.py op macOS/Linux):
Python : 3.12
In a venv : True
Env folder : .venv
Traceback (most recent call last):
File "env_check.py", line 20, in <module>
main()
File "env_check.py", line 12, in main
import httpx # installed with `uv add httpx`
^^^^^^^^^^^^
ModuleNotFoundError: No module named 'httpx'(Op jouw machine toont de traceback het volledige pad van het bestand; hier is alleen de naam overgenomen.)
Een paar keuzes in dit script zijn het waard om op te merken.
sys.prefix != sys.base_prefix — Python zelf weet of het in een virtuele omgeving draait. sys.base_prefix is de basis-Python waarmee de omgeving is gemaakt, en sys.prefix is degene die nu draait. Als ze verschillen, sta je in een omgeving.
De mapnaam, niet het volledige pad — Path(sys.prefix).name drukt alleen het laatste deel af, .venv. Het volledige pad is op elke machine anders; de naam is voor iedereen gelijk. Hoe minder machinespecifiek de uitvoer van een controlescript is, hoe makkelijker die is te vergelijken in de teamchat.
import httpx midden in de functie — imports horen normaal bovenaan een bestand, en dat is ook goed. Hier staat hij bewust midden in de functie, zodat in een lege omgeving de eerste drie regels worden afgedrukt vóór de fout. De foutmelding vertelt dan haar eigen verhaal: Python 3.12 is in orde, er is een omgeving actief, maar die omgeving heeft geen httpx. De oplossing is uv add httpx — of, als de pyproject.toml van het project het al bevat, uv sync.
version('httpx') — importlib.metadata is de standaardmanier om de versie van een pakket te lezen. Niet elk pakket heeft een __version__, maar elk geïnstalleerd pakket heeft metadata.
Wanneer het breekt
The term 'uv' is not recognized as the name of a cmdlet, function, script file, or operable program (op macOS/Linux: uv: command not found) uv is geïnstalleerd, maar de terminal waarin je typt is geopend vóór de installatie, dus die kent het nieuwe PATH niet. Sluit de terminal en open hem opnieuw (en in VS Code: de hele editor).
error: No pyproject.toml found in current directory or any parent directory Je hebt uv add buiten een projectmap uitgevoerd. uv add schrijft naar het bestand van het project, dus zonder project is er niets om naar te schrijven. Ga met cd naar het project, of voer eerst uv init uit als het project nieuw is.
ModuleNotFoundError: No module named 'httpx' De Python die het script draait heeft het pakket niet. Twee gebruikelijke oorzaken: het pakket is nooit met uv add toegevoegd, of het script is met gewoon python gestart in plaats van met uv run, waardoor de systeem-Python draaide in plaats van de omgeving van het project. Draai het met uv run env_check.py.
error: Failed to spawn: hello.py gevolgd door Caused by: program not found Je hebt uv run een bestandsnaam gegeven die niet in de huidige map staat — meestal een spelfout, of je staat in de verkeerde map. Omdat het bestand niet is gevonden, zocht uv naar een programma met die naam, vandaar dat het bericht vreemd klinkt.
× No solution found when resolving dependencies gevolgd door Because htpx was not found in the package registry ... Een spelfout in de pakketnaam (htpx). Het goede nieuws: een mislukte uv add verandert niets — pyproject.toml en uv.lock blijven zoals ze waren. Verbeter de spelling en voer het opnieuw uit.
.venv\Scripts\activate : File ... cannot be loaded because running scripts is disabled on this system Een beveiligingsinstelling van PowerShell. Voer één keer Set-ExecutionPolicy -Scope CurrentUser RemoteSigned uit en open een nieuwe terminal — of sla het activeren over en draai alles met uv run.
Stap 4 van 6 — Voorspellen
Test je begrip
Dit bestand wordt opgeslagen als check.py in het project hello-ai en uitgevoerd met uv run check.py. Wat wordt geprint?
import sys
print(sys.prefix != sys.base_prefix)
print(sys.version_info.major)- A`.venv`, daarna `3.12`
- B`True`, daarna `3`
- C`True`, daarna `12`
- D`False`, daarna `3`
Het pyproject.toml van het project noemt httpx, en uv.lock staat in de repository. Toch krijgt een nieuwe collega die de README volgt op een gloednieuwe laptop ModuleNotFoundError: No module named 'httpx'. Waar zit de fout in de README?
# README of a team project, "How to run" section:
# 1. git clone <repo-url>
# 2. cd summarizer
# 3. python main.py
import httpx
print("client:", httpx.Client.__name__)- AEen stap die `uv init` na de clone uitvoert ontbreekt
- BDe collega moet eerst `uv add httpx` uitvoeren, en daarna `python main.py`
- CDe regel `import httpx` moet van de bovenkant van het bestand naar een functie `main()` verhuizen
- DStap 3 draait de systeem-Python; er moet `uv run main.py` staan, dat `.venv` bouwt op basis van `pyproject.toml` en `uv.lock` en erin draait
Na uv init en uv add heeft het project pyproject.toml, uv.lock, .python-version en .venv. Welke hiervan gaan in de Git-repository van het team?
- AAlles behalve `.python-version`, want de Python-versie is een persoonlijke keuze
- B`pyproject.toml`, `uv.lock` en `.python-version` gaan erin; `.venv` niet
- CAlle vier, inclusief `.venv`, zodat collega's niets hoeven te installeren
- DAlleen `pyproject.toml`; `uv.lock` wordt gegenereerd, dus die laat je ook weg
Spelen hoort bij Pro
+30 XP wacht op je
Speel dit hoofdstuk met Pro
Lezen is gratis en het hele hoofdstuk is open. De eerste 5 hoofdstukken van elke gratis cursus speel je gratis. Vanaf hoofdstuk 6 horen vragen beantwoorden, XP verdienen en je reeks laten groeien bij Pro.
Ontgrendel spelen met ProJouw beurt
Als uv en Python 3.12 klaarstaan op je machine, maak je een nieuw project:
- Maak het project met
uv init my-first-agent --python 3.12, en voeg één pakket toe metuv add httpx - Schrijf het bestand
env_check.pyhierboven precies over in het project, en draai het metuv run env_check.py - Open
pyproject.tomlen laat zien dathttpxonderdependenciesstaat, en dat er eenuv.lock-bestand in het project is aangemaakt - Open het project in VS Code of PyCharm en kies de
.venvvan het project als interpreter, zodat er geen rode streep staat onder de regelimport httpx
Verwachte uitvoer (de httpx-versie kan nieuwer zijn wanneer jij dit doet):
Python : 3.12
In a venv : True
Env folder : .venv
httpx : 0.28.1
Client ready: True
Hello, AI engineer.Breek het daarna opzettelijk: voer uv remove httpx uit en draai uv run env_check.py opnieuw. Schrijf op hoe ver het script komt, welke fout er verschijnt, en wat er in pyproject.toml is veranderd. Herstel het daarna met uv add httpx. Deze kapot-maak-en-herstel-oefening kost twee minuten, maar in je eerste week op je eerste baan bespaart ze je de meeste tijd.
Stap 6 van 6
Uitdaging — de hoofdstukquiz
Tien vragen van makkelijk naar moeilijk. De laatste zijn met opzet lastig.
Speel met Pro