Reinout van Rees’ weblog

Pycon NL keynote: sustaining open source for the future - Georgi Ker

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

This year is the first community-organized Pycon NL: hurray!

Most of us use open source as users. It is free! But all those open source projects only exist because someone started it and because someone maintains it.

“Care became contagious”: she told the story about someone in Mumbay, India that started to clean up plastic waste that covered the whole beach. He and a 84 year old neighbor. Slowly other people joined in. Then a lot more. Care became contagious!

Python started when Guido van Rossum made a new language in his Christmas holiday.

But projects like this are fragile. The beach cleanup (almost?) stopped after 109 weeks: administrative lethargy, heckling, etc. (She said it stopped, but I guess it almost stopped, as later on she had photos of a clean beach with newly-hatched turtles). If you start a nice open source project, you’re probably not thinking my dream is to answer Github issues for the next 20 years.

Sustainability is not endurance. Sustainability is regeneration. Joining a community, but also having the option to leave (just as an example).

Open source is safe. In open source project, code is public, knowledge is shared. A community. The community is the infrastructure. The community is the reason the code is trustworthy.

The Python software foundation holds the trademarks and licenses. Infrastructure like python.org, pypi, the documentation website. It hosts/helps conferences.

Pypi, the Python package index. 81.000 requests per second. And there are only two full-time security people working on it. Seth Larson and Mike Fiedler. We can call them heroes, but we might also look at Python’s growth compared to the growth of its human infrastucture.

Our human infrastructure hasn’t grown with Python’s growth. And AI is making it more urgent. AI can consume whatever the community has to offer or has ever offered. Without giving something back. AI companies capture our value…

Public spaces are not self-maintaining. They need funding and public responsibility.

In 2025, the United Nations published the UN Open Source Principles. Countries are taking note. For example, Germany has the Sovereign Tech Fund, that invests directly in the people behind the code, supporting maintainers, community managers and technical writers.

She started Open community Leadership, helping communities create future contributors and leaders. The foundation is POPCOM: participation (how to join), ownership (how to gain responsibility), purpose (why people stay), connection (how relationships form), opportunity (how contributors grow), mentorship (how communities reproduce).

Regeneration takes people, time and money.

Open source is better together.

https://reinout.vanrees.org/images/2026/pyconnl-9.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Extreme low water in the Rhine: the ‘beach’ on the left should be fully submerged.

Pycon NL: what’s inside an asyncio event loop? - Taras Kozlov

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

An asyncio event loop is defined by asyncio.AbstractEventLoop. That’s a large API with more than 50 public methods, but only three are fundamental. At the lowest useful leve, the loop manages callbacks, i/o and timers.

  • We need a way to put events on a queue and a way to grab events from a queue and execute them. call_soon()

  • We need timers too, for callbacks that must be run after some time. call_later()

  • Sleep only knows about time. Often we want to sleep until the next time, unless a socket becomes ready first. So we need a “sleep” that can be interrupted by I/O readiness. add_reader(), add_writer()

His own example implementation of asyncio for educational purposes is at: https://github.com/tarasko/eduloop , it is only 250 lines. Handy if you want to understand asyncio.

He showed this simple example code, incrementally implementing the points above.

The nice thing about asyncio is coroutines. A coroutine is an extended kind of function that can be paused and resumed. The result is a “future”. A future represents an eventual result of an async operation. So: a future is pending until somebody supplies either a result or an exception.

For network connection there’s Transport and Protocol.

https://reinout.vanrees.org/images/2026/pyconnl-8.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. St. Gereon church.

Pycon NL: building resumable Python pipelines - Yuvraj Singh Pathania

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

Full title: fire, forget, regret: building resumable Python pipelines.

If you run a task in an async loop, there’s often no reference to the task. So it can be garbage collected! You can solve that by keeping a reference in some list. But even then, the whole process can die. What happens with your task then?

Often you have to re-run the task. He himself is into LLMs, so failed tasks that you have to re-run can become expensive.

BackgroundTasks is part of FastAPI and it works great for spinning off longer running tasks. Real handy, but there is no retry mechanism and no recoverability in case of crashes. “Fire-and-forget”.

You can use specific task queues. ARQ, Celery, Dramatiq. In this case, the job itself is safe and can be re-tried. But not the individual steps within the job.

What he wants is durable execution. Write down every step you finish; on restart, skip what is written. It can save you lots of time (and possibly money). It might be simpler to set up than you think.

His code + slides are at https://github.com/batman004/fire-forget-regret

https://reinout.vanrees.org/images/2026/pyconnl-7.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Model of the oldest parts of the St. Gereon church.

Pycon NL: zero-downtime multi-tenancy in Django - Thiago Bellini Ribeiro

2026-10-15

Tags: python, pycon, django

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

Full title: zero-downtime multi-tenancy in Django: from user-centric to organizations-based architecture.

He works for Sendcloud. Originally their code was 2010-style Django. Every business object (Parcel, Order, etc) is linked to a django User. But… users can belong to organisations and organisations should be the ones connected to the business objects. Ok, they moved to a “core” user and “sub” users. But still users could only belong to a single organisation, for instance.

What they actually need is many users per organisation. And also many orgs per user. Roles per membership instead of per user. They designed a new system based upon this.

But: they had around 20 Django apps and 40 models with a link to user_id. How to migrate? The solution was to use a “proxy model”. They started an “organisation” model that simply was a differently named Django model, pointing at the same table as the existing user model. This allowed them to keep almost everything the same with only minimal database migrations.

After that, they moved a little bit of functionality over to the new organisation model. Again, a small, minimal database migration.

They did it incrementally. They had all those apps and models to work through. Slowly but surely they got it done. Small steps that are backwards compatible help a lot.

They introduced a mistake-finder: an OrganisationAware mixin that logged direct .user access in production and produced errors in development. This helped turn up usage of the user model that wasn’t findable through basic grepping and searching.

They also used libcst, an abstract syntax tree parser for python to go through the entire code and try and find corner cases where the old way of working was used.

In the end, everything was moved over to the real organisation model and the organisation-proxy wasn’t needed anymore, so they could remove it. They

https://reinout.vanrees.org/images/2026/pyconnl-6.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Of course there’s a Hohenzollern-on-a-horse statue near the Hohenzollernbridge! This one is Wilhelm II, the Kaiser during the first world war (who fled to the Netherlands, btw).

Pycon NL: practical software architecture for Python developers - Henk-Jan van Hasselaar

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

First some terminology. Cohesion and coupling for instance.

  • Cohesion means how much the elements in a module belong together. “Belonging together”: working towards the same goal or function. Watch out what your answer is: is there an “and” in the sentence. “This module reads data and puts it in the database”. That’s a sign of lower cohesion.

    Cohesion also has to do with your mental load: what can you keep in your head at the same time?

  • Coupling. Basically the blast radius: how much breaks when you change an object.

  • Change. Not often talked about. Architecture is more than diagrams. Architecture actually is making future changes cheaper. No change, no pain.

Loose coupling, high cohesion is good. Tightly coupled, low cohesion is bad.

Python allows us lots of freedom. There is no enforcement of architectural boundaries. You have type hints, but they’re not enforced. Python’s basic assumption is that we’re all reasonable and responsible programmers.

Let’s look at an example problem. We have “the internet” that calls “our REST API” that stores stuff in “our database”. We start with a single function in our API that queries the database and returns the results. But then we want to uncouple the data and the presentation layer: some ORM around the database table that is called by the view function (=the original API function). All fine. But… when the database changes, the ORM layer changes and then the view function needs to change. Coupling, anyone?

How can we fix this? By having some sort of contract between the layers. A domain model in between. A change in the database means a change in the part of the code that creates the domain object, but the view function is unaffected.

But such a view function often also contains business logic. That often means you’re doing some talking to the database anyway. A normal approach is to put that part of the code into some “service” layer. You can also start writing adapters: convert the core domain models to some output format.

Closing remarks:

  • Your business rules deserve a home!

  • Put them somewhere the outside world can’t hurt them.

https://reinout.vanrees.org/images/2026/pyconnl-4.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Organ in the St. Aposteln church.

Pycon NL: practical observability - Daria Korsakova

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

Full title: stop firefighting: practical observability for Python APIs, workers & jobs. The most important points:

  • What does it mean for a system to be observable?

  • Does that answer look the same for an API, a worker and a job?

  • Metrics tell us something is wrong, but how do we find out what happened and where?

  • How do we get the system to tell us, before our users do?

  • Where do we actually start without doing everything at once?

They started with a prototype of a new system. They had questions like “does it work” and “is it fast enough”. So they added a bit of monitoring: just a couple of logs and some simple graphs. And pushed it to production right away…

What does “observable” mean? It means you can answer questions like: is it up? Is it ready to serve traffic? Is it doing useful work? Is it failing? Is it slow? What changed recently? Which dependency/workload/customer/job/event-type is involved?

Is the answer the same for everything? No. You can have an API that restarts just fine on an error. So: it is up again, no problem. But because of the restart, it might have gotten a new IP address that isn’t recognised by something else in your stack. So the API works, but the rest of the app doesn’t. (That’s a real case that they saw.) Or a nightly database import job might succeed just fine (but there’s no new data as an upstream pipeline failed).

Metrics can help you notice problems before they become critical. Like API response times that slowly creep upwards. Time to investigate! Or something really goes wrong and the number of “error 500” messages spikes. Then you have to move from your metrics to the logs. There you can hopefully see what went wrong. If you need to dive deeper, you can start to use tracing (she doesn’t recommend activating this right away).

Notifications. There’s a sliding scale between “no observability” (the user has to report errors) and “alert on everything” (leading to alert fatigue). She recommends starting with a low number of alerts and slowly working upwards from there.

How to start? Best approach: roll it out in phases.

  • Start with basic visibility: health/readiness, structured logging.

  • Then workload metrics: request rate, error rate, number of processed jobs.

  • Then high-confidence alerts: api not ready and so. “P99” latency. Job queue backlog without progress.

  • Then dashboards.

  • And last tracing and deeper instrumentation.

She wrote an article about it: part one.

https://reinout.vanrees.org/images/2026/pyconnl-3.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Hohenzollern railway bridge plus kathedral.

Pycon NL: 3D data science with Python - Sergio Peral

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

Why Python for 3D? It often used to be done in C++. He showed an example in C++ and Python: the Python example was much shorter. But: Python is often only the interface, behind the scenes the library you use is often written in C/C++/Rust/etc.

The library landscape. There are many libraries you can use. Loading and storing: laspy, pdal, pyproj. Arays and speed; numpy, scipy, numba, dask. Processing: open3d, trimesh. Visualisation: pyvista, vtk. Learning: scikit-learn, pytorch3d.

One real pipeline. He used a pointcloud of part of the Jaarbeurs complex (where the conference was taking place), sourced from the Dutch public https://ahn.nl data source. The density is about 18 points per square meter and it uses some Dutch coordinate system (“RD New”).

A point cloud is just a set of points in 3D space. You can also represent it as a mesh (3d areas). A “voxel grid” is also often handy: you convert what you’re seeing into small stacked cubes.

What you need to do in a project: acquisition, preparation, exploration, analysis, visualisation.

No single library does the whole job. A partial exception is numpy: every step uses numpy vectors internally. He loaded the data with “laspy”. Then voxel downsampling with open3d (he took the average of all points in a cubic meter). 700k points turned into 200k points this way: much more manageable. He then did a bit of clustering and colored the clusters by data from a land use database.

Making it fast. Using numpy’s array operations is key. Don’t iterate over a loop in Python, but let numpy do its work. That way, there’s highly optimised compiled C++ code doing the work.

Some takeaways. Think in arrays, not points. Look befor you compute (so: check your data for obvious errors or problems). Make it small first. Let compiled code do the work.

His presentation is at https://github.com/Sloppy1999/pycon-nl-2026-3d-data-science

https://reinout.vanrees.org/images/2026/pyconnl-2.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. Railway tracks (‘linksrheinische’) behind the hotel, at the site of the former ‘Köln Gereon’ goods yard.

Pycon NL keynote: believe in routes - Marcelo Trylesinski

2026-10-15

Tags: python, pycon

(One of my summaries of the 2026 one-day Pycon NL conference in Utrecht, NL).

Routes: not every route starts the way people think. Here’s his route through life.

You might know Marcelo from uvicorn, fastapi, starlette, logfire, Pydantic AI, MCP Python SDK, httpx2… It started for him in 2017 when he played league of legends for a full semester and failed all courses. This closed his main route: graduating on time and getting the expected job. Instead he got a good-enough job somewhere in Florianópolis (Brazil).

What was your closed route? It might be a degree you didn’t finish. A field that changed under you. A job you didn’t get. A move.

One thing he wants to talk about: curiosity needs a direction. You might be curious, but where does it get you? You might have a direction (like a degree plus the expected job), but direction alone, what does it get you? But if you have both curiosity and direction: that’s nice.

Marcelo was curious in open source. What helped him a lot was to get involved. With open source you can look at issues and start fixing them and slowly getting more and more involved.

In 2020, the web question in python was “Django or Flask”. He picked the third option: FastAPI, and started using it for his job. That resulted in bug reports or feature requests from colleagues that he then could fix in FastAPI itself. He even took over maintainership of python-multipart: by asking the not-really-active-anymore maintainer. Marcelo got the maintainership because he was already known in the community through his other open source work.

Asking can chance your path, just like with the maintainership of python-multipart. Likewise, he asked for a job at Pydantic though his open source contacts. And got it! He works for Pydantic ever since.

What can you open if you want to change your route? What can you do? Is it too late to:

  • Start contributing to open source?

  • Learn a new language?

  • Pick up a hobby?

  • Change careers?

According to Marcelo, it is never too late. One thing he’d focus on is fun. Have fun with open source, for instance, in his case. It almost started out as his hobby. And he likes AI right now. One of the things he’s having fun with right now is zttp, an IO-less HTTP parser for Python with a Zig core. He mentioned that AI helped him experiment. Another project is pgtask, a Postgresql-native durable task queue + workflow engine.

A big part of his personal workflow is to look at his github notifications for all his projects. Just look at one notification (and thus one issue or PR) at the time and to bring it a little step forward, one at a time.

Normally he handled between 300 and 700 pull requests per year. This year it is already above 2500 (due to AI). Like many maintainers, the workload has gone up. He noticed he actually made noticeably fewer releases this year, though.

Maintainance is a form of care. Care and feeding for your projects. Triaging issues, reviewing PRs, saying “no”, closing the noise. You’re a maintainer, too. Anything that only works because someone shows up. It might be your own life, your family, your club, your project.

Marcelo once got the tip to grow on three tracks at once. Don’t ignore any one of them, you need them all:

  • Professionally: grow in your job.

  • Personally: family, relationships, friends.

  • Healthily: exercise and nutrition. Body and mind.

You might notice that one of those three tracks is starting to eat the others. You can’t remember the last day without a laptop, for instance. Or you spend a year at home on open source and tell yourself it’s fine.

He made a comment about AI. He works on AI tools every day. He still doesn’t know where it goes. He knows some of the routes might be closing for you because of AI. As a maintainer, he actually uses AI. He lets AI review pull requests, he lets it write his one pull reuqets. Security advisories. But AI doesn’t diminish his enthousiasm and curiosity.

Remember the bring it a little step forward, one at a time he mentioned before? Your route will be different from Marcelo’s. But the only thing you need to get further along on your own route is to move a little step forward every time.

https://reinout.vanrees.org/images/2026/pyconnl-1.jpeg

Unrelated photo from our Nelen&Schuurmans company trip to Cologne/Köln in Germany. The salad I had for lunch on Saturday was tasty.

Nice schedule for upcoming Pycon NL

2026-09-28

Tags: python, django

In 2.5 weeks (Thursday 15 October), I’ll attend the Pycon NL one-day conference in Utrecht. Always a friendly conference with some good speakers.

I just took a look at the talks schedule and got pretty excited. A talk about 3D, point clouds etc and how to process it with Python: useful for the company I work for. I’ll attend the practical observability talk: we do observe and we have lots of metrics, but really tying everything together, especially with our Python apps, still needs some work.

Of course there are some talks, scheduled at the same time, that both look useful. “New static security scanner” versus “practical software architecture” for instance.

“Zero-downtime multi-tenancy in Django” pushes a lots of buttons for me :-) The talk before it looks like it will explain some theoretical background behind “data models”, with a bit of LLM explanation included. That might help me understand it all better (I’m not using LLMs myself).

“Resumable Python pipelines” hopefully broadens my view a bit. We’re using the Prefect task runner a lot within the company (I even gave a talk about it at PyGrunn and at two meetups). Recently, I’ve started using Django’s new “django-tasks” framework. So… some more input is always useful.

And, yeah, “what’s inside an asyncio event loop”: up till now I’ve kept all my own code synchronous. Nice, clear, debuggable. I’ve heard loud groans from colleagues that had to debug async code. But I’ve also heard very positive noises from the Django community about “free threaded python” and “that’s when Django’s async work can really pay off”. So: I’d like to know more about the inside of asyncio :-)

Well, on 15 October you’ll see my summaries turn up here on this blog!

September Python Leiden meetup summaries

2026-09-17

Tags: python, plone, django, pun

Two summaries from the September 2026 https://pythonleiden.nl/.

Maintaining Python packages to attract free and open source software contributors - Steve Piercy

Steve is in the Netherlands for next week’s Plone conference in Maastricht (NL). He’s been involved in open source software for over two decades.

What are contributors? Contributors to open source software? Why do you do it? Learning (I myself got a good programming education out of contributing to Zope/Plone while still at the university). You might want to give back. You might like the community, you like to belong to the community. Finding your tribe. Perhaps build a resume or CV. Help other people.

Why not? Negative online reactions. You want to really make money out of it. AI slop. You might not have time. Too busy. Life happens. You might enjoy walking your dog or doing gardening more. Or perhaps you just don’t know how! Or you don’t feel experienced enough (imposter syndrome). Perhaps you don’t think your English is good enough (he advocates just using Google Translate).

(He asked how many people had already contributed to open source: about half the room raised their hands.)

There are actually lots of ways to contribute. It is not all code! Read this page for some examples. You can report security vulnerabilities or issues. You can comment on issues and help getting them forward. Review pull requests. Extend the documentation. You can join discussions in forums or on Matrix. Write a blog post on a project. And… you can financially sponsor a project.

(He again asked who had contributed: now most hands went up!)

Where to start? Start with what you use and what you find interesting. This helps staying involved and getting into the community more and more. He himself liked web applications and especially forms: making sure they’re intuitive and safe and well-validated. And he liked documentation, so some of his first contributions were documentation fixes for open source projects.

Recently, he volunteered to take over maintainership of an open source project (a sphinx extension). There were lots of open pull requests and he asked the owners to look at it again and perhaps tweak it a bit and… everybody responded and a few weeks later he could make a new release with lots of fixes.

What is a maintainer? Well, basically maintainers are contributors who make releases. But ideally you also have to “tend your garden” and try to get your small community to thrive. One thing to keep in mind: you have to put your ego aside. If it is open source, it is really owned by your users, not by you. What do you have to do? Show up when someone has a question. Document your project (how to contribute, how to report bugs and security issues, etc.).

He especially mentioned https://djangonaut.space , that’s a great initiative to help people get involved with contributing. Same with https://djangogirls.org/ .

As a maintainer, you might also have to look for funding. There are options like “github sponsors”. But also NLnet (from the Netherlands) and the German sovereign tech agency that sponsor lots of projects.

A best practice of good maintainers is to have good tooling. Automatic tests + coverage. Build documentation. Formatting checks. zest.releaser for good releases.

The most important part of being a maintainer: how do you treat people.

There’s one big problem: AI. There are just too many pull requests and too many issues. You can never get through them if your project is reasonably popular. Dealing with it is hard. Several projects made the choice to disallow AI contributions. Also read https://leidendeclaration.ai/ , for the same problems are entering math and science, too.

But on the other hand… in the icalendar project that he helps maintain, they got a new contributor that made his first contribution based on AI. He liked that: the person got enough confidence through AI. They now have an AI guideline in their contributor guide now.

There’s are automated tools on github that can help you check pull requests and identify slop-generating accounts, for instance. A tip when confronted with suspected AI work: ask vague, clarifying questions. Just ask for a bit of clarification in a vague way: AIs can’t respond to vague questions, but humans can.

“Once, men turned their thinking over to machines in the hope that this would set them free. But that only permitted other men with machines to enslave them.” - Frank Herbert, Dune. Funny that he could write that 50 years ago.

Something mentioned in the discussion: people are now bidding on real github accounts in order to let AI bots use accounts that appear real…

Watch out with AI. One of the links he shared: https://pivot-to-ai.com/2026/09/08/students-who-dont-use-ai-are-ahead-on-every-measure/ . And, look at the kids: it was bad enough with social media, but AI is much worse. And freelancers are getting buried with soulless AI slop cleanup: artists get to clean up AI-generated images, for instance.

Choose wisely. A quote he wanted to give us to think about: teach the world you want.

Monitoring my washing machine - Michiel Beijen

Michiel has a 2021 Samsung washing machine that plays Die Forelle by Schubert when it is finished washing… But the washing machine sits in the garage so he can’t hear the sound. It is a smart machine, so there’s an iphone app for that! “SmartThings”. But the list of data it wants to collect about you is horrendeous. And the app is almost 1GB! No…

There’s also “home assistant”, written in python. There’s even a SmartThings API connection. But… from October 2026 onwards you need a $5/month samsung subscription!?!

There’s also “Matter”. They call it vendor neutral, standards compliant. Samsung supports it. But only for connecting Matter devices to SmartThings, not the other way around.

Next try: put a small camera in front of the washing machine’s display, add a bit of OCR text recognition to detect the remaining time from the image and add an http interface to it. An old webcam couldn’t provide a good camera. A raspberry Pi Camera 3 did the trick. (He later thought it would perhaps have been better to pick some old smartphone.)

He showed some graphs detailing how the washing machine estimates the time it will finish, including the adjustments it made halfway (adjusting for load or so).

Another approach that a colleague of him took: use a monitoring plug that measures the electricity used. Once the electricity usage drops off, the washing is finished.

Overview by year

Statistics: charts of posts per year and per month.