 Hello, everybody. Just for me to adapt a bit what I say to is attending the talk, how many of you do, or you can say, you do a fast-pro development in your day-to-day work? OK. Not that many. The rest is probably in research, hopefully. And how many of you have you been using Younger's framework before? OK, perfect. Then a bit about me and how I am not using this stack. I started programming some 15 years ago, building web platforms with basso scripts and CGI. Luckily, around 2009, I entered a startup call, F24, where they were using the Python stack. It was mostly soap at the time. And Younger started their life around that time. And I've been involved in a couple of startups mostly from that time. And in many cases, I've been using the Django stack. I say the Django stack because Python has many flavors. And mostly, for me, Django performed well in the past. The only exception, I think, I've been having is when I was doing Valve Fleet and tried out the Google App Engine type of approach. Now, what is OnTrack doing? I will give a very brief discussion. We just need to follow the small code examples. We will be discussing afterwards. So OnTrack is a bit-to-be marketplace. We just basically match pallets or industrial freight with available track drivers. Normally, track drivers have either two, three tracks or a very small company. It's hard for them to find jobs. For the customer, it's hard to find the available track driver. They need to call many people. They use email. They use fax. It's a back and forth. And we just simplify that the standard marketplace ways. What do we mean by fast product development? Usually, when you are building a startup, and this might be completely different if you are in research or if you are in a large company. But when you are in a startup, you normally tend to be in one of two phases. Either you are looking for product market fit, and then you need to iterate very fast. And really, nothing matters except finding product market fit. Because no matter how good your product is, no matter how automated everything is, no matter how well you dockerize everything, 100% test coverage, really night code astroptions, if you don't find product market fit, it will all end up in the bin. Now, one day you are lucky. And if you are lucky, and something makes click. And then it's the day when you start scaling and you start regretting all the choices you did to get there. In our case, this is a bit the revenue growth from on track. So this is six months trying to figure out what the hell we are doing in this logistics market that we have no clue about. And then six months saying, OK, maybe we got lucky. Maybe we figure something out. Now, how do we grow very, very fast? Luckily, we were, from the beginning, using Python, using Django, using Django Res Framework, which is a stack that I value a lot for this type of problem because it lets you perform well in both stages. You can go very fast in the prototype phase. And I will show afterwards a couple of examples of how extreme we want to get even a bit faster to put our product out there even a couple of weeks earlier. And once you get to the point where you satisfactorily figure something out about your market, the tools are there for you to scale. And it's not only scaling from the technology perspective. It's also scaling from the team size perspective. Now, current team, there are seven people who touch the backend. Only three people had previous Python experience. So it's very important for a stack. And this is something I really love about the Python world that you can easily jump in, coming from other languages, coming from other frameworks. Things that I really like about that stack is that it's very well documented. You have an awesome community behind it. It's very easy to read the code that your colleges wrote before you arrive. And especially, it's very opinionated. And I give statement here that I think many people will not agree, especially everybody who is very expert on something. And I have seen very many good Python programmers saying, like, wow, yeah, but Django, you know, there is a point that is really, really complicated. It's really messy. It makes too many opinions. I prefer to go with my flask thing. I put a couple of libraries. I know them by heart. And I have so much more freedom. And this works very well when it's you or two, three other very experienced people with that particular stack. When you need to quickly onboard, never underestimate the amount of time you will lose in discussing and re-discussing everything. If your friend has a couple of opinions, even if you end up in 80% of the quality of the possibilities you could get to, the fact that you do that three times faster, because you save a ton of research or a ton of discussions, it's something that actually comes to be an advantage. And you will have time later on to go for very specialized solutions on things that you can discuss a bit further. So what did we do or which lessons we learned in iterating fast? Lesson number one is regret nothing. Go for it and try to put something in front of your customer as soon as possible. The founder of LinkedIn used to say, if you are not the same of your product when you launch it, you launch it too late. And this is something that I agree in this particular environment. Like I said, it might not apply to other contexts, but it definitely applies when you are trying to build a startup very fast. This is the architecture principle that we tried to follow. We didn't use Django, and this is something that for me has been a lesson from past companies. If you use Django, the MVC approach to the max, you will very quickly be having too many points of entry into your backend, and it will get missing. So one thing we did was to focus on being API first and just allow for API entry to the backend, and then delegate the frontend, delegate the presentation layers to the more appropriate tools. Also that gives an advantage because the JavaScript wall is not stable, unfortunately, not like Python or Django, so it will change. For us, it was React now. We actually started with Angular, and it cost us a couple of weeks to move to React. It will hopefully cost us not so much time when the new JavaScript framework comes out, probably in autumn or whatever. A bonus point for having API first is one day your CEO decides they got a customer and the customer doesn't want to enter your beautiful website. They want that you integrate with the SAP system they have where they spend tens of millions for having it, and he doesn't want to train his people, no? And fortunately, and this is something that Django Res Framework gives you almost for free, is that you can have professional API ready for that situation. If you are not using Django admin, which is one of the main advantages of Django, how can you get an admin page when you have zero orders? Like how can you invest the least amount of money on it? Well, fortunately, Django Res Framework lets you manipulate your data. And this is intended not as an admin page, of course. It's a disaster for that. But it's very cheap because nothing. And this has two advantages. One is zero time until you have an admin interface because that's the API explorer. And another thing is you align the vocabulary with the people operating the system because they really know and understand how is the system behind because they actually need to use the same fields. This doesn't scale, of course, and it's a disaster past a couple of weeks, but you can launch two, three weeks earlier. If you need real-time notifications, also, there are many ways that are faster and better than web sockets. In our case, we quickly integrated with Slack so people would know, okay, something arrived at the system. As soon as we put there a link to the API wrapper and they could very quickly operate with almost zero time invested in our case. So we had more time to try to figure out what our customers want instead of developing internal back-office applications. Now, to do some code, this is another, this is a problem that you normally have when you have a very clever UX product guys that they can say the basic out system is very boring and we don't know how our customers want to use it. You might sell your application to one guy and then there might be another operator using it or they might sell the login details and how are you gonna map all this hierarchy of the people using your system. So one shortcut that we took was to say, okay, let's just figure out the login way where we just give people unique URLs. Again, this doesn't scale very well. There might be some privacy concerns there but it saves you a couple of weeks and it lets you understand how your customer interacts with your application and then by way of dialogue, you would discuss with him how she's sharing login details with her colleges and so on. This saves a lot of time for them in putting the password in a post-it and sharing it around in their office. Another shortcut that we found useful when modeling our system was to start modeling complicated things with the JSON fields in Postgres. So we were having this problem. We had shipments and then our business guy said, we need to add some extras. Okay, so what's an extra? So for instance, if the thing needs to be picked up after 10 p.m., then we should charge a bit more money. Okay, then we put a rule and then we put, okay, what does it mean more money, 10%? Okay, 10% on top, fantastic. And then if the track stays for a long time, then we need to charge more money. It's like, okay, how much more money? Well, it should be a fixed amount that we would decide later. Okay, who decides that and when. Oh, this is the admin guy, okay, fantastic. And then you go like, yeah, and we need another extra. Like what? Yeah, some tracks need lift gate. Okay, what the hell is a lift gate? Yes, this thing you put behind a track that lets you put easier the pallets up if you don't have like a specific machine to do that. Okay, fantastic, what's the price for that? Is this a percentage or is this an absolute number? Yeah, it's a bit more complicated because it affects the number of vehicle. If you have many pallets, it should be included in the price, but otherwise, it depends on this, like okay, fantastic, how the hell do we model that? And then you go to the engineering team and they are like, are these all the number of extras or will they add more? Like, if I know how this works, they will add more. So we started with the simple hack, which is we use PostgreSQL JSON. We don't need to model a lot and we take advantage of Django res framework serializers. So we just connect it directly, taking it out of complex loges and potential migration problems. Another problem we were facing very early with our modeling was that the permissions and the access control layer were not as easy as we figured out. So usually, and we were using don't repeat yourself framework, you discuss something like, okay, I want the user to access some models and from those models, I want the user to access some objects. That's kind of easy, it's easy to map. We had a bit more intense problems where people said, yeah, but some users should not see some attributes of the objects, even if they can access the object. They're like, awesome. And then in some cases, you should also not be able to see any kind of attribute. For instance, a truck driver should not see some attributes related with pricing in a specific shipment. So we were messing around a lot and we had some solutions. I'm not pretty happy with it and if you have some experience on the topic, it would be really nice to discuss afterwards other approaches. So we ended up using don't repeat yourself for advanced permissions on the models. Then we used the filters of Django Res Frameworks to add an extra level of permissions or control. And then we ended up in some cases with dedicated endpoints, a specific serializer. We have this kind of pattern of multiple serializers over one model that we were also seeing the other day on a similar chat. So that for how to try to put something out there very fast. Now, what happens when you get successful and start growing? Which kind of lessons were we learning here? Lesson number one, the newcomers to the stack will always get in trouble with the ORM. And again, there is not a simple solution. We were trying to train them, showing them some past Euro Python talks and doing a lot of code review, but it's very hard to train somebody new in Django. I mean, documentation is, I'm gonna say lacking, but it's a bit hard to follow there, you know? Because it's these N plus one queries where you end up putting the wrong property and then your queries go from 20 to 8,000 and you cannot figure out where the problem is. Then you teach them how to use prefetch and so on and then you're gonna figure out that of course prefetch works only if the query that uses it is very similar to the query that the prefetch does. Otherwise, you need to map it in more specific way so that you can reuse it afterwards. Again, if you have some good experiences in training people that are new to Django into this particular aspect of the problem, it's the only thing that we have found complicated and that gets people really complaining about the whole framework because of the magic of because of the decisions on there. I would be very happy to share experiences or even figure out ways of documenting this better so that there is a web page where you say, okay, after some playing around with the framework and some experience, go start read this page where you have a lot of documentation, talks, whatever that show you how to avoid the typical traps. Another lesson that we learned early on is if you have state transitions, use a finite state machine. There are very nice Python libraries very easy to use and it will help you map your abstractions better. While doing it, we found an interesting pattern coming from our mobile guys who said like, if we have status changes and mostly mobile, we want to go forward to advance. Why don't we instead of meeting you in the state you should go to, to avoid race condition, I tell you the state, it's a bit connected with what we had before about declarative attitude. I will tell you in which state I am and I will tell you that I want to go forward. And then we use the state machine in that way for the mobile phone, which is, they just tell us in which state they think they are and they want to go forward. We check if they are in that state, fantastic. We give them back the new state. If they were not in that state, we tell them sorry, somebody with higher privileges moved this state before, this is the new state, but there was something wrong so you can alert your customer that it was not a normal transition, sorry. This allows you to control the states in a different way, for instance, from an admin interface where you might need to go back and forth and from a mobile phone. And now on the closing part, a couple of thoughts not so much related with Django's framework, but a bit more higher level. One thing that I've seen that gets people to go very slow is to try to build everything themselves. It has been said many, many times, but as soon as you start growing something, try to get it asynchronous. You have fantastic salary if you are in this stack or something else in others for building queues or other types of architectures. Another thing that I observe many times when I talk to other startups is they build their own CRM, like lead generation, lead tracking engines, and they build their own billing because their case was very particular. Fun enough, billing is very complicated. All cases are particular, and you can rely on tools like Odoo, which is Python-based open source, lots of plugins from the community to do billing in many different countries, many different situations, and you can just slightly touch it instead of building from scratch. And another case where I found that we were doing templating, so kind of like front-end was for all these marketing applications. And in marketing, people come with like, oh, your transactional email is okay, congratulations for your order. Fine, we will design one, we will put it out there, we fill in the variables. And then they come and say, you know what, if it's the first order, we should put something different. You're like, awesome. I will do any if I will put something different. Yeah, and if it's VIP customer, we should put something else. They're like, fantastic. And you end up modifying something that there are tools that do it for yourself. In our case, we use customer IO, there are others, and we just send the parameters of the order and then the marketing team can do both templating there and they can also do the segmentation. So for all these internal or pseudo front-ends that you're not building like communication to your customer, you can also get it done outside. One final thought is if you really want to go fast, and that was interesting because I heard different thoughts in EuroPython and other talks, I don't believe that engineers or the developers should focus on the build phase alone and completely. I really disagree. I think this is a very waterfully approach. And going and saying, yeah, we just like to build and then somebody else deal with the customers. I think that this ends up in having the wrong solutions because you will just build what either you built before or what you have read online. And I think it's a much more valuable exercise when you get to be involved from early on in the decision process. Like if you can get involved in research and understand why are we doing what we do and get into a diverged phase where you're like, can we do something different? Can we do something crazy? Can we do something stupid? Can we do something that is maybe, something we should have never thought if we would have been in our own room seeing the tickets now that the spec that come from somebody else. So for me, those were the main learnings have been taken over the last year in OnTrack. And one thought, one final thought is like, if you feel that you are a bit out of the comfort zone because everything moves too fast, you can never get it completely under control. That's probably the point where you want to be. That's the sweet spot. And yeah, if you have been dealing with the youngers framework permissions, if you have been trying to teach other people about the M plus one problem, or if you just care about logistics, whatever, feel free to reach out to us. I would be super happy to have some discussion and talk, serve some experiences. We have a stand downstairs. We will be the social event and of course all the normal online channels like LinkedIn, Twitter, email us. Definitely looking forward. Thank you very much. Okay, thank you, Summer. We have 10 minutes left. So whoever has a question has time to ask it. So who has a question? No one. Well. Do you have a Swagger specification of your API? If you do, how do you generate it? Excuse me, huh? Swagger specification or open API specification of your API, do you have it? No, we don't have it yet. Thank you. So the way we work is the only integrations we do is with very, let's say, slow moving partners like the typical partner that would do an implementation for you connected with the SAP or like very large company. For them, they prefer to see the documentation via PDF and so on. And then what we do is we send a PDF because for them it's important so they know it's fixed in a point of time. And then we all commit to the API being that way. And then we spawn a new instance with fixed data and we just give them this very same front end. Thank you. I was wondering whether... Are you building only the API or you somehow have some connections to the client-side rendering? And now you're doing... Because I was in the talk in the next room a bit earlier and they're talking about client-side rendering and speeding things up. So I was wondering, are you doing something similar? Can you repeat? Didn't get the whole point. Do you render like HTML and stuff on the backend or you just serve the API and that's all? So on the backend, we just do an API. We are lucky in a way compared with my past projects where we had to do a server-side rendering so we took advantage of something that is usually not normal in the industry. We just do SEO for the home page. So we don't do SEO for the main platform. And the home page we have not built with Django and Django Res Framework. The home page is a small flash application where we can do a lot of templates and that we do server-side rendering completely. And then as soon as the customer wants to play with anything, we move them to our single-page app which is a React application and there it's all client-side because we don't need to do SEO on all that interaction. Lucky you. Otherwise we would need... Hi, thank you for the presentation. How do you manage your tests or how do you write your tests using Django Res Framework's class-based views? So we have a set of tests against the API. So we use spy tests and we try to test everything from the point of an API consumer. Yeah, so you act not like a unit test but like a... More functional tests, I would say. Okay, thank you. Some of our tests are unit tests but they are written normally from that perspective. So we have a mix of tests actually but from there. So that's how we code it. So we don't have a specific test within some of the modules. Yes, that's what it is. Thank you. So any more questions? Then I will ask one question if we have time for somebody else to answer. How do you train people in the N plus one problem if you have been doing it? Or alternatively, how do you do permissions, advanced permissions with Django Res Framework? There were many Django Res Framework people. Like when you cannot just give an object but you need to give parts of an object or when you have people that can do certain transitions of your finite state machine for instance but not others. In my case, we're doing something that's not rest. It's not really permission related but you can bind it to the permission. We have different set of fields for the least view of the resources in Res Framework and different set for the details. So practically, I'm hacking the core of the serializer which is a bit ugly but I can hack the fields and provide different set of fields. Maybe you can use something similar and bind it to the request and the user permissions. Thank you. Any other questions or answers? Well, if not so, then thank you and thank you.