PyGrunn: layered architecture - Mike Huls

Tags: python, pygrunn

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

Full title: layered architecture for readable, robust, and extensible apps.

Note: there’s a related article on his own website :-)

Layered architecture resonates with people that make okay applications: their application do what they need to do. But once people start asking for changes, they get nervous. There might be huge functions. Or there might be no tests, “as it takes too much time to spin up the database”. Brittle applications. Small changes are disproportionally expensive.

The goal of this talk: create apps that are readable, robust and extensible. By using the principle of separating everything in layers with a specific responsibility. It is not a one-size-fits-all solution: you have to adapt it to your situation.

The layers that he proposes:

  • Interface: how the ouside world calls your application. An API or UI.

  • Infrastructure and Repository: your contact with the outside world (like a database).

    • Infrastructure is tools. A http client. A mail sender.

    • Repository: persistence. SQL queries, caches. The aim is to decouple the rest of the system from db/cache/etc.

  • Application: heart of your system, orchestrating the business logic. The Interface talks to the Application layer, the Application layer talks the infra/repo. And uses the Domain layer.

  • Domain: constraints and definitions. He often uses Pydantic models here. It reflects the business meaning. It should be strict. Fail early. The “language” used should be a shared language between the engineers and the business people.

There are some rules, like the Interface only talks to the Application, not directly to the Infrastructure. And your code should be structured the same way. So a repo/ dir, an infra/ dir etc.

What are the benefits?

  • It is more readable, you know where stuff is. This also helps with onboarding.

  • It is more understandable, also to business people.

  • Your app will be much more maintainable.

  • Structure is clearer.

  • Because you have more separation between concerns, validation is easier, so you tend to do more of it.

  • Evolvable. You can build upon your existing code instead of modifying it.

How to get started?

  • Start with separate directories. If you wonder where a function should go, it probably has too many responsibilities :-)

  • Add tests.

  • Start small.

  • Focus on validation. Fail early.

  • Isolate the business logic.

  • Concentrate on the borders and separations.

Something to watch out for is making your models too big. You might have to split it into separate systems with their own responibility. A payment system, separate from the inventory system, for instance. You might want to create a small, focused shared domain system.

https://reinout.vanrees.org/images/2026/lac-de-kruth1.jpg

Unrelated photo: the “lac de Kruth-Wildenstein” reservoir during a family holiday in France in 2006.