 Welcome to the last regular talk of the weekend in this room. I can see there are a couple of people coming up, so I'll talk for a little bit longer. This is the last intro I'll do, I promise. I'll be off the stage. We better get started then. The last people are wandering in now. Leonardo is going to talk to us about clean architecture in Python. He's a software engineer in the film industry, which I think is really cool, a company called We Got Pop, and author of a book of the same name. Now I'm told by many authors that it doesn't pay that great, so if we can listen to the talk and appreciate the advice, maybe we can go out and buy the book as well. He didn't pay me to say that, I promise. So with that, over to Leonardo. Thank you very much. Thank you. Thank you. I am the third Italian in a row in this room, and I dare to say this is statistically significant, right? So about me, I just got an amazing introduction. I'm a software developer and a blogger, and I'm the author of a book named Clean Architectures in Python. Let me start with a question. What is the definition of architecture? And Vitruvius, who was a Roman architect first century, in his book, The Architecture, speaks about firmitas, utilitas, benustras, which in modern English is durability, utility, and beauty. So he says that architecture deals with something that should last the test of time, standard test of time, sorry, be useful and be beautiful. When it comes to software architecture, so software development, the dictionary gave me an interesting definition. Software architecture is the art and science in which the components of a computer system are organized and integrated. So first of all, art and science, how many of you consider themselves artists? Many consider themselves engineers, right? But artists? Interesting. The second thing is organization and integration. So architecture, software architecture, has to deal with where components of your system are and how data flows between these components. Now that we know, superficially at least, what architecture is, the second question is do we need an architecture? And the very short answer is yes, I don't have that much time, but my point is if you don't decide anything about your architecture, someone will decide for you, typically your framework. Many of you, if you create web applications or mobile applications, use frameworks. The framework enforces an architecture. Unfortunately, the framework is just part of the system. So no decision is already a decision. The third question is what is the meaning of clean? I guess it's very easy to understand what unclean is, this. I don't want to work in such an environment because I don't know which cable I have to pull. It's too risky. While in a clean environment, you know where things are. You know why components are there, and you know what something is. What is the clean architecture? This. So the clean architecture is a layered architecture. So it's a way to create systems based on layers. Here we have three, well, four layers. Let me spend a couple of minutes on this slide. Layered architecture means that when you create something in your system, you are not free to put it where you want. Components are forced to live in a certain layer according to their nature. Here we have entities, use cases, and external systems, plus a half layer, which is called gateways. The important thing in a layered architecture like this is that whatever lives in an internal layer, like, for example, entities, doesn't know anything about what lives in outer layers. I come up with an example in a second. But it's important to understand that if you create, for example, a Python class in the entities layer, you are not allowed to name, to call, any class that has been created in an outer layer. The golden rule of the clean architecture is that external layers talk to internal layers through simple structures. Simple structures are, for example, structures defined by the language, lists, dictionaries, or structures defined in an internal layer, like entities. And you talk outwards through interfaces. Why? Because you are not allowed, as I said, to call a specific class that has been defined outside. You don't know about it. So you have to go through an interface. We don't have in Python specific construct for interfaces, like, for example, in Java. But we can still use interfaces. So this is my example. Let's say we are dealing with a very simple model, an object. I am creating a clone of eBay, for example. In the entities layer, there is a class object. As you can see, this is not a model like, for example, Django models. This is a very simple class. It might be a data class. It might have methods. But it's definitely not connected with a database. This is something new, probably. My use case is retrieve a list of objects. OK, so for example, I have a cart. I have, I don't know, a filtering. Someone is searching for an object. So my use case lives in the use case layer, use cases layer. And the use case is a simple class. I can instantiate it and execute it. The only thing you can do with a use case is to execute it. It's very, very simple. So I call execute. In 2019, we are probably talking about a web application. But it could be a mobile application. It could be a command line interface. I'm just giving you an example. If this is a web application, I can go with flask, for example, and create an endpoint like this. Cool. So the task of the web framework is that of receiving HTTP requests and translating these requests, extracting the parameters, like the query string parameters, for example, and cooling the use case. So the HTTP request becomes a call with some parameters. Then we have a repository because we need to extract data from somewhere. In this case, for example, a database. Again, it could be something different. Let's say a database. The database, as you see, lives in the external system layer. Why? Because I don't want to be coupled with a database. I just want to say there's a database somewhere, something that can provide data. But if I want to access the database, I need an interface. And the interface is specific for my business. It's not an interface that maps the whole database to Python, for example, but it's a specific interface. The interface maps what the database returns in terms of a specific language into simple structures and entities. Again, as you can see here, there's an example. Very brief. An example of an interface towards Postgres. I expose one method, which is list, that accepts some filters. I have a query that depends on these filters. And I am returning some entities. So the use case has to receive also the repository interface. As you see, I added the dictionary plus database interface. Because this is dependency inversion, the use case cannot call the interface directly, cannot name it, because the use case doesn't know the class is there. So I have to pass the instance to the use case. As you can see here, I initialize the repository. Then I call the use case passing the repository instance. And then I call the use case the execute method. Now, the use case calls the repository interface. So inside the use case, what happens is that the use case has to interact with the database somehow, interacts with the interface, extracts data, and applies the business logic. This is the core of your application. Because when you create an application, the core of it is the business rules. You shouldn't be concerned with or the user clicks a button on the graphical user interface. Fine. But what happens? The user is deleting a message. OK, this is the business use case. So what happens in the use case is that we run the business logic, and then we return a result. Where does the result go? The result goes back to the external system that called the use case. In this case, the web framework. So here, you see I collect the result of execute in a result variable. And at this point, the web framework is in charge of converting this response, which might be entities, for example, or again, simple structures, into an HTTP response. So as you can see from this picture, I am applying the separation of concerns. OK, so every actor in this system is dealing with a specific thing. So the web framework is dealing with HTTP requests and responses. The use case is dealing with some parameters and some data. The database interface is dealing with the database. Advantages of this architecture are many. There are many advantages. Two of them that I want to mention are testability and ease of change, if you want, easily changed. So testability is this. Testing the components of this system is very easy. Because if I want to test the use cases, if you look at this class, testing it is very simple, because I just need to pass a dictionary and a mock of the repository interface. And I have to test that the use case gives me back the correct entities and an interface call. It's a very simple test, five lines. Testing the HTTP endpoint is very simple. Again, I need an HTTP request, some mocks for the use case for the repository, and then I have to test the outputs. My point is I don't need to instantiate a database, for example. If you are used to Django, just to name one framework, very good framework, by the way, when you test your models, you have to have a database running, not here. When do you need a database? When you test the repository interface, obviously. Is Matt Wozinski here? No, he lives there. He's dealing with database interfaces. So in this case, you need an integration test. So here you need the real database running, and here you need to, for example, spin up Docker images. These are slow tests, one of the three. Now that I give you a very simple example, I want to address a couple of other questions. So is this the definitive architecture? I don't think so. So this is a very good architecture. I really, really suggest using it. But this is not the best architecture, because I believe there is not a single solution to every problem. So one of the problems of the clean architecture is that it's a layered architecture. There are a lot of layers. I showed you the minimum amount of layers for, but you might have more. Layers means data transformation. Because as you see, something comes out of the database, becomes a simple structure, goes into the use case, then becomes another structure, then becomes a HTTP response, blah, blah, blah. So you have all these data transformation. This means time. This means that you are affecting the performances of your system. So not every system can be created with a clean architecture. It's up to you to understand this. It's not a panacea. And the second question is, is it possible to migrate an existing system towards the clean architecture? And my advice here is to detach simple cases. For example, endpoints. If you are dealing with a web application, you might start with simple endpoints. For example, the login endpoints. For example, some data instructions. And implement them in a different system created from scratch with a clean architecture. Don't try to move your whole Django application towards the clean architecture in one go. It doesn't work. Don't do it. I have a lot of time. OK, fine. So there is one thing I want to say that is not in the slides. But there are many books about domain-driven design, about clean architectures. You might, yes, thank you. You might argue these books come from the Java community. Many people writing books about these subjects come from the Java community. And we say many bad things about the Java community. Definitely the language is not the best one around, probably, please. But the Java community has been addressing these issues for the last 30 years. So we definitely have something to learn from those people. And I definitely believe we should get in touch with them. Harry Percival and Bob Gregory are about to write a book with Orelie, called, well, their working title is Pythonic Application Architecture Patterns. They're definitely titled with the different. Orelie agreed to publish it with an open source license. So you can find it on GitHub. You can already read it. You can send poor requests or something, if you believe you can contribute to it. And there is already a book about clean architectures in Python. I published it last Christmas. It's available for free. So you are kindly invited to go and download it and read it. I'm really, really looking forward to discussing with people architectural problems. Because my point today here is to start again a discussion about architectures. I believe we have incredible frameworks in the Python community. One is Django, for example. It's really, really a good product. But we are not addressing some of the problems, like the architectural problems. We are delegating the framework. So we should start discussing again these things. I am seven minutes early. So maybe time for questions, if you want. Thanks. I love that architecture. I used to work with that sort of architecture. Now I work with Django and it makes me a bit sad inside. You mentioned Django. And you mentioned walking to a new way of doing things. Is there any advice that you can give me to make Django, to mold it into a more clean architecture? OK. Yeah, with Django it's hard because Django, well, for starters because it's a very good framework, but it tries to do too much for me. So for example, Django models are tightly connected with the database. So it's difficult to work with Django and models that are not connected with the database. My point is, generally speaking, you can always wrap things and trace a boundary. So you might, as I said, one thing you can do is to say, OK, I isolate part of my system. Some endpoints, for example, if you are working with Django, it's a web application. So I solute in some part of it and say, OK, I moved towards something different. Maybe with the same database. If you create a database interface that works with what Django created, you can deal with it. But yes, definitely is what I was saying before. Don't try to bend Django, the whole structure that you created with Django towards the clean architecture. You should try to move Django to its part of the system. So dealing with HTTP requests. Probably Django is really hard. I chose Flask in my example exactly because it's from the ground up, it's simpler. But yes, I don't want this discussion, this talk, to be like clean architecture versus Django. But my point is, where I mentioned the web framework, I mean a web framework. So whatever. Django can be there. But definitely, if Django wants to deal with the database, no, not in this architecture. I hope I answered. Oh, got one over here. Hi, thank you for your talk. You're welcome. I was wondering, many modern systems are moving to, for example, a microservice-based architecture where there are several components and they imagine each of the components having this general shape. But can something like this be used to design the architecture at a larger scale or how different components connect to each other or what kind of patterns do you envision that are relevant at the scale? That's interesting. OK, complex question. OK, short answer, we might discuss it later. Short answer is, I believe the power, the main point of the clean architecture is layering, so separating concerns. OK, so this is the point of microservices as well. So when you create microservices, it's a bad word nowadays, but why do we want microservices? We were discussing with someone at Lantz about monolithic architectures. What's the definition of monolithic? A microservice is monolithic. If you trace a boundary around the microservice, it's a monolith. So the point is, it depends on what you are doing. So what is the definition of microservice? What part of your system should you decouple from others, not everything? And you will have coupling. So I know I'm not giving you a straight answer, but my point is the clean architecture is a software architecture, but generally speaking is about putting components in the right layer and enabling the communication between them and forcing some rules, which is the golden rule, like small, simple structures and interfaces. But yeah, we can discuss about it, definitely. Thank you. I'm sort of going back to your opening slide and wondering if perhaps the work of Christopher Alexander, who inspired the design at patents people, might be relevant here. Definitely, I didn't mention it because I thought I didn't have time, but what you are saying is that the design pattern, which is a very important book in our job, has been inspired by architectural concerns. I didn't read the book Alexander wrote, so I cannot answer directly. I believe the main thing I learned from Alexander not having read the book is he observed something that happened in his job, that happened in his community, and he tried to formalize this. So we shouldn't be scared of saying, this is what happens when we create web applications, this is what happens when I deal with databases, this is what happens when I create big systems. And trying to, instead of avoiding things or masking problems addressing them, this is what I can say, but again, it's a limited experience with that book. Alexander's book. Thank you very much. We'll draw questions to a close there. Thank you.