#215: The software powering Talk Python courses and podcast Transcript
00:00 Have you ever wondered about the software stack powering Talk Python, the training websites,
00:03 the mobile apps, the video and audio delivery, and more?
00:06 While at first glance, it might seem pretty simple.
00:09 There's quite a bit going on, actually.
00:11 We have our own custom search engines.
00:13 We deliver about 15 to 20 terabytes of traffic per month.
00:16 Our course video streams from eight locations throughout the world.
00:19 Our database server is sending about 12 megabits of traffic sustained all day, all night,
00:25 with no media in the mix.
00:26 And all of this stuff is powered by Python.
00:29 So this week, it's a bit of a role swap.
00:30 Dan Bader from RealPython is here to interview me about the Talk Python tech stack.
00:35 But we do get a chance to compare my tech stack with RealPython's, a site which is becoming quite an important one for developers in the Python world.
00:43 This is Talk Python to me, episode 215, recorded on scene at PyCon 2019 in Cleveland on May 6th, 2019.
00:52 Welcome to Talk Python to me, a weekly podcast on Python, the language, the libraries, the ecosystem, and the personalities.
01:11 This is your host, Michael Kennedy.
01:13 Follow me on Twitter, where I'm @mkennedy.
01:15 Keep up with the show and listen to past episodes at talkpython.fm.
01:19 And follow the show on Twitter via at Talk Python.
01:21 This episode is sponsored by Linode and Backlog.
01:25 Please check out what they're offering during their segments.
01:27 It really helps support the show.
01:28 All right.
01:29 Hey, folks.
01:29 We got a little bit of a different one this week.
01:33 So I'm excited to be here with Dan Bader from realpython.com.
01:37 Hey, how's it going, everybody?
01:38 It's good to see you, Dan.
01:40 Likewise.
01:41 This is so unreal because the last couple of times when I was on your show,
01:44 we were not sitting right next to each other at a hotel in Cleveland, but we were doing this over Skype.
01:49 And so it's kind of cool, actually.
01:52 It's super cool.
01:53 Yeah.
01:53 And greetings, everyone, from the tail end of PyCon.
01:55 Not quite from the conference floor anymore since they cleaned that up.
01:58 So now we're at the hotel floor.
02:00 Yeah.
02:00 And it was a really sweet conference.
02:01 I mean, I don't know.
02:02 I'm sure you had a great, fantastic time, too.
02:04 I know you were always swarmed and surrounded by people and fans that want to take photos and chat with you.
02:09 And yeah, it's really, really cool.
02:10 It's one of my favorite times of the year, honestly.
02:12 It's exhausting, but it's great.
02:14 Yeah.
02:14 Yeah.
02:15 I know it was an awesome conference.
02:16 I mean, thanks to everybody who organized it and put it on.
02:18 It was really, really amazing.
02:20 I feel like it's just getting better and better every year.
02:22 And there's more interest in Python.
02:24 And it's just so cool to hang out with the community.
02:27 Yeah, absolutely.
02:28 You meet all these people that you collaborate with on the internet or other things.
02:33 And you would never run into them because they live in Australia or Vancouver or wherever.
02:38 Yeah.
02:39 But here you run into all of them.
02:40 It's amazing.
02:40 Yeah.
02:41 It's really, really cool.
02:42 And one of the things I like the most is when you've been working with somebody or you know
02:45 them online, but you never actually met them or been on a video call.
02:48 And then you run into them.
02:49 You're like, oh my God, I had no idea.
02:51 Oh, this is you.
02:51 Like, this is so cool.
02:52 And it's, yeah, it's just been a ton of fun.
02:55 Yeah.
02:55 Another one of the takeaways, I guess, is everyone's just a person, right?
02:59 Like all these people working on these amazing projects.
03:02 They're really open to meet you and share ideas.
03:04 And like, if you just go and say hi, like chances are, you know, that you'll get to learn a lot
03:09 about, you know, whatever you're interested in.
03:11 Totally.
03:11 Yeah.
03:11 I think everybody is really, really welcoming.
03:13 And I mean, that's the whole point.
03:15 I mean, that's, I'm sure it's the same thing for you.
03:17 Like, that's why I go to these conferences, right?
03:18 To hang out and meet new people.
03:20 I'm not going there to hide behind my laptop or just be in like business mode, but it's
03:24 just fun to walk around and chat and grab a cup of coffee or beer with somebody.
03:29 Yeah, absolutely.
03:29 I consider this my geek holiday.
03:31 Yeah.
03:31 So I did say the opening that we have something a little bit different.
03:35 So we're going to sort of reverse the roles.
03:37 And Dan is going to interview me somewhat, but we're also, I'm also going to have a lot of
03:42 questions for you, Dan.
03:43 Sounds good.
03:44 Yeah.
03:44 I'm looking forward to this.
03:45 So a lot of folks have asked various questions at different angles, like how have you built
03:51 your Python stack?
03:54 Or why are you serving your audio this way?
03:56 Or how did you build your new mobile apps that you released?
03:59 Just all these different questions about the tech involved in the podcast and the training
04:04 and all the derivative stuff from that.
04:06 So I decided, Dan, you would be the best person to sort of represent the audience on that side
04:14 of the conversation.
04:15 Because one, you're super knowledgeable.
04:17 We're good friends.
04:18 But also, because you are also running a pretty high-end website.
04:23 Like, RealPython is one of the biggest Python sites out there these days, isn't it?
04:28 I mean, it's kind of hard to measure that in terms of, I don't know, like impact and everything.
04:34 But I can share some stats.
04:36 We just hit 1.3 million unique users per month.
04:39 So that's like several million page views a month just on RealPython.com alone, which
04:44 to me is just an insane number.
04:46 So yeah, I think, first of all, thanks.
04:49 And I think we're up there somewhere.
04:50 Yeah.
04:50 It's awesome.
04:52 Yeah.
04:52 It's definitely really, really growing since you've taken over stewardship of that resource
04:59 in the last year or two.
05:00 And it's awesome to see.
05:02 So we're going to talk about RealPython.com and what you're up to as well.
05:05 Cool.
05:05 All right.
05:06 I guess one of the things I did want to start to set the stage with before we get into
05:11 this conversation is we'll talk about some part and people might go, well, why didn't
05:16 you build that serverless?
05:17 Or why isn't that a microservice?
05:19 Or couldn't you have hosted this here in that way?
05:23 And probably the answer is yes, yes, and yes.
05:25 But I'm not doing any of those because there's just a lot of ways to make this work, right?
05:32 There's a lot of choices out there.
05:33 And I think maybe that's even why people are interested, right?
05:35 If like if it was you go to HP and you ask for a rack of servers and you set up this software
05:41 on it and you put it on the internet and that was the answer, like nobody would ask, how
05:45 many servers do you have?
05:45 I have three, one U servers.
05:47 Okay.
05:47 Interesting.
05:47 Right.
05:48 But because there are all these choices, I think it's interesting.
05:50 But I also want to just set the stage, like the choice that you might have made may
05:55 be different than the choice I'm making or the choice that Dan is making.
05:57 But, you know, just be aware, like they may all work, maybe better, maybe not.
06:03 I don't know.
06:03 But yeah, we're not judging.
06:05 And so please give us the same favor in return.
06:10 And I think there's also, you know, with all of this stuff, there's a huge like hindsight
06:14 effect here, you know, happening here where sure, we could have built this probably on a
06:19 number of different platforms and hosting services and tech stacks.
06:24 But a big reason, I mean, for me personally, why I'm doing all this stuff, you know, why
06:28 I love being involved with the Python community and being able to teach in the Python community
06:32 is that I get to play with these things and build software in the way that I like to and
06:37 that I enjoy.
06:39 So not everything is like a pure what is like the most effective or efficient way to do
06:44 this.
06:44 So that's so interesting.
06:45 You just made me realize I did the same thing, but unconsciously.
06:50 So like, I knew nothing about deploying on Linux.
06:53 So I feel like I originally tried going down the platform as a service route and like things
06:58 that would hold my hand as much as possible.
07:00 And then I'm like, no, I feel like I need to know this.
07:03 So I'm going to go force myself to use the infrastructure as a service thing and learn
07:08 Nginx and MicroWisgi and Linux and all these deployment things and how they work together.
07:12 So that if I guess so, I wasn't be a weak spot for me or something.
07:17 And I do feel like I took that on as like a learning challenge as much as a good way to
07:22 deploy.
07:22 I think it also works really well, but like also to learn, right?
07:25 Like if you get a chance, totally.
07:26 It's worth pointing out that you and I both run small businesses.
07:30 We are not at a huge enterprise with somebody that has made rules about what tech we can
07:34 use.
07:34 We can use anything long as like we're willing to live with the consequences, right?
07:39 And so at least personally, I use that as an opportunity to say, I want to use this tech
07:43 so I can learn it as well as I think it might be a good idea.
07:45 Yeah.
07:46 I think that's a big part of it.
07:47 And then, I mean, also, you know, wouldn't it be a shame if the biggest Python podcast was
07:52 hosted on a bash script somewhere?
07:54 Like it's got to be built on Python.
07:57 It's a Java app.
07:58 Yeah, I guess nobody's questioning that decision, right?
08:00 To build the app in Python versus some other tech stack.
08:03 Exactly.
08:04 I kind of think like set the stage, we're running on Python, both of us.
08:08 Let's start there, actually.
08:09 That's an interesting case because when I started the podcast, I didn't want to start a Python
08:16 website.
08:16 I wanted to start a podcast.
08:18 And yet, I needed a website to serve the RSS feed and the MP3s so that I could have a podcast,
08:26 right?
08:26 Like it was table stakes.
08:27 And right now, there are pretty decent options for hosting a podcast if you're willing to pay
08:32 a little bit.
08:32 Like fireside.fm is not bad.
08:34 Brian Okken uses that for testing code, for example.
08:37 When I started Talk Python, there was a few options and they were bad options.
08:41 Like they were not so good.
08:43 So, I looked at that and I said, well, am I serious about this?
08:46 Like do I want a site that looks good and people will respond to?
08:49 Or is going to look like the worst WordPress theme you've ever seen?
08:54 But technically, it will be an RSS feed.
08:56 And who cares?
08:57 You don't go to the website, right?
08:58 Yeah.
08:59 Yeah.
08:59 I totally get that.
09:00 And a lot of this stuff has changed also, I think.
09:03 Because when did you start Talk Python training?
09:05 I started...
09:06 Or the podcast?
09:07 The podcast started in April 2015.
09:10 The training site started in 2016 and February 15th.
09:15 I know because that was my day I was free from full-time employment.
09:18 Yeah.
09:19 And so, you know, with all of this stuff, I think, especially in the podcasting space, you
09:24 know, a lot has changed.
09:25 I mean, now it's sort of a legit thing like hosting a radio show.
09:28 You know, my parents listen to podcasts and not my grandparents, right?
09:32 But like people know about that this is a thing.
09:34 And when I think back, you know, even like three, four years ago, it wasn't at that level.
09:39 I mean, even just looking at the apps, you know, I really like the Overcast app, for example.
09:42 I don't think that was out back then.
09:43 And, you know, it was just all like basically Apple, iTunes or something.
09:47 And it's really changed and grown since then.
09:49 So now there's probably all kinds of different options.
09:51 But there's a lot of personal investment and all this like custom software that you've built.
09:57 I mean, that we've both built for our businesses.
09:58 And there's sort of also a barrier to move to something else.
10:02 I feel like we sound super defensive talking about this stuff.
10:05 Well, I think it's really interesting to consider like, should I have just said, no, I'm not going to build, say, for example, talk Python.fm and Python and build it myself and do the web design myself and all of that and figure out how RSS feeds and work.
10:19 And how am I going to get the video or the audio delivered without like breaking the bank and bandwidth and all of that kind of stuff.
10:24 Like I could have just put my credit card in at Podbean, got a crappy site for, you know, $5.
10:30 I don't know what the price is or whatever.
10:32 And just gone with that.
10:33 But, you know, I felt like there's going to be a point where I want to do something that it doesn't do.
10:38 And do I want to be walled off over there?
10:41 And also, it was a little bit of a learning experience, like you had said, like, oh, this will be to be a cool thing to run to understand how it all fits together.
10:48 So I just understand it better.
10:50 Yeah.
10:50 But, you know, I would say like three months in, I never started the podcast thinking I would get sponsors.
10:55 I thought that was a crazy idea.
10:56 It would just be something that I could, you know, have a community of people I interact with because I didn't have that.
11:02 But about three months in, one company approached me and said, hey, we would love to sponsor your show.
11:07 It looks so nice and polished and professional compared to all the other stuff out there.
11:11 And it's because all the other stuff was hosted in places that were like super cookie cutter and not so great.
11:17 And I'm like, it started to feel like it paid off at that point.
11:19 Like, oh, yeah.
11:20 And I can like feature them in this way that wouldn't be possible if it were there.
11:24 You know, like it slowed down the start, but it seems like it really paid off in a long term.
11:29 Yeah.
11:29 And that makes a lot of sense.
11:31 And I just wanted to add to that, you know, also looking at my experience kind of building a custom tech stack.
11:38 There's a huge element of survivorship bias in all of this where if you can pull it off and you can, you're successful with a custom solution, it's going to be awesome.
11:48 It's going to make you unique and you're going to be able to build out all these unique features.
11:51 But for every like 20 people who are trying to start a podcast of their own, there's going to be a lot of people who never make it to the actual recording because they're spending five months building their own infrastructure.
12:02 I've been there, you know, not with a podcast, but with other stuff.
12:05 That's a good thing to keep in mind for everything, right?
12:08 Like getting started is the most important thing in this journey for whatever you're doing, right?
12:14 I guess just to put a bow on that, like when I decided I'm going to try to build a site and see if I can make it work before I decided to host something else, host somewhere else.
12:23 I started out on a Friday.
12:24 I said, all right, done with work.
12:26 I really want to create this thing.
12:28 I'm going to just go all in on this weekend.
12:30 And by Monday morning, it was like live and beautiful and ready.
12:33 And so it was like, I'm willing to try a couple of days to see if doing it myself is crazy or not.
12:38 And then I would have maybe gone and, you know, paid a couple bucks to Podbean or whatever, right?
12:43 I wouldn't have waited three months before I even tried the podcasting side of the thing.
12:48 It was like, this is exciting.
12:50 Let me try it.
12:50 And if it works, I'll go with it.
12:51 Otherwise, I'll pull a ripcord and do something else.
12:53 Yeah.
12:53 Yeah.
12:54 Like do a little experiment and then see how far you can get.
12:56 Yeah.
12:56 Yeah.
12:57 Yeah, exactly.
12:59 So maybe, I don't know, maybe it's worth talking a little bit about the just quick fly over the tech stack.
13:04 What do you think?
13:04 Yeah, I think it'd be interesting.
13:06 I mean, how do you want to slice and dice this?
13:08 Like maybe we should talk about like, first of all, what are the main services that you run for your podcast?
13:14 And you've got the training site and all these other things.
13:16 Right.
13:16 Because they all have different goals and constraints and whatever, right?
13:20 For example, the training site demands low latency video delivery where the podcast site, it doesn't matter at all if that's delivered a little slower because it auto refreshes on your app and you just open it and it's there.
13:31 Yeah.
13:31 So let's see.
13:32 I have talkpython.fm, which is the website.
13:35 And let's just group the audio delivery in for that one.
13:39 I have pythonbytes.fm that I do with Brian and it's audio delivery.
13:43 And I've got the training site.
13:45 The Talk Python site and the Python Bytes site have custom search engines that I have as REST endpoints.
13:52 So search.talkpython.fm, for example.
13:55 You can consume that and search that if you want.
13:58 And internally, the site uses that so you can search for stuff and whatnot.
14:02 Same for Python Bytes.
14:03 So there's kind of that side of things and the audio delivery there.
14:08 And then there's the training site.
14:10 And the training site is actually a lot more complicated, I would say, on the infrastructure side because it's got to deliver the videos.
14:17 It's got to do e-commerce.
14:19 It has a bunch of accounts.
14:21 But also it has to have the video delivery, low latency, anywhere in the world.
14:26 It has the apps, right?
14:27 Now it has the apps, the iOS and Android apps around it and so on.
14:32 So, yeah, that's probably the landscape.
14:34 Also… Your mobile apps.
14:36 Yeah, inbound, outbound, email.
14:38 We've got a bunch of services there, like the video stuff, right?
14:43 So when we record the videos, we don't release what we record.
14:47 We have to transform it into certain formats that work well in like iOS and are minimized in their like video size based relative to, say,
14:56 the resolution.
14:56 And there's like all that processing pipeline is pretty interesting as well.
15:00 Yeah, this is super cool.
15:02 I mean, it's kind of mind-blowing, you know, to go over this and sit down and really tease it apart.
15:06 Like what are even all the services that you run?
15:09 Because it's so much stuff, right?
15:10 People would… Isn't it just a podcast?
15:11 I thought this myself.
15:13 Yeah, you know, it's a podcast.
15:14 So what do you need, you know, a laptop to record this?
15:17 Like we're sitting here.
15:17 It's kind of a nice and minimal setup.
15:19 But there's a lot of infrastructure that is powering all this stuff so that your listeners get to enjoy this on their commute and in their cars.
15:28 I mean, just to give people a sense, like a while ago, I sort of summed up all the data usage, bandwidth usage of my various servers and whatnot between the database and then the audio.
15:39 Not even counting the videos, which are their own special thing.
15:42 And I think it was running at like 17 terabytes of traffic a month.
15:45 Oh, wow.
15:46 It's a lot of Python.
15:47 It's a lot of Python.
15:48 It's a lot of Python.
15:49 So, yeah, it's pretty cool.
15:51 It's actually pretty awesome to see.
15:53 Amazing.
15:53 Okay, so this makes us even harder to kind of slice and dice this and dive into the most interesting bits.
15:58 I know one of the things that you and I have had some conversations about is the whole like, you know, monolith versus microservices and most recently also the serverless approach.
16:07 And I think it would be interesting to talk about that a little bit because I feel like now there's sort of a return to the monolith in the industry where people got burned by the server.
16:16 Yeah.
16:17 Yeah.
16:18 The pendulum has swung a little backwards, right?
16:20 So, I felt a little uncool, to be honest, a couple of years ago.
16:24 Same here.
16:25 Because people are like, dude, how are your microservices working?
16:27 I'm like, well, there's three services, right?
16:30 There's, say, talkpython.fm and then it also has like the search service and then it has an audio delivery bit that's like a little bit separate.
16:38 But that's not really microservices so much, right?
16:41 Microservices are way more small grained, certainly.
16:44 You know, and talkbython training is like definitely a monolith.
16:47 But I try to have a really pragmatic view of these things.
16:49 Like, I'm not Google.
16:51 I'm not Facebook.
16:52 I'm not LinkedIn, as Brian likes to say, right?
16:55 Like, why do I need to trade that off?
16:57 And I guess in this context, I'd love to hear your thoughts on this.
17:00 But when I think of like the, should it be a microservice or should it be more monolith, it feels to me like what I'm doing is taking the complexity and moving it from code complexity in a monolith to operational complexity in a bunch of services.
17:14 I'm better suited naturally with my experience to handle code complexity than DevOps complexity.
17:20 If I was maybe really good at DevOps complexity and not so good at code, maybe I would have chosen microservices, but that wasn't where my capabilities were.
17:28 So I'm like, I'm going to play to my strengths here and just stick with this.
17:30 Yeah.
17:31 Which I think that is the best solution if you're running a small business.
17:35 And I mean, in our case, we're both building all of the software ourselves.
17:38 Yeah.
17:38 And we're basically the CEO and CTO and main chief account of all this stuff in one person.
17:45 And so I think especially then to go down a route of adding a lot of complexity, like operational complexity early on is not a good place to be.
17:54 And like what I found really inspiring is Basecamp as a company.
17:58 I mean, there used to be 37 signals.
17:59 I love their stuff.
18:00 I used to read like Getting Started, their book religiously.
18:03 Yeah.
18:04 Yeah.
18:04 And it's, you know, it's really good, really good books.
18:07 And I think also really, just a really, really inspiring company and really good or like really interesting from a tech stack perspective too, because they're totally going down the monolith route.
18:16 I mean, their CTO is basically the inventor or creator of the Ruby on Rails framework, which is pretty much like Django in the Python world.
18:23 And they're purposefully building software using monolithic approach so that they can be effective with a small team, which is ultimately if you're running a one person or two person business, super important.
18:36 Like, I mean, you want that.
18:38 That 20% efficiency or whatever is massive when you're small.
18:41 When you're a huge company, huge companies are massively inefficient, like from my experience.
18:46 So that's pretty interesting.
18:48 I'm definitely a fan of just having things working simply and knowing that you can change it, right?
18:54 We could break it into microservices if we need to, but yeah, same.
18:57 And I feel like just serverless is just like that, but plus more.
18:59 Like it's more pieces I got to manage.
19:02 And so until I need it, I feel like I'm going to stick with what I'm doing.
19:06 Yeah.
19:06 Yeah.
19:07 And to me, it's interesting also that, you know, your search service is a separate thing.
19:12 So you're, it's almost a little bit of a hybrid model there for you.
19:16 Yeah, a little bit.
19:16 Where, and I think the Python bytes, that's a separate.
19:19 That's a separate app, right?
19:21 And it's similar for me where real pythons are a separate app, right?
19:22 And it's similar for me where realpython.com is like a monolithic web app, but then we
19:27 have this feedback form system that's separate or the PyCoders weekly newsletter that I run
19:32 is also a separate application.
19:34 And I think it makes sense to kind of slice things up this way because then you can treat
19:40 those systems in isolation.
19:42 And I guess the question is just, you know, when, I think it's a spectrum of like monolith
19:46 to microservice to let's say serverless, maybe it was like really, really tiny microservices
19:51 basically.
19:52 And so, I mean, we're both not running pure monoliths, right?
19:56 In that sense where if it was a pure monolith, like everything you have, like the podcast
20:01 and all the APIs, the search.
20:02 It would be one single thing.
20:04 Yeah.
20:04 Yeah.
20:04 I have eight different servers that are participating in like all the stuff we described at the beginning.
20:09 So maybe I don't know when it is a microservices architecture versus when is it a monolithic
20:15 architecture?
20:15 Because I mean, you basically have a search microservice in that sense, right?
20:19 So I've always been struggling with those terms a little bit.
20:22 Yeah.
20:22 I think there's two driving forces.
20:24 One would be technical and the other would be sort of team personal based.
20:30 Like, is there a technical reason to have those two things separate?
20:32 Do you want to consume them separately?
20:34 Should they be versioned separately?
20:36 Should they live on separate servers?
20:38 Things like that.
20:39 That's maybe a technical thing that'll push you into this mini microservice light?
20:44 Microservice light?
20:45 I don't know whatever you call it, right?
20:47 We're going to term.
20:48 And then the other one is, do you have people who are not experienced with the whole thing,
20:54 but maybe they could work on the search service, right?
20:57 Like if I had somebody who was like a junior developer who came on and I was going to have
21:01 them work on the search service for a month, like it's not really worth it and it's not
21:04 that big, but imagine it were, right?
21:06 Like it might make sense to have that separate.
21:08 They can deploy it and live with it.
21:11 And if they take down the search service, it's not the end of the world.
21:14 You know what I mean?
21:15 But if they take down the main site, like all of a sudden it's a problem potentially.
21:18 And so I feel like certainly microservices are easier for different teams to work on different
21:23 bits or different people to work on simpler bits.
21:25 But like you said, we're mostly doing the software development ourself.
21:29 And so that's absolutely not a pressure that is applied to our stuff.
21:34 Yeah.
21:34 I think that's a good point where you want the ability for one of those services to go down.
21:39 Like if it's an experimental new thing that you built, let's say like the search and you're
21:43 playing with the or working on the search feature, trying to make it better in some way, you want
21:48 to gracefully degrade the experience for everybody who's using the website.
21:52 Maybe search doesn't work, but everything else would still work.
21:54 I did that, for example, when I built like an ad serving, like an ethical ads platform for
21:59 realpython.com.
21:59 And it's now also used on PyCoders Weekly and some other sites.
22:03 And there was the same thing where it's like, you know, I don't really know if I'm going to
22:06 be running this thing in a couple of months.
22:07 It's more an experiment.
22:08 And instead of kind of polluting my monolithic code base with that new thing, I'd rather have
22:14 it separate.
22:14 And so I could also scale it independently.
22:16 So I'm wondering if that also factors into your decisions, like maybe search needs to be
22:20 scaled differently or one of these sites is going to grow faster than the other ones.
22:23 Yeah, absolutely.
22:24 Like if you need to scale one part a lot, it's easy to just scale that tier or put a load balancer
22:30 in front of that.
22:31 Also, it's running under different core domains and different SSL certificates and stuff.
22:37 So maybe that makes it a little easier to have it separate, like search.talkpython.fm, not
22:41 talkpython.fm/search.
22:43 Although that's kind of maybe minor.
22:44 I could change that around.
22:46 But yeah, it's certainly a consideration.
22:47 This portion of Talk Python to me is brought to you by Linode.
22:53 Are you looking for hosting that's fast, simple, and incredibly affordable?
22:57 Well, look past that bookstore and check out Linode at talkpython.fm.
23:01 Slash Linode.
23:02 That's L-I-N-O-D-E.
23:04 Plans start at just $5 a month for a dedicated server with a gig of RAM.
23:08 They have 10 data centers across the globe.
23:10 So no matter where you are or where your users are, there's a data center for you.
23:14 Whether you want to run a Python web app, host a private Git server, or just a file server,
23:19 you'll get native SSDs on all the machines, a newly upgraded 200 gigabit network, 24-7 friendly
23:25 support even on holidays, and a seven-day money-back guarantee.
23:28 Need a little help with your infrastructure?
23:31 They even offer professional services to help you with architecture, migrations, and more.
23:35 Do you want a dedicated server for free for the next four months?
23:38 Just visit talkpython.fm/Linode.
23:41 One of the differences between both of our setups there that I'm personally really interested in
23:47 is that for the hosting aspects of the infrastructure, we're using different approaches.
23:53 Absolutely.
23:53 The way I understand it, you will actually provision an individual virtual server and then run an
23:59 application on that.
24:00 Let's say Python Bytes has its own virtual machine somewhere in the cloud.
24:03 I'm more like the infrastructure as a service model, whereas most of my stuff runs on platform
24:08 as a service providers like Heroku.
24:10 I don't provision my own Linux server and keep it updated.
24:12 I just kind of offload that.
24:14 And so I'm really interested in how the infrastructure as a service model is working for you.
24:19 If you ever considered switching, for example, or if you see some benefits in it.
24:22 It's working pretty well.
24:23 I feel like I've definitely gained a lot of experience that I wouldn't have, right?
24:27 Like, give me 15 minutes, I could set up a new HTTPS service on Nginx backed by some, you know,
24:33 MicroWiz gear, GPU record or something.
24:35 And having like that experience, DevOps experience, I think is nice.
24:39 I think the way I kind of got there was a little bit of that learning and exploration stuff.
24:44 I kind of wanted to have that as a skill set.
24:46 So like, let me try it.
24:48 And, you know, when I started, it was like $10, two $5 servers, one for the database.
24:53 Maybe it might have just been one, right?
24:55 Like on the same server even or something.
24:57 But it was like really just a quick little easy way to get started.
25:00 And it worked really well for me.
25:02 I'm like, this thing is just perfect.
25:04 It works.
25:04 It's up all the time.
25:05 I love it.
25:05 As things have grown, it's gotten a little more complicated.
25:08 And I feel like I'm still really happy the way it is.
25:11 But it's sort of taken on its own life a little bit to have.
25:15 Because you're provisioning your own databases, right?
25:18 You're not going like, oh, Amazon, I need to.
25:20 So the way I have it set up is I have MongoDB as my server.
25:23 I didn't start with MongoDB, but I have it.
25:25 And I have the different services.
25:27 And they have all different databases, but they all are on the same database server, right?
25:32 So all the main sites, training.talkpython.fm, Talk Python itself, Python Bytes,
25:37 they all have their main server in like a load balance failover server.
25:41 So if I got a reboot or do maintenance, I can just like automatically through Python with an API.
25:46 Like as part of the deployment stack, what happened or flow, it'll switch it to this other super, super cheap cloud server,
25:54 handle the traffic well enough while it's off, and then switch it back.
25:58 Right?
25:58 But all of those share a central MongoDB virtual machine that's like, instead of having a bunch of small ones,
26:04 I bought like one high, high performance one and they just share it.
26:07 Yeah.
26:08 Yeah.
26:08 And it's fine.
26:09 I mean, like if you go log into the MongoDB server and you pull up in load and you say,
26:13 what is the traffic on this server?
26:14 Like the average bandwidth is about eight to nine megabits per second continuously.
26:22 So it's getting a lot of work.
26:23 But if you pull up the CPU usage, it's one to 2%.
26:26 Yeah.
26:27 I mean, it's like, it could take way, way more of what it's getting than it does.
26:31 So why did I choose that?
26:32 Why don't I go on Heroku or something like that?
26:35 I feel like what I got is already working.
26:36 I'm really happy with the way it works.
26:38 I can make it do just what I want.
26:41 Any change that I want to make, I feel like the sky's the limit, right?
26:46 I want to change how Nginx works.
26:47 Fine.
26:47 I want to make it serve HTTP2 for this part, but not for that.
26:50 I can totally do that.
26:51 Did you ever have like some incident with the database, let's say, where you have to rebuild it from scratch or restore it?
26:57 I've never had any problem.
26:58 The database, it's been that configuration, let's say, for about two and a half years.
27:04 I've never had it go down or get corrupted.
27:08 What I have had is the network infrastructure inside the hosting, inside the host has had issues.
27:16 So the things couldn't find the server, but that wasn't the server process fault or the machine.
27:21 It was like the glue was broken for a little, but that's still, you know, like a couple minutes
27:26 if you sum it up over all those years.
27:28 The thing that makes this challenging that you avoid, which I want to hear your side of this here in a second,
27:33 is I can manage all this stuff, but I'm not running MongoDB in a replica cluster,
27:39 which would be the way for like true 100% availability because the changes that I need to make to it are like incredibly small.
27:46 But about once a month, there's a 10 second downtime because the underlying server has security patches.
27:53 Yeah.
27:54 And so I got to reboot the thing that is the center of that hub.
27:57 Yeah.
27:58 And so I've actually built stuff into say Talk Python, the training site, for example,
28:01 that I'll flip a switch to say the app is in off mode and every request will send you over to a page that says,
28:07 we're doing a major upgrade, please hold on.
28:09 And it has a meta tag that refreshes every five seconds and it notices when the database switchbacks on,
28:14 it takes them back to the page they tried to get to.
28:17 Come on, man.
28:17 That's not good enough.
28:18 We need eight nines.
28:20 Now, I realize like some people have to have 100% availability, but for my world, like 10 seconds downtime per month is acceptable, right?
28:29 I don't know.
28:30 That's the way I have it set up.
28:31 Tell us about what you're doing at RealPython because I get a lot of traffic.
28:34 I maybe do more pure bandwidth because I have audio in large quantities.
28:39 I think you do.
28:39 Pretty sure you do.
28:40 But you definitely do more requests.
28:41 I probably get under two or three million HTTP requests that are data-driven Python requests,
28:48 not static files and whatever, per month if I add them all up across all the things.
28:53 But I'm sure that you get quite a bit more.
28:55 So you're running a totally different setup.
28:57 Tell us how that goes.
28:58 The setup that I use for RealPython, like all the other stuff like the Ethical Ads platform, PyCoders,
29:04 pretty much all runs on Heroku these days.
29:06 And the downside is it's a lot more expensive than provisioning your own box.
29:09 But the upside is that, you know, recently I was going on my first vacation in like a really, really long time.
29:16 And my wife and I were going on this hike and we're coming back to civilization.
29:21 Very far away from a computer.
29:23 Very far away from a computer.
29:24 Of course, I brought the computer.
29:25 Yeah, so did I.
29:26 I'd never go about it just in case.
29:28 We're coming back from a site.
29:29 And I checked my phone and there's like 50 Slack messages.
29:31 Not 50, but, you know, it's like Slack is on fire.
29:34 Like the real Python Slack is on fire.
29:35 And I checked my email and there's like all these exception tracebacks.
29:40 And I'm like, oh my God, oh my God, oh my God.
29:42 And it looks like the database passed.
29:44 You know, some issue with the database.
29:45 That service has just disappeared.
29:46 And then I keep reading further down.
29:49 And I get this email from my hosting provider, from Heroku, from where we have the database set up.
29:55 And the way it works is you just say, okay, you know, I want the Postgres database, this version with this many rows of capacity.
30:00 And you get that box provisioned and they do all the backups and they provide an automatic failover and all of that.
30:07 And so I scroll down the emails further and I'm like, oh, okay, they detected that five minutes ago and already switched over to the failover automatically.
30:13 And then reprovisioned the master and kind of switched it back.
30:17 And I didn't have to do anything.
30:18 And it totally saved me probably like at least an afternoon of work while the website would have been down.
30:24 And not a regular afternoon of work.
30:26 A vacation.
30:26 Sorry, honey, we were going to be on the beach.
30:29 Because now I'm in the hotel frantically fighting this bad internet afternoon of work.
30:33 Exactly.
30:34 And so I was like, oh man, this is great.
30:36 I very much like that.
30:39 And so I was always a bit worried that something really bad would happen from a hosting perspective if I was going to start provisioning all my own boxes and then updating them.
30:46 This is a constant fear of mine of just like what happens if it just goes down.
30:50 It hasn't been a problem yet, but that doesn't prove anything.
30:53 It's just it hasn't happened yet.
30:54 Right.
30:54 Yeah, totally.
30:55 It's a real fear that I also have all the time.
30:58 Yeah.
30:58 Yeah.
30:58 Yeah.
30:58 It's pretty interesting.
30:59 But you're pretty happy with the platform as a service?
31:01 I'm really happy with it just from a usability friendliness perspective as a developer because I don't have to worry about installing.
31:08 When the whole Spectre thing happened and all of these interesting...
31:12 Oh, yeah.
31:13 We had that 10 second downtime for a lot of reasons.
31:16 Yeah.
31:16 Yeah.
31:16 Yeah.
31:17 Yeah.
31:17 Yeah.
31:18 Yeah.
31:18 You know, I didn't really have to do anything about it because I just basically tell the platform, like, here's the code for the app.
31:24 Here's the services that I need.
31:26 So I need like Redis as a cache.
31:28 I need Postgres as the database.
31:30 And just give me an endpoint that I can talk to or like credentials for the database.
31:35 And they will keep it patched and updated and make sure there's backups.
31:39 And there's like, it's always like a failover primary, secondary system.
31:42 And I very much like the sense of security it gives me.
31:47 But on the other hand, I mean, it's probably fairly unlikely that your server will just melt down.
31:52 And so what are you really getting?
31:54 You know, maybe it's worth the trade-off.
31:56 Yeah.
31:56 I mean, you're already protected of hardware failures on the IaaS systems because they'll move your VM across.
32:03 I've had several times the underlying machine has died and we moved your VM over somewhere else.
32:09 Yeah.
32:09 And it just kept rolling.
32:10 Have you ever considered like running your podcast on real, like bare metal in your living room, in your office room?
32:16 No.
32:16 I'll tell you a funny story really quickly.
32:19 Slight diversion, but I think it's worth it.
32:20 So this is from 19, I remember where I was.
32:25 This is like 95, 1994, 95.
32:29 I remember like the first Mozilla browser came out in 93.
32:33 So I had a friend who was a web designer friend.
32:38 And this predates all the like hosting.
32:40 Yeah.
32:40 I mean, this is like a couple of years in the internet.
32:43 And he somehow, I have been thinking back, I have no idea how he did this.
32:46 He had gotten the job to build the website of one of the major helicopter manufacturers in the world.
32:54 Wow.
32:54 Right?
32:54 And he was hosting, he was hosting all of his sites on his laptop in his house.
32:59 But, but we had a party at his house and somebody walked by and tripped on the power cord and unplugged it.
33:08 But it didn't turn off right away.
33:10 Right.
33:10 Cause it just went to battery.
33:11 Yeah.
33:12 But a few hours later that ran out of battery and it turned off and he went to sleep.
33:15 He woke up the next day and people were upset.
33:17 Like, why is the website?
33:18 Oh no.
33:19 We had a server failure is what he told him.
33:21 But it was, we had a party and someone pulled the cord on the laptop.
33:23 Is that insane?
33:24 Would that ever happen now?
33:26 Yeah.
33:27 It goes to show like how much this, this whole industry has changed.
33:31 I mean, maybe that's what they're doing at Heroku.
33:32 I don't know.
33:33 It's like in somebody's basement.
33:36 Yeah.
33:36 No, I would never, I would never consider on like bare metal.
33:40 Like there's just having the failover at the network level and just the bandwidth and the
33:46 flexibility, the geolocations, right?
33:49 Like I think a lot about where stuff located for different purposes.
33:52 That's going to be interesting too, to chat about that aspect because I know that for the
33:56 video delivery, for the courses, you're doing some really interesting stuff.
33:59 Like basically you built your own little, like not little, but like a content delivery network
34:03 to be like physically close to the person that's watching the video.
34:07 The first thing I hear when I talk to people about this is you're not just using a CDN and
34:13 I'm sure I'm going to hear some stuff about this again, because it's irresistible.
34:16 It seems to talk about it, but I'm not using CDN.
34:19 I'm using something else that lets me create, have more control over the visibility of the
34:23 URLs and the content, because I don't want to have just public content, even if it's sort
34:27 of protected on the app side.
34:29 It's like once you have URLs, they're just public, right?
34:31 So I have a way to like create signed short-term URLs.
34:34 But yeah, the video delivery is really important.
34:37 So that doesn't happen out of my servers.
34:39 That happens out of other places throughout the world.
34:41 So I have like eight locations.
34:42 Like there's a site in Mumbai, there's one in Sydney, there's one in Tokyo, there's one
34:47 in Ohio, right?
34:48 Where we are here and so on.
34:50 And so when you go to training.talkpython.fm and you play a video, not the little marketing
34:54 videos, but like all the other real content, the first question the site asks is, who are
34:59 you?
34:59 Are you logged in?
35:00 Are you allowed to do this?
35:01 The answer is yes.
35:02 Then the next one is, where are you?
35:03 Right?
35:04 So it'll figure out what of the servers that it has available to it, which one is closest
35:10 to you.
35:11 And then it'll, it'll stream it to you from that location, wherever you happen to be.
35:15 Nice.
35:15 Yeah.
35:16 And then to get it in those locations.
35:17 I've got one place I upload to.
35:20 And then this little system, a little like unit, a system unit from system D Python thing
35:27 that runs continuously on one of the servers.
35:29 And anytime it sees a change to like the main location, it'll synchronize it throughout the other seven places in the world.
35:36 So, you know, upload it to one place, walk away, you know, seven minutes, a few minutes
35:40 later, like it's in the different seven locations.
35:42 Yeah.
35:42 So the crazy thing to me here is that, that you're also doing your own video transcoding
35:47 and all of these things to be able to deliver to the app and to different browsers.
35:51 And yeah.
35:52 Well, I tried to just publish the Camtasia videos and they wouldn't play on iOS.
35:55 And then they were too big in other places and stuff.
35:58 And you've got to have certain underlying, like it's not good enough.
36:03 It's just an MP4.
36:04 Yeah.
36:04 It's got to have like this version or like these settings, or it can't be over like 1.5
36:09 megabit encodings for certain things.
36:11 And it's super painful.
36:13 And so actually shout out to Cecil Phillip.
36:15 He pointed me towards this.
36:16 So what I found and started using, I mean, obviously it's, you know, been around is Amazon
36:23 has something called elastic transcoder service.
36:25 All right.
36:26 So elastic transcoder service lets you come up with a very carefully structured set of transformations
36:32 to your video and you give it a video and it'll generate that, like give it a five minute
36:37 video and 20 seconds.
36:38 And you have like an output that is perfect for streaming on the other devices.
36:42 So I wrote a Python script that'll go to a set of like a course videos folder, run it.
36:48 It'll take all the videos.
36:50 It'll upload them to a temporary location in S3.
36:52 And then it'll use the API to talk to the transcoder service and have it drop into another
36:56 location in S3 when it's done.
36:59 And then when it's done, it'll grab it, download it, put it in a different spot on my stuff.
37:02 And just here's like the sort of streaming version of that course you just built.
37:06 It's awesome.
37:07 It still seems crazy to me, but I mean, I know that you're a really good engineer.
37:10 And the fact that you can pull this off, I think is really, really amazing.
37:13 When you told me about this the first time, I just thought it was mind blowing.
37:17 Because I was like, I'm just going to use Vimeo.
37:19 Well, here's the thing.
37:21 I started out with Vimeo.
37:22 I started out using Vimeo.
37:23 And it was really good until it wasn't good enough.
37:27 Right?
37:28 Like Vimeo was good, but it would periodically, like the embedded player stuff would stop working,
37:33 you know, and it'd be down for like 15 minutes.
37:37 It'd be like, you know, I'd start getting emails.
37:39 Michael's site's down.
37:41 I'm like, yeah, I know.
37:42 But it's 100% out of my control.
37:44 Then I would get questions like, hey, can I play this at 1.5 speed?
37:47 Like, no.
37:48 Player doesn't do 1.5.
37:49 It doesn't have speed.
37:50 So, no, I'm not.
37:51 I can't do that.
37:52 Just on and on.
37:53 Can I have an offline version or whatever?
37:55 Right?
37:55 Like there's all these things that you start to want and they eventually pile up.
37:59 And you're just like, okay, well, if not that, then what?
38:03 Right?
38:03 Because it was working mostly great.
38:05 But then it's like, all right, well, now it gets really complicated really quickly.
38:09 But, you know, it didn't start that way, right?
38:12 Like I was selling the courses.
38:14 Things were going great.
38:15 And then like I needed more than I could get from that sort of pro setup I had,
38:20 like the pro account or the business account I had set up with them.
38:23 I'm like, all right, that's, you know, thank you for your service.
38:26 But it's time for me to move on and do something else.
38:28 And by the way, this is way more expensive, right?
38:30 Like I'm paying for the bandwidth.
38:32 Oh, yeah.
38:32 Oh, I better do so.
38:32 And the transcoder is pretty cheap.
38:34 It's like $10 to transcode like hours of video or something.
38:37 And you do that once, but the bandwidth is more.
38:40 This portion of Talk Python to Me is sponsored by Backlog from NewLab.
38:45 Developers know the importance of organization and efficiency when it comes to collaborating on a team.
38:50 And Backlog is the perfect collaborative task management software for your team.
38:55 With Backlog, you can create tasks, track bugs, make changes, give feedback,
38:59 and have team conversations right next to your code.
39:01 You track progress with features like Gantt and burndown charts.
39:05 You document your processes right alongside your wikis.
39:08 You can integrate with the tools you use every day like Slack, Jira, and Google Sheets.
39:12 You can automatically register issues from email or web form submissions.
39:15 Take your work on the go using their top-rated mobile apps available on Android and iOS.
39:20 Try Backlog for your team for free for 30 days using our special URL at talkpython.fm/backlog.
39:27 That's talkpython.fm/backlog.
39:31 So would you say the fact that this also makes your offering unique, your website is unique,
39:38 sort of like a bespoke design, build it from scratch, like the search, all of that stuff is unique.
39:44 It makes you special.
39:45 And it makes, I think, as a visitor or reader, follower, consumer, it feels different to go on one of your websites than like a run-of-the-mill WordPress site.
39:54 So is this something that sort of happened organically or is this something that that was your goal initially?
39:58 I would say it somewhat happened organically, but it was also somewhat of a goal,
40:03 like especially around the training stuff.
40:05 Like there were a lot of options.
40:06 Like I could have used Teachable or Thinkrific or Udemy, or I could have partnered up with Pluralsight or one of those sets of people, right?
40:15 Those types of platforms.
40:17 And the consideration there was this is like my bet on my future.
40:23 And this is the most important thing I consider that I'm doing for the next couple of years.
40:28 I want it to be as nice as it can be.
40:29 I know I can build a better site than Thinkful or whatever, Teachable, these different places.
40:34 And I think it'll be more special if it's not just under some subscription place like Pluralsight or Safari Online or whatever, right?
40:42 And so I actually thought as hard as I could, like, is there a way I can avoid doing this, right?
40:49 Because I really don't want to.
40:50 It's getting in my way.
40:51 It's going to take me like weeks.
40:52 Like that actually took a long time.
40:54 It was like almost a month to write the site and all that stuff.
40:57 But in the end, I decided, you know, if I just do it like a band-aid, just pull it off, do it now, I'll be in a better place, you know?
41:05 And like keep in mind, this is like, this is the decision I had to make like the day I quit my job and I had no income and I could have no income until that was done, right?
41:14 It wasn't just like, oh, maybe I'll evolve it, whatever.
41:16 That gets you motivated, yeah.
41:18 Yeah, that'll get you going.
41:19 Like you'll get it written quick.
41:20 You know, when I think back, like we've been chatting about this stuff for a long time, right?
41:26 Yeah, absolutely.
41:26 Developing our stuff there in parallel.
41:28 And you've sort of drawn me into that direction more to do more custom stuff.
41:33 We had a real similar debate, right?
41:35 You're like, I could probably just set up some WordPress thing and make this happen like for real Python or whatever it was you were doing at the time.
41:40 My first Python education website, debater.org, which is still around, sort of my personal thing there.
41:46 That was a custom, sort of like a static site generator, but it was just all serving it from memory.
41:52 So it was like written in the BottlePy framework.
41:54 And, you know, way back when I wrote it in 2012, I didn't really know what I was doing, to be honest.
41:59 So it's kind of limping along.
42:01 And when I had the chance to do things properly with real Python, I was sort of torn between, oh, I would love to do something custom.
42:11 But I also know that there's downsides to it in the long run.
42:16 It's like a constant friction that is on you.
42:18 Like I would say I spend at least 10% of my time just keeping things running and smooth and adapted.
42:25 Like it doesn't, I don't know why, but it seems like there's always just a little bit of friction.
42:29 And you wouldn't have that necessarily with the other stuff, right?
42:31 Yeah.
42:32 Well, it's or so you would think, right?
42:33 I guess so you would think.
42:34 I was talking to a lot of people just in the web dev space.
42:37 And, you know, I used to work as a backend engineer for a company in Vancouver.
42:40 And shout out to Mobilify, a really cool company.
42:42 And my friends were pushing towards like, oh, just use WordPress.
42:46 You know, you can get all the plugins if you want to hire somebody.
42:49 There's a lot of people who know about WordPress and PHP versus Python.
42:53 You can buy a theme, you know, there's like this whole ecosystem for this stuff.
42:56 And, you know, back then I think we had a similar conversation about this.
42:59 And we're like, you know, you should really consider doing a custom implementation because
43:03 then you can tailor it exactly the way you want to.
43:06 And I'm so glad I changed my mind or partially you convinced me and that I rewrote realpython.com
43:12 as a Django app because now it is sort of a superpower being able to have a really tailored
43:17 and unique workflow for all the authors contributing to the site, you know, for our editing team
43:23 and just to be able to, you know, run something like a little linter on an article.
43:26 And I don't have to A, write that in PHP.
43:29 And then B, I think the other thing is as soon as you get, so for example, my wife's website,
43:34 she has a graphic design portfolio.
43:35 We built that on WordPress and that's cool and all.
43:39 You're so effective and fast in the beginning, but then you start running into all these issues
43:44 with these plugins playing together.
43:45 And maybe you don't even fully understand the underlying tech.
43:48 Like you can jump into Python and fix it.
43:50 Like, can you actually resolve that problem with PHP?
43:52 Yeah, no.
43:53 No, me either.
43:54 Some people, yes, but me, no.
43:57 Yeah.
43:57 Yeah.
43:58 And that's a big pain now where it's like, well, you know, this plugin is getting updated
44:01 and then there's like a new big new release or some security patch.
44:04 And these things are not all updating in sync and they're kind of all doing their own thing.
44:08 And it blows up a lot.
44:10 Whereas if you run your own application, you have a lot of control over the deployment process
44:14 also.
44:15 And so like in retrospect now, I'm really glad that it's a custom Python app.
44:19 Yeah.
44:20 Yeah.
44:20 That's awesome.
44:21 I guess the question is, how are we all going to feel about this in five years from now
44:24 where it's like, oh God, you've got to maintain this thing.
44:27 Actually, this brings me to another question that we haven't really touched on yet.
44:30 Like choice of Python web dev frameworks.
44:32 Yeah.
44:33 So you're using Pyramid, right?
44:34 Yeah.
44:35 I'm using Pyramid and you're using Django.
44:36 For the most part.
44:37 Yeah.
44:37 Django.
44:37 For the most part.
44:38 Yeah.
44:38 I'm also using a little bit of Flask for some APIs that people don't see, but they're there.
44:43 Yeah.
44:43 It's got some BottlePy in there still for debater.org, but everything else is Flask.
44:48 Yeah.
44:49 So that's an interesting one.
44:50 You know, there's two things that I really, really liked about Pyramid.
44:54 And keep in mind, this is 2015, not 2019.
44:57 When I decided these things, right?
44:59 Yeah.
44:59 Yeah.
44:59 So at least for one of them, one's unchanged, one's true.
45:03 For when I went, like my personal web style is like a minimalist, bring the little pieces
45:10 together.
45:10 I'm kind of a micro framework type person.
45:11 So I thought Django is nice, but it feels like kind of bigger.
45:15 I need to understand more of it at once.
45:18 And I felt like with the micro frameworks, I could like learn it piece by piece.
45:22 You know, like I'm going to understand this little part here.
45:24 And like, I don't know what that does.
45:25 I don't need to know.
45:26 I mean, that's actually on the Pyramid framework site.
45:29 Like one of their principles is you can be effective with a partial understanding of Pyramid.
45:33 Like I can call it.
45:34 So anyway, so I was considering Pyramid.
45:37 I was considering Flask and a few other things.
45:39 But when I, at the time, super underscore that, at the time I went to the Flask website and
45:46 said, this is for Python 2.
45:48 It may, may work on Python 3.
45:51 Your mileage may vary.
45:52 We have no guarantees for you there.
45:55 Right.
45:56 And I'm like, whoa.
45:57 I don't know if I want to get into that.
46:00 Right.
46:00 Like I don't want to start a brand new thing on Python 2.
46:03 If like that's its world.
46:04 I did a quick check of the performance stuff and Pyramid was faster than the other two on Python 3.
46:10 I think Flask was faster on Python 2, but that didn't make me happy.
46:13 Right.
46:14 I want to be on Python 3.
46:15 So, you know, having no legacy code, I'm like, all right, let me try this Pyramid thing.
46:19 The other reason I really like Pyramid is the Chameleon templates.
46:22 Like I very much dislike the style of the Jinja templates.
46:27 And it's not just Jinja, you know, C# has the Razor space that's very similar.
46:32 Django's templates are similar.
46:33 What I don't like is template languages that are very much not HTML.
46:39 Like you can't take a Jinja template and load it in a standard HTML editor and have it think it's okay.
46:45 Right.
46:45 Because you've got that angle bracket percent for something, something like their angle bracket percent and for all over the place.
46:52 Right.
46:52 Whereas Chameleon is more angular or view like, like Vue.js, like where it's attribute driven.
46:58 So you might have an attribute that is not understood, but that's valid HTML other than tal colon condition has a string.
47:05 Right.
47:05 Right.
47:06 It's like, I don't know what attribute means, but it's valid HTML.
47:08 Oh, does it actually like parse the template as XML or whatever?
47:10 And then like, it makes sure that it's valid.
47:13 Yes, it does.
47:14 Because if you have an unclosed tag, it freaks.
47:16 That is cool.
47:17 I had no idea.
47:17 Yeah.
47:17 It's like true HTML that's like extended by Python.
47:21 And also it's more, you can't write arbitrary Python code there.
47:26 You have to like have a little better architectural separation.
47:28 Those two things, when I got started, I'm like, okay, I like both of these about Pyramid.
47:33 And I didn't consider Django as much because it's a micro frameworks bent that I have, I guess.
47:38 And that's a personal thing, right?
47:39 Yeah.
47:39 No, for sure.
47:40 Yeah.
47:40 And I think it also, yeah, I guess like depends on the nature of the site and your workflow.
47:44 I think you do a lot of like terminal driven stuff, right?
47:48 When you just showed me your deploy process or when you, like, what does it look like for you?
47:52 I'm really interested in the workflows, right?
47:54 Because for a new podcast episode to go out, like what's going to happen once we're done recording this and you want to publish it on the website?
48:01 Oh, that's a good question.
48:02 So when we're done recording this right now, recording it, I'm going to convert it to multi-track WAV files.
48:07 I'm going to hit it with some audio filters, some quick editing, quick leveling.
48:12 So even if our mic settings are different or our distance we're holding our mics are different or like normally it's recorded at different locations, it all sounds like we're in the same room mostly.
48:20 I'm going to send that off to Marco.
48:22 Shout out to you.
48:23 I'm sure you're editing it now.
48:24 And Marco is an awesome guy that's been supporting me for a long time.
48:26 And he edits it into its final form.
48:29 I take that back.
48:30 I actually have a bunch of other little bits, like the ad bits and the intro bits and the music.
48:34 And I do all that in GarageBand because GarageBand is good for multi-track stuff.
48:40 I don't actually do the audio editing there, but I do like the composition of the tracks there.
48:44 Put that into an MP3.
48:45 I upload that to S3.
48:48 Like manually with the...
48:50 I'll use Transmit, but yeah, yeah, yeah, exactly.
48:52 So I upload that.
48:53 And then it goes into the Python world.
48:56 So then I log into a backend on Talk Python.
49:00 And I say, here's a new episode.
49:02 I type in the details and I say, here's the URL on S3.
49:05 And you could just serve it off S3.
49:07 But the amount of bandwidth that's going through there, like let me just do a quick test here.
49:11 So we have...
49:12 I want to have the right numbers and I want to make enough stuff here.
49:15 So if I served it off S3, it would be like $600 or $700 a month, which is not the end of the world,
49:20 but it's not ideal, I guess, right?
49:23 Especially when I was getting started.
49:24 And so I actually have another server, another virtual server that has tons of available paid bandwidth, right?
49:31 And with that, I just put it on there and just serve it out of IntuneX as a static file.
49:35 So when I add the S3 URL, it'll like grab it.
49:40 It's sort of a cache server.
49:41 Like it'll ask from the place it actually comes from.
49:43 And if it's not there, it'll get it from S3.
49:45 But if it is there, it'll serve it off disk.
49:47 And the reason is like that I'm even doing that is if for some reason I need to stop doing that or it goes down,
49:54 then I can just flip a switch and it'll fill back to S3.
49:58 So S3 is always there as like a reliable backend for the media content.
50:03 And as far as like updating the content on the website goes, like you...
50:08 There's like a little editor backend I built.
50:10 Okay.
50:11 Yeah.
50:11 Yeah.
50:11 Like a little web form or something where you could...
50:13 Yeah, exactly.
50:13 Like, you know, four or five pages that'll edit episodes, edit guests, things like that.
50:18 Yeah.
50:18 It's interesting.
50:18 Like I was just thinking like maybe a big part of the, you know, different approaches there is for your workflow
50:24 because it's so, it's heavily media based, right?
50:26 Like the deliverable is an MP3 file.
50:29 Yeah.
50:29 And so...
50:30 There's a lot of steps I can't avoid no matter what, right?
50:32 Yeah.
50:32 Yeah.
50:33 And it's like a different, you know, when I compare this, for example, to RealPython,
50:37 RealPython is more like a multi-user online magazine, really, right?
50:42 Yeah.
50:42 Like from the backend perspective.
50:43 And Django is great for that because it was built for that purpose, you know, at a news organization.
50:48 And so, at a newspaper journal.
50:50 And so, it was like a perfect natural fit for that because it gives you all this like amazing admin interface and all that stuff.
50:57 But when you're doing a podcast, like a lot of the technical aspects, you got to build a custom workflow for that anyway.
51:03 Like because a lot of it is like audio processing distribution and the content delivery.
51:08 Whereas with more like a magazine-based site, it's more you're doing a website.
51:13 You need multiple people interacting with the site side of things, right?
51:15 Yeah.
51:16 Yeah.
51:16 Where my main work is on the media locally and it just happens to be delivered there.
51:20 Yeah.
51:21 Interesting.
51:21 Here's the thing.
51:22 It's like, could I change things to do something better?
51:24 Maybe, maybe not.
51:26 But it's like...
51:26 It's all relative.
51:27 And it's just, it's working so well for me.
51:29 Like it's totally spot on.
51:31 So, and I'm happy.
51:32 So, you know, it's all good.
51:33 Yeah.
51:33 Yeah.
51:33 No, for sure.
51:34 I think, yeah, that's like the biggest thing to keep in mind there that it's all...
51:38 As long as it works, there's not necessarily like...
51:41 There's not a huge benefit to improving things much beyond that point.
51:45 I mean, I want to rewrite things all the time.
51:47 But realistically, you want extra...
51:49 It's a diminishing returns thing.
51:50 Right.
51:50 Absolutely.
51:51 For example, like you launched your mobile apps now.
51:53 Right.
51:54 That is a huge thing.
51:55 Instead, you could have spent the last year like rewriting all of your existing infrastructure.
51:59 Right.
51:59 Exactly.
51:59 So, it's in the hottest new framework.
52:01 It could be all Vue.js or whatever.
52:03 Right.
52:03 Like on Docker.
52:04 But whatever.
52:05 I got my mobile app and that adds true value.
52:07 Right.
52:08 When you're a small group of people working on something, you got to focus where it counts.
52:12 So, maybe that's worth talking about a little bit.
52:14 You know, people ask, you know, did I use Python for my mobile apps?
52:17 So, people who don't know, released two apps where you can take the courses in a much better
52:24 way on iOS or Android phones or tablets, whatever.
52:27 Right.
52:27 There's a lot of...
52:28 Especially on iOS, there's a lot of limitations to trying to do that through even a nice web
52:32 app.
52:32 It's just not the same.
52:35 So, having something truly native there was super important to me.
52:39 And I've wanted to do it for a long time.
52:40 And I knew it was going to set me back in terms of productivity and getting stuff done.
52:44 But I finally broke down and did it.
52:46 So, I guess the first question is what's it built in, huh?
52:49 Yeah.
52:49 Is it Python?
52:50 Man, I wish it was Python.
52:52 I tried to make it Python.
52:53 I even looked at Ionic for a while.
52:56 Ionic's pretty cool.
52:56 But I wanted something native for iOS, something native for Android.
53:01 I didn't want to do Kotlin and Swift.
53:03 I have a decent amount of experience with C#.
53:06 Right.
53:07 And the JavaScript.
53:08 So, the two choices were do something with Cordova phone gap type of thing, maybe on Ionic and some front-end framework there.
53:15 Or do something native with C# and Xamarin.
53:17 So, Xamarin takes your code and compiles it down to native instructions on iOS and on Android.
53:23 And it's like a true native app.
53:24 So, that's what I ended up doing.
53:25 And as far as the native apps go, like the mobile apps in this case, I think you've done some experimentation in the past, too, with like Electron and stuff like that.
53:35 Yeah.
53:35 That's more for the desktop side.
53:36 Yeah.
53:36 I had originally like prototyped it out with Electron.js.
53:39 And I was going to like move that to Ionic because they have the widgets that look native on the devices.
53:44 And they're just like, it was a constant whack-a-mole.
53:47 Like, I fixed this.
53:48 Boom, that broke.
53:49 I fixed this.
53:50 Boom, that broke.
53:50 And I'm just like, all right, this sucks.
53:51 I don't want to do this.
53:52 Like, let me try something else, you know.
53:54 Yeah.
53:54 You know, Xamarin is 100% free, right?
53:57 So, that's cool.
53:58 Plus, you were a C# developer in another life.
54:00 Yeah, exactly.
54:00 So, I had enough experience that that was not a horrible choice to me.
54:04 Like, would I prefer to write in Python?
54:05 Yes.
54:06 But can I go write?
54:07 In fact, what I did was I wrote the prototype in C# and WPF on Windows because I knew how to do that.
54:14 I didn't know how to do it on iOS or Android.
54:16 And then I hired a developer to help write that for the mobile stuff and just worked with them on that.
54:22 And that was a really good experience.
54:24 What was it like publishing these mobile apps?
54:27 Because, I mean, we're, in a way, I feel like we're really jaded creating content for the web or programming stuff for the web.
54:32 I guess what I could say is I didn't realize how good we had it.
54:35 I'm serious.
54:38 I mean, holy moly.
54:40 Like, the stuff would break all the time.
54:41 I would get builds from the guy I was working with and it would be like, oh, this doesn't work anymore.
54:46 Oh, did you do a build clean rebuild all on it?
54:49 No, I forgot.
54:50 Oh, now it works.
54:52 You know, you're like, what the heck is going on with this stuff?
54:54 You know, then you hit the app store and the gatekeepers.
54:57 And, oh, my God.
54:58 It's so super scary.
55:01 There was one person I was working with at Google and one person, presumably, I'm working with at Apple.
55:06 And if both places rejected the app over and over.
55:11 And it was like, well, if I can't make this person happy, the last four months of work go down the train.
55:16 And my hope of having a mobile app are gone.
55:18 And there's this person who is massively incompetent.
55:22 Like, let me just give you, I'm not going to go too long, but I just want to say I have a lot of sympathy for mobile developers now.
55:28 So, I submit the app on Android and the title is Talk Python Training Player, Talk Python Training Courses, something like that.
55:38 Yeah.
55:38 That's the title.
55:39 The subtitle is Take Talk Python Courses on, you know, on your device.
55:43 But in the description, it said Talk Python Training for Android is the best way to take our courses.
55:49 You can learn Python.
55:51 You can learn to be a web developer and so on.
55:53 Boom, rejected.
55:53 Why was it rejected?
55:55 It was rejected because there is an app called Learn Python and I'm trying to impersonate it.
55:59 Like, where do you get that?
56:00 And eventually I see where it says you can learn Python here.
56:03 I'm like, oh, they must think.
56:04 But it's like not the title, not the subtitles.
56:06 No graphics are about it.
56:08 Like, but way down there's the word you can learn Python.
56:10 It's no more verbs, man.
56:11 It's all trademarks.
56:12 So, I had to have an argument for four days because there's like a 12-hour turnaround period of it can say you can learn Python.
56:18 And that doesn't mean it is associated with an app whose title is Learn Python.
56:22 Eventually, the thing that broke that loose was, let's try a different word.
56:26 Let's say it was physics or music.
56:28 You want to, you can learn music with our app.
56:31 Does that mean we are the app called Learn Music?
56:34 No.
56:35 But like, I had to have this conversation for days with this person.
56:38 And if they just disagreed with me, they decided then I'm out of the app store.
56:43 Yeah.
56:44 You've made that investment to build the apps and somebody has worked on it for weeks and, you know, you have to coordinate everything.
56:50 Like, I pay for it, you know, like pay for the development.
56:52 Yeah.
56:52 And you can't find out until you're done.
56:54 Yeah.
56:54 Right?
56:54 You can't pre-submit it and see if they like it.
56:56 Right?
56:56 Yeah.
56:57 You can't.
56:57 That's what we're thinking.
56:58 Yeah.
56:58 Yeah.
56:58 That's cool.
56:58 Keep going.
56:59 You do it all and you try to launch it and they say no.
57:02 And it could be reasonable or it could be unreasonable.
57:04 Yeah.
57:04 Unreasonable.
57:05 But anyway, I'm super happy they're out.
57:07 I guess to round out that conversation, there's a bunch of APIs it works with.
57:10 And of course, those APIs are all in Python on the server.
57:13 But the thing you have on your phone is a Xamarin app, which is, I think, is a pretty cool thing that we have like 95% code reuse, visual designers, everything, and debuggers for it.
57:24 95% code reuse across the various platforms and so on.
57:27 I think that's going to help a lot in just keeping things manageable.
57:30 Right?
57:31 Because again, it's coming back to like, you're not 100 people working on infrastructure.
57:34 I can't have a Kotlin team.
57:36 Right?
57:36 Like, I don't know what this stuff like.
57:37 Yeah.
57:38 And you've got to be able, in the worst case scenario, you've got to be able to go in and jump in and maybe do a bug fix or something.
57:42 Yeah.
57:43 Yeah.
57:43 Something quick or whatever.
57:44 Right?
57:44 Like, if it were massive, I'd hire somebody.
57:46 But other than that, like, yeah, you want to be able to at least take it over if you have to somewhat.
57:50 Yeah.
57:51 So, that worked pretty well.
57:52 It's a really cool app.
57:53 I mean, you showed me later and I installed it on my phone.
57:55 And it's just really smooth and fast.
57:59 Thanks.
57:59 I think for a first release, like, it's really, really cool.
58:01 Yeah.
58:02 Yeah.
58:02 I'm really happy how it came out.
58:04 I'm glad we did it.
58:05 But boy, it was a shaky process to get there.
58:08 Yeah.
58:08 Yeah.
58:08 Not technically, but, like, approval and stuff.
58:10 Yeah.
58:11 I guess, you know, one more thing that I'd like to, like, sort of exchange.
58:14 Well, I'm doing what you're doing just so people can know.
58:17 Is, like, so, we have the stuff hosted.
58:20 Like, you talked about Heroku.
58:21 I got my servers and so on.
58:22 But I also use AWS for a bunch of stuff.
58:25 Even though I'm not on EC2.
58:27 I'm not a huge fan of EC2.
58:28 I think it's really expensive and really complicated.
58:31 I think it's built for, like, running Netflix and other massively awesome things.
58:36 But if I just want a server, you know, it's like, well, my security groups aren't, like,
58:41 I just want a little firewall and I just want to, anyway, let's not make that a rant.
58:44 But even though I'm not using AWS, I'm still using Elastic Transcoder.
58:48 I'm using Simple Email Service.
58:50 I'm using S3, Stripe.
58:53 I've got Stripe, MailChimp.
58:55 There's a bunch of other services that get involved here.
58:59 Like, how about you?
59:00 Like, what else are you using?
59:01 It's so fun, or not fun, but it's hard to think about this and, like, remember all the
59:08 services.
59:08 I know.
59:08 I'm sure I'm missing some.
59:09 But, like, for me, like, in terms of software that I use, Redis plays a big role.
59:14 Like, it's basically our caching system in between the database and, or not, you know, not in
59:19 between in any sort of, like, physical direct sense, but, like, the Django app will talk to
59:22 Redis and put some stuff there as a cache, like, the sessions live there.
59:25 I was wondering, like, are you using anything like Memcached or Redis or any apps?
59:31 I've considered using Redis for some of the search, like, build up a search index and
59:37 put it there.
59:37 But in the end, I'm just using MongoDB.
59:40 Yeah.
59:40 I mean, I'm using Postgres for a lot of things, like the full-text search.
59:45 I was like, let's just see how far we can get with Postgres full-text search.
59:48 And it's actually amazing how much modern databases can just do for you.
59:52 Yeah, that's awesome.
59:53 Where you, yeah, you don't have to invent this stuff from scratch or build your own index.
59:57 Yeah.
59:57 Yeah.
59:58 As far as infrastructure goes, yeah, I've got, actually, PythonistaCafe.com is hosted
01:00:02 on a DigitalOcean box.
01:00:04 Okay.
01:00:04 That's been really helpful.
01:00:05 Yeah, awesome.
01:00:05 And, yeah, I've been super happy with their service and, you know, just rock-solid hosting,
01:00:09 I felt like.
01:00:09 Let me throw one thing out there for people listening, by the way.
01:00:12 If you're thinking about hosting and you want to be on Amazon, check out Amazon LightSail.
01:00:15 Do you know about LightSail?
01:00:17 It's, like, really small.
01:00:18 So, it has the same pricing as DigitalOcean and Linode.
01:00:21 In bandwidth.
01:00:22 You get a free terabyte with a $5 server, which is $100 worth of bandwidth on S3 equivalent.
01:00:28 Nice.
01:00:28 And so, if you just want to be on Amazon, but you don't want all that stuff, like, and,
01:00:32 you know, LightSail as well.
01:00:33 Anyway, keep going.
01:00:34 Yeah.
01:00:34 Yeah.
01:00:34 Yeah.
01:00:35 Also use S3 and then CloudFlare as the CDN in front of everything.
01:00:40 You do a lot with CloudFlare, right?
01:00:41 Yeah.
01:00:41 It's been incredibly useful.
01:00:42 They have this great image transcoding service that is totally transparent to you, where they
01:00:47 will recompress your images and do, like, a browser detection.
01:00:50 So, if you're on Chrome or, like, modern Firefox, they will transcode your images to WebP
01:00:55 and then serve them out.
01:00:56 And that could, you know, reduce your image sizes to, like, basically half them.
01:01:00 And I don't have to go and, on the back end, write the logic for, like, oh, does this
01:01:04 specific version of Chrome support this format or Safari or whatever?
01:01:09 No, it can't be WebP.
01:01:10 It's got to be whatever.
01:01:11 But they make that decision for you and they can update those rules for everybody.
01:01:14 So, that's been incredibly helpful.
01:01:16 I guess we're basically out of time, Dan.
01:01:18 And there's, like, still so much more stuff we could talk about.
01:01:22 Email, I think, would be super interesting.
01:01:24 But maybe we'll do another one of these if there's interest.
01:01:27 Yeah, I guess we could come back.
01:01:28 I guess one other thing that people ask a lot that I just want to throw out there, it's,
01:01:31 like, why MongoDB and NoSQL versus relational?
01:01:34 Oh, yeah, yeah, yeah.
01:01:35 Yeah.
01:01:35 And to me, like, it's just the modeling stuff in the NoSQL database is really easy.
01:01:40 But the one thing I really love is, like, I've not done a database migration in two years.
01:01:44 Right?
01:01:45 But the data models have changed a lot.
01:01:46 Right?
01:01:46 Because the document databases or schema can just adapt most of the time to the new classes,
01:01:51 especially if it's additive and not subtractive.
01:01:53 You've never been burned by that?
01:01:55 Like, I kind of like having a schema I can trust.
01:01:58 Yes.
01:01:58 So here's the reason I don't think I've been burned by it is I have, to me, I know the schema
01:02:03 safety structure is in the app code.
01:02:06 So I have a special tier whose job it is to just talk to the database.
01:02:10 And it always enforces the schema.
01:02:12 And, like, I never, ever talk to it anyway other than through that part of code.
01:02:16 Okay.
01:02:16 And so...
01:02:17 The schema is in the business code.
01:02:18 There is still a schema because otherwise the code won't run.
01:02:21 Yeah.
01:02:22 But if you just ad hoc it or if you have five apps to talk to it and they don't share
01:02:25 that bit, then you very well could get burned.
01:02:28 So I'm just super careful because I've done it before.
01:02:30 And I think, like, if you're the sole developer working on it, I think that's a great model
01:02:35 too, right?
01:02:35 Where, yeah, you can take these shortcuts and they're basically fine.
01:02:38 But as soon as you have, like, I don't know, if you have a team of, like, 50 people working
01:02:42 on an application, then that stuff just starts breaking, like, every single day, right?
01:02:45 Where it's like, oh, who put a bunch of strings into this integer field?
01:02:50 Exactly.
01:02:51 Yeah, but for example, I use Mongo Engine, which is like SQLAlchemy or Django ORM, and
01:02:56 it will not let you put strings where integers go, for example, right?
01:02:59 So the safety is in the data access layer, but it's not that it's not there.
01:03:03 You know what I mean?
01:03:04 Right, right.
01:03:04 It's just shifted, like, it lives in the application versus the database.
01:03:07 It's kind of like the monolith versus microservice conversation as well, right?
01:03:11 Yeah.
01:03:11 Is there anything that we both really wanted to talk about, but we haven't yet?
01:03:17 I feel like we covered a lot of stuff.
01:03:19 We haven't really talked about Python bytes, I think, the infrastructure for that.
01:03:23 Well, Python bytes is pretty much like a fork of Talk Python.
01:03:26 Nice.
01:03:27 So it's real, real similar.
01:03:28 Yeah.
01:03:28 I mean, it's got its own instance of an app and database and stuff, but it's basically the
01:03:32 same.
01:03:33 We got the training stuff.
01:03:34 I think that's pretty much, I guess.
01:03:35 If you were to do this all over again, like right now, and you had a month to rebuild it,
01:03:39 like infinite time to rebuild it, how would you do anything different?
01:03:43 I don't know that I would do too much different.
01:03:45 Like, I'm really happy where things are.
01:03:48 Like, it doesn't go down.
01:03:49 It's easy to maintain.
01:03:50 It's cost effective.
01:03:52 The way I got here was like a circuitous path of like, oh, I'm going to try this platform
01:03:56 as a service thing.
01:03:57 Oh, it's kind of not really reliable.
01:03:59 Oh, I'm going to use SQLite so I don't have to deal with this other stuff.
01:04:02 But like, oh, now things are outgrowing that.
01:04:04 And just, I would have gone more towards either where I am or maybe towards Heroku or something
01:04:10 like that, where you are, if I felt like a platform as a service would have made me happier.
01:04:15 I don't think I would change too much, but I would have gotten to where I was a lot better.
01:04:19 But like, that's more quickly, like that's the curse of knowledge, right?
01:04:23 Like you kind of, how about you?
01:04:24 Yeah, I feel the same.
01:04:26 I mean, I'm pretty happy with how like all of the hosting aspects and the technical side
01:04:32 of that.
01:04:33 I think, I mean, it's much more about creating.
01:04:35 I have to continuously remind me of that, right?
01:04:38 where like the goal of this business is to provide really, really good training material
01:04:43 to people and to enable people to learn better and become better Python programmers.
01:04:48 Right.
01:04:48 Neither of us are selling tech.
01:04:50 We're selling content and education and experiences.
01:04:54 And this is just the facilitation layer.
01:04:57 Yeah.
01:04:57 And so from that perspective, I'm super happy with the tech.
01:05:00 And I think, you know, also considering that, what we just said, it's really important that
01:05:04 it's fun to work with the tech and that we get to work with all these interesting tools
01:05:09 and learn more about them so we can go out and teach others about them and share that.
01:05:13 So from that perspective, yeah, I'm super happy.
01:05:15 I mean, I would want to rewrite it in PHP or anything like that.
01:05:18 No, definitely not.
01:05:20 The themes, they're just not worth it.
01:05:22 Don't do it.
01:05:23 All right.
01:05:24 Well, Dan, thanks for doing this.
01:05:27 Don't like sort of interview me and sort of 50-50 hosting of the show today.
01:05:32 I really appreciate it.
01:05:33 It's been a ton of fun.
01:05:33 Yeah.
01:05:33 This is so cool to do this in person, like sitting next to each other.
01:05:36 Like initially it was like, oh, you know, when we're talking to each other, there's no delay.
01:05:40 Like usually there's like a 200 millisecond or I don't know how long delay is like over Skype.
01:05:42 We talk over each other all the time because of the latency and stuff.
01:05:45 Yeah, it's great.
01:05:46 The bandwidth is awesome right here.
01:05:48 Yeah.
01:05:48 It's 3D too.
01:05:50 It's all cool.
01:05:51 Thank you, Dan, for doing this.
01:05:53 And I can certainly recommend folks come out to PyCon next year.
01:05:56 Hopefully you could see some of this live as well.
01:05:58 Oh, yeah.
01:05:58 No, it was great.
01:05:59 It was, yeah, just a ton of fun.
01:06:01 We're going to be, PyCon is going to be in Pittsburgh.
01:06:03 So that's, I've never been to Pittsburgh.
01:06:05 Me either.
01:06:05 I'm looking forward to it.
01:06:06 I'm looking forward to that.
01:06:06 All right.
01:06:07 Well, cheers.
01:06:08 Thanks for being here.
01:06:08 All right.
01:06:09 Thanks so much for inviting me again.
01:06:10 Bye.
01:06:11 This has been another episode of Talk Python to Me.
01:06:15 Our guest, or should I say guest host, was Dan Bader.
01:06:20 And this episode's been brought to you by Linode and Backlog.
01:06:23 Linode is your go-to hosting for whatever you're building with Python.
01:06:27 Get four months free at talkpython.fm/linode.
01:06:31 That's L-I-N-O-D-E.
01:06:32 With Backlog, you can create tasks, track bugs, make changes, give feedback, and have team conversations
01:06:39 right next to your code.
01:06:40 Try Backlog for your team for free for 30 days using the special URL talkpython.fm/backlog.
01:06:47 Want to level up your Python?
01:06:49 If you're just getting started, try my Python Jumpstart by Building 10 Apps course.
01:06:54 Or if you're looking for something more advanced, check out our new async course that digs into
01:06:59 all the different types of async programming you can do in Python.
01:07:02 And of course, if you're interested in more than one of these, be sure to check out our
01:07:06 everything bundle.
01:07:07 It's like a subscription that never expires.
01:07:09 Be sure to subscribe to the show.
01:07:11 Open your favorite podcatcher and search for Python.
01:07:13 We should be right at the top.
01:07:15 You can also find the iTunes feed at /itunes, the Google Play feed at /play,
01:07:19 and the direct RSS feed at /rss on talkpython.fm.
01:07:24 This is your host, Michael Kennedy.
01:07:26 Thanks so much for listening.
01:07:27 I really appreciate it.
01:07:28 Now get out there and write some Python code.
01:07:30 Thank you.
01:07:37 Thank you.
01:07:44 Thank you.