Harout and Andrew are the engineers behind pinplanet, a free Django-based mobile app to pin where you’ve been. We discuss moving from a PWA to native iOS, Kotlin for Android, testing and performance challenges along the way, type hints, and more.
Carlton Gibson 0:06
Hi, welcome to another episode of Django chat. I'm Will Vincent joined by Carlton Gibson. Hi, Carlton
Hello Wil.
Will Vincent 0:12
And we're very pleased to welcome Harout and Andrew from pinplanet. Welcome both of you.
Harout Boujakjian 0:15
Hello. Hey guys. It's nice to be here.
Will Vincent 0:19
Yeah, thank you for joining us. So I'm excited to talk about your app and plan it because it's a chance to talk about something from prototype to production, since you've been working on for several years. But hopefully you still remember those early, early days. So maybe we could start with what is pin planet and then we'll go from there.
Harout Boujakjian 0:34
Okay, so pin planning is an app that lets you pin where you've been, it's a way to keep track of all your travel memories in one place. So like, let's say, for example, that you visit Portugal, and somebody asks you about it later, they want to know your travel Rx pin plan, it helps you essentially keep track of all of that, you'll be able to go back and tell them all the spots you visited, like the restaurants or hotels, museums, etc. You can keep track of your photos, you have your travel buddies, so it also functions as like a trip planner. And then you get to visualize all of your pins on a on a 3d Globe, as well as a
Will Vincent 1:06
2d map. That will that was one of the things that's most striking when I first sign up for it is that the 3d Globe? Can I ask what are you using to generate that at that time? No, that's not Django. But what are you using to generate the globe? Also,
Harout Boujakjian 1:18
I have to ask, which, which globe? Are you talking about? The one in the getting started or the one on the profile now? Oh, because there's two different?
Will Vincent 1:24
Yeah, that's true. Either. Tell me how they're different. And
Harout Boujakjian 1:29
I can answer both. The the one and that's in the Getting Started prompts is our older globe, it was a web globe that are built in JavaScript using d3. And then the newer globe takes advantage of Apple's MapKit. So they have a way to render 3d Globe. It's a little bit more performant. Okay. So we started using that one on the profiles instead of the web one. Okay. Very cool.
Carlton Gibson 1:52
Okay. And on the back end is using geo Django is this Yeah, yeah. Yeah. All right. Good. You were on a Django show? Go on. Tell us about that. What's what's the what's the down and do it? So like, what's the how do you any build such an app? Because it's quite cool to play with. And
Harout Boujakjian 2:11
okay, so the the front end is the front end is completely native. We did start as a web app. And we're definitely happy to talk about talk about the PWA aspects as well. But so the front end is iOS for right now. We are in the midst of building an Android app. And we're actually getting pretty close to releasing it. The back end is Django and obviously a little bit of geo, Django and then our databases is Postgres. We have Redis server running for cash. Everything runs on EC two instances. So that's good. That's like the Okay, quick, quick and dirty.
Carlton Gibson 2:42
Right. So brilliant, but so it's literally just the two of you. Yes,
Harout Boujakjian 2:46
we are. We're the engineering team. Yeah, okay.
Carlton Gibson 2:49
So here's here's what I want to know. How's it going building a Django back end? Okay, in just a few easy two instances scaling Okay, fine. No problem a PWA. To begin with. Okay, do you know the get that then an iOS app? Oh, hang on. And then in two to two pairs of hands get quite so much done. Must be challenged.
Harout Boujakjian 3:10
I don't even know how to answer that. I'll answer it a little bit. I think that we were like a pretty efficient engineering team. Andrew and I, Andrew nice skills. We complement each other really? Well. That's my answer. But I want to hear what what Andrew thinks. It's
Andrew Hornstra 3:26
about as hectic. As you as you kind of made it seem it sounds. Yeah, especially with with adding iOS. And we now sent him over suddenlink. We're supporting so many different versions of the app and with a PWA was just one thing. And it's, it's been it's been a bit but yeah, like Haroon said, every time I have an issue, I go to him, and he tells me how you, you miss this very obvious thing, or vice versa. And so it works out very well. And
Harout Boujakjian 4:02
let me just say on the air that Andrew is my Python guy, so I know Python pretty well. But if I really like want to get into Python details, then I then I go to. So I think this synergy works really well.
Will Vincent 4:13
Now who who? Yeah, I was gonna say who's so iOS? Are you both writing Swift? Or are you dividing that and versus Java for Android? How's that division of labor happening?
Harout Boujakjian 4:23
So no, I do iOS fully. Andrew has been taking over the Android app. I helped a little bit over there. It's it's more like a maybe like an 8020 split. And then both of us also do back end handle database stuff handle server stuff, but that's more I would say Andrew specialty is back end but I'm you know, I'm comfortable getting in there as well.
Carlton Gibson 4:42
Okay. And since we're in that, like, Andrew, you have you been digging into the whole Kotlin thing in Android or yet to Java base. We're
Andrew Hornstra 4:50
100% Kotlin and jetpack compose.
Carlton Gibson 4:56
Brilliant. And so for the listeners Like jetpack compose is a bit like swift UI. It's one of these declarative UI frameworks that you can just sort of spell it out. And then the runtime works out how to render it. And so you're not, it's simpler and quicker, I guess.
Andrew Hornstra 5:10
Yes. Simpler in syntax. The, the titular composition aspect of Jetpack compose is. Sometimes it feels inconsistent, and like a bear to wrestle with. But I'm sure that's a that's
Harout Boujakjian 5:29
an understatement. From the literal.
Carlton Gibson 5:34
So the essential complexity of UI design didn't just disappear. So
Andrew Hornstra 5:37
you know, it didn't,
Carlton Gibson 5:41
ever. Okay, so here's my burning question about Kotlin. Since you've been doing it, you go into Kotlin websites are like, you know, a cross platform, multi this multi that and then they got this thing down the bottom, it says iOS, and oh, so is it yet at the case that you building chunks of your app in it for both iOS and Android? In Kotlin? Not?
Andrew Hornstra 6:03
We're not doing that. And we're not going to go in that direction? We're, we're sticking with native for both? Which is? Yes, a lot of work.
Carlton Gibson 6:14
Okay, so can I ask why? Because the like, you know, and this comes back to the idea, well, you know, PWA is or why don't just ship ship a PWA and ship it to every platform? Why go native in the first place? You know, why? Why not try and use the cross platform code, then like, what does native only give you? Well,
Harout Boujakjian 6:29
it depends what, what exactly you're asking for. So is it the difference between PWA versus native iOS? Or is it something like Kotlin multi platform, which is saying, Alright, you're gonna use one code base to also build iOS and Android? Because the answers are different,
Carlton Gibson 6:44
right? No, it really kind of eats bugs, right? Because I'm still basically fascinated by the fact that the two of you are building a back end plus multiple front ends, like, we just want one pair of hands. And that's kind of incredible, in a way, it's kind of really hard to do, and to do it at high quality. You know, that's a lot of effort. So I'm, I'm kind of trying to tease from you. The decisions that lead you to go that that hardest of routes. Okay.
Harout Boujakjian 7:12
All right. So the easier one is, the easier way to answer this is why we didn't go called Kotlin, multi platform, I think it's mostly it's mostly me, I just don't believe in these cross platform solutions, they always, they always sell it a lot better than it actually is like, you get the first 80% done really well. And really fast. But then the second 50%, you're pulling your hair out, and you go gray by the end of it. So that's that's the reason for that. The reason we went from PWA to native is because that's more complicated. We've trained users for 10 plus years, you know, over a decade to look for apps in the App Store. So when you tell them, Oh, I built this app, and they're like, oh, okay, what does it call them? You look for it in the app store. And we're like, oh, it's actually not in the App Store and trying to get over that hurdle is is very, very difficult. That in Notifications, yeah, that in push notifications. So that was gigantic.
Carlton Gibson 8:06
A lot. There's a lot of people in the word wall world who are kind of cross with the way that PWA is just aren't as capable as native apps.
Harout Boujakjian 8:14
It's really unfortunate. Because like two years ago, I was such a huge advocate of the web. And I still love the web, I think I think the web is the best cross platform solution. There's nothing that comes close to like the cross platform capabilities of the web, because every platform essentially has some version of a browser. And that's awesome. But yeah, Apple in particular, does their absolute best to just make that experience not so great.
Carlton Gibson 8:39
I think the Basecamp app is like that, right? It's essentially web views with a with a very small native wrapper around it to integrate with the with the iOS, but essentially, all of the views are exactly the same, you get the Basecamp website.
Harout Boujakjian 8:54
Yeah,
Carlton Gibson 8:55
I don't know. Okay. All right. So one more question here. And then I'm gonna let we'll have a go because, well, I've got you're both on the hook. So the big Impedance Match for me is the serialization between so you've got the Python back end, and you serialized it, I know your JSON objects, and then you deserialize into Swift objects and, or your Kotlin objects or whatever. So, too, can you describe how you've how you've dealt with that and what your pain points have been? And you know, what, what you've enjoyed and what you haven't, and, you know, we'll, I think follow up there. But also, there's another little switch back to that Kotlin bit, would you reuse the Kotlin bit just for that kind of networking layer? Or you know, is that just doesn't bring enough to the table?
Andrew Hornstra 9:39
Yeah, I can, I can speak to I can speak to the Kotlin aspect of that. I've, I've only been using Kotlin for, I guess three or four months, three months. Yeah. Well,
Harout Boujakjian 9:50
it's remarkable that you've been able to build the app and then three months, so a lot
Andrew Hornstra 9:55
of work, but I really, really enjoyed it. Collin. And I've been very impressed by how intuitive the syntax can be. The the library we're using for the client side, HTTP is K Tor. And that's also a server side. So I, I think one of my next projects will be a Kotlin server side application just to mess around with that. But for now, I think we're just because of the complexity of a two man team managing four machines, two platforms. Yeah, we will stick with just one for now. But
Harout Boujakjian 10:44
and let me just chase, I'll answer the serialization piece, which I think is interesting. It's basically double the amount of work and there's no way around that, like, we have our DRF serializers, which, you know, will serialize and deserialize the data and we've slipped that into input and output serializers nowadays, and then in Swift or Kotlin. You know, we have essentially very similar waste to the you know, quote, unquote, serialize the data into Swift and Kotlin objects,
Carlton Gibson 11:09
you but you end up writing a set of kind of almost boilerplate classes in Java in Python, and it doesn't matter if you're using Garraf serializers, or, you know, Python decorators and characters. Like, it's still boilerplate. It's still rubbish, right? And then you've got the same in Swift with the coding, you know, the coding Protocol, or whatever it's, it's called, but it's again, and they've got lots of utilities, like they know how to map from Python names to Swift names. Okay, great. But it's still rubbish to write those. And they spend a lot of time doing that, right? Yeah,
Harout Boujakjian 11:41
yeah. There's no way around it. I feel like we put the bill in a while ago. And we're like, yeah, that's, that's okay.
Carlton Gibson 11:47
It's costly. But what about what about LLM 's and co pilot and these things have anything there to speed up all of your, your work, I
Andrew Hornstra 11:58
think we've we use, we use Chachi. Btw, one time, a while ago, probably six or seven months ago. And it helped. Yeah,
Harout Boujakjian 12:09
there was some weird web view layer we were doing, we're trying to send some data to the web view for the Old Globe. And then there was like one line that we got from chat GPT. But for the most part, I don't, I don't actually ever use GPT. But I do the support in PI charm. I think if that counts is pretty good.
Andrew Hornstra 12:28
Actually, I can say that. I've used chat GPT a few more times. It's never given me any code. That was something it's never given me any changes, any code I can include, mostly because of troubleshooting very complicated problems. And the difficulty is almost always something so mature, and like as many files as we have, explaining what the problem is. And if you can do that, you have a pretty good shot at fixing it yourself.
Carlton Gibson 12:58
So you're still essentially the bottom line is you're still when it comes to the serialization and deserialization. He's still sort of having to maintain that mapping layer. You
Harout Boujakjian 13:08
know? Yeah. Yeah,
Carlton Gibson 13:10
I had. Yeah.
Will Vincent 13:11
Have you there. We, we recently had Simon Willison on who's obviously a big advocate of MLMs. But I mean, have you tried? Was it pi Asst. Right, that's the new PI charm, one that they just launched. I haven't had chance to play with it myself. But it's sort of like their copilot that they just the new update to the PI charm.
Harout Boujakjian 13:33
I did recently try it. I didn't like it. Actually. I thought it was kind of it was like a little annoying, because some of the suggestions were were just not right. And it kept doing weird casing like it would give me camel case in Python. Is that is that the right one? Yeah, not the underscore, not the snake case. Gave me camel case names. I'm just like, you know, this
Will Vincent 13:53
is Python. So Carl, did you like co pilot though, right? Yeah,
Carlton Gibson 13:56
no, but I like it for these kinds of boilerplate T things. And I like it, you know, I'm like, I had Okay, so today I was writing a property that maps from choice fields and make sure it's displayed in the right way. And it's like, okay, I need some tests for it. So let's select it Copart and do some tests for this. And it gives me the half a dozen cases, and I don't have to take them out by hand. I'm like, okay, that's fine. And the rest of its, you know, not useful. But that little bit saves me a few minutes. And I used to write API's for living. So I back in the day, I used to write iOS apps with the DRF back in and the bane of my life was this mapping of serialization or D serialization. And every time it updates and every change, it's like, Okay, I've got to make a change in the app to the serializer change in the RF back into the serializer. Make sure that that's backwards compatible or reintroduce a version then point Ah, just it was kind of like the legwork of the you know, it's not difficult. It's not challenging. It's not it but it's, it's the stuff that needs to be done the grind work and My hope with these toolings is that they can automate that in some way that they can take away a little bit of the mundane 80 of that particular mapping task, which it, you know, it's not difficult. But it's time consuming.
Andrew Hornstra 15:15
I think the direct integration entirety ease is going to be the biggest the biggest value add for. I mean, this is a very obvious thing to say. But for developers, just because swapping back and forth between Windows copying and pasting, waiting for the output there and just the amount of task switching, it's it has a higher cost to your productivity than I think either of us were willing to willing to take to fit that into our workflow. The
Harout Boujakjian 15:45
other the other kind of issues that were both of us are jumping between two IDs, we both use PI charm. And then I also use Xcode and Andrew, Andrew uses Android Studio. So it's a kind, it's a little tricky. You know, unfortunately,
Carlton Gibson 15:59
yeah. And I guess, part of me is, I'm sorry, I'm gonna keep banging the same drum. I realized, but so this part, the promise of the Kotlin layer is that if you could incorporate that as a library into your iOS app, that mapping could be done, like once in the one layer, but whether or not you can, you know, I'm not gonna ask the same question again. Got that.
Will Vincent 16:21
All right. Well, we've we've, we dove right into it. But I'm actually curious if we could back up to how you two met how like your backgrounds in programming and how it led you to Django? Because that's always interesting to hear. I know you both I believe studied at George Mason University. Is that right? And maybe that's how you met? Yeah. Is that how you met as well?
Harout Boujakjian 16:41
We We met through a friend that I guess also went to Mason, and then have we've been working together ever since I can I can tackle the question first, if you want just quickly go through my background. So I studied math, like applied math and computational mathematics at Mason, I did a lot of programming. I actually, surprisingly, I'll say this, something where I took AP computer science in high school, and I just did horribly. It was in Java, it was just like the worst experience. And then I retook the class A couple months later, after the AP exam and in college, and it was in Python, and I did much, much better and everything just clicked. I don't know if it was because I didn't like Java, or just because Python is a great language. But that was kind of where it started. And then, you know, as every math major unfortunately goes through, you do a lot of MATLAB, when you're doing kind of computational programming. This, this was just just a life that I live for a couple years. Then I went back to Python, I did some data science was a data analyst for a little bit. And then at some point after that, like, you know, while doing data science, I started building tools for people. And this for me was just like the big switch. When I started building like tools for data scientists or business analysts or project managers, I realized, okay, like software engineering is the thing that I really love. And then, and Python has always been my my go to choice for for building backends. I jumped around, I did flask, I did fast API. I did Django, and they kind of did the entire rotation. Again, I guess fast API wasn't as big at the time when I first started. And then I don't know something about Django, just, I mean, this is so cliche to say, but like, the batteries included aspect, the stability, the maturity of the framework, I was just like, Yeah, this is awesome. I, I'm just going to use this,
Carlton Gibson 18:23
the that that response lives, local innovation, as you said, it's like, somehow, it's like when you're building an advocate here to sort of get out of your way. And, you know, there might be different frameworks or different options, but Django is quite sweet. And it's on its way. It's quite, you know, saddle the edge is not COVID Over the years, so it fits the whole very well.
Harout Boujakjian 18:45
Yeah. All right, Angela, you wanna
Andrew Hornstra 18:48
so also went to Mason, I studied math and physics, and didn't do didn't do hardly any programming for a very long time. I took one computational data science class, CTS, 130, did a little bit of MATLAB did not enjoy it at all. And then said, I think I'll be able to have a career as a physicist with no programming very naively. And both of those things were wrong. So I didn't end up going and doing grad school. And later on at, at Mason, I decided, You know what, I really should learn how to program and started with Python again, and read through. Jake VDPs Jake Vander classes, amazing whirlwind tour of Python, and Python data science handbook. And those are some of my favorite tools. Some of my favorite books that I've read on learning Python, love those. So I read through those did some automate the boring stuff. And then found my way at a at a bank as an analyst doing work with Pandas for about a year, moved on to being an analyst just doing sequel for eight hours a day. For two years, I found my way back to working on huge models with terabytes of data in PI spark. And then, eventually, Rutan, I started working together right after that, and a start up doing doing Django. Well, I was doing Django and I, when when he told me he wanted to do Django for the back end, I was, I had a trip to Chicago planned. So I was, I got all my stuff together, got on a train. And the train was like 1820 hours. I just did the Django tutorial on the train. I did the dear of tutorial on the train. And I think to this day, we do about Well, I do about 30% of my code is written on an Amtrak super,
Carlton Gibson 21:07
did you commute regularly? Or do you just have to go on special trips to get anything done?
Andrew Hornstra 21:13
Man, it's got to be both. It has to be at I go down to, I'm in Arlington now. And I head down to Richmond to see family and friends pretty regularly. And you have trains just the perfect, it's the perfect place to work. Cheaper than an office probably
Carlton Gibson 21:35
cheaper than a co working Yeah.
Will Vincent 21:39
Back when I was in college, I went to William and Mary for undergrad and I would go up to Boston, which is almost as long as it can go. It's about 15 hours, but this is pre This is 20 years 20 plus years ago, so I would just read two, three books. But there is something you know, as an adult, or as a parent, you know, to Carlton's point to like not be interrupted, you know, train is sort of like daytime, you know, middle of the night. No one's going to bother you vibes. Which is Yeah, hard to come by.
Andrew Hornstra 22:10
It's great. And you you cannot leave, you can't distract yourself with something else. Wi Fi is too slow to stream, right. No excuses.
Carlton Gibson 22:20
So just don't just don't download the, the series before. We've got nothing. So, so unpin planet, geo data. So gone, we don't talk enough about geo dango. I think on the show, it's like probably the best geo platform, you know, for the web out there. And yet, we hardly ever mentioned it. So give us a you know, give us give us your experience with geo Django and entity
Harout Boujakjian 22:44
wanna short.
Andrew Hornstra 22:48
Geo Django on macOS is our current setup for local Dev. And we don't have it in Docker, which has led to some frustrations. It by far the most difficult part was getting it installed, getting everything working all the correct versions of everything, making sure it's detected. Pointing Django at the right set in the settings at the right. G doll files and all that stuff. It's just as utilities,
Harout Boujakjian 23:20
it's fair to say that we still have nightmares about G dal and proj. Installation.
Andrew Hornstra 23:26
And absolutely, brew. Yeah,
Harout Boujakjian 23:29
and brew brew doesn't help in this case, it just things become a gigantic mess. If
Will Vincent 23:33
there was a Docker image to end all images, would that help her? No, because
Harout Boujakjian 23:39
we used to work in Docker. But honestly, at some point I just got annoyed with like having to rebound and then the container caches maybe sometimes a little too strong. So you have to rebuild the entire container setup. And then it just ruins your flow. So at some point, I remember talking to Andrew, I was like, let's just put, let's just run G unicorn directly on our death machines. And then, and it's just so much faster.
Andrew Hornstra 24:00
If you can't tell, we're really into doing things that do not scale.
Will Vincent 24:07
Well, they scale eventually. Yeah. And it's just the two of you. So you can get away with both figuring out your local dev setup right with you. Who was 20 of you, then I think that's where, you know, the Docker pain is kind of
Harout Boujakjian 24:23
the maybe these are the perks of a two person team currently.
Will Vincent 24:27
I think so. Yes. Yeah. But anyways, yeah, so do you. Yeah. So once it's installed, though, what was I mean there so there's obviously Django project Doc's. But like, how did you? How do you learn that? How did you baby step your way to building pin planet with it?
Harout Boujakjian 24:41
So the well let's let's talk about our use case first. So the thing the reason why we wanted to use geo Django and really post GIS is because we want it to be able to automatically capture, like, if you pin somewhere from the lat long we want to know what continent that's in and then that also acts Send it to what country that sent so we can run some continent and country stats like that are that are on the profile. So we basically we took a bunch of GIS data, we put it in, it's about like 100 megabytes. I think it's like you could even look it up. It's the coastlines one meter resolution thing. alyssum data. Yeah, we've we put that in post GIS. And then every time you kind of place we run an ST can, I think it's st contains an ST contains query to basically say, take this point, this lat long point, and then tell us like, which of these countries it's in, and then which continent it's in. So that that's like the extent of our current post GIS use. But we want to extend that to cities as well. So we can also start capturing some city data.
Andrew Hornstra 25:45
Yeah, the, the, I think, yeah, the extent to what we use geo Django for is that SD contains, that's very nice to not have to write some raw queries on and be able to do this, it's really convenient to be able to just slightly extend the ORM with the geo Django extension. That's, it gives me a lot more confidence about having that work in the future.
Carlton Gibson 26:13
But yeah, you're not going to write it yourself. Yeah. Yeah.
Andrew Hornstra 26:18
And it's, I guess, the biggest issue we've run into, has been when we tried to parallelize testing, outside of installation, when we try to parallelize testing, because we, like, re recreating that database, with all of the all the geo data in it was was a bit of a pain, because
Harout Boujakjian 26:44
you need this is one of the cases where you need the 100 megabytes of, of your GIS data in the database, even if you recreate it, so we have to re import it every time you recreate the database. It's a little bit of a testing. Like there's some hassle there. Yeah,
Carlton Gibson 26:58
I'm wondering if there's some clever snapshotting DB snapshotting technique you could use where you just sort of swap in a snapshot and get back and then speed that up. But you know, haven't got one, two lessons. If
Harout Boujakjian 27:09
you find one, send it our way. Because that would make our testing much faster and easier. It does
Andrew Hornstra 27:13
give me an idea, though. Thank you for saying that.
Carlton Gibson 27:15
There's I'm sure there's some Postgres thing that does that. Oh, I'll find I'll look it up when we're offline. I'll see if I can
Will Vincent 27:22
search. So I had fun playing around with your search. Can I ask what what are you using to power that? How? How was it building out search because that's, that's a non trivial thing to what search while like when I saw on like I, I typed in just the zip code for a place. For example, I guess once I was all logged in, there was a plate for play set where you've been I, I believe I typed in, yeah, I typed in zip code, or I typed in the name for
Harout Boujakjian 27:47
our, for our search, we use Apple Maps. And thankfully, in Swift, they actually have a way to just, you could just start typing stuff in and they send the request for you. So this is really useful. And then we're also we're actually also using Apple Maps, but their server API's for Android to have a consistent search experience.
Andrew Hornstra 28:08
I've been for a while. I've been for a little while, trying to convince her route to make our worst decision yet. Which is to take the sub terabyte of OSM data out there loaded into a post GIS instance. And host our own search functionality with that awful idea. You something that's already out there. But
Harout Boujakjian 28:44
the worst part is that when you're two engineers, and both of you guys know, like how to do stuff like this, and you're excited by big tasks, like I'm sometimes like, well, maybe maybe we should do that. And then I think you got a terabyte of data to host. You're gonna have to do caching and all this stuff. So I
Andrew Hornstra 29:01
will look at our issues list and decide, yeah, that's a good procrastination thing. It's
Will Vincent 29:05
like, ooh, like this big.
Carlton Gibson 29:08
I got to university. Is every engineering decision ever, ever writ large? No, it's like, we want to do this ourselves. Because clearly, we'll do better than what's available. But can we? Yeah,
Will Vincent 29:19
it's all about the journey anyways.
Harout Boujakjian 29:21
So for the place search. So like, if you go back to the Explorer page, and you start typing stuff in, that would actually is I think it's just an i contains right now, we had considered setting up Elasticsearch, but there were there. I guess it's the prioritization is the real answer for why we haven't done that we want to we want to improve search,
Carlton Gibson 29:39
actually. And then you did explore Postgres search before going all the way to Elastic right to a separate thing.
Andrew Hornstra 29:46
I'd set up a full text search set up for for that functionality and tweaking it it. It wasn't great. I'd set up trigram search as well. And we just couldn't get the results to be to feel good when you're, like actually searching it. So we'd always type in some really, people are gonna look for London, right or New York. And you could get one to work well, and one to just not work well at all. And, yeah, we gave up and I can teams just works really well. It gives you what you expect. That's my
Carlton Gibson 30:27
favorite story. Yeah, it
Will Vincent 30:29
wasn't it wasn't an issue. I mean, I think there was something like I was I added in like Django con us and I typed in Durham, and just Durham and the default was in the in the UK, which makes sense, but then I just added, you know, NC. I mean, it was, yeah, it was, it was more than sufficient. And searches, you know, everyone compares you to Google. So it is sort of like it asymptotes pretty quickly on the results unless you're building a search engine yourself. Anyways, okay, that was, that was one thing I want to ask about. Can we can we talk about the PWA? How did you? So what, what actually was the PWA? What was that? Set up? Okay,
Harout Boujakjian 31:03
yeah, so the way that this initially happened, and was my girlfriend, who I this is maybe that one beginning portion of the story that we didn't talk about. So this idea came from my girlfriend wanting to pin all the places she had been to. And this started in November 2021. So at the time, because I had done so much web development. And I was working at a company where it almost felt like I was at an agency, I was just constantly building new projects. I said, Alright, let me see if I can take what you want, which is an app and build it on the web. And that's where the kind of the PWA came up, I realized, like, okay, you can actually add stuff, you can save it directly to your home screen, it will function like an app. So I ended up writing tons and tons of JavaScript, which I'll say this on the air, I like JavaScript, I don't have an issue with it. I don't think it's a better language than Python. So. But in any case, I built the initial versions of it as a web app. And we even promoted it pretty heavily as a web app, like, you know, got a bunch of people to install it. And then, about three months into it, Andrew and I started working together on it as well, because a one person engineering team for such a big project just just doesn't work. And And now, I can't imagine, I can't even remember what it was like to work on this without Andrew also being here. But we had, we had a web app, obviously, the constraints that I talked about at the beginning of the episode, which is like, finding web apps in the App Store don't have that functionality doesn't exist, push notifications don't exist. Apple makes the experience not so great. We bit the bullet and said alright, we should probably just go native, it
Andrew Hornstra 32:46
hard to convince the users to to come to you, especially when you have so little visibility. So you got to you got to go to where they are. Yes.
Carlton Gibson 32:54
But you'd like the visibility in the App Store is not great. Unless you're like one of the chosen five apps, they put on the, you know, the homepage there. Like you'd never find pin planet by browsing right? You'd never find some other indie app by browsing. So it's, you got to do the same amount of marketing. Well, the
Harout Boujakjian 33:14
cool thing actually, is that similar to SEO, there is ASO which is app store optimization. And if you get keywords, you can actually rank for stuff, which is somewhat surprising. huge
Andrew Hornstra 33:26
increase in signups from Yeah, one keyword tweak. Yeah,
Harout Boujakjian 33:31
we we did like we've done small keyword tweaks here and there to see, the trickiest part is actually thinking like, well, you know, this kind of app isn't like the norm. You know, Instagram is the norm nowadays. Like if you think about, alright, I want to upload my photo somewhere or social media stuff you think of that. But painting all the places you've been to isn't something that people are always thinking about. So one of the hardest parts of this project is actually thinking like, alright, well, what would a user potentially type in to find the kind of thing that we've created?
Will Vincent 34:01
Yeah, I mean, one, I don't know if you thought of the single one. I'm familiar with families that have like a family, you know, map, right. And then they pin like, where the family has gone or like, you know, different colors, like if somebody for big does, I don't know, if the family angle plays into it at all. I would think it's more like the 20 Something backpacking crowd would be like the default but there's also Yeah, I know, a number of families I know have that big thing. And we're always like, oh, we should we should have that. But we don't have a wall that would work for it. But yeah, it's a tricky thing, I guess. Well, you know, that's that's why there's business problems separate from tech problems, I guess. Right. And so, yeah. Carlton, you have a question?
Carlton Gibson 34:44
Oh, go Yeah, no, so in that case, then, I guess it's that journey is like how are you finding scaling? Yeah, I mean, you obviously coping but there comes a point in which you're gonna need a third pair of pants and a fourth, to keep growing
Harout Boujakjian 35:00
Yeah, I think right now that if we were to bring on another person, we'd probably bring on someone that does more marketing, honestly, because Anna on the other end, who is our third co founder, she's kind of alone in that regard. Like I help I try to help out as much as I can with marketing. But that's obviously not I'm not amazing at it, although I have been putting together tic tock videos, which is another story. But the way we would we would hire, we'd hire a marketing person. And Andrew and I would just continue to work together. It's not fair to her because like, if we got if we got another engineer, and she's like, still alone, doing all the marketing and stuff by yourself, you know, didn't
Carlton Gibson 35:38
know I guess, but you feel like so. But the flip side of that, you must feel like you're not drowning. You don't you, you're doing fine, you'd be running the servers running the back end, you're building the front end platform, the front end applications, you seem to be handling that very well.
Andrew Hornstra 35:53
We've built, we spend a lot of time and put quite a bit of effort into building out that kind of supporting tech infrastructure, we've yet we put a lot of time into our testing. We didn't start out with testing, we kind of we added it several months in. And that was a that was a big dedicated effort where we said we want to just we want to test, I think we just did all of our views. Yeah. And we've just maintain that coverage, we've got like 93% coverage, I think we checked recently, we have almost 500 assert statements. I mean, yeah.
Harout Boujakjian 36:36
Which, which gives us a lot of confidence to like continue to, you know, shift stuff around and build new features in the backend. So
Andrew Hornstra 36:44
took a lot of time, but it's saved many times more.
Harout Boujakjian 36:49
So that's that's one half of the story. The other half actually, is we spent a considerable amount of time like getting using Ansible. But like writing or writing our own playbook, so that we can spend stuff up if we ever need to, which actually has happened multiple times where like, you know, I can't even I can't, I wish I could remember a good one to say, like a good reason why we brought down one of our servers, and then we brought it back up, like within just a couple of minutes. I think it was Redis, I think we had done something with our Redis server. And then we decided, like, alright, you know what, this is not working, we want to upgrade to a larger server, we just brought that one down and brought the new one up. And like, it was so fast, and it gives you so much confidence to know that okay, even if something happens to the API server, we'll create a new server, a new EC two server, and then we'll run Ansible. And we're good. And that really, really does give you a lot of comfort.
Andrew Hornstra 37:38
It takes, you know, five minutes for us to deploy as many as many of these servers as as we want, because of the time investment into Ansible. upfront, which was, you know, maybe two or three days spread out a couple of weeks.
Will Vincent 37:55
Were you always on easy to write I believe I read somewhere your Heroku at one point, or did you always go easy to No,
Harout Boujakjian 38:03
no, no, we've we've always been always easy to and easy to
Will Vincent 38:07
write. And I assume that's because you both have prior experience in work settings using EC two. Or you just jumped right to EC two, just because that's what the big kids do.
Andrew Hornstra 38:17
I think he's looking me to confirm, yes, we both have experience with with EC two. Andrew
Harout Boujakjian 38:24
is more Andrew is actually more comfortable with AWS because of his work. When he was in banking, I used to work at a company where you could like just go to an internal website and provision a new Linux server. So for me, and that was like the easiest way to basically set stuff up. So both of us have a lot of experience, like running stuff directly on Linux. And I don't know, I guess, maybe we just find that it's easier.
Andrew Hornstra 38:48
Yeah, it's, it's very, we get a machine. We don't get someone's platform. We don't get like this specialty hosting. We get machine. I can SSH into it. I can do what I want. That's to me that simpler. So yeah, that's why we
Harout Boujakjian 39:08
stuck with easier. But let me say that. And I think this happens to us from time to time when newer younger, junior engineers say like, oh, well, how should we go about deploying this? I never recommend AWS, I never recommend an easy to instance, I never recommend anything Linux, I'm like, use a pas, it's so much easier. You have Heroku you have fly, there's a bunch of them. It makes it so so much easier. Because I think the unfortunate thing is like, it can be really scary. And when you're new to programming and deployment, and you see all the work you have to put in, you're like oh man, this is what I got to go through.
Carlton Gibson 39:42
And I it's like a cliff of complexity. Yes. Like, wow, all of that. So I want to dig into your testing. So you testing the Django, your Django application, mainly kind of with the view test API client or the test client and we're testing the view interface yet. Yeah, yep. Is that right? Yeah. And then And I imagine you've got if you've got special model methods or whatever, you might have a particular unit test to cover that, because, you know, helps you write the thing, if nothing else. What about testing against the front end application? So how do you? How do you test your iOS app or your Android? Android app? Yeah, how
Andrew Hornstra 40:16
do we test it?
Harout Boujakjian 40:18
We don't, unfortunately, the the problem with the front end is it's so dynamic, not in terms, like it's dynamic in terms of how frequently things are changing. And unfortunately, they're just this is probably the point where the two person team breaks out a little bit, we just don't have the manpower to say, alright, let's go through and do the same amount of testing for our front end. We're,
Andrew Hornstra 40:41
we spend so much time learning new ways to do things and mistakes that we were making, that we would have to rewrite our tests so frequently, more frequently. And I think we'd catch anything breaking because things haven't really, things haven't really been breaking too much. Well, fingers crossed. But actually, why
Carlton Gibson 41:05
to wait till you get off the show. Yeah, exactly.
Harout Boujakjian 41:07
Though, I will say the one thing that's actually useful here is that both swift and Kotlin are typed languages. And coming both of us have written, obviously use Python and JavaScript, which are super dynamic, but the type languages can actually save you from a lot of these really little mistakes.
Andrew Hornstra 41:25
I did not Yes, appreciate what you get from that kind of strict typing, and explicit typing with with these languages. And, man, I really like it's not a necessity for me going for I'm still very happy with Python. I still enjoy writing that more. But it's, it has not been an impediment for writing Kotlin it, it's forced me to think more about what I'm what I'm writing and code reusability. But, yeah, it's been very, very nice feature. Not in my way at all. Surprisingly,
Carlton Gibson 42:08
it's like if it runs is there's a reasonable chance it runs right.
Harout Boujakjian 42:12
Yeah. Yeah. So surprisingly,
Will Vincent 42:14
actually, who would have thought? Well, that's one of the the open questions, I guess, in the Django community is, you know, whether to mandate or support typing. And so far, they haven't weighed in which, because there is obviously the trade off for beginners, if you say, okay, just raises the bar a bit more. And yet, I would say the majority of projects at scale seem to use some sort of typing with with Python, because it saves you time in the long run.
Harout Boujakjian 42:44
Can I just say that I'm very pro type hints for Django as well. And I follow the issue. And I'm like, Okay, I really hope to get to this soon. But I don't know. But we do we actually use type hints for everything. That's not Django and Python. Okay, yeah, everything we've written, I think I like all of our utility methods and stuff we, we type int,
Carlton Gibson 43:05
and using, like a type checker with that as well. Are you doing?
Harout Boujakjian 43:09
We're just using built in PI charm. The problem is I installed my pi, and then it complain that all of the Django stuff isn't type. So it's Yeah, yeah.
Carlton Gibson 43:19
I know that if you read the my pie docs, in some depth, it talks about how to progressively type your project. But it's like, it's really hard to get anything going at all. It's like, I'm here for a day, and I'm still getting 1000 errors. And I'm maybe I'm not clever enough to work out all the config options. But surely, there should be a my pipe aggressive commands that just sort of says, Look, start off with this one. Can you fix this one? Okay, you fix that one? Can you fix this one now, but that doesn't exist? So
Will Vincent 43:48
we've mentioned performance, but I'm curious as you've gone from prototype to production, have there been some notable big performance issues that cropped up and? And how did you deal with them? I mean, I'm sure there are but you know, just like speeding up your tests or caching, like, is there anything that comes to mind? Because I find those are always interesting to hear. What, what, what pops up as you scale?
Andrew Hornstra 44:11
One of the one of the testing speed ups, we actually, it was an issue that we ran into at first where we had we were still sending our images because you can upload images for your places. And we have some sample images. And we we mock the the upload because we have a lot of custom stuff in that. They were still getting sent to s3 through tests. And I think s3 right now is littered with a bunch of test images. Yeah,
Harout Boujakjian 44:47
test underscore one test underscore two.
Andrew Hornstra 44:52
So finding finding the right testing configurations overriding your storage is a A config, which was with the new for to update for a while it was tough for us to it was tough to get the storage pointed towards a local towards storing locally. Yeah,
Harout Boujakjian 45:16
we couldn't get filesystem storage to work in testing after the for to upgrade. And we followed the issue and some people had very similar issues, but not exactly. And then I don't know what we did it works now four to 440s. Or I guess maybe yet had a fix for
Andrew Hornstra 45:32
it. There was there was a small line in the in the patch notes about something I think it's like prioritizing how it gets storage that gets the proper storage. I don't recall exactly what it was. But it it fixed it. It works now. But we talked about earlier for performance for testing, we tried parallelizing it, which worked really well until we needed to load in all that OSM coastline data.
Harout Boujakjian 46:01
Oh, actually, you know, what's a really good performance thing that I'll start it, but Andrew will, will finish it for our Explorer page, when you first click it open, and you get all of the people's pins. We have a monster SQL query for that. We don't have any, there's no machine learning just yet. We had considered putting it in. But again, perks of a two person team, it's a little too much effort. But that was taking multiple seconds. It was taking maybe one or two seconds in dev. And then I ran it in praat. And it was like multiple seconds. And then I told the injury. I was like, Okay, we have we have an issue. And then yeah,
Andrew Hornstra 46:39
that was. So we have, we have this ranking of all of our places ranking with noise. And it looked at all 10,000 of our pins. And it did a lot of it did a lot of operations, a lot of counts a lot of over windows and parts in it. This is all ORM by the way, which is been very and very nice. And we managed to cut it down to what, like 150 to 100 milliseconds. Yeah, roughly something like that, just by excluding ones that we knew we wouldn't, we wouldn't use. So the simplest solution, cut out a ton of our actual query time where we just went in, and we're not going to want to present you know, in the Explorer things without images, right, it's gonna be a boring thing to look at, and they're not going to get to it anyway, no one's going to scroll to 4000. And this
Harout Boujakjian 47:48
is like a crazy six way, seven way join, like this. So much data is coming, we basically aggregate our entire database. And we're wondering why like, ah, and why is it so slow? Yeah, good. It's like, well,
Carlton Gibson 48:00
what's, what's nice is that you've, you've got multi second query, bit of brain work comes down to, you know, quick enough. often the case that people are like, Oh, why is your Django slow? Or no, your query is slow. Let's fix your query. And we fix the problem, right, Carlton?
Will Vincent 48:17
Whether it was a Matias Django image field that we just highlighted in the newsletter, right? Do you think you was this?
Carlton Gibson 48:25
Yeah, well, I haven't. I wish use I'm using that on a project. I wanted a IDE, it's just a little field that lets you pick up upload an image but and pick a point of interest are placed in the image to sort of be the focal point if in case he gets cropped, and I wanted that for Avatar images, you know, you upload an image, you want to crop it round, and you want to say, look, that's the that's, that's the bridge of my nose there. So that's the point. And there are various options. And but I want it for various reasons. I wanted to use that one, because it's mainly because it's less code.
Harout Boujakjian 49:00
Let's call actually, I don't I don't think if I haven't heard of that one. We can look into that when you talk.
Will Vincent 49:06
You don't subscribe to the Django news newsletter because it was featured in there.
Andrew Hornstra 49:11
You know, I read every single one of those
Will Vincent 49:14
meetings. Sometimes, yeah.
Harout Boujakjian 49:17
I don't know what it is. Maybe I prefer the podcast, over over reading. I don't know what it is. Every time I see podcast episode, I'm like, oh, boy, here we go. Okay, that's how I that's how I stay up to date with all this stuff. And in Django for real though, people are surprised like, like, how do you know all the stuff about ginkgo and I'm like, There's an amazing podcast. And it really does help.
Andrew Hornstra 49:37
I just spent too much time on Twitter. Yeah,
Will Vincent 49:39
yeah. Okay, well, I feel a little bit better because sometimes I feel like I'm repeating myself because you know, if it's like in the newsletter we mentioned in the podcast, maybe I write something about it, but I know that not everyone is following every single thing that I do. So I need to that's good to hear.
Harout Boujakjian 49:53
I will say, Oh, just one comment about the the images, the our problems with images actually weren't even in Django, they were a client side, because when you are uploading images straight from your phone, we're talking. I mean, nowadays, like five to 10 megapixel images are not, it's not out of the norm, multiply that by potentially 1020 30. Like if you add photo dump images to your place, plus you add images each year spots, that's like I remember the first time I had added a pin something it took over a minute, and she had like five or six images. And I thought, that's a problem. So we actually have to handle compression on the front end. And resizing before we can even send it.
Carlton Gibson 50:33
Brilliant. And so you will actually crop the image on the client before uploading Oh, yeah,
Harout Boujakjian 50:39
yeah, we so we don't crop but we do. We do resize. And we had a very light amount of compression to bring it around 500 KB. And then that makes the request significantly faster.
Andrew Hornstra 50:50
We know what dimensions we're going to present to the user.
Carlton Gibson 50:54
And right. So you've no point having outside of that. Yeah,
Andrew Hornstra 50:57
that's that's been the nice part about developing for mobile. Yeah, you've got a bunch of different screen sizes. But versus, you know, if you're developing for desktop web, I don't have to support and care about a 34 inch monitor. And the 21 inch monitor at the same time. Yeah.
Carlton Gibson 51:15
And the angry user who uploaded their panoramic picture that yeah, why
Andrew Hornstra 51:21
can't this be full quality? 100? Meg? Yeah.
Will Vincent 51:27
Well, we're working on time, are there can you tell us? Like what's next for pin planet? Right, like you have, obviously an Android app coming? Are there any new new things you're excited about? Working on related to it?
Harout Boujakjian 51:39
So I think the Android app is the biggest one. We have tons and tons of people that are asking about asking about it on Android. And I guess now, hopefully, I'm not sure when the podcast will come up. But I imagined the Android app will be out either before then or very close. The other kind of cool thing that we're doing is we're building a version of pin planet for the vision Pro, the Apple vision Pro. Hopefully that will be coming out. We put a video out like a short snippet out on YouTube. And we've posted on our socials and stuff and people seem to there seems to be a little bit of interest there. I can't afford the vision pro gods. I can vote for them. See,
Carlton Gibson 52:20
I go for kids. I can't afford.
Andrew Hornstra 52:23
I've seen that the simulator. Would you show that to me? It looks it looks really cool. Yeah. Oh, we're on iPad
Harout Boujakjian 52:28
two. Oh, yeah. Pin planet does actually also work on iPad. Oh,
Will Vincent 52:32
how is that a recent thing? Or is that that also supported back?
Harout Boujakjian 52:37
That was back in October, most of the work was figuring out how to automatically resize images based on the width. And then once I figured that out, it actually turned out to be not super difficult to do. So.
Will Vincent 52:50
Well, there's, I mean, there's so many different sizes of iPads these days. But I guess on your end, it wasn't as like three times as much work to support three different sizes with like the mini the air in the pro?
Harout Boujakjian 53:02
Surprisingly not No, no, once once we figured out how to resize images automatically that that was like the big thing. And then iPad handles, you can do iPhone does it as well. But on iPad, it's a bigger deal for dynamic type. And once we kind of constrained our dynamic type to not be like super gigantic tax, like one letter is the size of like half the screen. If you constrain it a little bit, then you have you have an app that works on iPad pretty easily.
Andrew Hornstra 53:26
So Android, I'm worried about though some devices won't even honor your contracts for certain events. Like if you tell them you can only pick this many images, some devices just will say we'll pick as many as we want. So that that I'm worried about, but we'll
Will Vincent 53:43
crop it to myself, there must be a hierarchy of you know, the top two or three Android support devices have or I think have the lion's share. Or maybe not, I'd actually had it on Yeah. Well,
Andrew Hornstra 53:56
from whatever publicly available data. Right got. Yeah. And that's what we're targeting.
Will Vincent 54:01
Right? Yeah. Yeah, it's it's a thing of it's it doesn't sound it says they're big enough issues, I want to let you know.
Carlton Gibson 54:10
It doesn't sound as if it's changed too much. From my day. It was like very much like, you know, on the the iOS devices, though, it was not too hard to customize. And then there was a sea of different androids options, and you had to just pick the ones you had the sort of capacity to support basically.
Harout Boujakjian 54:26
Yeah. So like when you have like pixels are amazing, Samsung, higher end, Samsung devices are amazing. Like those are the easiest to support. But then you have these random. I actually, I guess not random. They're probably hugely popular devices in countries like India or China or Bangladesh. And it's like, Alright, these these are a little bit hard to to support because they're, they're less expensive, but they're way less powerful. So yeah, you need an app that can also work, hopefully 80% as well. On the lower end devices, you know, the ones that aren't quite as powerful. So it's, it's tricky to that's a tricky portion to balance my opinion. So that's also
Carlton Gibson 55:08
a cool engineering challenge. And can I make this kind of make the app proficient so that it will run on another end device? I think we have the same problem with websites, right? If you load all the JavaScript in the world, your your website won't run on a lot of people's phones. So okay, let's see if we can keep it a bit lighter. So we're more open to everybody. That's cool. If you had a magic wand, and you don't have to just say Django, maybe you had a magic wand, what would you fix? I'll let you both have an answer if you want.
Harout Boujakjian 55:35
Okay, I have I have two answers. The first one would be, I'd love to have typing in Django, that would be one. And then second, I feel like this one maybe is a little bit less of a selfish one. I would want rest framework and channels to be a part of core because in my opinion, I think this is hurting the marketing of Django. And this is coming from someone who has done a lot of like JavaScript, I love JavaScript, I do a lot of front end work. And I also love Django. It's like my go to framework of choice for anything I do in the backend. But unfortunately, like we as a community are competing with VC backed JavaScript frameworks like next. And we need to, I think not having like API support, at the very least in core, makes it look like Django is a framework that only does, you know, like old server rendered HTML templates, when actually you can build very robust, stable API's with with Django and also WebSocket support. So that would that would be mine. I think more for the benefit of the community. interested?
Carlton Gibson 56:41
Good. Andrew, if you go,
Andrew Hornstra 56:44
the easiest one is to just say, throttling. I ran into some issues with like, the granularity of throttling. And, you know, we wanted to restrict more of our rights versus our reads and kind of ran into some, we want to make a more custom solution for that. But the the biggest thing that's actually caused me the most time had been, the RM is very nice, I use it a lot. I almost exclusively use the rm in, in pen planet, with some exceptions for our analytics dashboard. But, and I understand that it's trying to be sequel back end agnostic with the language that it uses for some of its methods. But man, sometimes I feel like there's such a disconnect between the operations you do on the, in the RM and what's actually happening in the sequel, and I'm very much a sequel person, I have a lot of experience with it. And I can appreciate not wanting to require that kind of experience for, you know, the new developer. But sometimes it feels like there's, there's gotta be some middle ground where you can more closely reflect the SQL standard, versus an abstract ORM of its own design. without sacrificing the accessibility to new developers, it makes it easier to come back to after a while. If you're working on Kotlin for a bit, and you've written SQL, and you come back to Django, and you're like, alright, what, what are these keywords mean, what's actually happening? When does it allow me to not get the ID in this instance, versus requiring me to include the ID? Yeah,
Carlton Gibson 58:43
yeah, no. Okay. Well, I
Will Vincent 58:45
think we're, we're gonna have Simon shred on in the future. Who, who is that? Right, Carlton? I believe he agreed.
Carlton Gibson 58:53
Yeah. He said, Yes.
Will Vincent 58:55
He's sad, because it's very, very in the weeds in the Django or so we can we can pose that to him? I'm sure he has a take. We can say, Yeah, Andrew wanted to know.
Carlton Gibson 59:11
Right, God, well, you will get, you're gonna,
Will Vincent 59:12
is there anything we didn't? We didn't bring up in our discussion. So obviously, people can go on the App Store, and maybe the Android store will put a link, by the time it comes out for pin planet. Are there other ways people should stay in touch? I
Harout Boujakjian 59:25
don't, I don't think anything. I don't think anything else really comes to mind. You know, if you use the app, leave us a leave us a rating in the app store that does actually help out significantly. Yeah, find that. And then other than that, I don't think there's anything else. I mean, it's been a really fun journey. I just want to emphasize again, that like, Django is a, it's just a phenomenal back end framework. And it is boring. And that's amazing. It's mature, it's stable, it stays out of the way you know that it's working. It you know, when you have to deal with all the other complexities of building an app. It's nice when you don't have to worry about one portion of it. You know that. Okay, this just works. And that's, that's awesome.
Will Vincent 1:00:04
Good. Well, we agree, obviously. But yeah, I think it's also Yeah, for the two of you for the two of you. I mean, it's it's quite a complex, mature feeling app. And so the fact that, you know, you can build it in a relatively short period of time. You should feel proud of that, and also speaks to the power of Django. So, yeah, thank you.
Andrew Hornstra 1:00:23
Thank you very much.
Carlton Gibson 1:00:24
My route. Andrew, thank you for coming on. That was I've really enjoyed the chat. It's been absolutely super. Thanks for joining us folks with Django chat.com. And we'll see you next time. Bye.