#373: Reinventing Azure's Python CLI Transcript
00:00 Deploying and managing your application after you create it can be a big challenge.
00:04 Cloud platforms such as Azure have literally hundreds of services.
00:08 Which ones should you choose? How do you link them together?
00:11 In this episode, Anthony Shaw and Shane Boyer share a new CLI tool and template
00:17 they've created for jump-starting your use of modern Python apps and deploying them to Azure.
00:22 We're talking FastAPI, Beanie and MongoDB, Async and Await, Bicep DevOps,
00:27 Automated CI and CD pipelines and more.
00:30 Plus, we also get to catch up on other Python work happening that Anthony is involved with.
00:35 If you're interested in deploying or structuring modern Python applications,
00:39 you'll find some interesting takeaways from our conversation.
00:42 This is Talk Python to Me, episode 373, recorded May 12, 2022.
00:48 Me too.
00:48 Welcome to Talk Python to Me, a weekly podcast on Python.
01:04 This is your host, Michael Kennedy.
01:06 Follow me on Twitter where I'm @mkennedy and keep up with the show and listen to past episodes
01:11 at talkpython.fm and follow the show on Twitter via at Talk Python.
01:15 We've started streaming most of our episodes live on YouTube.
01:19 Subscribe to our YouTube channel over at talkpython.fm/youtube to get notified
01:24 about upcoming shows and be part of that episode.
01:27 This episode is brought to you by Sentry and their awesome error monitoring product,
01:32 as well as NordVPN.
01:34 What you do on the internet belongs to you, not ad companies.
01:38 Keep your connection private and safe with Nord.
01:40 Transcripts for this and all of our episodes are brought to you by Assembly AI.
01:45 Do you need a great automatic speech-to-text API?
01:47 Get human-level accuracy in just a few lines of code.
01:50 Visit talkpython.fm/assemblyai.
01:53 Anthony, Shane, welcome to Talk Python to Me.
01:56 Hey, how are you?
01:57 I'm doing well.
01:58 It's great to have you here.
01:59 Yeah, yeah.
02:00 I'm excited to talk about this re-envisioning how Python works on Azure as a developer story
02:07 that you all are working on.
02:09 And from the really quick preview I've seen, it looks really exciting.
02:11 You must be excited to share it.
02:13 Yeah, it's been an adventure to figure out what's the fastest way to get a developer
02:17 kind of up and running on Azure and in the cloud without having to learn a whole set of new things.
02:23 That's kind of the goal here.
02:24 Sure.
02:25 And Shane, you and I, when we first started talking, we were reminiscing back to Azure in
02:31 the early days when there were only a couple of services.
02:34 Right.
02:35 Yeah.
02:35 Back in Silverlight.
02:36 It ran on.
02:37 Silverlight.
02:38 It ran on.
02:38 Silverlight.
02:39 Right.
02:39 Silverlight.
02:40 Oh, my goodness.
02:41 Right.
02:41 Those were the days.
02:42 What was that?
02:43 2008-ish?
02:44 Maybe a little earlier even?
02:46 Yeah, that sounds about right.
02:47 Yeah, we had Silverlight.
02:49 I think we had three actual products, and this is long before I started at Microsoft,
02:54 and SQL Server was its own portal.
02:57 So it had its own little space.
02:59 And now we're like, I don't know, well over 100 different things that we can do in the portal.
03:03 Yeah.
03:04 I don't know how many folks who are listening have actually gone to the portal and pulled
03:10 it up and sort of just browsed it.
03:12 But between Azure and AWS, it's just like a paradox of choice.
03:16 There's just layers of, oh, my gosh, the screen is full of icons.
03:19 Oh, I opened up one, and that was a subsection of now we have like deploy features that fill
03:24 the screen, right?
03:25 It's quite the challenge to get up and going, right?
03:27 Yeah.
03:27 I think if you ask any web developer, hey, you've got code.
03:32 How do you run this on the cloud?
03:33 And it's like, it depends, truly takes full meaning, you know, when it comes to that.
03:39 And, you know, before it was, you know, maybe it was just a slider bar for scaling,
03:45 right?
03:45 Like, oh, I want maybe two or three.
03:47 And now it's like, oh, well, it's based on CPU and this and how the moon is moving.
03:50 And like, there's just so many different ways that, you know, we can scale a web app or any
03:55 part of our architecture now.
03:56 And so many areas in which the pressure might be exerted that it needs to scale rather than
04:00 just CPU.
04:01 Yeah, totally.
04:02 Before we get to it, though, just like quick introduction for you.
04:04 I guess, Anthony, people know you.
04:07 You've been on the show so many times.
04:08 It's fantastic to have you back.
04:10 Yeah, it's great to be here again.
04:11 Yeah, for sure.
04:12 It's always good to have you on the show.
04:13 And when you're not on the show, we're often talking about you, about some project that
04:16 you're doing, some pet that lives in your IDE or some comic sans font using, all sorts of
04:22 fun things.
04:23 Yeah.
04:23 Rumors of a golden jacket somewhere.
04:25 Yeah.
04:26 Well, I didn't realize how close you were to the golden jacket.
04:28 That's amazing.
04:29 We have to work on that.
04:30 So just give us a quick catch up and then Shane, you can introduce yourself.
04:34 What have you been up to?
04:35 Anthony?
04:35 Have we spoken?
04:36 Yeah.
04:36 Anthony, have we spoken since you moved to Microsoft?
04:38 I think we have.
04:40 I can't.
04:40 I'm not 100% sure, but let's assume we haven't.
04:42 Tell people about what you're up to these days.
04:44 Yeah.
04:44 So I'm kind of working on advocating for Python within Microsoft and then working on advocating
04:51 Python outside of Microsoft as well.
04:53 So I'm still doing a lot of open source work, but then within Microsoft, I guess, trying to
04:57 integrate Python more into our products and stuff like that.
05:01 And also get the Python community and things like that more into how we work and find out
05:07 more about how Python is being used across the company and how we can do better as well.
05:12 So I've been focused on performance and security.
05:16 They're kind of two things I'm always interested in, but also like modern Python applications and
05:21 how they kind of come into play as well.
05:23 So yeah, so many things I couldn't possibly list them all over the last, the first year I've
05:28 been at Microsoft for over a year now.
05:30 And I made less than it was like 50 things I think I'd done in the first year.
05:33 But yeah, it's been a whirlwind, but really fun.
05:36 It has.
05:37 And you just came back from PyCon.
05:38 I want to give us a quick report from being on the scene.
05:42 Did I see you on the big screen, big stage giving a talk there?
05:45 Yeah, it's my first time doing that.
05:47 That was fun.
05:47 Awesome.
05:48 Congratulations.
05:49 Yeah, it's terrifying.
05:50 Yeah, so I gave a short update on behalf of Microsoft.
05:54 I was also in the diversity and inclusion.
05:57 I'm on the diversity and inclusion work group at the PSF.
06:00 And we had like a panel discussion on the stage.
06:03 And then I also gave a talk, like a full talk at PyCon.
06:06 What was your talk on?
06:06 It was on performance anti-patterns.
06:09 Yeah.
06:09 And that's it from your Perf Lint project?
06:12 Yeah.
06:12 So I basically gave background to the performance Lint project that I've been working on and
06:17 what things I'm looking for in code and why they slow it down.
06:20 And then just trying to demonstrate what the difference is to people on 3.9 or 3.10.
06:25 So like a simple one line code change can make 60% difference in terms of how quickly the code runs.
06:32 And then you can get into the debate again with people that no list comprehensions are just loops.
06:36 They don't make it any faster.
06:37 You're like, okay, can we run the benchmarks again?
06:40 And let's have another.
06:41 Yes, that's great.
06:42 So that's good work.
06:43 Last thing, what's the status of Perf Lint?
06:47 Is it a thing people are using already?
06:49 Is it still under development?
06:50 Yeah, it's definitely very early beta.
06:52 It raises a lot of false positives at the moment.
06:54 But it's raised some really interesting things on production code bases that I've run it against.
06:59 So for example, our serverless platform is Azure Functions.
07:03 That's all.
07:04 The Python serverless is all written in Python.
07:07 And it uses gRPC for communication.
07:10 So I'm actually running the performance linter against that code base to look at ways that we can make it faster.
07:16 And there's a list of stuff that I'm working through with the engineering team.
07:20 So yeah, trying to put that to proof instead of just making it theoretical.
07:24 That's a really good test case, actually.
07:25 And performance, if you can improve performance of the fabric of the cloud,
07:30 then you've made it better for everyone, right?
07:32 Yeah.
07:32 So there's a couple of loops I was looking at, which probably get executed hundreds of millions of times a day.
07:38 So I'm like, okay, what if I can improve that by like 10%?
07:41 Then that's going to make a big difference.
07:42 Yeah, absolutely.
07:43 Awesome.
07:44 Well, it seems like you're having a good time there.
07:46 I'm happy to see you've found a new home.
07:48 Yeah.
07:48 Yeah, indeed.
07:49 Shane, welcome to the show.
07:50 Tell people about yourself.
07:51 Thanks.
07:51 It's a hard act to follow.
07:53 I know.
07:53 I did perf at my last job.
07:54 So I appreciate any perf improvements.
07:57 So yeah, I've been at Microsoft now six years.
08:00 It'll be six years in the summer.
08:02 So in about a month or so.
08:03 And it feels like some days it's six days.
08:06 Some days it feels like 60 days.
08:07 Others it's 60 years.
08:08 So yeah, what do I do at Microsoft?
08:10 I run an end-to-end and developer experiences team for Azure inside of DevDiv.
08:16 We do work closely with Anthony and other folks on his team too around just finding out what is hard about running Python and the other languages on Azure, on our tools, VS Code, Visual Studio, and how to get your code on the cloud and all the things that come along with it.
08:35 Everything from docs to the actual components, the services, and what's that full story and kind of where are those pain points.
08:43 And then working with those service teams to find out what makes sense to you, what feels like a Python developer should feel.
08:51 One of the early things that Anthony brought forward was, these are great.
08:56 It's great that we have logs, but it's not how I want to see logs, right?
08:59 So I think that, you know, that makes sense.
09:01 And that's the, again, like you talked earlier, that's the fabric of, you know, a developer.
09:06 Like I want to, when something goes wrong, we want to fix, you know, fix what it should look like so I can find that problem fast.
09:12 And those are types of things that we dig into and report up and help solve on our team.
09:16 Yeah, there's this story of when Scott Guthrie was put in charge of Azure.
09:21 Scott Guthrie being the guy at Microsoft, who was really responsible for a lot of the developer experience and took a bunch of the people on the team and had them all sit down and say,
09:29 okay, get an app on Azure.
09:31 And it was apparently a real struggle.
09:33 A lot of the people didn't succeed.
09:34 And it was like, this is the problem.
09:36 We need to fix this.
09:37 And I think that made it a lot better in some ways.
09:40 But it sounds to me like you're kind of doing a microcosm of that with Python, with the two of you.
09:45 Yeah.
09:45 And we do it for many, you know, for every type of developer, every language stack in Python is important to us for, you know, the very reasons that like Anthony mentioned, like some of our core components are actually written in Python, right?
09:57 And we want the, we appreciate that part of what we're doing and how those applications are written.
10:03 And again, the perf.
10:05 And that's a very classic story that you bring up because it's often referenced and probably a core reason why my team exists now does because we still have, you know, we have to solve those problems.
10:15 Yeah, sure.
10:16 Well, it's like we said, it's fabric, right?
10:18 And if the fabric is scratchy or itchy, you don't want to wear it.
10:21 And that's a really big problem, right?
10:23 You want to make this as smooth and seamless for people to get it right without bouncing off the walls too badly.
10:29 Yeah, for sure.
10:29 For sure.
10:30 Now, we're going to talk about this project that you all are working on, which is super exciting about structuring Python applications and deploying them to Azure.
10:38 Before we do though, you know, there's some other interesting folks working with you at Microsoft these days.
10:45 A lot of core developers, like Microsoft's doing a lot of stuff with Python these days in terms of the number of core developers.
10:51 I mean, obviously, you know, taking over GitHub is like a big step into the whole open source steps that you're all taking.
10:59 But, you know, the sort of the direct contribution to Python is super interesting.
11:02 And the most significant one, I guess, that we could talk about is when was this?
11:07 A little while ago, we had this big announcement that back in 2018, Guido Van Rossum retires as BDFL.
11:16 And that was it.
11:17 The steering council was created.
11:19 Governance thing was up in the air, but then figured out and seems to be really nailed.
11:23 And then hung out at home for a while.
11:25 COVID hit.
11:26 You couldn't really travel, do too much.
11:27 He's like, you know what, I kind of want to go back and do some interesting stuff.
11:30 So now Python creator Guido Van Rossum joins Microsoft and, you know, talk to him about that some and whatnot.
11:37 But still, very interesting.
11:38 You guys are working with him.
11:40 Most recently, I spoke to him and Mark Shannon about the Shannon plan and making CPython five times faster.
11:47 So, you know, Anthony, you want to give us sort of an update on the stuff you see going on?
11:51 I mean, I know you might not be like directly involved.
11:54 Yeah, we were actually testing.
11:56 And doing some of the PyCon.
11:58 So at the Microsoft booth, so the team that they're talking about, so Guido, Mark Shannon, there's now seven people on that team.
12:06 All core developers are working full time.
12:09 Apart from Guido, Guido is part time.
12:11 But all the others working full time on the Shannon plan and a whole bunch of other concepts.
12:15 And what they're doing is basically making changes to see Python core to make it faster.
12:21 Targeting Python 3.11, which will be out in October this year.
12:26 3.12 and 3.13.
12:29 Some of the ideas are actually penciled for 3.13.
12:32 Right.
12:32 This is like a five-year plan that Mark had laid out of.
12:34 If we could make it 1.5x better each year, compounding is good and we'll get fast.
12:40 Yeah, exactly.
12:40 So some of the fruits of that are actually coming out in 3.11.
12:44 So we were actually doing some live benchmarks and stuff at PyCon on different workloads and things like that.
12:50 I'm seeing 25% performance gain on most workloads, which is awesome.
12:55 And in some cases up to 60%.
12:57 So it depends very much on what your workload is.
13:00 But yeah, that's 3.11.
13:02 But I think some of the bigger changes are coming in 3.12.
13:05 So basically, there's a core team of people working full time now on CPython itself.
13:11 And not a fork of CPython, they're working directly on CPython with the core development team.
13:16 Right.
13:16 As amazing as the stuff that was done over, say, like Cinder and Instagram, right?
13:21 Really interesting stuff, but it was kind of like, we forked it.
13:24 Here's a sort of interesting thing we built.
13:26 Take it or leave it.
13:27 Take some ideas.
13:28 Off it goes.
13:28 It's really different to say where like the next time you just apt upgrade or brew, upgrade your Python, it just gets better.
13:36 Chocolatey upgrade, however you do it, right?
13:37 Yeah, definitely.
13:38 So yeah, the 3.11 changes already, I think, could benefit everybody.
13:42 And getting people onto the newest version of Python is definitely going to help everyone in the long term anyway, because it's got a list of other cool features.
13:48 It's pretty remarkable that after 30 years, you can make one of these big step changes of that significant of a performance improvement.
13:57 Yeah, definitely.
13:57 Yeah, it's great to have a dedicated team working on this, but I mean, they're not the only people working on it.
14:02 There are engineers from all over and other core developers working on contributions and stuff like that.
14:07 But it's good that we can sponsor a full-time team to work just on this specific area.
14:12 So Guido is kind of coordinating that.
14:15 And a lot of the ideas come from Mark Shannon's plan that was on the podcast last year.
14:20 Do you know any of the story around like the no-gil type of stuff?
14:24 Yeah.
14:24 There was Eric Snow's sub-interpreters.
14:27 There was like Sam Gross' actual no-gil stuff.
14:30 Yeah, there was actually an open space at PyCon on that specific topic and performance in general.
14:37 And Sam Gross is there, as well as the Cinder team, the team that works on Pyodide, and a lot of other core developers.
14:47 And that was discussed in detail.
14:49 I know that from what I've heard, I think Sam Gross is still working on his no-gil branch and trying to break it down into smaller chunks that can be merged, like smaller pieces that can be merged individually.
15:01 Because there's quite a number of changes in order to get that whole thing done.
15:05 But it's still carrying on because it was targeted against what was now an older version of Python than as Python continues.
15:12 Like 3.8 or something like that.
15:13 Yeah.
15:13 So Cinder, I think, was 3.8 and they're trying to get it to 3.9.
15:17 But yeah, as Python continues to march forward, it gets harder and harder to upstream those things.
15:22 Yeah.
15:22 Still very exciting.
15:24 Yeah.
15:24 So the reason I ask is, you know, the work that Vito and Mark and team are doing is sort of orthogonal to that no-gil work, right?
15:31 Like this is, a lot of stuff he's working on is just make it run faster single core.
15:35 And then if you could unlock it for multi-core and each core, like it's a really nice multiplicative thing.
15:41 You could easily see Python 20, 40 times faster if you could say, well, you can scale it across 10 cores.
15:47 And it got four times faster.
15:48 Yeah.
15:49 So Eric's still working on his sub-interpreters.
15:51 Mark is conceptually looking through a JIT specification.
15:55 And they're working through specialized compilation as well at the moment, which is partially coming out in 3.11, but then more of that coming out in 3.12.
16:02 Amazing.
16:03 So yeah, it's going to just leaps and bounds, I think, in terms of performance difference.
16:07 That's so exciting.
16:08 Last thing to ask on this topic, and then we'll get to the main topic.
16:11 Pidgin.
16:12 Pidgin is somewhere involved in this performance thing, your JIT thing that we've had you on the show before to speak about.
16:17 And so is that involved in any way, or is it sort of a parallel story?
16:21 Yeah, I'm sharing some of that with the team.
16:23 So things that I learned in Pidgin that worked, what made a difference, and especially in the JIT, like where there were gains to be made.
16:31 My desire, really, is that the learnings from Pidgin can be part of the future of CPython, and then Pidgin isn't required.
16:38 So if CPython gets its own JIT, and if some of the other stuff that Pidgin could do was part of CPython, then I think that's a win-win, because you don't have to install something separately.
16:48 If you just get the performance gains out of the box, then that's a win for everyone.
16:52 Yeah, absolutely.
16:53 Cool.
16:54 Well, that's really encouraging to hear all those improvements coming.
16:58 Awesome.
16:58 Thanks.
16:58 Well, let's start off our conversation here by just talking about deploying to the cloud, right?
17:05 I mean, your goal really is to make deploying to Azure awesome.
17:09 Yeah.
17:10 But let's just take a step back and talk about deploying to the cloud.
17:14 You know, when people talk about deployment, well, let's just say they have a FastAPI, Flask Django, whatever app has a database, they've developed it.
17:21 And usually it's a huge gap to go from.
17:24 Well, I got it to work on my machine using SQLite and the tutorial.
17:28 Now I need it to run.
17:30 And it all said, well, you need to learn about SSL and servers and Nginx and all these things.
17:35 You're like, whoa, whoa, whoa.
17:36 I don't even know Linux.
17:38 This is like a big step to take.
17:42 This portion of Talk Python To Me is brought to you by Sentry.
17:45 How would you like to remove a little stress from your life?
17:47 Do you worry that users may be encountering errors, slowdowns, or crashes with your app right now?
17:53 Would you even know it until they sent you that support email?
17:56 How much better would it be to have the error or performance details immediately sent to you,
18:01 including the call stack and values of local variables and the active user recorded in the report?
18:07 With Sentry, this is not only possible, it's simple.
18:10 In fact, we use Sentry on all the Talk Python web properties.
18:14 We've actually fixed a bug triggered by a user and had the upgrade ready to roll out as we got the support email.
18:20 That was a great email to write back.
18:22 Hey, we already saw your error and have already rolled out the fix.
18:26 Imagine their surprise.
18:27 Surprise and delight your users.
18:29 Create your Sentry account at talkpython.fm/sentry.
18:34 And if you sign up with the code talkpython, all one word, it's good for two free months of Sentry's business plan,
18:41 which will give you up to 20 times as many monthly events as well as other features.
18:45 Create better software, delight your users, and support the podcast.
18:50 Visit talkpython.fm/sentry and use the coupon code talkpython.
18:57 How do you guys, Shane, how do you think about sort of the spectrum of options and how people are doing it?
19:04 It's interesting because when you're creating that, you know, on your own machine, that's the environment, right, that you have to worry about.
19:11 And even when we are deploying to on-prem machines, at least we could walk over and touch the, you know, for you rack that was there.
19:19 We knew kind of what it was running on.
19:21 Right.
19:21 And a lot of times you plugged into, somebody had a database for you.
19:24 Yeah.
19:25 You ask them to create the database.
19:27 Right.
19:28 They ask you, you plead for a database to be set up and they give you a connection string and then that's that, right?
19:34 You know, here's your connection string and you're on your way.
19:37 I think the thought of now is, you know, how do I set this?
19:41 How do I provision it?
19:42 How do I deploy my code to the stuff that I've now provisioned there?
19:48 How do I make all the connections between my front end and my middle tier and my, my backend stuff?
19:55 How do I secure that with all of my environment variables and connection strings and, you know, monitoring is there.
20:02 I mean, then how do I just, you know, as a developer for me, I go, that's a great, I want to do that one time.
20:08 And then really, I just want to change my code and check in my code.
20:11 Right.
20:11 I just kind of want it to run.
20:13 Yeah.
20:13 That's for me.
20:14 That's, I want to get to that point.
20:16 And I think if, even if I have a very few amount of components, I've had meetings at companies that lasted three or four weeks, just talking about how are we going to set all this stuff up?
20:26 You know?
20:27 And the promise of the cloud is, hey, we can do this super fast.
20:30 And sometimes that's not so much true.
20:32 You know, it's still very challenging.
20:34 Yeah.
20:34 Previously it was, I need a server in our data center to be provisioned and we got to order it from Dell or wherever and wait for it to go.
20:42 And now it's really easy to go to the cloud and get it, but there's a lot of decisions to make.
20:47 Is it, are we getting VMs?
20:49 And then it's my job to run shell scripts to set up Nginx and other things.
20:54 How do I scale?
20:55 What's the topography of that?
20:57 How do I set that up for possibly what if we need to scale the web end or whatever?
21:01 Maybe we use Docker, maybe we use a platform as a service, right?
21:05 Like that could be a long conversation because ultimately it's somebody's responsibility.
21:09 If it doesn't, if it doesn't work out right, they're going, you know, you're going to have to come in on the weekend and fix it.
21:15 Yeah.
21:16 Or be at least responsible to make sure it keeps running.
21:18 Right.
21:18 Yeah.
21:18 Who do I call when it breaks?
21:19 Yeah, exactly.
21:20 Okay.
21:21 So where are you seeing people who you're talking to a lot going?
21:25 I mean, we've got, I think on one far end, like at the very far end, like if you turn it to either negative one or 11,
21:31 depending on which side you consider this to be on, bare metal.
21:34 That's very rare these days, but VMs and then Docker, Kubernetes, platform as a service, maybe, maybe some more functions.
21:42 Yeah.
21:42 Yeah.
21:43 Functions live in there.
21:44 Yeah.
21:44 VMs.
21:44 Usually 100% alone, but.
21:45 I think VMs are still very popular with, with some companies who are just trying to get to the cloud.
21:51 Right.
21:52 It's very easy to kind of park your car in somebody else's garage.
21:55 Right.
21:55 I think that's okay.
21:57 It's there.
21:57 Well, it's, yeah, it solves the biggest problem is how do I get a reliable internet connection that's fast and a server and network infrastructure that I don't have to take care of.
22:05 Yeah.
22:05 I think those are still, it's still very, it's a very viable option for some folks.
22:10 The PaaS option is, again, most companies can still run a very sophisticated system on PaaS.
22:18 The one thing that I'm seeing right now is that companies are wanting to, in small, even small companies, or even they hear Kubernetes, they hear the promise of it.
22:28 It's scalability, it's responsive, it's self-repairing.
22:30 Zero downtime.
22:31 Yeah, no downtime.
22:32 Scale to zero.
22:33 Like all the, all the buzziness that comes with it.
22:37 And, you know, there's the memes that go around with, you know, the tiny box on a tractor trailer.
22:42 Like I put my blog on Kubernetes.
22:44 You don't need it, but everybody wants it and they're not sure why.
22:48 And then it's just cost prohibitive in both manpower and management and cognitive load and all of the things.
22:56 So there's that aspect of it.
22:58 We want to find a place that is somewhere in between.
23:00 Like what if I could have all the promise of Kubernetes, but not have to learn Kubernetes, right?
23:05 And that's another thing that we're talking about with things like Azure Container Apps.
23:09 Right.
23:10 And being able to have kind of best of both worlds.
23:13 Right.
23:14 And looking forward, I don't want to get into it yet, but just to give people a preview is you guys have built a CLI tools for Python and some templates that kind of help people realize that goal.
23:24 Much more quickly than just, all right, well, I guess I'm going to set up a Kubernetes cluster and nodes and all that kind of stuff.
23:31 Yeah.
23:31 Yeah.
23:32 Okay.
23:32 Well, Docker is an interesting one, right?
23:35 To do Kubernetes, you got to do Docker, right?
23:37 Or you got to do containers at least.
23:39 There's the look how easy it is to run Docker.
23:42 I just, you know, get the image, Docker run, off it goes.
23:47 Unless you've got multiple tiers like many apps do, right?
23:51 I've got like a database layer and maybe a background worker service for like emails and other long running jobs.
23:58 And then all of a sudden coordination that becomes really hard.
24:01 Yeah.
24:01 I'd say that like kind of where people start off with containerization is the Python app itself.
24:08 So the Python code, whether that's in like a Whiskey application or using ASCII or something.
24:15 So that's like Django, Flask, FastAPI.
24:18 So like running that in a container is a great place to start.
24:22 But hardly ever is that the whole application.
24:24 You know, just Flask and Django alone, you need some sort of web app at the front end, like a HTTP server, like Nginx or something.
24:32 And then you need the distribution to Whiskey.
24:35 So you need Genicorn or Yuvicorn or Hypercorn or one of the other corns to connect between the HTTP front end and the back.
24:43 And then once you've got that in place, you're like, okay, I need to configure my SSL certificates and my DNS and stuff.
24:50 So you can do that.
24:52 But I think people start to try and try to jam everything into one container.
24:56 Yeah.
24:57 And that's where it kind of gets.
24:58 Until it absolutely explodes.
25:00 You're like, all right, it just won't take it anymore.
25:01 Right.
25:02 But preserve that.
25:03 Just call run on it as long as you can.
25:05 Right.
25:05 Yeah.
25:06 People I imagine are trying.
25:07 Yeah.
25:07 Yeah.
25:07 And they're not supposed to be persistent.
25:09 Like, you know, containers are supposed to be immutable, but you can attach storage to them, which is where it gets tricky with databases.
25:16 Because really running something like Postgres and Docker, you can, but like, it's not going to be particularly fast.
25:24 And you've got all these extra challenges of if the image stops, then what did you just lose?
25:30 So, yeah, I think containerization is great to get some of the Python environment complexities.
25:36 Like, you know, you've got a virtual environment to configure.
25:39 How is that installed?
25:40 What version of Python?
25:41 So, there's like all the bits of Python that are specific to getting the Python app running consistently in one place and another.
25:47 So, Docker is great for that.
25:49 Containerizing is great for that.
25:51 But you often find yourself needing more than one container, which is where things start to get complicated.
25:56 Because then it's like, okay, I've got Redis in there.
26:00 I've got, I want to run Nginx in one container.
26:03 I want to run my app in another.
26:05 So, then how do you like coordinate all that stuff?
26:09 Right.
26:10 And just how do I keep them connected, right?
26:13 Because in regular non-Docker world, you just say my Redis string connection string is this.
26:19 My database connection string is that.
26:21 Nginx says I route traffic over either this Unix socket or through this HTTP socket.
26:28 But those are not stable as these Docker images come and go separately, right?
26:34 It gets tricky to connect them still.
26:35 Yeah, there's a connection and the coordination of it.
26:38 And things like Docker Compose, I think, helps with that there.
26:42 Anthony mentioned a very valid point around databases and containers.
26:47 I think when container development started to kind of hockey stick a little bit, I can't tell you how many times I answered the question, should I run my database in a container?
26:55 And I was like, well, no.
26:57 And then it was like, well, why not?
27:00 And I was like, okay, here's the 15 reasons why you should never do that.
27:03 Yeah.
27:03 And I go to my framework and write in the tutorial that shows me how to run Postgres.
27:07 Yeah, it was more of a like, what happens when it dies?
27:11 You know, and they go, oh, no, I mean, I lose my data.
27:14 Yes.
27:14 It says don't do that.
27:16 But they serve very well for, you know, emulating those big cloud managed services like Redis and like, you know, Postgres and stuff like that.
27:25 They would typically run in a managed service instead of trying to have your entire world, if you will, running on your local machine.
27:32 And then the other part of that is how many is too many?
27:35 If you, you know, the microservices type of, you know, scenario of are you going to run 200 individual containers on your local machine?
27:44 There is a cap where it's just too much, you know?
27:48 Yeah, yeah, for sure.
27:49 And we're even seeing some sort of swinging of the pendulum, I guess you would call it, back to articles like, give me my monolith back.
27:58 Life just got too hard.
28:01 Now, you know, my personal philosophy, and I'm not suggesting anyone else has to adopt it.
28:06 But when I think about these things like microservices versus monoliths and Docker and Kubernetes versus more simple things is I try to keep the complex parts in the areas that I'm really good at and not push them to areas that I have a little experience with.
28:20 Like, I don't have a great DevOps background, so I don't want to push tons of the complexity to DevOps and keep the code simple because I can handle complex code, but I can't handle complex DevOps.
28:29 Yeah.
28:29 Not right now anyway, you know?
28:31 So for me, I kind of try to think of the balance of like, what works for me, you know?
28:34 I literally saw an example where somebody was saying, I manage all of my configuration in its own repo, and then that sucks into my DevOps pipeline.
28:44 I was like, what is happening?
28:45 I'm not even going to talk about that.
28:49 You know, I'm sure that works for you.
28:51 But like you said, unless you really understand that level of, you know, complexity, you know, it's no thanks.
28:58 If you specialize in that area, then maybe that's exactly your secret sauce.
29:03 Yeah, yeah.
29:03 But if you don't, don't like see someone else be doing that and go, I should just do that because it's working for them.
29:09 Like maybe, but it's not a clear, I should just go that way, I think is the story.
29:13 Yeah, and I think just like in a coding world, like we can use things like, you know, interfaces and polymorphism to the nth degree.
29:20 And for a simplistic programmer, you know, examples, they're going, why are you doing that?
29:25 Because I can just do it in a single file.
29:27 Thanks.
29:28 Exactly.
29:29 Why do we have like dependency injection registries when it's 50 lines long?
29:33 Like I really just don't.
29:34 Yeah.
29:34 It's just not.
29:35 It's hello world, man.
29:36 Yeah, exactly.
29:37 Exactly.
29:38 It's just a manuscript script.
29:39 Right.
29:39 All right.
29:40 So maybe that probably sets the stage a little bit for the work that you two have been doing in this project we're going to talk about.
29:46 But one more predecessor, bit of history.
29:49 So one of the notable things about the Azure CLI, that is the CLI that everyone uses when they're not working in the crazy, belated, very full management portal, is built in Python, right?
30:02 Yes, it is.
30:03 Yes.
30:03 But it's not that that actually makes any difference for Python people.
30:06 It's just an interesting detail.
30:08 But that one is not focused as much on helping developers get their code out as maybe helping IT DevOps side of the world, DevOps on Azure.
30:18 Right.
30:18 I would say its primary goal is referred to as kind of a management ops plane functionality.
30:25 There is some capabilities in there for, you know, pushing up simplistic, you know, web applications.
30:31 There's a web app command where I can kind of get a simple page up.
30:36 And there's some static web apps capabilities within that command.
30:39 But when you get into, you know, a full kind of job to be done for a developer focused type of activity that does not serve that type of persona.
30:50 Sure.
30:50 All right.
30:51 Well, that brings us to your project.
30:53 Does your project have a name?
30:55 Just so people know, at the time of us talking about this, this is not yet released.
30:59 Yeah.
30:59 But at the time people are going to be listening to it, it will be released.
31:03 And so.
31:03 Yeah, sure.
31:04 I'm kind of behind the scenes.
31:05 Maybe I can pull up your screen here and start from there.
31:09 We'll call it the like lowercase Azure developer CLI.
31:13 Okay.
31:14 Because if it's uppercase, I think that means it has a name.
31:16 So we'll say it's the lowercase Azure developer CLI.
31:20 It's a standalone install.
31:21 Command is AZD or AZD, depending on where you're from.
31:26 Don't don't alienate Anthony.
31:28 Yeah.
31:28 Much of the other rest of the English speaking world.
31:31 Yeah.
31:31 Everywhere but the US.
31:33 And its primary goal is to, you know, make it easy for developers to get up and running
31:40 with both infrastructure and code, you know, in Azure based on at least initially, we've
31:46 got some out of the box templates to help establish kind of a getting started kind of to do app,
31:54 which at least in this particular example, we have a to do application that's got a Python
32:00 FastAPI middle tier with a React JS front end.
32:06 And then the back end is supported with Azure Cosmos DB with Mongo API.
32:12 Right.
32:12 So the way it's going to go now is it will have the Mongo API, but Mongo, the Mongo API can be pointed
32:19 at Cosmos DB, your document database in Azure, right?
32:22 Correct.
32:22 Correct.
32:23 Correct.
32:23 Let me ask another really quick question on that.
32:26 What's the interaction with the Mongo API?
32:30 Like, is there an ODM they're using?
32:31 Is it just PyMongo or rather motor or something like that?
32:34 Yeah.
32:34 This app was built within ODM.
32:36 It was built with Beanie.
32:37 I love Beanie.
32:38 I've, I converted the talk Python.fm and Python bytes.fm over to it.
32:42 The really big one left for me is the training site, which is massive, but it's, it's getting
32:47 some Beanie on it as well.
32:48 Yeah.
32:48 So for like a fully async ASCII app on FastAPI, Beanie is a great option because it's
32:54 like async from end to end and it uses the async motor client for talking to Mongo.
32:59 Yeah.
33:00 So yeah, it's super fast.
33:01 So that's what we've built for the to-do app, which is like the demo application.
33:08 This portion of talk Python to me is sponsored by NordVPN.
33:11 I've been a pain and happy NordVPN customer for over a year now.
33:16 So when they approached us to become a sponsor of the podcast, I was excited because it's
33:21 a product I've already been recommending.
33:23 I use NordVPN almost universally throughout the day on all my devices, whether it's my
33:28 Mac, my iPhone, or my iPad, I enable the auto connect feature and Nord keeps my connection
33:34 protected and ad free.
33:36 I'm sure you've heard that VPNs can keep your traffic private on public networks.
33:41 And that's true.
33:42 But let me tell you why I use NordVPN.
33:44 Privacy and malware protection.
33:46 First, privacy.
33:47 Ad companies are slowly eroding our privacy.
33:50 Shadow profiles are being built for you and being built for me by combining tracking scripts,
33:55 ISP data, and through data brokers.
33:57 If these were just being used for commercial ads, it'd be one thing.
34:01 But we've all heard stories about how groups have been targeted to affect negative social
34:06 outcomes.
34:07 Think Cambridge Analytica.
34:09 With Nord's built-in network-wide ad blocking and IP hiding, you'll limit the data that all
34:15 of these players get to collect on you.
34:16 What's so sweet about using Nord for this is it works across all of your apps.
34:20 Not just a browser plugin, but even native apps on your phone can't contact or load most
34:26 ads.
34:27 These same ad networks have been hijacked to deliver malware.
34:30 Nord also includes network-level malware protection as an added layer of safety.
34:35 And Nord has a great offer for you.
34:36 Use talkpython.fm/NordVPN to get a massive discount on a two-year plan that includes a free
34:43 month.
34:43 Nord is also risk-free.
34:45 There's literally no risk to you with their 30-day money-back guarantee.
34:49 Give it a try.
34:50 And if, like me, you love it, great.
34:52 If you don't, they'll issue a refund and you can pretend the entire situation never happened.
34:57 Say no to being manipulated by ad companies and enjoy the free and open internet on all of
35:03 your devices.
35:04 Visit talkpython.fm/NordVPN to get your subscription started today.
35:09 Yeah.
35:11 So let me see if I can summarize this for folks before we dive into more detail.
35:15 Basically, you guys have built this full stack-ish.
35:19 I guess full stack fits.
35:20 Full stack, FastAPI, document, database, JavaScript front-end app that sort of natively integrates
35:28 in the ways that you would expect it to in Azure.
35:31 Not just you can get it up there and get it to run, but it's got different sections.
35:36 It uses a hosted database.
35:38 It integrates with CICD.
35:40 It has tests that plug into all those kinds of things and so on.
35:43 And so you can take that and sort of publish that to Azure.
35:46 But then, of course, you can just use it as a prototype to say, well, we don't need to do,
35:50 we need this other thing.
35:51 So we'll swap out, whatever.
35:53 Yeah.
35:53 Right?
35:53 Something like that.
35:54 Yeah.
35:54 I would say there's a couple of key components.
35:57 You know, we do all of our commands.
35:59 Again, it's command line based.
36:01 We focus on a CLI first approach to this for a couple of reasons.
36:05 A, it feels natural for a lot of developers who kind of are on a terminal constantly, but
36:11 also allows if VS Code wants to build an experience on top of it, if PyTorch wants to build an experience
36:17 on top of it, they can, you know, because they just call into those same hooks.
36:21 But also...
36:22 Can we consume the CLI as a Python library?
36:26 Well, that's a good question because we are also looking at making this an extension inside
36:33 of the core Azure CLI.
36:35 So we have actually wrapped this as a Python extension.
36:38 Okay.
36:39 For them.
36:39 Interesting.
36:40 Yeah.
36:40 I mean, you can always sub process it around all day you want, but...
36:43 It's written in Go.
36:44 Okay.
36:45 Got it.
36:45 Yeah.
36:45 So it's A, it's super lightweight.
36:47 It's like five and a half megs.
36:49 It's really small.
36:50 And once you have the binary, you have it.
36:53 That is one of the true beauties of Go.
36:56 Yeah.
36:56 Yeah.
36:56 The other parts of it, like you mentioned, if there's pieces of this that, of the app,
37:01 if I back up one section here, is that a lot of the samples that we come across, they are
37:07 a hello world.
37:08 They're a very simplistic app.
37:10 And once you kind of go through the process, when you're all done with it, you're like, okay,
37:15 this is great.
37:15 I built my hello world app.
37:17 Now what?
37:18 Right.
37:18 This is an opinionated structure that allows you to swap out components, build upon it.
37:25 Like I can take out the FastAPI if I want to use Flask or Django or whatever.
37:29 I can swap that out and do it.
37:31 Swap in Postgres if I'd like.
37:33 We have an infrastructure as code.
37:35 Right now we're using Bicep to do that.
37:37 And in the future we'll support things like Terraform and other IAC providers.
37:41 And that's just how we would swap out any of the infrastructure.
37:44 Right.
37:45 This particular sample, we are targeting the Azure container apps as a host, as our target
37:51 host.
37:52 But we do support paths.
37:53 And in the future also things like Kubernetes.
37:56 Yep.
37:56 And also in terms of the, how cloud native is it?
38:00 If you don't scroll away just yet, come back.
38:02 Okay, sorry.
38:02 Yeah, no worries.
38:04 In terms of just how cloud native it is, like how much does it reach into all those things?
38:09 Basically for areas that are interesting.
38:12 Azure container apps, right?
38:14 So you've got, Anthony, let me know what this sounds like.
38:16 You've got maybe an Nginx type of container.
38:19 And then you've got one that runs UVicorn, FastAPI, Workers.
38:25 Yeah.
38:25 There's two containers in this example.
38:27 But like, yeah, Azure container apps is more where you've got a collection of containers that
38:32 form an application.
38:33 Like if you put that in a Docker Compose or something.
38:35 Yeah.
38:36 And then we kind of spin those up for you and manage that for you.
38:39 So you don't have to think of or plan about things like Kubernetes.
38:42 And it does SSL certificates and DNS and everything else for you.
38:47 So nice.
38:48 So you don't have to worry about let's encrypt and stuff.
38:50 Yeah.
38:50 Yeah.
38:51 Does all that for you.
38:51 So nice.
38:52 And then that hosted Cosmos DB.
38:55 Yeah.
38:55 So Cosmos DB is the document database on Azure.
38:59 And when you deploy it, you can choose which API you want it to have.
39:03 You can pick the Cosmos API or you can pick a Mongo API.
39:06 So if you pick the Mongo API, then you can use your existing Mongo tools and clients with it.
39:12 Like Beanie and so on.
39:14 Yeah.
39:14 Exactly.
39:14 And that would just work.
39:15 Okay.
39:16 And then monitoring.
39:17 Azure Monitor.
39:19 This is like Sentry type stuff, right?
39:21 Like is it up?
39:22 Is it running into errors?
39:23 Does it also do performance or just sort of error?
39:26 Yeah.
39:26 It will do all of your calls.
39:28 Basically it does tracing between all of the different containers or different components
39:32 of the app.
39:33 You can look at telemetry between those calls.
39:35 You know, how long is a call taking to the database?
39:38 You know, you can look at the individual calls, see where the errors are, trace those down to
39:42 like it was a get call on, you know, the to-dos collection and actually look at those and
39:49 then introspect those inside of Azure Monitor.
39:51 So it's pretty detailed.
39:52 Yeah.
39:52 That's really nice.
39:53 Yeah.
39:53 I use that stuff all the time for my sites, you know, if I run into a problem, probably
39:58 the first place I go is the actual log.
40:00 But if it's not super clear right away, I'm like, all right, let's go to the monitoring and
40:03 see the local variables and see what was going on for real.
40:07 And then the last one is secrets.
40:09 Like it is nice to just check in your API keys into Azure and to GitHub.
40:15 I don't understand why I heard you're not supposed to.
40:17 No, I understand why you're not supposed to.
40:21 Yeah.
40:21 Yeah.
40:22 The Key Vault is really great in the sense of, yeah, this is kind of, it is the sauce, if you will, where we keep the connection string for the Mongo database.
40:31 And then within the actual FastAPI app, we can then connect to the Key Vault to pull that out securely.
40:39 And then really the nice thing about Key Vault is if we need to change it, we can just change that one key and not have to kind of redeploy all the other apps.
40:46 It's just great.
40:46 It's just great.
40:47 And then from a local development story there, we use environment variables to have that locally as opposed to passing it around or keeping it in a GitHub repo, of course.
40:59 Got it.
41:00 The apps kind of like built in a way that we said, if we were building a production app, this is how we do it.
41:07 So like Shane said, it's, it's the example app is opinionated because we've picked how we've configured Python version environments and how I've done the testing and how the ASCII configuration works and stuff like that.
41:18 But it's done in a way that it's okay.
41:20 This is a production style web app that we put together.
41:24 And here's how you would deploy it using this new, the new AZD CLI.
41:28 So the new Azure Dev CLI.
41:30 And the other important thing is that you don't have to learn all these new concepts.
41:34 So it's not like we've said, okay, we've got our own configuration language that we're going to throw at you.
41:40 And we've got our own, you know, like here's a hundred YAML files you need to write or stuff like that.
41:46 It's try to keep it as native as possible.
41:48 So in the Python application, in the web app, then there's a Docker file and there's a pyproject.toml.
41:55 And, you know, if you want to run the Docker file locally, you can do that.
41:59 One of the opinions that you're, you're choosing is like use poetry, for example, right?
42:02 Yeah.
42:02 Yeah.
42:03 Yeah.
42:03 So using poetry to manage the dependencies and make those, I guess, pinning dependencies and making them between creating things like lock files.
42:11 But also if you work on the repo, the demo repo in VS Code, you know, you can run and debug the app locally as well.
42:19 So you don't have to figure out all the extra complexity.
42:21 So, yeah, we kind of really thought, okay, let's write, you know, a production type application using all the normal tools we would use,
42:29 which is like Docker files and pyproject.toml requirements files.
42:33 And then on the front end app, like, you know, it's in React.
42:37 So we've got our normal project and Node.js configuration and stuff.
42:41 Right.
42:41 All the NPM stuff.
42:42 Yeah.
42:42 And then what would the, what would the developer need to describe that in a way that then can be deployed up to the cloud and trying to make that as simple as possible?
42:50 Sure.
42:51 Yeah.
42:51 So Shane, you spoke about Bicept.
42:54 Right.
42:54 As a way to get your things up.
42:55 And I think it might be worth touching a little bit on the Bicept story.
42:58 Sure.
42:59 I mean, that's usually arm wrestling for me, but I'm thinking, no, no.
43:03 Bicept, Bicept is, it's like Ansible or Terraform.
43:06 Yeah.
43:07 But it's, it's one of these, it's kind of a Azure native thing, right?
43:11 For DevOps.
43:12 Most Azure DevOps folks would understand if we said, hey, what's your arm template look like?
43:18 Azure resource manager.
43:19 Management template.
43:20 Yes.
43:21 Yeah.
43:21 Management.
43:21 Lots of JSON, a lot of JSON, thousands of lines of JSON.
43:26 Not easy to write, read, or kind of understand.
43:29 Bicept is a simpler format and kind of self-describing almost.
43:34 So we use that right now to describe the resources that we're going to provision and deploy our app to.
43:41 And in this particular case, in this template, we have a number of templates, but in this template,
43:46 we're putting together a container registry.
43:49 We're provisioning the container apps environments, you know, the web apps, the Mongo database, a lot of things that, you know, if you did those individually, it would take a lot of time to do.
43:59 So we're doing that all as a part of the one single line command to do that.
44:04 So we're looking at implementing, you know, other IAC providers like Terraform and Pulumi as well.
44:11 And, you know, if that makes you happy in your place, you know, we're not hiding anything in what we're doing.
44:18 We're more of an orchestrator of the tools instead of hiding some secret commands to make all this happen.
44:25 We like folks to kind of see what the steps are to do it.
44:29 We're just going to do the steps for you in a single press of the button, press the easy button, you know?
44:33 Yeah.
44:33 Yeah, absolutely.
44:34 Right.
44:35 That's great.
44:35 So maybe, Anthony, it would be a good time for you to sort of talk us through some of the code and the projects,
44:41 because I think that'll give people a sense of what they're getting in terms of what this app looks like.
44:47 Yeah.
44:47 So the demo app that we put together has got two main containers on the front end, which is the React.js web app,
44:55 which is all running under Node 16, and then a FastAPI API, which does basically the middleware between the front end and the database in the back end.
45:05 So the React.js one is an app that we wrote to demonstrate a lot of functionality and to-do management app, basically.
45:14 But in terms of the FastAPI app, that...
45:17 The canonical example that people may try.
45:19 Yeah, exactly.
45:20 And the FastAPI one is the one that I worked on with the team.
45:24 And that's really kind of looking at, okay, if we did a modern Python application, how would we write it and how would we deploy it?
45:31 And like I said, using poetry for requirements management and stuff.
45:35 But you could use whatever.
45:36 This is an example.
45:38 You don't have to use poetry.
45:39 But I'm just showing the latest approach and the latest design with the application.
45:45 And then if you want to swap out or change bits of it, obviously you can do that.
45:49 So yeah, the project itself has got a pyproject.toml.
45:52 We're using FastAPI, Uvacorn, and then Beanie is the ODM.
45:56 And then a nice package...
45:58 Maybe just tell people real quick about just what Beanie is, just so that...
46:02 I've had Rumin on the show before, but maybe not everyone knows.
46:06 Yeah, so if you're working with FastAPI, often you would describe models that the API reads or writes or reflects using something like Pydantic.
46:16 So these are kind of your data classes.
46:18 So Beanie basically allows you to write Pydantic style models, data classes, and then read and write those from a Mongo database.
46:29 So this app is basically written in a way that the to-do list items, the tasks and stuff like that, are all reflected in a models file.
46:37 And then Beanie does the work of actually putting those in a database.
46:41 So we have a to-do list.
46:43 We can also do things like to-do items.
46:46 And each of those are a document, but they're written in a way that's very similar, basically identical to how you'd write a Pydantic model.
46:53 Beanie also allows you to...
46:55 Right, just slightly different base class.
46:56 Yeah, Beanie also allows you to lazily reflect Beanie models into Pydantic models.
47:02 So when you're working with FastAPI, you can get all that nice functionality of using Pydantic, but you get a lot of the performance of basically trying to keep it as close to the actual document in Mongo as possible.
47:14 So yeah, that's one big challenge people have to overcome when they use stuff like Pydantic, which is like, when do you put stuff into Pydantic models?
47:25 Like if you're reading a thousand rows from the database and you're just going to give that straight to the user, there's no point in reflecting all that into Pydantic and then sending it back out again.
47:34 Right, doing all the conversions or whatever craziness.
47:36 Yeah.
47:36 Yeah, or just slow it down.
47:37 Yeah, okay, cool.
47:38 And so this is a really good choice because it matches the native MongoDB API and it matches FastAPI on at least two levels.
47:46 Pydantic models are all about driving the data exchange and the open API specification, which is fantastic.
47:52 But then also Beanie is an async ODM.
47:56 So what you do, it allows you to fully leverage the scalability of FastAPI.
47:59 I think it's a great choice.
48:01 It's a nice configuration and it's nice to run as well.
48:03 It's pretty responsive.
48:04 And then what we did on the app itself, so in FastAPI, a couple of things that you have to do are configuring cores, which is always fun.
48:13 And then we've put tracing in the app as well.
48:16 I just ran into a cores error on just an HTML file I opened.
48:21 I'm like, there is no server.
48:22 I can't do cores.
48:23 Please don't do this.
48:24 Yeah, it becomes a bit of a challenge.
48:27 It does.
48:28 So on FastAPI, we've been doing a lot of work over the last year on a project called OpenTelemetry.
48:33 It's a cross-company open source collaboration to create basically a tracing and eventing framework across multiple languages.
48:44 So you can use OpenTelemetry in Go, Rust, Python, and basically install.
48:50 Does it connect into the thing that Shane was talking about with the Azure monitoring?
48:54 Yeah, it does.
48:55 And it also connects into a whole bunch of other monitoring tools.
48:58 It's not the Azure monitoring library for Python.
49:01 It is an agnostic library.
49:03 Nice.
49:03 Which is, it's got support for FastAPI.
49:05 It also has support for lots of other Python components.
49:10 So when you get the actual logging data, for example, if your app crashed or somebody made a request which gave a 500 error, in Azure Monitor, you get the full stack trace and you get all the events that led up to that as well.
49:23 So it's not just a log file, basically.
49:25 We're actually putting stuff in the Python app to get all the tracing information.
49:28 You can also use it to see like performance regressions and like slow pages or slow requests.
49:35 So in Azure Monitor, you can actually go and see what are like the slowest requests I've had to the application and what was the cause of that.
49:41 Yeah.
49:41 And none of that stuff is proprietary.
49:43 It's all basically using OpenTelemetry, which is open source.
49:46 But we have a special source is the exporter.
49:49 So we export OpenTelemetry events to Azure Monitor.
49:53 Okay.
49:53 Yeah, this all looks super nice.
49:55 And the reason I wanted you to talk through this is the project looks really nice.
49:59 It looks like an app that I would like to use as a starting place for my final destination rather than just, oh, cool.
50:07 There's a main.py or app.py.
50:09 It's all just jammed in there.
50:11 And like, you know, it feels like a good starting point.
50:14 Yeah.
50:14 And then, like I mentioned, like debugging is set up already.
50:18 So yeah, in VS Code, you can either debug the React app or the API, the FastAPI app.
50:25 And that will run the whole application locally.
50:27 Does that run just on your local machine or does that like fire up the containers?
50:32 It just runs on your local machine.
50:34 So it would run FastAPI locally.
50:36 I give that a thumbs up.
50:37 Yeah, yeah.
50:38 So if you wanted to, for example, debug the front end and it needs to get, just go start the back end and then go debug the front end.
50:44 Something like that, right?
50:45 Yeah.
50:45 Just trying to keep it super simple.
50:46 Yeah, no, that's good.
50:47 And then we also wrote tests for both components.
50:50 So yeah, the ToDo app comes with its own unit tests for FastAPI and then for the front end as well.
50:58 And then all of that's set up in VS Code.
51:01 Well, it's all, they're all pytest tests.
51:03 So if you just want to run pytest over it, then you can.
51:05 But yeah, asynchronous FastAPI tests are a bit fiddly to set up the first time.
51:11 So we've done all that as a demo as well.
51:12 Yeah, this is great.
51:13 And one area that we haven't talked about yet, Shane, when you deploy this, and we can talk about how to do that in just a second, is that it automatically sets up, at least with one of those CLI commands, CI, CD, continuous integration and continuous delivery or deployment.
51:29 And these tests that Anthony's talking about, these automatically just like start running on check-ins for you, right?
51:36 Like that whole lifecycle is connected here.
51:39 Yeah, it's, Anthony, I don't know if you could maybe scroll up and touch on the GitHub actions that are included there.
51:46 So with every template that we're providing out of the box, we include the GitHub actions in order to run those.
51:54 So on the builds, we'll actually provision, deploy, and we would include the test run as well as a part of the container build.
52:03 If it's targeting containers or if it's paths, we would have the test command, which is not in this particular one.
52:09 But it would be like AZD test would be the command that would run.
52:13 It would run through all the testing that are in there depending on the platform.
52:17 Yeah, that's great.
52:17 So yeah, it gets us to that point.
52:19 Like I said, as a developer, I just want to check in code and know that my tests are going to run.
52:25 If they pass, it deploys to the environment that's specified.
52:28 And it gets me to a happy place as a developer, you know?
52:32 Right, right, right.
52:34 You don't have to know about this stuff.
52:35 And, you know, to some degree, that might not be 100% true, right?
52:38 Like if your code is running somewhere, you need to have some level of understanding, even if you don't have to directly touch it.
52:45 But I think one of the big benefits is for a lot of people, you can start running there and you can kind of grow into a better, deeper understanding.
52:52 You don't have to like swallow the whole, I learned all of the Linux configuration all in one shot just to get it to even start, you know?
52:59 Yeah.
52:59 And I think it's important to mention a couple of times is that even though we have a command, like in order to get this whole architecture that Anthony just walked through,
53:09 if I wanted to get this into Azure, I would just run AZD up and then pass in the name of the template repo, you know?
53:18 And it would then deploy all of that and run it for me.
53:22 Yeah, yeah.
53:23 Let's talk about like, we've got the app.
53:25 Anthony talked about running and developing it locally.
53:27 Right.
53:28 Now what?
53:28 Like I actually want to get it up and running.
53:30 I want CI, CD.
53:31 I want all the things.
53:33 Yeah.
53:33 So if I started from nothing, if I was just opened up, you know, VS Code or my command line or whatever I'm in in a terminal,
53:40 I could just run AZD up and then pass in a --template.
53:44 And in this particular case, it would be like to do dash Python, ACA dash Mongo.
53:50 Right.
53:51 And that would clone that repo.
53:53 It would then start to provision those resources on Azure, you know, based on your login to Azure and then use the BICEP infrastructure definitions to create that target host if it's PaaS or Azure container apps.
54:07 And then build and deploy, you know, the API, the front end, and then make all those connections and so on as we walk through how that's all put together.
54:16 Right.
54:16 And so it's worth thinking about that, those BICEP DevOps commands and configuration, if you want a slight variation of what this gives you, you change the BICEP and then AZD up just uses your slight variation, right?
54:29 Well, yeah, exactly.
54:30 And, you know, one of the services that is very common to use, you know, in our, in our apps nowadays is Redis.
54:35 Like if I want to add Redis and make a couple of changes, I could just put that definition in my BICEP code, add in the environment variables that are necessary to, you know, expose in my app and call up.
54:47 And then we would then push them into Key Vault, you know, provision the service, redeploy the code.
54:53 And hopefully if we typed it all right, it would happen right.
54:56 Right.
54:56 So that would be the way to do that for sure.
55:00 If I run the AZD, you know, pipeline command and help that establish my GitHub repo and kick off those workflows in the GitHub actions.
55:09 At that point, I could just make those changes to the BICEP files and check those in.
55:14 And then the workflow would kick off that process for me.
55:16 That's cool.
55:16 Can I start from code and then do this?
55:19 Or do I do the template to create the code and the GitHub repo?
55:22 Like if I already have a GitHub repo, for example.
55:24 Yeah, that's a good question.
55:25 And we have some documentation and walkthroughs on how to, what we call Devify your project.
55:32 And basically it will walk you through how to set up that an infra folder.
55:37 That infra folder will contain the BICEP definitions.
55:41 And we've got an Azure.yaml file, which will hold a couple of the kind of naming structures that we have as an opinionated way to name things.
55:50 And then also set up that target host.
55:52 Again, it's that PaaS or is it, you know, app service or is it container apps or AKS?
55:57 So a little bit of setup.
55:58 And then you can start using AZD up or AZD deploy.
56:02 You just want to deploy the app to then, you know, take your code and push it onto the platform.
56:08 Okay.
56:09 That sounds really good.
56:10 What about the, talk about the continuous delivery part.
56:14 So I've got this created.
56:15 I've got a GitHub repo.
56:16 It's up and running.
56:17 How do I associate a domain name, by the way, first?
56:20 Well, the domain name, we would push it onto the, obviously onto Azure and then create that.
56:25 Like your app.
56:26 Yeah.
56:27 Do it UID.Azure or something like that.
56:29 Blah, blah, blah.
56:30 Azure websites.net slash la, la, la.
56:32 Yep.
56:32 Then that would be part of that configuration inside of Azure portal or through the management
56:39 plane where you'd actually kind of go through of associating your domain name with whatever
56:45 your entry point is.
56:45 In this case, it's going to be the React front end, right?
56:48 So I would go into that particular app service and set that up with your DNS and such there.
56:53 Yeah.
56:53 You probably want to, you probably want the API if you want to surface an API out of fast
56:58 API.
56:58 Yeah.
56:59 And then you want the React front end, obviously, for most people.
57:02 Yeah.
57:02 And you could add, if you want to get into things like that, one of the pieces you could
57:06 add is things like Azure front door or, you know, API management or something like that
57:11 in front of those components too.
57:13 Okay.
57:14 Well, that step is like a separate step.
57:16 Yeah.
57:16 You go in there and you configure it because how often do you really want to have a thing
57:20 messing with your DNS?
57:21 Yeah.
57:21 As little as possible.
57:23 It's a one-time shot.
57:24 That's all I want to do with.
57:25 Yeah.
57:25 Please wait 24 to 48 hours for this to propagate.
57:28 Like, no.
57:29 You know, it's funny.
57:30 I haven't had a DNS chain, knock wood.
57:33 I haven't had a DNS chain to take longer than a few minutes nowadays, but.
57:37 Yeah.
57:38 It is a lot better than it used to be.
57:39 I've done it.
57:40 I just changed all of our email and stuff around and there's been a lot of MX records and the
57:46 like verification keys and yeah, it's.
57:48 No matter how many times you do it, you're sure you did it wrong.
57:51 Yep.
57:51 That's for sure.
57:52 Yeah.
57:53 All right.
57:53 So back to my original train of thought.
57:55 I was like, let's just sort of kind of wrap this up with the continuous delivery.
57:58 I've got the app up.
57:59 Now we know how to get the domain associated with it and whatnot.
58:02 You know, presumably go and buy a domain wherever you buy domains.
58:05 Point it at it.
58:06 Let it map over.
58:08 But then I make some changes and I get push a thing.
58:11 What happens now?
58:12 Yeah.
58:13 If you set up your, your CI CD pipeline, it would then run through that same process.
58:17 And we showed it in the GitHub actions here and talk through it.
58:20 It would run your test, do the deployments.
58:23 We do support multiple environments.
58:25 So we can help set up a, like a dev or a QA environment as well, other than just a single.
58:32 Like a staging.
58:32 Yeah.
58:33 Sort of thing that people can.
58:34 Yeah.
58:34 And then you could set up some processes, you know, within Azure, like, hey, this passes,
58:39 let me do a, an IP switch or however you manage that in, in a platform based on your scenario.
58:45 But yeah, we get to that point where we're just checking in code and having a positive track.
58:48 Okay.
58:49 And do you, what's the branching structure look like?
58:51 If I just push domain, is that going to go live and I got to work on a dev branch to not
58:56 do that?
58:56 Or is there like a prod branch or?
58:58 Yeah.
58:59 You can set that up in your GitHub action.
59:00 Right.
59:01 Okay.
59:01 Right now we have, the template is just going to work.
59:03 If I don't do anything, what happens?
59:05 It's main branch.
59:06 Main branch goes straight to production.
59:08 That's right.
59:08 I love it.
59:09 Y'all are just carefree to test for it.
59:12 Do it live.
59:13 The users are the testers.
59:14 Let's go.
59:15 Do it live.
59:16 No.
59:17 Okay.
59:17 Got it.
59:17 So you would just tweak your GitHub action Yable file and change your branch name or something?
59:22 Yeah.
59:22 You could set some conditionals in the GitHub action based on the environments that are coming
59:26 in.
59:26 Cool.
59:26 Anthony, what were you going to say?
59:28 Yeah.
59:28 It assumes a single branch strategy, but I mean, or you can tell it to generate the template
59:33 for you and you can put that template wherever.
59:35 It's pretty easy nowadays to say with GitHub, you know, which branch and stuff this should
59:41 apply for, or this pipeline should only run on pull requests.
59:45 Or my recommendation to people is that you keep main highly protected.
59:49 You don't let people push directly to main and it can only be merged into, and then it has
59:54 to be reviewed and stuff.
59:55 I think keeping a clean main branch is good strategy anyway.
01:00:00 You can have a feature branch or release branch separately to that.
01:00:05 So probably the main branch would be your dev, your sort of live dev environment.
01:00:09 And then maybe you want a feature branch or release, so main release branch separately
01:00:14 to that, but using the same templates.
01:00:16 So all you're really changing is the targeted environment names.
01:00:19 Yeah.
01:00:19 Okay.
01:00:20 That sounds like good advice.
01:00:21 All right, guys.
01:00:21 Well, we're getting a little short on time now.
01:00:23 This looks like a really interesting project.
01:00:25 I love the technical choices on the backend, you know, that you've made to sort of create
01:00:31 building blocks for people.
01:00:32 I guess we could wrap it up real quickly with, we've got this more DevOps-y management,
01:00:37 IT-like CLI that people have used previously.
01:00:40 If they're doing Python stuff and they kind of want this container-hosted world, this is
01:00:45 probably the recommended way, at least from you all.
01:00:47 Yeah.
01:00:47 Yeah.
01:00:48 If you want to get started and...
01:00:50 Fantastic.
01:00:50 All right.
01:00:51 Anything else you want to add about this?
01:00:52 I'd like to call it a show.
01:00:53 No, nothing from my side.
01:00:56 A template that you can kind of build upon.
01:00:59 Shane is frozen.
01:00:59 Something that you want.
01:01:00 Oh, no.
01:01:00 Shane is frozen.
01:01:01 A production-style app.
01:01:02 This is a great way to get started.
01:01:03 I thought he was just getting tired because it's late where he is, but no.
01:01:06 All right.
01:01:07 Well, Anthony, I'm sure this is not going to come as a big surprise given all of your current
01:01:12 work and stuff.
01:01:13 But I'll ask you the final two questions first, and then we'll hopefully get Shane
01:01:16 back shortly.
01:01:17 Good to write some Python code?
01:01:18 What editor are you using these days still?
01:01:20 Definitely VS Code.
01:01:21 But tell people about the font.
01:01:23 Comic Sans Mono.
01:01:25 So it's a Comic Sans font, but in Mono space.
01:01:29 Awesome.
01:01:29 Is it a nerd font?
01:01:30 There is.
01:01:31 I think there's a nerd font flavor of it.
01:01:32 I haven't configured my terminal to use Comic Mono yet because I think that'd be going
01:01:36 a bit far.
01:01:37 It actually looks...
01:01:38 It'd be madness.
01:01:39 It looks better than you think.
01:01:40 It looks good.
01:01:41 It looks way better than you would think Comic Sans looks.
01:01:44 And it's really readable.
01:01:44 I would totally be down to it.
01:01:46 I had to make a DNS joke.
01:01:47 You did.
01:01:49 You took yourself offline, but you're back.
01:01:51 And just in time to answer the question, have you written some Python code?
01:01:55 What editor are you using these days?
01:01:56 I use VS Code.
01:01:57 Right on.
01:01:58 I don't know.
01:01:58 I use VS Code for taking notes.
01:02:00 I mean, it's just...
01:02:01 Yeah.
01:02:01 It's Markdown or if it's in Mark...
01:02:03 Everything's in Markdown or whatever code, so...
01:02:06 Yeah.
01:02:06 All my notes these days are in Markdown.
01:02:08 If not like a Google Doc, Zoho Doc, something like that.
01:02:11 It's definitely in Markdown.
01:02:12 It was like...
01:02:13 I think it was like three years ago.
01:02:14 I was in a meeting with Chris Diaz, who's the kind of owner of VS Code.
01:02:18 And he pulled up his screen and he started taking notes in VS Code.
01:02:21 And I was like, I'm an idiot.
01:02:23 I should be doing that.
01:02:25 Yes.
01:02:25 Just go to the bottom right.
01:02:26 Change that little language to Markdown.
01:02:28 You're good to go.
01:02:29 That's right.
01:02:29 Absolutely.
01:02:30 Notepad.
01:02:31 Notepad is dead to me.
01:02:32 Yeah.
01:02:33 The problem I have at the moment is I've probably got too many extensions.
01:02:36 I just realized this morning I have 99 now.
01:02:38 So I'm nearly at three figures.
01:02:42 There might not be room at the UI to just display that number.
01:02:47 It might stop at two digits.
01:02:49 Just kidding.
01:02:49 Yeah.
01:02:50 That's awesome.
01:02:51 I tell you, I didn't even...
01:02:52 The first bit of...
01:02:54 Here's some irony.
01:02:54 The first time I ever wrote Python was...
01:02:57 It feels like 100 years ago, but...
01:02:59 Was actually to write a Sublime add-in to enable .NET IntelliSense for .NET Core.
01:03:08 So I was on the OmniSharp team to write the add-ins for that.
01:03:12 So completely like not Python related, but I was using Python to enable .NET and Sublime back in the day.
01:03:18 That's cool.
01:03:19 Yeah.
01:03:19 So very meta.
01:03:21 Yeah.
01:03:21 Using the editor to write the editor.
01:03:22 All right.
01:03:23 And then notable PyPI package.
01:03:25 Anything you want to give a shout out to?
01:03:26 I mean, we definitely mentioned a bunch of fun ones, but...
01:03:29 Yeah.
01:03:29 I'd say Beanie Perflint, which is one of mine.
01:03:32 But yeah, check out Perflint if you want to.
01:03:34 And check out Beanie as well.
01:03:36 It's a really nice approach to document databases in asynchronous front ends.
01:03:42 Yeah.
01:03:42 Especially if you're doing FastAPI.
01:03:44 I was going to say, I used to struggle with document databases and Pydantic and Beanie made my life a whole lot better.
01:03:52 Yeah.
01:03:52 I think we all concur.
01:03:53 Beanie.
01:03:54 Definitely a good one.
01:03:56 Good call.
01:03:56 Cool.
01:03:56 Yeah, absolutely.
01:03:57 All right, guys.
01:03:58 Final call to action.
01:03:59 People want to get started with this.
01:04:01 Once it's out, what do they do?
01:04:03 When they're listening to this, it'll be out.
01:04:04 So not to confuse folks.
01:04:06 I've got a link that folks can go and check this out.
01:04:09 It'll obviously be in the show notes.
01:04:11 It's a short link.
01:04:12 It's an aka.ms and it's try-aca-python.
01:04:17 Right on.
01:04:17 And they can see the project template, sign up for our preview, check out the repos, et cetera.
01:04:23 Cool.
01:04:23 Yeah, it looks like you need a project.
01:04:24 And definitely people are doing Azure.
01:04:28 It supercharges you into a ton of best practices.
01:04:31 Yeah, for sure.
01:04:32 Well, nice work.
01:04:33 And thanks for joining me to talk about it.
01:04:34 Yeah, I appreciate the time.
01:04:35 Thanks.
01:04:35 Yeah, you bet.
01:04:36 Bye.
01:04:36 This has been another episode of Talk Python to Me.
01:04:40 Thank you to our sponsors.
01:04:42 Be sure to check out what they're offering.
01:04:44 It really helps support the show.
01:04:45 Take some stress out of your life.
01:04:48 Get notified immediately about errors and performance issues in your web or mobile applications with
01:04:53 Sentry.
01:04:53 Just visit talkpython.fm/sentry and get started for free.
01:04:58 And be sure to use the promo code talkpython, all one word.
01:05:02 Say no to being manipulated by ad companies and enjoy the free and open internet.
01:05:08 Get NordVPN on all your devices.
01:05:10 Set auto-connect and relax.
01:05:12 Visit talkpython.fm/NordVPN to get your risk-free subscription started today.
01:05:19 Want to level up your Python?
01:05:20 Want to level up your Python?
01:05:21 We have one of the largest catalogs of Python video courses over at Talk Python.
01:05:25 Our content ranges from true beginners to deeply advanced topics like memory and async.
01:05:30 And best of all, there's not a subscription in sight.
01:05:33 Check it out for yourself at training.talkpython.fm.
01:05:35 Be sure to subscribe to the show.
01:05:37 Open your favorite podcast app and search for Python.
01:05:40 We should be right at the top.
01:05:41 You can also find the iTunes feed at /itunes, the Google Play feed at /play,
01:05:47 and the direct RSS feed at /rss on talkpython.fm.
01:05:52 We're live streaming most of our recordings these days.
01:05:54 If you want to be part of the show and have your comments featured on the air,
01:05:58 be sure to subscribe to our YouTube channel at talkpython.fm/youtube.
01:06:02 This is your host, Michael Kennedy.
01:06:04 Thanks so much for listening.
01:06:05 I really appreciate it.
01:06:06 Now get out there and write some Python code.
01:06:08 I'll see you next time.