Onderzoekssoftware en reproduceerbaarheid

Hoe maak je een Jupyter notebook die ook over vijf jaar nog werkt

Lieke de Vries Lieke de Vries
· · 8 min leestijd

Stel je voor: je opent een Jupyter notebook van vijf jaar geleden.

Inhoudsopgave
  1. Waarom breken notebooks zo snel?
  2. Vergrendel je omgeving met dependency management
  3. Maak je notebook portable met containers
  4. Schrijf robuuste code in je notebook
  5. Versiebeheer is geen optie, het is verplicht
  6. Test je notebook regelmatig
  7. Documenteer alsof je het voor een vreemde schrijft
  8. De samenvatting: je vijf-stappenplan
  9. Veelgestelde vragen

Je drukt op "Run All" en… niets werkt. Errors over errors. Pakketten die niet meer bestaan. Python-versies die niet meer matchen. Klinkt herkenbaar? Geen zorgen, daar gaan we vandaag iets aan doen.

Als onderzoeker wil je dat je werk herhaalbaar blijft. Dat is letterlijk het doel van reproduceerbaar onderzoek.

Maar hoe zorg je ervoor dat je notebook over vijf jaar nog draait alsof het gisteren is geschreven?

Hier zijn de strategieën die écht werken.

Waarom breken notebooks zo snel?

Voordat we ingaan op de oplossingen, is het goed om te begrijpen waarom notebooks kapotgaan.

Het probleem zit hem bijna altijd in de omgeving, niet in je code zelf. Python-pakketten worden continu bijgewerkt. Een functie die vandaag werkt, kan over zes maanden hernoemd of verwijderd zijn.

Python zelf evolueert ook: code geschreven voor Python 3.7 kan problemen geven op Python 3.12. En als je gebruikmaakt van externe API's of datasets, kunnen die URL's gewoon verdwijnen.

Kortom: de wereld om je notebook heen verandert voortdurend. Jij kunt dat niet stoppen, maar je er wel op voorbereiden.

Vergrendel je omgeving met dependency management

Dit is verreweg de belangrijkste stap. Je moet exact vastleggen welke versies van pakketten je gebruikt.

Gebruik altijd een requirements.txt of environment.yml

Een simpele requirements.txt is een goed begin. Maar nog beter: gebruik een environment.yml bestand als je met Conda werkt. Dit bestand legt niet alleen pakketversies vast, maar ook de Python-versie zelf. Zie het als een foto van je complete werkplek.

Iemand anders (of jijzelf over vijf jaar) kan die foto gebruiken om exact dezelfde werkplek op te bouwen. Voor serieuzere projecten zijn tools als Poetry of pip-tools een enorme upgrade.

Ga verder met Poetry of pip-tools

Deze tools maken een lock-bestand aan dat exact vastlegt welke versies van alle pakketten — inclusief sub-afhankelijkheden — zijn geïnstalleerd.

Geen onverwachte verrassingen meer.

Maak je notebook portable met containers

Wil je echt zeker zijn? Stop je complete omgeving in een container.

Docker: je notebook in een doos

Met Docker pak je alles in: besturingssysteem, Python-versie, alle pakketten, alles. Je notebook draait dan in een geïsoleerde omgeving die nergens van verandert.

De Jupyter Docker Stacks bieden kant-en-klare images die je direct kunt gebruiken. De leercurve is best steil, maar de garantie die je krijgt is ongeëvenaard. Over tien jaar nog steeds werkend?

Binder: de low-effort optie

Met Docker geen probleem. Als Docker te zwaar is, probeer Binder (binder.mybinder.org). Je uploadt je notebook en configuratiebestanden naar een repository, en Binder bouwt automatisch een draagbare omgeving. Iedereen kan dan je notebook online openen en uitvoeren — zonder iets te installeren.

Schrijf robuuste code in je notebook

Zelfs met een perfecte omgeving kan je notebook falen als de code zelf kwetsbaar is. Nooit absolute paden gebruiken zoals C:/Users/Jan/project/data.csv.

Harde paden zijn je vijand

Gebruik relatieve paden en zorg dat de mappenstructuur bij het project hoort.

Check je aannames expliciet

Nog beter: gebruik het pathlib pakket, dat paden platform-onafhankelijk maakt. Voeg controles toe aan het begin van je notebook. Controleer of bestanden bestaan, of je werkt met beheerde Conda environments voor reproduceerbare analyses, of de juiste Python-versie draait, of vereiste kolommen in je dataset aanwezig zijn.

Vermijd deprecated functies

Een paar regels code aan het begin kan uren debuggen besparen aan het eind. Houd je code bij met de nieuwste versies van je gebruikte bibliotheken. Als je een waarschuwing ziet over een functie die "deprecated" is, vervang die dan meteen. Die waarschuwingen zijn letterlijk voorspellingen van toekomstige errors.

Versiebeheer is geen optie, het is verplicht

Gebruik Git voor al je notebooks. Ja, zelfs als je alleen werkt.

Git geeft je een complete geschiedenis van elke wijziging, en je kunt altijd terug naar een werkende versie. Combineer dit met een platform als GitHub of GitLab, en je hebt automatisch een back-up én een manier om je werk te delen. Tip: gebruik nbdime of jupytext om diffs van notebooks leesbaar te maken. Standaard notebook-diff's zijn namelijk onleesbaar omdat notebooks JSON-bestanden zijn.

Test je notebook regelmatig

Klinkt misschien overdreven voor een notebook, maar het is het waard. Wil je meer weten over computational notebooks voor reproduceerbaar onderzoek?

Automatiseer de test met nbconvert of pytest

Je kunt een notebook automatisch laten draaien met nbconvert of met het nbval pakket (een pytest-plugin).

Voer periodiek een "herstel-draai" uit

Zo test je of het notebook nog werkt zonder het handmatig te openen. Zet dit in een CI/CD-pipeline en je wordt gewaarschuwd zodra iets breekt. Plan eens per halfjaar in om je notebook op een schone omgeving te draaien.

Installeer de laatste pakketversies, voer alles uit, en repareer wat breekt. Dit kost misschien een uur per jaar en bespaart je enorme problemen op de lange termijn.

Documenteer alsof je het voor een vreemde schrijft

Over vijf jaar ben je die vreemde. Schrijf dus helder uit wat je notebook doet, waarom je bepaalde keuzes hebt gemaakt, en hoe iemand het moet uitvoeren.

Gebruik Markdown-cellen ruim leg uit wat er gebeurt. Voeg een "Setup" sectie toe aan het begin met instructies voor het installeren van de omgeving.

En documenteer ook wat niet werkt of waar je tegenaan loopt — die informatie is goud waard voor je toekomstige zelf.

De samenvatting: je vijf-stappenplan

Wil je een notebook bouwen die de tand des tijds doorstaat? Dit is je checklist:

Eén: Leg alle dependencies vast met een lock-bestand (Poetry, pip-tools, of ten minste een pinned requirements.txt).
Twee: Overweeg Docker of Binder voor maximale portabiliteit.
Drie: Schrijf robuuste code met relatieve paden en expliciete controles.
Vier: Gebruik Git voor versiebeheer en deel je werk op een platform.
Vijf: Test regelmatig en documenteer alles helder. Geen enkele van deze stappen is moeilijk. Maar samen maken ze het verschil tussen een notebook dat over vijf jaar nog draait en een dat alleen nog frustratie oplevert. Begin vandaag — je toekomstige zelf zal je bedanken.

Veelgestelde vragen

Waarom werken notebooks soms niet meer na een tijdje?

Notebooks kunnen na verloop van tijd niet meer werken omdat de omgeving waarin ze draaien verandert. Python-pakketten worden bijgewerkt, API's verdwijnen en de Python-versie kan incompatibel worden met de code die je eerder hebt geschreven.

Wat is dependency management en waarom is het belangrijk voor notebooks?

Het is belangrijk om dit te voorkomen door je omgeving te ‘bevriezen’.

Hoe kan ik de afhankelijkheden van mijn notebook vastleggen?

Dependency management houdt in dat je precies vastlegt welke versies van alle benodigde pakketten je gebruikt. Dit zorgt ervoor dat je notebook over een paar jaar nog steeds draait, zonder onverwachte problemen door updates of veranderingen in de omgeving. Het is essentieel om reproduceerbaarheid te garanderen.

Wat zijn Docker en hoe kan het helpen bij het maken van een portable notebook?

Je kunt de afhankelijkheden van je notebook vastleggen met tools zoals `requirements.txt` (voor een eenvoudige oplossing) of `environment.yml` (voor Conda-omgevingen), die de Python-versie en alle pakketten met hun versies vastleggen. Dit creëert een ‘foto’ van je werkplek.

Zijn er alternatieven voor Docker om mijn notebook portable te maken?

Docker is een manier om je hele omgeving – inclusief besturingssysteem, Python en alle pakketten – in een container te verpakken. Dit zorgt ervoor dat je notebook altijd op dezelfde manier draait, ongeacht waar je het uitvoert, en dat het niet wordt beïnvloed door veranderingen in de hostomgeving. Ja, als Docker te complex is, kun je Binder gebruiken. Binder stelt je in staat om je notebook online te delen en te draaien, zonder dat je Docker hoeft te installeren. Het is een handige optie voor het delen van notebooks met anderen, maar minder controle over de omgeving.


Lieke de Vries
Lieke de Vries
Expert in Open Science principes

Lieke adviseert onderzoekers over het publiceren van FAIR data volgens de nieuwste normen.

Meer over Onderzoekssoftware en reproduceerbaarheid

Bekijk alle 28 artikelen in deze categorie.

Naar categorie →
Lees volgende
Waarom onderzoekssoftware ook FAIR moet zijn en niet alleen jouw data
Lees verder →