Fast product development using Django Rest Framework. #lessonslearned
Fuentes, Samuel
Fast product development using Django Rest Framework. #lessonslearned A year ago we decided to use Django and, specifically, DRF as the cornerstone of our upcoming fast-iterating web platform. In this talk I discuss why and how the architecture has evolved, key decisions made and the lessons we learned along the way. I'll share the techniques we used for iterating quickly and how the technology supported (and shaped) them. In addition some quirks and DRF-specific tricks will be brought along the way. Expect a general talk about how Python (and specifically DRF) can be used as a based for quick product iterations, a discussion regarding how to build and evolve a platform to meet those needs and some DRF-specific tidbits. No previous knowledge is required but experience in web development will make the content more accessible
 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 fast-pro development in your day-to-day work? Okay. Not that many, the rest is probably in research, hopefully. And how many of you have you been using the Angular framework before? Okay, perfect. And a bit about me and how I end up using this stack. I started programming some 15 years ago, building web platforms with BASO scripts and CGI. Luckily around 2009, I entered a startup call F24, and they were using the Python stack. It was mostly soap at the time, and Django started their life around that time. 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 Valflit and tried out the Google App Engine type of approach. Now what is OnTrack doing? I will give a brief discussion. Just need things 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. That goes on and forth, and we just simplify that the standard marketplace way. What do you mean by fast product development? Usually when you're building a startup, and it might be completely different if you're in research or if you're in a large company, but when you're 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 not 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 is 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 we will figure out, 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, our 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. 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 on board, 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 all 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 messy. 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 front end, 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. 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. 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 these are 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 this is 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, OK, 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 a problem that you normally have when you have a very clever UX product. Guys, they can say the basic auth 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 going to map all this hierarchy of the people using your system? So one shortcut that we took was to say, OK, 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 our 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. OK, so what's an extra? So for instance, if the thing needs to be picked up after 10 PM, then we should charge a bit more money. Then we put a rule. And then we put, OK, what does it mean more money? 10%? OK, 10% on top. Fantastic. And then if the track stays for a long time, then we need to charge more money. It's like, OK, how much more money? Well, it should be a fixed amount that we would decide later. OK, who decides that and when. Oh, this is the admin guy. OK, fantastic. And then you go like, yeah, and we need another extra. Like what? Yeah, some tracks need lift gate. OK, what the hell is a lift gate? Yeah, this thing you put behind a track that lets you put easier the pallets up if you don't have a specific machine to do that. OK, 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 vehicles. If you have many pallets, it should be included in the price, but otherwise it depends on the size. Like, OK, 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 a simple hack, which is we use a 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 logis 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 the repeat yourself framework, you discuss something like, OK, 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, track drivers 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 Framework to add an extra level of permissions or control. And then we ended up, in some cases, with dedicated end points, 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's 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. And documentation is, I wouldn't say lacking, but it's a bit hard to follow there. Because it's these n plus 1 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 going to 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 ways 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 of the magic, of the decisions on there. I would be very happy to share experiences, or even figure out ways of documenting this better. So there is a web page where you say, OK, after some playing around with the framework and some experience, go start to read this page where you have a lot of documentation, talks whatever that shows 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 partner coming from our mobile guys who said, 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 heard 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 this was not a normal transaction, a 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, a couple of thoughts, not so much related with Django Res 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. They have 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. Funny 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 transaction and email is OK. 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. You'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 this internal or pseudo front ends that you end up 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 had different thoughts in Europe, I think in 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 are 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, the spec that comes from somebody else? So for me, those were the main learnings I've been taking over the last year in OnTrack. One final thought is 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. So if you have been dealing with the Younger's Framework permissions, if you have been trying to teach other people about the Mplus1 problem, or if you just care about logistics, whatever, feel free to reach out to us. I would be super happy to have some discussions and talk, share 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. APPLAUSE OK, thank you, Sammer. We have 10 minutes left. So whoever has a question has time to ask it. So who has a question? No one? Well. Ah. 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 SAP or like a 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 frontend. 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 HTML and stuff on the back end or you just serve the API and that's all? So on the back end, we just do an API. We are lacking 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. Like, 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 Frameworks 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. OK, 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 you ask. 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 1 problem if you have been doing it? Or alternatively, how do you do permissions, advanced permissions with Django Res Frameworks? There were many Django Res Frameworks 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. Thank you.
 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 fast-pro development in your day-to-day work?  Okay.  Not that many, the rest is probably in research, hopefully.  And how many of you have you been using the Angular framework before?  Okay, perfect.  And a bit about me and how I end up using this stack.  I started programming some 15 years ago, building web platforms with BASO scripts and CGI.  Luckily around 2009, I entered a startup call F24, and they were using the Python stack.  It was mostly soap at the time, and Django started their life around that time.  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 Valflit and tried out  the Google App Engine type of approach.  Now what is OnTrack doing?  I will give a brief discussion.  Just need things 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.  That goes on and forth, and we just simplify that the standard marketplace way.  What do you mean by fast product development?  Usually when you're building a startup, and it might be completely different if you're  in research or if you're in a large company, but when you're 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 not 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 is 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 we will figure out, 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, our 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.  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 on board,  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 all 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 messy.  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 front end, 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.  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.  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 these are 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 this is 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, OK, 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 a problem that you normally  have when you have a very clever UX product.  Guys, they can say the basic auth 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 going to map all this hierarchy of the people  using your system?  So one shortcut that we took was to say, OK, 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 our 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.  OK, so what's an extra?  So for instance, if the thing needs to be picked up after  10 PM, then we should charge a bit more money.  Then we put a rule.  And then we put, OK, what does it mean more money?  10%?  OK, 10% on top.  Fantastic.  And then if the track stays for a long time, then we need to  charge more money.  It's like, OK, how much more money?  Well, it should be a fixed amount that we would decide  later.  OK, who decides that and when.  Oh, this is the admin guy.  OK, fantastic.  And then you go like, yeah, and we need another extra.  Like what?  Yeah, some tracks need lift gate.  OK, what the hell is a lift gate?  Yeah, this thing you put behind a track that lets you put  easier the pallets up if you don't have a specific machine  to do that.  OK, 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 vehicles.  If you have many pallets, it should be included in the  price, but otherwise it depends on the size.  Like, OK, 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 a simple hack, which is we use  a 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  logis 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 the repeat yourself framework,  you discuss something like, OK, 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, track drivers 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 Framework to add an  extra level of permissions or control.  And then we ended up, in some cases, with dedicated end  points, 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's 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.  And documentation is, I wouldn't say lacking, but it's  a bit hard to follow there.  Because it's these n plus 1 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 going to 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 ways 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 of the magic, of the decisions on there.  I would be very happy to share experiences, or even figure  out ways of documenting this better.  So there is a web page where you say, OK, after some playing  around with the framework and some experience, go start to  read this page where you have a lot of documentation, talks  whatever that shows 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 partner coming  from our mobile guys who said, 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 heard 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 this was not a normal  transaction, a 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, a couple of thoughts, not so much  related with Django Res 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.  They have 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.  Funny 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  transaction and email is OK.  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.  You'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 this internal or pseudo front ends that you  end up 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 had different  thoughts in Europe, I think in 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 are 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, the spec that comes from somebody else?  So for me, those were the main learnings  I've been taking over the last year in OnTrack.  One final thought is 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.  So if you have been dealing with the Younger's Framework  permissions, if you have been trying  to teach other people about the Mplus1 problem,  or if you just care about logistics, whatever,  feel free to reach out to us.  I would be super happy to have some discussions and talk,  share 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.  APPLAUSE  OK, thank you, Sammer.  We have 10 minutes left.  So whoever has a question has time to ask it.  So who has a question?  No one?  Well.  Ah.  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 SAP or like a 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 frontend.  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 HTML and stuff on the back end  or you just serve the API and that's all?  So on the back end, we just do an API.  We are lacking 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.  Like, 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 Frameworks 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.  OK, 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 you ask.  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 1 problem  if you have been doing it?  Or alternatively, how do you do permissions,  advanced permissions with Django Res Frameworks?  There were many Django Res Frameworks 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.  Thank you.
Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_0_119.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_120_191.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_192_14519.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_14520_19739.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_19740_25427.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_25428_30659.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_30660_30707.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_30708_30935.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_30936_31139.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_31140_31211.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_31212_31427.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_31428_32603.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_32604_33095.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_33096_34631.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_34632_34679.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_34680_34739.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_34740_34811.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_34812_34979.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_34980_35027.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_35028_35243.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_35244_35795.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_35796_36563.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_36564_36839.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_36840_37547.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_37548_37607.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_37608_37895.png Samuel_Fuentes_-_Fast_product_development_using_Django_Rest_Framework___lessonslearned_0hrf83ZIKw0_37896_38028.png
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 fast-pro development in your day-to-day work? Okay. Not that many, the rest is probably in research, hopefully. And how many of you have you been using the Angular framework before? Okay, perfect. And a bit about me and how I end up using this stack. I started programming some 15 years ago, building web platforms with BASO scripts and CGI. Luckily around 2009, I entered a startup call F24, and they were using the Python stack. It was mostly soap at the time, and Django started their life around that time. 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 Valflit and tried out the Google App Engine type of approach. Now what is OnTrack doing? I will give a brief discussion. Just need things 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. That goes on and forth, and we just simplify that the standard marketplace way. What do you mean by fast product development? Usually when you're building a startup, and it might be completely different if you're in research or if you're in a large company, but when you're 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 not 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 is 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 we will figure out, 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, our 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. 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 on board, 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 all 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 messy. 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 front end, 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. 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. 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 these are 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 this is 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, OK, 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 a problem that you normally have when you have a very clever UX product. Guys, they can say the basic auth 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 going to map all this hierarchy of the people using your system? So one shortcut that we took was to say, OK, 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 our 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. OK, so what's an extra? So for instance, if the thing needs to be picked up after 10 PM, then we should charge a bit more money. Then we put a rule. And then we put, OK, what does it mean more money? 10%? OK, 10% on top. Fantastic. And then if the track stays for a long time, then we need to charge more money. It's like, OK, how much more money? Well, it should be a fixed amount that we would decide later. OK, who decides that and when. Oh, this is the admin guy. OK, fantastic. And then you go like, yeah, and we need another extra. Like what? Yeah, some tracks need lift gate. OK, what the hell is a lift gate? Yeah, this thing you put behind a track that lets you put easier the pallets up if you don't have a specific machine to do that. OK, 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 vehicles. If you have many pallets, it should be included in the price, but otherwise it depends on the size. Like, OK, 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 a simple hack, which is we use a 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 logis 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 the repeat yourself framework, you discuss something like, OK, 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, track drivers 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 Framework to add an extra level of permissions or control. And then we ended up, in some cases, with dedicated end points, 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's 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. And documentation is, I wouldn't say lacking, but it's a bit hard to follow there. Because it's these n plus 1 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 going to 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 ways 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 of the magic, of the decisions on there. I would be very happy to share experiences, or even figure out ways of documenting this better. So there is a web page where you say, OK, after some playing around with the framework and some experience, go start to read this page where you have a lot of documentation, talks whatever that shows 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 partner coming from our mobile guys who said, 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 heard 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 this was not a normal transaction, a 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, a couple of thoughts, not so much related with Django Res 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. They have 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. Funny 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 transaction and email is OK. 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. You'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 this internal or pseudo front ends that you end up 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 had different thoughts in Europe, I think in 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 are 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, the spec that comes from somebody else? So for me, those were the main learnings I've been taking over the last year in OnTrack. One final thought is 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. So if you have been dealing with the Younger's Framework permissions, if you have been trying to teach other people about the Mplus1 problem, or if you just care about logistics, whatever, feel free to reach out to us. I would be super happy to have some discussions and talk, share 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. APPLAUSE OK, thank you, Sammer. We have 10 minutes left. So whoever has a question has time to ask it. So who has a question? No one? Well. Ah. 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 SAP or like a 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 frontend. 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 HTML and stuff on the back end or you just serve the API and that's all? So on the back end, we just do an API. We are lacking 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. Like, 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 Frameworks 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. OK, 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 you ask. 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 1 problem if you have been doing it? Or alternatively, how do you do permissions, advanced permissions with Django Res Frameworks? There were many Django Res Frameworks 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. Thank you.
I say to is attending the talk, how many of you do, or you can say you do fast-pro development in the Django stack because Python has many flavors, examples we will be discussing afterwards. So from the beginning using Python, using Django, I value a lot for this type of problem, because 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 is the architecture principle that we tried to better than web sockets. In our case, we quickly advanced permissions on the models. Then we used problem is. Then you teach them how to use complaining about the whole framework of the around with the framework and some experience, go Framework, but a bit more higher level. One thing is to try to build everything themselves. They Thank you. So the way we work is the only