6 minuten leestijd · 29 januari 2026
Microsoft Fabric is een aantrekkelijke keuze voor datateams die snel willen itereren. Maar voor wie uit een code-first wereld komt, is het “DevOps-gat” in Fabric een serieuze frustratie.
Hoe dwing je PEP8 af, draai je unit tests en bewaak je codeconsistentie als je logica opgesloten zit in notebooks?
Dit probleem bestaat al langer, maar het modieuze antwoord is tegenwoordig: “gebruik gewoon een AI-agent die het oplost.”
Alleen: tussen dataprivacy, internationale dataresidency, en het risico op hallucinaties, voegt AI vaak vooral complexiteit toe — en die hebben we niet nodig.
Het goede nieuws: omdat Fabric notebooks nu via Git synchroniseert als vrijwel interoperabele Python-bestanden, kunnen we een robuuste, local-first CI/CD-pipeline bouwen met Ruff, Pytest en de Python AST-module (Abstract Syntax Tree).
Zonder AI. Gewoon vakwerk.
De filosofie: waarom “saaie” tooling wint
Als Senior Data Engineers willen we een pipeline die deterministisch, snel en begrijpelijk is. Geen magie, geen verrassingen. Het doel is een workflow die:
-
Consistentie afdwingt
Geen discussies meer over regellengtes of formatting. -
Modulariteit stimuleert
Code die niet in een functie of class zit, is nauwelijks testbaar. Dat dwingt betere gewoontes af. -
Leesbaarheid verbetert
De meeste tijd besteed je aan code lezen. Modulaire, gelinte code is simpelweg goedkoper in onderhoud. -
Onafhankelijk blijft
Geen API-calls naar externe diensten. Alleen pure Python op je build agent.
Door dit in je eigen Git-omgeving te regelen (Azure DevOps, GitHub, GitLab) houd je volledige controle.
Vergeleken met AI-agents hebben “saaie” tools bovendien duidelijke voordelen:
-
Geen hallucinaties – de linter volgt PEP8, geen gokwerk.
-
Geen API-kosten – je gebruikt CPU-cycles die je al betaalt.
-
Geen governance-nachtmerrie – gevoelige data blijft binnen je vertrouwde Git-omgeving.
Deel 1: de “magie” uit notebooks linten
Fabric-notebooks zitten vol magic commands (%pip, %sql, %run). Handig voor snelheid, funest voor standaard linters zoals Ruff — die crashen direct.
De oplossing: de preamble-strategie
We verbergen magic commands tijdelijk, zonder te vergeten waar ze stonden.
Dat doen we door regels die met % beginnen te prefixen met een unieke comment marker, bijvoorbeeld:
Waarom die drie pipes (|||)?
Als Ruff regels toevoegt of verwijdert, hebben we een waterdichte manier nodig om onze magic commands terug te vinden. Met een unieke preamble kunnen we ze na het linten altijd exact herstellen.
Implementatie in Python:
Over multi-line magics
IPython staat technically toe dat magic commands meerdere regels beslaan met backslashes.
Maar eerlijk: als je dat doet, bouw je een onderhoudsprobleem. Houd je magics simpel en je Python-logica modulair. Tijd verspild aan onleesbare code is duurder dan welke compute dan ook.
De pipeline-flow
-
Transformeren –
%→#||| % -
Linten & fixen –
ruff check --fix file.py -
Herstellen –
#||| %→% -
Committen – als er wijzigingen zijn, commit de pipeline ze terug
Voorbeeld output:
Pro-tip: vertrouw je het niet dat een bot direct commit?
Laat de pipeline een aparte branch maken (fix/linting-XYZ) en open automatisch een PR. Een mens klikt nog steeds op merge — veilig én schaalbaar.
Zo zeurt je pipeline niet over technische schuld.
Hij lost ’m op.
Deel 2: unit testen zonder de “Run All”-ellende
Notebooks testen is lastig. Een import voert vaak het hele notebook uit.
Als daar een zware Spark-job in zit, mag je 20 minuten wachten tot je test faalt — voor één helperfunctie.
De oplossing: de AST (Abstract Syntax Tree)
In plaats van het bestand uit te voeren, parsen we het met Python’s ast-module.
We zoeken gericht naar:
- functies
- classes
- imports
Die halen we los uit het notebook en laden we in de test-scope, zonder top-level code te triggeren.
Wat levert dit op?
-
De “modulariteitswortel”
Alleen code in functies en classes wordt getest. Losse rommel bovenin telt niet mee. -
Geen side-effects
Geenif __name__ == "__main__"-constructies of hacks om executie te voorkomen.
Echte Spark, lokale snelheid
Geen zware mocks.
We starten lokaal een single-node Spark-sessie op de build agent (Azure DevOps of GitHub Actions).
Spark + Delta installeren gaat verrassend snel op moderne agents.
Je test echte transformaties en schema-logica, zonder Fabric-capaciteit te gebruiken.
Tests
Met toegang tot Spark en je notebook-functies kun je tests schrijven — zelfs in notebook-vorm, zoals je in Fabric gewend bent.
Wat je test, en hoe je dat onderhoudbaar doet, verdient een aparte blog.
conclusie
Dat Fabric notebooks opslaat als transparante Python-bestanden is een cadeautje voor Data Engineers.
Het maakt het mogelijk om bewezen software-engineering-principes toe te passen, zonder de snelheid van notebooks te verliezen.
Met AST voor selectief testen en een simpele preamble voor magic commands slaan we een brug tussen rapid prototyping en productie-kwaliteit.
Het resultaat: een consistente, onderhoudbare codebase — zonder extra complexiteit. En zonder hallucinaties.
"*" geeft vereiste velden aan
