#453: uv - The Next Evolution in Python Packages? Transcript
00:00 Have you ever waited around for pip to do its thing while installing packages or syncing virtual environments,
00:05 or even through some higher-level tools such as pip-tools?
00:09 Then you'll be very excited to hear about what just got announced from Astral,
00:14 a PIP-compatible CLI tool called UV.
00:17 It's like PIP, but 100 times faster.
00:19 Charlie Marsh from Rough Fame and the founder of Astral is here to dive in.
00:24 Let's go.
00:25 This is Talk Python To Me, episode 453, recorded March 12, 2024.
00:31 Welcome to Talk Python To Me, a weekly podcast on Python.
00:49 This is your host, Michael Kennedy.
00:51 Follow me on Mastodon, where I'm @mkennedy, and follow the podcast using @talkpython, both on fosstodon.org.
00:58 Keep up with the show and listen to over seven years of past episodes at talkpython.fm.
01:03 We've started streaming most of our episodes live on YouTube.
01:07 Subscribe to our YouTube channel over at talkpython.fm/youtube to get notified about upcoming shows and be part of that episode.
01:15 This episode is sponsored by Neo4j.
01:18 It's time to stop asking relational databases to do more than they were made for and simplify complex data models with graphs.
01:26 Check out the sample FastAPI project and see what Neo4j, a native graph database, can do for you.
01:33 Find out more at talkpython.fm/Neo4j.
01:38 And it's also brought to you by us over at Talk Python Training.
01:41 Did you know that we have over 250 hours of Python courses?
01:46 Yeah, that's right.
01:47 Check them out at talkpython.fm/courses.
01:50 Hey, y'all.
01:52 I have a quick announcement before we jump into the conversation with Charlie.
01:55 And sticking with the theme of the episode, I'll keep it quick.
01:57 Over at Talk Python, we just released a new free course.
02:01 It's all about working with audio in Python, converting it to text, applying all sorts of AI awesome sauce, and more.
02:08 We end up with a dynamic web app that lets you have a ChatGPT style Q&A with a podcast, guests, and hosts starting from just the RSS feed.
02:18 It's really mind-blowing.
02:20 As a sweet bonus, the course shows you a bunch of hands-on examples of FastAPI, HTMX, Beanie, MongoDB, and more.
02:27 I hope you love it.
02:28 Give it a look as it is 100% free, no strings attached.
02:32 The link is on the episode page, in your podcast player show notes, and at talkpython.fm/courses.
02:38 Hey, Charlie.
02:40 Hey.
02:41 Welcome.
02:42 Yeah, thanks so much for having me back on the show.
02:44 I really appreciate it.
02:45 Yes, it's really great to have you back on the show.
02:48 You and your team are doing awesome work these days and making a big dent in Python.
02:53 Thank you.
02:54 Thank you.
02:54 Hopefully a good dent, I guess.
02:56 Yeah, I guess you could make a good dent or a bad dent.
02:59 But no, I meant that in a good way.
03:01 Definitely in a good way.
03:02 I appreciate it.
03:03 Yeah.
03:04 Yeah, I think excellent work.
03:05 It's really, it's kind of surprising how some of these tools just come in and just catch fire in a way.
03:12 I don't know how you felt about it, but it seemed more than I would have expected.
03:16 I mean, I did not expect your things to be popular, but they became really popular really quickly.
03:21 Yeah.
03:23 Yeah.
03:23 I mean, it was different, you know, with Ruff and with UV, this sort of context around it has been pretty different.
03:30 Because with Ruff, like when I started working on Ruff, no one knew who I was or had any reason to care about what I was doing.
03:37 And the project just grew, you know, grew over time.
03:41 And then I knew that when we were working on UV, like there would just be a lot more of an expectation around like anything we build.
03:47 Yeah.
03:47 The spotlight was already shining, right?
03:49 A little bit.
03:50 Yeah.
03:50 Yeah.
03:50 And that's awesome because it means our stuff gets traction.
03:53 Also, it comes with a lot of responsibility.
03:56 It means anything we release, we're, you know, we're kind of committed to maintaining.
03:59 So, like, yeah.
04:01 Yeah.
04:01 Yeah.
04:01 It's been very interesting, like this kind of release cadence versus what happened with Ruff.
04:07 Well, you have more people behind the scenes helping you out, right?
04:10 I do.
04:11 Yeah.
04:11 Thankfully.
04:12 Yeah.
04:12 Tell us, you know, maybe that's a good place to just kick off our conversation is, you know, we're talking a bit about Ruff for everyone.
04:20 And Ruff was the thing that really launched all of this.
04:24 But you started a company, Astral.
04:27 Yep.
04:27 Got some funding behind it.
04:28 Yep.
04:29 Building awesome tools.
04:30 Yeah.
04:30 Just give people the broad view of your world these days.
04:32 Yeah, totally.
04:33 So, yeah, I started, this all started when I released Ruff probably like a year and a half ago, maybe at this point.
04:42 And at that point, it was really not just a side project for me, but very much an exploratory project.
04:49 Like I was kind of curious about building faster Python tooling, really, and curious about getting better at Rust and all this stuff.
04:58 And Ruff, when I released it, it's, you know, it was a lint or it is a linter, but it kind of brings a lot of different tools together.
05:07 So if you're familiar with like Flategate or Pylent, but also Black, Ruff is designed to kind of bundle all those tools together.
05:16 So it can detect problems with your code.
05:19 It can fix them automatically.
05:20 It can reformat your code.
05:23 So often when we see people like adopting Ruff, they're replacing like 20 or 30 tools with Ruff.
05:29 And, you know, it has, there's a bunch of nice things about it, but ultimately it's very, very fast and hopefully a lot simpler for users.
05:36 Yeah.
05:38 But, go ahead.
05:39 I was going to say, it's really nice that it's just one tool that brings that all together.
05:44 You know, it's not a patchwork.
05:45 Well, here's how we use ISORT and here's how we use Flategate and here's how we use this and here's how we use that, you know?
05:50 Right.
05:51 I think ISORT's a really good example because instead of having an ISORT's a great tool, but instead of having a separate tool to do your import sorting, Ruff Frames import sorting is just a lint rule.
06:00 And so you don't have to learn a bunch of different tools and figure out how to sort of merge them together.
06:06 And, you know, Ruff, again, when I released it, it was just a side project and it sort of took off.
06:14 You know, there were, it was originally, you know, I released it in part because I had this thesis that like Python tooling could be much faster and Ruff was meant to evidence that.
06:25 It was meant to be an example of what I saw as like this potential to build really different Python tooling.
06:30 And took off a couple of big projects like FastAPI and such were kind of early adopters and it just grew and grew and grew from there.
06:41 And I started a company, Astral, you know, shortly after based on a lot of these ideas.
06:47 So again, Ruff in this context was meant to be, you know, the goal wasn't necessarily to start a company just based around Ruff.
06:54 The goal was to start a company based around, you know, the ideas behind Ruff, which is, can we build really different Python tooling by, well, it's all written in Rust.
07:07 It's sort of an implementation detail, right?
07:09 But ultimately what we're trying to do is build like really high performance Python tooling, but also tooling that works together really well and simplifies things.
07:16 So tackle, it's not just about performance.
07:19 It's also about tackling a lot of, I guess, what I see as the complexity in Python tooling today.
07:24 And really trying to, I guess, challenge certain status quos and respect others, but challenge some status quos in what it feels like to work with and use Python.
07:36 And so, you know, our focus as a company, you know, right now we're very, very focused on our open source roadmap and our open source tooling.
07:47 So that's Ruff now, UV, which we'll talk about in a bit.
07:52 And these are, you know, MIT licensed, you know, fully open source tools that we build.
07:58 And ultimately our goal is to build and sell paid services that integrate really well with the tooling and are kind of like the natural next thing you need when you're building with Python.
08:08 So, you know, we'll never charge money for like the tools themselves.
08:12 Those remain free, permissively licensed.
08:14 But our goal is to kind of build, you know, imagine you're building with Python, you need to deploy a web server.
08:19 There's a lot of things that you need naturally to do that.
08:22 So for people who are already using our tools, what are the natural next things they need and how can we build really good services on top of the tooling that just integrate with it really well?
08:30 So that's kind of the premise of the company.
08:32 There's like really two focuses to the roadmap.
08:34 It's like the open source and the commercial.
08:37 And our goal is to have an incentive structure where we're just continuously aligned to like invest a ton in the open source and grow it as much as possible in a really natural way.
08:46 So you're not going to do like per line fix pricing.
08:49 You get a million, million line fixes a month free and then no, I think it's an awesome model.
08:55 And, you know, open source 10 years ago, it really looked like it was already super vibrant and super making huge dents in the space.
09:07 Right.
09:07 Really a lot of people adopting it.
09:10 But I think there was kind of a funding side that was a little bit missing.
09:14 I still remember like, you know, buy me a coffee type of links, like send me 10 bucks.
09:18 Yeah.
09:19 If you like this.
09:20 And that's just it's not a job.
09:22 That's hardly a hobby type of thing to get stuff done.
09:26 You can't have a team of people focused on it.
09:28 And it had traditionally really been around kind of a beneficial.
09:33 I need to find a big tech company that's willing to give me sufficient amount of time to work on this project.
09:39 To sort of fund its existence.
09:42 Or maybe I'm a consultant and I'm I create Flask, but I consult on Flask, that type of thing.
09:47 Right.
09:47 And I think it's just super positive to see more direct ways people are making open source successful.
09:54 You know, I think.
09:55 Yeah, I appreciate that.
09:56 I wish.
09:56 Yeah, I think.
09:57 You know, I wish I sort of wish that there were more more good examples of that working.
10:02 There are some for sure.
10:05 You know, for me, it was pretty clear.
10:06 Like it was immediately clear to me.
10:08 I needed to work on a rough full time if I wanted the project to succeed.
10:11 And that's kind of a microcosm of the bigger the bigger challenge, which is like we wanted to build like we really wanted to like professionalize the building of this.
10:20 You know, the work on this project and bring in more people to help build it.
10:24 And so, you know, ultimately, it's not obviously it's not it's not charity.
10:28 It is venture funding.
10:29 And ultimately, we need to build a business, you know, around the tooling to make it, you know, to make it sustainable.
10:38 But, you know, again, for me, I want the incentive structure to be such that like the open source is obviously free, open source, extremely permissively licensed and truly open source.
10:50 Like we have tons and tons of contributors.
10:52 We have a huge community around it.
10:55 And I'm just glad that we've been able to, you know, bring in more people to kind of supercharge the development of it all.
11:02 So, yeah.
11:02 So I guess you talked on you touched on this before, but we're now eight people.
11:07 So we've grown, you know, it was it was I guess a year ago it was just me in March.
11:14 So over the past year, our first two team members joined actually in March of last year.
11:20 So almost exactly a year.
11:21 And, yeah, we're completely distributed.
11:25 So we're, you know, we have people in U.S. Pacific time all the way to Bangalore.
11:30 So we're just, you know, around the like open source.
11:35 We're kind of all over the world and and just building, you know, building all this stuff out in the open.
11:41 It's such a good fit to be a distributed company as an open source with open source roots, because the tools of open source in some degree for software in general, but especially for open source is asynchronous.
11:54 Yeah.
11:55 Semi-connected, you know, kind of the zen of get, but for the way you work.
11:59 Right.
12:00 And it makes it super easy to hire just the most engaged people, regardless.
12:04 Yeah, exactly.
12:04 Yeah.
12:05 The people who are willing to commute to my office in the office park.
12:08 Yeah.
12:09 It was I would be pretty surprised if a single person I've hired would have been willing to move to New York, which is around based.
12:19 So from that perspective, it was a no brainer, which is and actually, you know, multiple people we've hired.
12:25 Our relationship with them started on the repo.
12:28 Yeah.
12:29 InRuff itself.
12:31 And then almost everyone we've hired, we discovered through open source in some way or had some relationship through open source in some way.
12:40 Yeah.
12:41 So, yeah, it's been a really it's very much in it's also very much in the DNA of the company, which is, you know, we actually also intentionally try to hire people who have been maintainers.
12:51 Right.
12:51 And have a lot of experience with that, too.
12:53 We view that as a really important skill.
12:55 Yeah, that's excellent.
12:56 So we talked about Ruff.
12:59 One thing I do want to give a bit of a shout out to is I don't remember.
13:03 I think I found this on Mastodon.
13:05 I can't remember where somebody talked about it.
13:07 But one of the things that Ruff does, one, it changes code, which is awesome.
13:12 I love your Ruff format story.
13:14 But it also just tells you, hey, this could be better.
13:16 You're violating PEP 8.
13:17 You're violating this other convention or even a security thing.
13:21 Right.
13:21 But the why is the why of that, I think, requires a little bit of experience.
13:26 Like, why should I use this kind of loop or that kind of comprehension over another?
13:32 Right.
13:33 It's people told me that who are much better have been doing this longer.
13:37 I shouldn't do it.
13:38 Why?
13:38 When you have when you have 700 rules, there's a lot of why.
13:42 And so you guys came up with this thing at docs.astral.sh slash rules, put in links that literally for each one of these has like a little example.
13:52 And what is good and what is bad and when you should use it and so on.
13:57 You want to tell people about this a bit?
13:59 I think it's a mess.
13:59 Yeah, totally.
14:00 So we didn't have, I mean, we obviously didn't have this when we started the project.
14:04 And then we accumulated a lot of rules.
14:08 Like, when we decided to add this, I think we already had like hundreds of rules.
14:12 And the motivation for the format really comes from Clippy, which is the linter used in Rust.
14:20 Okay.
14:21 And they have really, Rust in general has a really good documentation culture.
14:24 And Clippy has this nice format, very similar to ours.
14:27 We've made some adjustments, but it's pretty similar around how you document lint rules, like what's the motivation and giving examples.
14:34 And so we were like, all right, let's, we want to do this.
14:37 And we just over a very long period of time and a lot of contributors contributed on this documentation, but it took like six months or something probably to document it.
14:46 And now, yeah, now we can, now we require it for all rules.
14:49 So it's much easier to add going forward, but it was a huge effort to add this.
14:53 And, you know, some of the explanations too are very extensive and detailed with lots of references.
14:59 Yeah.
15:01 Yeah.
15:01 Yeah.
15:02 I pulled the one up for iSort, unsorted imports, which is error i001.
15:07 And it also talks about whether it can automatically fix it, what this does, why is it bad?
15:13 So it says things like consistency is good, use a common convention for imports to make your code more readable and idiomatic or Pythonic.
15:20 Yep.
15:20 And it just gives an example of bad, good.
15:22 Right, right.
15:24 I think that's nice.
15:25 Yeah.
15:25 And, you know, we've started to put more stuff in here over time too.
15:28 Like whether, like in some cases we let users apply automatic fixes that aren't completely safe, like by opting in.
15:36 Like it might change the meaning of your code and you kind of need to be careful.
15:39 And so over time we've started to document that here too, like rules that have unsafe fixes.
15:43 Why?
15:44 Like in what case might it break your code and what should you look out for?
15:47 So, yeah, we want it to be a tool with really good, like we're kind of inspired by Rust in this way.
15:55 Because Rust has a really good documentation culture and also the Rust like compiler itself has really good error messages.
16:02 It's sort of famous for that, like when your code doesn't work, it's really good at telling you why.
16:06 It doesn't always get it right, but it has famously good error messages.
16:09 And that's something that we try and channel too, to like when we make changes to configuration, like just putting extra effort into trying to make like those, those like error messages and those hints helpful.
16:19 But yeah, it's a lot of work.
16:20 So I appreciate you.
16:21 I appreciate that you called it out.
16:23 I'm sure it looks like a lot of work, but it's one of those things that's, where else are you going to get this knowledge, right?
16:29 I mean, I know you can go search for one at a time, but in this aggregates is really good.
16:34 Right, right, right.
16:37 This portion of Talk Python to Me is brought to you by Neo4j.
16:40 Do you know Neo4j?
16:42 Neo4j is a native graph database.
16:45 And if the slowest part of your data access patterns involves computing relationships,
16:50 why not use a database that stores those relationships directly in the database, unlike your typical relational one?
16:57 A graph database lets you model the data the way it looks in the real world, instead of forcing it into rows and columns.
17:04 It's time to stop asking a relational database to do more than they were made for and simplify complex data models with graphs.
17:11 If you haven't used a graph database before, you might be wondering about common use cases.
17:16 You know, what's it for?
17:17 Here are just a few.
17:19 Detecting fraud.
17:20 Enhancing AI.
17:21 Managing supply chains.
17:23 Gaining a 360-degree view of your data.
17:26 And anywhere else you have highly connected data.
17:29 To use Neo4j from Python, it's a simple pip install.
17:34 Neo4j.
17:35 And to help you get started, their docs include a sample web app demonstrating how to use it both from Flask and FastAPI.
17:42 Find it in their docs or search GitHub for Neo4j Movies Application Quick Start.
17:47 Developers are solving some of the world's biggest problems with graphs.
17:51 Now it's your turn.
17:52 Visit talkpython.fm/Neo4j to get started.
17:57 That's talkpython.fm/Neo4j.
18:00 Thank you to Neo4j for supporting Talk Python to me.
18:06 So Ruff will fix a lot of these things for you.
18:09 And one of the things that I like to do is I just have it integrated into my editor these days.
18:14 So both with PyCharm and with VS Code, if I just say format this document, that's a Ruff format.
18:21 Nice.
18:21 Yeah, yeah.
18:23 So we have a VS Code extension.
18:25 And it supports formatting, autofixing, all that kind of stuff.
18:30 The PyCharm one's a third-party one, right?
18:35 Someone else decided to make that.
18:36 Yeah, the JetBrains one is by Huda.
18:39 And it's, yeah, that's like a community extension.
18:45 We're considering doing our own at some point because there's a lot of demand for, obviously, we have a lot of users who use the JetBrains stuff.
18:53 I mean, I use it.
18:54 So we may do our own at some point, but there's a community-maintained one right now.
18:58 And that's based on, we have sort of like a language server.
19:02 So there's kind of like an underlying piece of technology that wraps rough, that powers all of these editor integrations.
19:08 So you can also use that from like NeoVim or Sublime Text or Emacs.
19:13 All of those editors support the LSP.
19:15 And so you can actually, it's the same thing that powers the VS Code extension.
19:20 Just that's wrapped in some VS Code specific stuff.
19:23 But it's the same piece of technology.
19:26 We're actually rewriting that right now to make it sort of like more natively integrated into Ruff, which will let us do some cool things.
19:34 So it should get like actually significantly better, I think, over the course of this year because it's becoming more and more of a priority for us.
19:41 Yeah, cool.
19:42 The whole LSP thing is pretty interesting.
19:44 I think it's really opened up a lot of editors being better.
19:47 Yeah, it has.
19:49 And it made it, like from our perspective, it made it way easier to build like editor integrations.
19:55 Because we just built an LSP and then it like works for like everyone, almost.
20:01 Yeah.
20:04 Like the JetBrains stuff, it does support the LSP, but I think only in the paid version, not in the community version.
20:11 So like there's some limitations around it.
20:13 But in general, like if you support the LSP, like it's actually very easy to build editor integrations that work with everyone, which is like super, super useful.
20:20 Yeah.
20:21 Instead of rebuilding your own integration for every single thing, which is not fun.
20:26 Yeah, it's a lot.
20:27 All right.
20:27 Well, let's talk about the main project here.
20:31 The main reason for being here today is UV.
20:35 Tell people what UV is.
20:37 This is your next big project, next big tool.
20:40 Yes.
20:40 Yeah.
20:41 UV, we released UV a little under a month ago.
20:47 And this is something that I've wanted to do, like basically since we started the company, I wanted to start, I thought there was an opportunity to build some really interesting tooling in Python packaging.
21:00 And UV is kind of the first milestone in that.
21:03 So UV, in its current form, it's designed as a sort of drop-in alternative to PIP, pip-tools, like if you use pip compile, pip sync, and virtualenv.
21:17 So it takes those three tools and tries to bundle them into one.
21:22 And so it can do things like, you know, given a set of input requirements, generate a requirements.txt file similar to what you'd get from pip compile.
21:32 It can, you know, you can do uvpip install-r requirements.txt, uvpip install black.
21:40 So it's really intended right now to be sort of, you know, it won't always, we don't support absolutely 100% of what pip does, but it's, we try to be pretty close.
21:53 And so in many cases, the intention is that people can basically drop in UV in their project that uses pip today and get, in many cases, like very, very significant performance improvements.
22:07 So similar to Ruff, like some of the goals we had for this project were one, it should be very, very fast.
22:14 And UV, it's really fast.
22:18 In particular, there's like a benchmarks.md in here, actually, if you want to click on that.
22:25 Now scroll up.
22:27 Does that do it?
22:28 Oh yeah, that works too, I guess.
22:29 That was smart of me.
22:31 Yeah, so it's really, really fast, especially if you've already have, if you're, if you have things cached, which is pretty common.
22:41 So like often on your machine, when you're doing like pip install-r, whatever, a lot of those packages, you've probably installed them at least like once before on your machine.
22:52 Or maybe you deleted your virtual environment and you're recreating it with the exact same dependencies or something like that.
22:57 UV is like very, very well optimized for that case.
23:02 So if you have a package that you're installing multiple times, like the installation is effectively free.
23:08 And it's also a lot more like disk space efficient.
23:12 We use kind of like, we store all of them in one place and kind of copy them into your virtual environment so that you don't have like many, many different copies of the package too.
23:20 So this was all kind of taking techniques and inspiration from like other ecosystems and other package managers and kind of molding them to fit Python's model for how packaging and dependencies work and all the specifications.
23:37 And so again, the end result is like you, you know, installing into a virtual environment, a package that you've already installed before is basically free.
23:44 And yeah, a lot of these things are just like way, way, way faster.
23:49 Similar to rough, like dramatically faster.
23:52 Yeah.
23:53 Yeah.
23:53 And similar to radically.
23:54 And I think, you know, it's worth pointing out that like on one hand, we all have an extra 10 seconds, right?
24:01 Or of course, whatever.
24:04 But in the aggregate, all of these things are just like little paper cuts over your day, you know?
24:09 And so, yeah, sure.
24:11 I can format the code and I could use something nice and sure if it takes 20 seconds.
24:15 Okay.
24:15 But then you stop running it because it's kind of a hassle and you're just, you're in your flow.
24:19 And this is kind of the same way.
24:21 It's like, oh, I want to maybe see if there's a new, some new packages for this project as I'm sitting down to work on it.
24:28 Like, okay, well, wait for a pip compile to run and you wait and you wait and then like, okay, now it's done the onto the development version and you wait and you wait.
24:37 And like, you know, it's just some of these things that are instant.
24:40 You just ask the question more and it just doesn't break your train of thought, you know?
24:45 Totally.
24:46 I think there's like maybe like three different things that come to mind here when we think about performance.
24:50 Because like, yeah, okay.
24:52 In this case, like it may not seem to change your life if you're going from one second to, you know, 50 milliseconds.
24:58 But I think three things come to mind.
25:00 So one, like for companies and large projects, this can actually be like a really big difference.
25:07 And so if you're at a company and you have like a big monorepo with like a bunch of different sub projects, they all have requirements files and you want to bump a dependency.
25:15 That can be like, at that point you're talking like 15 plus minutes for a command.
25:22 And so like for the larger the project gets, obviously the more performance matters and the more it helps out.
25:28 And we're trying to build tooling that can basically scale.
25:30 I don't know about like to arbitrarily large projects, but like two large projects and useful for companies too.
25:35 You know, the other thing I'd say is I think there's something that happens like when tools, when you make something like way faster, it just changes a lot of the ergonomics around what it's like to do things.
25:47 And so, you know, in this case, like, okay, so installing into a virtual environment, a package that you've already installed before is free now.
25:57 And so how does that change things?
25:59 It's nearly instant.
26:00 So how does that change things?
26:01 Right.
26:01 So that means like if you mess up your virtual environment and have to delete it and recreate it, it doesn't, it doesn't cost you anything.
26:07 It's totally, it's totally ephemeral.
26:09 You can throw it away and recreate it at any time.
26:11 And like, that's just like a different, like, it sounds small, but that's kind of like a different relationship to a virtual environments than before where it's like, okay, I created the virtual environment now.
26:18 Oh no, my virtual environment.
26:19 So I messed up.
26:20 I got to recreate it.
26:21 Like we want to just change a lot of the dynamics around some of those like abstractions.
26:25 And then the other thing is this performance budget or this, if you think of performance, like a budget, this buys us a lot of room.
26:33 And so like the fact that we are so fast on some of these things means that we can do things that otherwise might be like prohibitively slow.
26:41 And this is more sort of forward looking and for the future.
26:44 Like one thing that we're thinking about a lot right now is this idea of like resolving Python dependencies for many platforms because it's a little bit complicated, but you know, pip compile and pip and UV, they're really designed to only work on like the current Python platform and the current Python that you're using.
27:01 So if you're on like macOS and you run pip compile, it will give you dependencies that are correct for like macOS and your current Python version, but they might be wrong on Windows because Python and Python, you can have dependencies that vary based on things like the current Python version or the current operating system.
27:23 And so one example would be UV loop, right?
27:26 For people trying to speed up.
27:27 I think it doesn't work on Windows.
27:28 It doesn't work at all on Windows.
27:30 That's right.
27:31 And so, yeah.
27:31 So that's a very common one.
27:32 Yeah.
27:34 And it is, I think, very common that this is a very common thing, like on like lots of really, really popular packages have these kinds of markers, these what are called markers, which basically makes the dependencies conditional based on the current Python.
27:49 And so, you know, like again, like in pip and pip-tools, UV right now just locks for the current Python poetry and I think PDM, but poetry for sure does this very interesting thing where they actually try to lock.
28:05 They try to resolve for like all possible platforms.
28:09 And that's something, it's really convenient because it means that like you kind of do one lock and then any user anywhere can like use that and it works.
28:17 And it's kind of like guaranteed to be right as opposed to maybe it doesn't work on Windows or whatever else.
28:24 And so we're pretty interested in like that, adding that behavior and that's going to be like more expensive.
28:30 And so if we have something that's really fast right now, it kind of like opens up a design space of interesting things we can do to solve that problem while still being, you know, very fast.
28:41 So that's kind of how I think about performance.
28:44 Like I think it's, I think people like a little bit underrate how much of an impact it can have on even small interactions.
28:50 Because once you try something that's much faster, it's often hard to go back to the other thing.
28:55 But I'm glad you've had that experience at least.
28:59 Yeah, absolutely.
29:00 A couple of interesting comments.
29:02 Danny says, if it takes 10 seconds, I go to triage that issue on GitHub and come back five minutes later, right?
29:07 Like that's kind of where I was getting at with the flow stuff.
29:10 It's like, okay, I'm ready.
29:11 Mind wonders and you're kind of like starting over.
29:15 Yeah.
29:16 And then Henry out in the audience also says, hey, Henry.
29:19 Also, this doing things so quickly, it encourages good environment usage because if doing things the right way is just as easy and as fast as doing it the wrong way, you might as well do it the right way.
29:29 That's a nice thought.
29:30 That's a nice thought.
29:30 Yeah.
29:31 Yeah.
29:31 It is.
29:32 Yeah.
29:32 I think there are certain things though where we aren't any faster.
29:39 And I'm interested in thinking about those and what we can do about them.
29:44 The most obvious one is in Python, sometimes when you install a dependency, you might have to build it from source.
29:53 And in Python, you often are installing things like NumPy, which includes some native code.
30:01 And so actually turning that into something that your system can run is kind of expensive.
30:05 And you typically don't have to think about this with NumPy because they ship what are called wheels, which are kind of like these pre-compiled artifacts.
30:16 But not all packages ship wheels.
30:19 You could be on a platform that doesn't have a wheel.
30:21 For a variety of reasons, you might get the raw NumPy source code and then have to compile it down into a build distribution.
30:33 And for us, if we get into that situation, it's not going to be any faster because we still have to build the thing from source.
30:41 Yeah.
30:41 Just like this.
30:42 That's the slowest part of the whole process.
30:44 Yeah.
30:44 And so there are some cases and some bottlenecks where I'm kind of thinking about how could we do even better there.
30:51 And there are actually things that are changing in the standards that have made this a little easier.
30:55 There's this new thing called metadata 2.2.
30:58 Sounds cool.
30:59 I know.
31:00 It basically lets you read the metadata.
31:03 You thought you liked metadata 2.1.
31:05 Yeah.
31:05 Yeah.
31:06 We're actually on 2.3 now.
31:09 I'm just kidding.
31:11 But the point of that is it's a standard that makes it so you don't have to build the thing as often.
31:18 If you just want to know the metadata of NumPy, for example, you may no longer need to build it.
31:24 And before you did.
31:25 And so the standards are moving in a helpful direction here.
31:28 But I just thought I'd call it out because like the source distribution, there are cases where it won't be faster.
31:33 And I'm pretty interested in those.
31:35 But people should know that they also exist.
31:37 There's also, it's not just time.
31:40 There's also security issues around that, right?
31:42 If things are still based on building source from source and then running the setup pie to see what the metadata is.
31:50 It's both slow and also potentially running arbitrary code just to install a thing, which can make you, I mean, I don't know.
31:57 Rarely has anything gone wrong with just installing running arbitrary code off the internet.
32:01 But sometimes it could go wrong.
32:03 Yeah.
32:04 It would be nice to get to a world where that's not required or at least for dependency resolution.
32:11 And like the standards are moving in that direction.
32:13 Yeah, exactly.
32:14 I mean, you might, if you're going to use it, you're going to have to get it.
32:16 But if you just want to know, well, what versions do I need to put these two things together?
32:20 You shouldn't have to do that.
32:21 Yeah, exactly.
32:22 Because today for NumPy, for example, if you didn't have a wheel, you would have to run some arbitrary code to ask it for its dependencies.
32:28 Yeah, exactly.
32:29 Well, let's talk about some of the usages here.
32:32 Let's see some more interesting comments in the chat.
32:35 I'll get back to them.
32:35 First of all, you know, is it like Highlander the movie?
32:40 Should there just be one?
32:42 Is UPy a thing that I put into, say, my requirements file if I want to use it?
32:47 Or do I install it just once for my machine?
32:49 Like, what's the scale?
32:51 UV.
32:52 So there's a lot of different ways.
32:54 You can, there's a lot of different ways to install it.
32:56 You definitely can install it into a virtual environment.
32:58 My general recommendation would be to install it on your machine once.
33:03 Because an interesting thing about UV is you don't need Python to install it.
33:09 And it doesn't have, you need to have Python on your machine.
33:13 Because we need to be able to, for example, build source distributions or know where to install the thing.
33:19 Right?
33:19 We have to install into a virtual environment somewhere.
33:22 And so you have to have Python installed on your machine.
33:26 But UV does not depend on Python.
33:27 So like it can install into arbitrary virtual environments or into arbitrary other Python interpreters.
33:33 So that's why we generally recommend using like these standalone installers that we have at the top of this snippet on the screen.
33:41 They're like the curl and the PowerShell invocations.
33:45 Those will install a single binary on your machine that's UV.
33:52 And from there, you can use UV to install into virtual environments that it creates, to install into your system Python, to do whatever.
34:00 So like I would say most people, based on the statistics, based on our download statistics, most people still install UV with PIP, which makes sense, which is not that surprising to me.
34:11 But I would generally recommend having like one UV install on your machine.
34:15 Although if you do install into a virtual environment, like that's also totally fine.
34:19 Like nothing's going to go wrong.
34:20 It's just not completely necessary because a single UV can already install into that virtual environment.
34:26 Right.
34:26 You're never going to import UV.
34:29 No.
34:29 I mean, you might, but in general, people are not going to.
34:32 I think you can.
34:34 I'm trying to think what would happen.
34:36 It's not like things like pie tests and other things.
34:42 A lot of times there could be just one of those, but then you want to use fixtures and you need to import something out.
34:48 So then it really needs to be in the virtual environment and accessible like a library.
34:52 But this is just something you run maybe even before your codes, before your virtual environment exists.
34:57 Right.
34:57 Like it is, it really kind of does ideally exist outside of it, I think.
35:01 Yeah.
35:01 Ideally it exists outside of it.
35:03 And there are some cases where you'd want to install it within the virtual environment, but ideally it exists outside of it.
35:07 The other thing that's nice about using the standalone installers, like at the top here, is soon we're going to ship like a self-update command.
35:16 So you can do like UV self-update and it will update UV to the latest version.
35:20 And we can't really support that if you install it with a different package manager, like pip or brew.
35:25 Those have their own upgrade commands, obviously.
35:27 But like if you install it with our installer, then like we can control the upgrades and stuff like that and provide some other features.
35:36 So that's generally what we recommend, but obviously we're always going to support like installing with pip and stuff too.
35:41 Yeah.
35:41 I'm all about pipX these days.
35:44 I really like...
35:45 Yeah, we're pipX.
35:46 That's mine.
35:46 Yeah, yeah.
35:48 PipX really, you know, you can just say, kind of like brew, you can say upgrade all my Python CLI tools.
35:53 PipX upgrade all.
35:55 Yeah, yeah.
35:55 Yeah, yeah, yeah.
35:57 I find rough and UV is just, you guys are moving super fast and there's frequently an update.
36:02 There are often updates, yeah.
36:04 Yeah.
36:06 Yeah, and then, you know, the UV interface, like it's meant to be pretty familiar to, or it's meant to be, I guess, hopefully very familiar to people who have used, who are already using pip and other tools.
36:18 And so like UVVM creates a virtual environment.
36:22 And then there's, we have this sort of pip subcommand.
36:27 So like UV pip install flask.
36:29 And that doesn't call or use pip in any way.
36:33 We're just using pip here to convey what the interface looks like.
36:37 And part of the motivation there is at some point in the future, we probably want to add a new interface to UV that's a little bit more high level.
36:49 So you could think of something like Poetry, where they have like Poetry install.
36:55 You know, they have this sort of higher level interface for interfacing with packages.
37:00 We want to do something like that.
37:03 And so that's why we left the top level of the interface clear, because we might kind of like integrate and, sorry, innovate and like ship a bunch of stuff that would otherwise break this interface.
37:13 So like, by putting this stuff under pip, we basically created this like isolated space where we can make sure that those commands like keep working no matter what we choose to change in the future.
37:25 And it's very similar to the pip's interface, right?
37:27 It's like pip install, then it could be a package name.
37:29 It could be a requirement, dash R requirements file.
37:31 We support editable installs.
37:33 We support like URL dependencies, get dependencies, all that kind of stuff.
37:38 Right.
37:39 All the stuff you might normally do pip install something for the most part, that's the same.
37:44 Yep.
37:44 Yeah, exactly.
37:45 And we support a lot of the same flags, too, that like pip supports.
37:48 So like --index URL, --extra index URL, like --no binary, like all that stuff.
37:54 Like we've put a lot of, we don't support every flag, but we've put a lot of effort into supporting a lot of them.
38:00 And we've added more over time.
38:01 Like now we support like --no build isolation and stuff like that, that maybe most listeners have never even had to look at.
38:08 But like, you know, these things matter in some circumstances.
38:11 And so like over time, our goal is to add like more of the interface.
38:15 But, you know, I would say for common use cases, I would expect that it just works.
38:22 Like just adding UV at front, like it should just work.
38:25 Now, as you become more complex, it won't.
38:29 And you'll run into some, we have a whole document of like subtle ways that we deviate.
38:33 Some are intentional.
38:34 Some I consider bugs, right?
38:36 Like some we want to fix over time.
38:37 But the intention is that for most people, we want it to just work.
38:41 Once we fix the first round of bugs following the release, of course.
38:44 Yeah, yeah, sure.
38:45 So you've got a uv venv VIMP, for creating a virtual environment.
38:50 And it has a lot of the flags that Python dash MVNV would have, where you can say, you know,
38:57 bring along pip or upgrade things or set the prompt name, that kind of stuff, right?
39:02 Yeah, exactly.
39:03 Yep.
39:03 Similar for UV, PIP, and then stuff.
39:06 What I find I do for most of my work, at least if I'm not trying to teach or do a presentation,
39:11 where people are like, what did you just do?
39:13 These all have kind of aliases, right?
39:15 Like UV, PIP, install, dash, R, requirements.txt is just PIR, pip install requirements.
39:21 You know, things like that, right?
39:22 Yeah, yeah, yeah.
39:23 And so try to just take the common stuff.
39:25 And it doesn't matter if it's pip or UV really backing it from my CLI ergonomics, right?
39:33 I'm just, I use my alias.
39:35 And if I want to change that, I just go and edit it.
39:38 And so for me, it was super easy to switch to adopt these things because I'm like, I edit
39:43 my ZSH RC file once and now everything just, I just do the same stuff and it works, but
39:49 the new way, way faster.
39:50 Yeah.
39:51 And, you know, the goal of like pip compatibility has been interesting because there are actually
39:57 like some things that we very intentionally want to do differently.
40:00 And like, I won't speak for the pip maintainers, but I think in some cases, there are probably
40:05 things that they would do differently too, if they could.
40:08 I think so too, yeah.
40:09 Yeah, because like PIP, I mean, pip is extremely important and its number one goal is like,
40:16 it needs to be like robust, right?
40:19 It needs to keep working and it needs to be compatible.
40:22 And because it's like, it's truly like the cornerstone of like a lot of the Python ecosystem.
40:27 And so PIP, it's very, it's harder for them to change things, especially in a breaking
40:32 way.
40:32 And they have to be really thoughtful and do that over a long period of time.
40:36 And so we're in kind of a privileged position, honestly, because we come in with a new tool.
40:41 We can actually do a bunch of, choose to do things differently.
40:44 And some people will get upset about it, obviously, because they're like, this isn't exactly how
40:48 pip does it.
40:49 I'm trying to hold firm on some of those things and also be open-minded on others.
40:53 Right.
40:53 But like, you know, like one thing that we do that's different, that's, I guess maybe it's
40:58 not evident from this exact, from this screen exactly, or I guess it sort of is.
41:01 So when you do UVVM, we default to the name .vm.
41:05 So like, if you don't provide a name, we just default to .vm.
41:08 And there was a PEP to make that a standard that got pulled back.
41:13 But like, it's not like we're trying to make it a standard, but I just think it's a good
41:16 default.
41:16 Like we want to abstract away some of this stuff.
41:18 And so you can just like have a virtual, you can obviously pass a name if you want,
41:21 but we default to .vm.
41:23 That's different from other tools.
41:24 And then, you know, the other thing is when you do UVPIP install, by default, we require
41:29 a virtual environment.
41:30 And so if you do UVPIP install Flask and there's no virtual environment, like we'll throw, we'll
41:37 error.
41:37 And it doesn't have to be active.
41:39 We'll look for it in the current directory, even if it's not active.
41:42 So like if you do UVVM, then UVPIP install Flask, like it will work.
41:46 And in my opinion, it will do the intuitive thing, which is it will install into the environment
41:50 in the current directory.
41:51 So it's like, it's trying to provide...
41:53 It will traverse up.
41:53 Like if I'm a little farther down, it'll go up and say, oh, just, oh, that's amazing.
41:58 Exactly.
41:58 So it'll find the virtual environment in the current directory or any parent directory.
42:01 So like for me, that's just like a nice default workflow that encourages virtual environments
42:10 and like doesn't get in your way about it.
42:11 And we do have a flag for installing outside virtual environments, but the difference is in
42:15 UV, you have to opt in if you want to do something like install into the system Python.
42:20 It's a very virtual environment first while abstracting away a lot of the details of virtual environments.
42:26 So there are things like that where we've made intentional decisions.
42:30 In my opinion.
42:31 Yeah.
42:31 Yeah.
42:32 And I think, and it's nice because we can start with that behavior and we're in a privileged
42:40 position because we can start with different defaults.
42:42 Yeah, for sure.
42:43 So if I do, excuse me, if I do a UV, VNV for a virtual environment, then maybe I UV pip install
42:53 something, but then I forget and I pip install something else.
42:58 Does it break?
42:59 Is it okay?
42:59 As in the third time there's no UV?
43:02 Well, yeah, exactly.
43:03 Like, so I'm in UV pip install, something UV pip install that.
43:07 And I was, oh, I forgot this thing.
43:08 It was pip install.
43:09 Oh, I forgot the UV.
43:11 To this day.
43:11 No, it shouldn't.
43:13 It shouldn't break.
43:13 Assuming.
43:14 So let's say you activate the virtual environment.
43:16 Yeah.
43:16 Yeah.
43:16 It's already activated.
43:17 Okay, cool.
43:18 So you do UV VM, you activate the virtual environment, you do UV pip install flask, and then you
43:22 do pip install black or whatever.
43:24 Yeah.
43:24 Something, yeah.
43:25 That should work just fine because like the thing that we ultimately create in the virtual
43:30 environment, like that's all based on standards.
43:33 So like the stuff that we do in the virtual environment to install packages, it should look
43:38 like roughly indistinguishable from what pip would do.
43:41 And it's totally interoperable with pip.
43:43 So like similarly, if you did pip install and then like pip install flask and then UV pip
43:48 uninstall flask, like that would work correctly.
43:51 Like pip would install flask and we would remove it because everything that pip and UV are doing
43:55 in the virtual environment is based on standards.
43:58 So the way that we add and remove packages, all that kind of stuff, it should be totally interoperable
44:03 with other tools.
44:03 Okay, cool.
44:04 PyPI is pretty good at having analytics around what packages are being downloaded, what's popular,
44:11 what platforms.
44:12 Do you do anything like send a user agent or something so that people could answer the
44:18 question?
44:18 Or how many people are using straight pip and how many people are using UV in a year?
44:23 Yeah, we sent, we set a UV user agent and it's right now it's just UV in the UV version.
44:29 There's an open issue in the repo from Pradyan who works on pip that outlines all this stuff
44:37 that pip includes in its own user agent, which we want to add, which is pretty interesting.
44:43 I actually didn't know this.
44:44 So pip in its user agent includes a lot of things about the current Python platform.
44:49 Data that they use in PyPI basically to inform decisions.
44:56 Like, oh, no one's using Python.
44:58 Right.
44:58 This is just, I don't think this is actually how it's used, but just as an example.
45:01 Oh, no one's using Python 3.7 anymore.
45:03 Let's lower priority on that because no one's installing Python with Python 3.7.
45:08 And so we want to add, we don't have that right now.
45:11 We're planning to add it.
45:13 But yeah, it will be interesting to see.
45:16 We can get statistics over time too on like UV and pip and how common they are in different
45:21 dimensions.
45:21 Yeah.
45:22 You know, one thing that would be kind of fun to have is, I'm not sure if it's at all
45:26 interesting to you, but to have some kind of cron job or background thing, even if you
45:33 just interact with UV, if it kind of kicked off sort of a background process that did its
45:37 thing, but, you know, take the history of maybe the top 500 packages plus the ones you've
45:43 used and just kind of keep a cache up to date on your system.
45:46 So if you're on an airplane or you're in a coffee shop or for some reason, the internet's
45:51 not great.
45:51 Like it's kind of pre-filled the cache and everything's there.
45:55 Yeah.
45:55 And that kind of, that might be fun.
45:58 Yeah.
45:59 We do have a dash track offline flag, which will like, it forbids network requests, obviously,
46:05 but it, so like it'll, it'll try and do the full install without accessing the network.
46:09 Yeah.
46:10 That's cool.
46:10 It would be cool to pre-fill the cache.
46:12 Yeah.
46:12 But it's just like, you know, if you're a UV user and you sit down on your computer and
46:16 for some reason the internet's out, I'm at a conference, I'm doing a talk and it's got
46:19 the dreaded, terrible conference wifi.
46:21 It's not the end of your demo.
46:22 It's just like, yeah, see how fast this is?
46:24 It's amazing.
46:24 Yeah.
46:25 Yeah.
46:26 Yeah.
46:26 Yeah.
46:26 It was actually, it's actually funny because like the benchmarking, like when we do benchmarks,
46:30 benchmarks can just vary so dramatically based on like internet connectivity, right?
46:36 Like that's often, that is often the bottle.
46:38 I mean, it's not, it's clearly not always the bottleneck because we're able to be faster
46:43 than other tools.
46:43 So like if it was always the bottleneck, I don't think that wouldn't really be true, but, but,
46:48 but it matters a lot.
46:49 Yeah.
46:49 And so sometimes I'll throw on, on macOS, they have a tool called network link conditioner.
46:54 So you can actually force.
46:56 Like drag your network down.
46:57 Yeah.
46:58 You can force it down.
46:59 And the categories are like, it's not literally called like bad mobile phone or something,
47:04 but it's, that's like basically what it is.
47:06 Yeah.
47:06 It's like, it's like, it's like very lossy edge network.
47:09 Like those are like the pre-built category.
47:11 It's pretty funny, but like it is actually, that's a very helpful thing for benchmarking.
47:14 Yeah.
47:15 And sometimes actually, if you have a really good network connection, sometimes it's actually helpful
47:18 to, to set that anyway, to a pretty good level, because then at least it'll be like very consistent
47:25 across your executions.
47:27 Anyway, it's something I've learned over time.
47:28 Yeah.
47:29 That is super interesting.
47:31 So one of the things I think it's interesting to consider here is obviously this is way faster.
47:36 I saw some of the announcements and some of the discussion around the announcements and the
47:43 people were really surprised how fast this is.
47:45 And I think, I don't think Rust is the full answer.
47:48 I mean, you tell me if I'm wrong, but like one part, obviously making the code run ultra
47:52 fast, that is an important part of it.
47:55 But it also seems like you all have rethought some of the internal algorithms and some of
48:00 the caching and some of the ways things work, maybe with a fresh take on it, or you're not
48:04 constrained by the way it's been done for many, many years.
48:07 So what elements are at play to make it as fast as it is?
48:11 Is it just Rust or is it something else?
48:13 So Rust is important, but the way I typically talk about frame it is that Rust is kind of like an
48:20 enabler to writing really fast programs.
48:23 It forces you to slash lets you care about certain things that matter a lot for performance that like
48:32 in Python, there's actually just no way to care about them.
48:37 I'm talking specifically here about memory allocation.
48:39 Like in Python, that all just kind of happens.
48:42 In Rust, you're forced to think about, am I going to allocate memory here or not?
48:46 And like, when is it going to be deallocated and all that kind of stuff?
48:48 And so that unlocks the ability to care and like be really careful in how you manage it.
48:54 And so Rust is like a really important, Rust is an important part of the success story here.
48:58 But I think it's like really, I think it would be really like very incorrect to say that it's
49:05 like all about Rust and it's not a Rust versus Python thing.
49:08 Right.
49:09 Like if we could just recompile pip with.
49:11 Yeah.
49:13 So if you took.
49:14 If you took.
49:14 Cython or something.
49:15 Boom.
49:15 It would just be.
49:16 No, it wouldn't be as big of a deal.
49:18 Right.
49:19 If you took pip and just like rewrote it line by line as close as you could in Rust, like
49:24 it would probably be faster than pip, but it would not be nearly as fast as UV.
49:28 Like we just do a lot of things differently.
49:30 And part of like, I guess evidence for this too, is like throughout the development of UV,
49:35 there were like multiple pull requests that sped up like UV as a whole by like 30 to 50%.
49:41 So what does that say?
49:42 That says that like, there's lots of different, those were all Rust programs.
49:45 Right.
49:46 So like we were able to write the same Rust program many times, optimizing it more and
49:51 more and more.
49:51 Right.
49:52 Right.
49:52 And so there's like so much engineering that went into making it fast.
49:57 Some of it's like how the cache is designed.
49:58 That was like a really important piece.
50:00 And that's actually something that like pip could also do.
50:04 And I think like it's possible a good outcome here actually is that like pip is able to take
50:10 some of these changes and incorporate them over time.
50:13 And we are kind of the guinea pig for that.
50:17 Like we're going to kind of change user expectations a little bit about how the cache is set up.
50:21 Like we're going to run into bugs about platform compatibility.
50:26 Like we're going to run into bugs based on this cache design.
50:28 Right.
50:29 And like hopefully that could at some point help inform pip if they choose to redesign their
50:33 cache this way.
50:34 The cache design is really big thing.
50:35 And then just a lot of like profiling the program, figuring out what the bottleneck is, and then
50:42 like solving the bottleneck and just like really intense engineering work that was not me, but
50:47 was like other people on the team to optimize some of that.
50:49 Like a good example is it's like it sounds silly, but like we found that a bottleneck when
50:55 all the data is cached and you're trying to do a resolution.
50:57 So there's no network requests.
50:59 Everything's local.
51:00 One of the bottlenecks that we kept running into was parsing and comparing versions, version
51:06 specifiers.
51:07 So like in Python, when you have a requirements file, you have like FastAPI is greater than
51:13 version one or whatever.
51:14 And then in the FastAPI file, you have like FastAPI version 1.0.0, blah, blah, blah.
51:19 So like those, like parsing those, and then we were comparing those.
51:24 We were doing comparisons between version markers like so many times.
51:30 Because it was just a constant thing in dependency resolution.
51:32 It's like, can I use this dependency?
51:34 Well, does it fit to this range?
51:35 So Andrew Gallant from our team, like rewrote that parser and the version comparison specifier.
51:44 And it's like, it's like one of the most incredible pull requests I've ever seen.
51:47 Like it's like so, like every, every commitment is like so interesting.
51:50 And he like optimized it so massively that it was like, he's basically representing the version
51:55 in the end by like, like a 64 bit, like a U64 integer and comparisons is just like compare
52:02 the two integers.
52:03 And like, there was just so much engineering that went into it.
52:05 And it sped up the cache case by like 30%.
52:07 And so there's a lot of, there's just a lot of engineering that went into it.
52:12 And, you know, again, it's harder for pip to do some of those things because they, the code
52:17 bases, they have a lot, they have, they have actual users to support, right?
52:22 Like we were able to do this before we launched publicly.
52:24 Like we could break things, like we can do things, you know, we can make massive changes
52:30 to the code base in short periods of time.
52:31 So, you know, we're in kind of a privileged position to be able to really optimize the
52:35 performance like that.
52:36 But, you know, it's a big part culturally of what we wanted to do too, is like, we're going
52:41 to make this thing extremely fast.
52:42 Yeah.
52:43 I'm seeing also interesting secondary effects, you know, talks and not, not, I think that's
52:49 talks, talking about using it, making it faster.
52:52 Just now here, Henry says build 1.1 is faster from looking at UV and the next version will
52:57 also add UV as an installer choice, which is pretty impressive.
53:00 Yeah.
53:01 That's been a really cool, that's actually something I didn't really anticipate, but I'm
53:05 really glad has happened, which is that there's a little bit of like, we ended up building
53:11 something pretty modular.
53:12 And so there's been a little bit of a, or a lot of like integrations with UV that people
53:17 have been building.
53:18 Like, like, Bernard had the, had the talks UV thing that was out like within a week, I
53:23 think, which was like use UV to power talks in different ways.
53:28 Yeah.
53:28 Yeah.
53:28 Knox, I think supports it bill pipe a slash build.
53:32 You know, I've talked, I've talked to the hatch maintainer, you know, like he's pretty interested
53:39 in making UV like an optional backend for hatch.
53:43 So like that's really cool to me because it's all just like magnifying the impact.
53:48 Yeah.
53:49 And again, I don't know how much of that I anticipated, but it's really cool to see that
53:55 like you could plug it into these other tools and they can just like go much faster.
53:58 Yeah.
53:58 So I don't know.
53:59 I mean, that's been like, that's actually been like a big highlight from the release, honestly,
54:04 has been the reception from like other maintainers of other tools who have been excited to integrate
54:08 it in different ways.
54:09 Cause it's just not, it just didn't happen.
54:11 Like rough wasn't nearly as much of a fit for that kind of thing.
54:15 Like there just aren't as nearly, there are some, but it's just not as natural to have like
54:19 integrations with rough in that way.
54:21 But for UV, it makes a lot of sense and it's been really cool to see.
54:24 Yeah.
54:24 It's more, UV is more of a building block than rough is rough fits in editors and CI and
54:29 stuff.
54:30 Yeah.
54:31 Okay.
54:31 Yeah.
54:31 And there were, there were other tools, but yeah, it was, it's, it's mostly an end user thing
54:36 and not a library, I think.
54:37 All right.
54:38 All right.
54:38 So a couple of interesting things out in the audience.
54:40 Let's, let's knock them out.
54:42 Okay.
54:42 So Tushar asks, and this is, I think a big tension that's building in the Python packaging space
54:49 is packaging tools use Python to do stuff.
54:53 What are the packaging tools control the Python?
54:56 Who, who is controlling whom here?
54:59 And so Tushar asks, will UV also install Python sometime soon?
55:02 Can I just express, Hey, I want to use 312 on this and these dependencies.
55:07 Yeah.
55:07 We almost, we almost certainly want to do this.
55:10 I don't think it will be, it won't be required.
55:13 Like you can still use your own Python, but we almost certainly want to add Python bootstrapping.
55:19 So like, that's another reason why the dream workflow is like you use the standalone UV installer,
55:25 because then it's like, it will actually install Python for you too.
55:29 And so like the reason, so then it's like, you don't have to have Python on your machine basically to start being productive with UV.
55:36 You can just bootstrap the environment for you.
55:38 And we can also do, you know, yeah, it would just be nice if you did, you know, pip compile, like UV pip compile, --Python 3.13 or something.
55:50 And then we just like bootstrapped Python 3.13 and did the resolution on your machine.
55:53 Like that's, that's kind of the workflow that we're trying to build towards.
55:56 Yeah.
55:56 Since you're so UV centric as well, it could be UV, V and V, you know, dash that version.
56:02 Yeah.
56:02 A hundred percent.
56:03 And then we bootstrap it.
56:04 Yeah.
56:05 If you don't have, if you've got a cache, you just give it.
56:07 And if you don't, then you, you get it on the machine.
56:09 Exactly.
56:09 Yeah.
56:10 Yeah.
56:11 So we'll definitely, we'll definitely do this.
56:12 again, I do think it's important that it's not like required to use like the UV pythons.
56:17 Yeah.
56:17 we actually kind of had to do like a minimal version of this for, for our CI and testing.
56:25 so, but it was a bash script.
56:28 And then I think it became a Python script, but eventually it would be like built into UV.
56:32 Yeah.
56:32 Yeah.
56:33 Yeah.
56:33 I think that would be really.
56:34 Yeah.
56:35 I think it'll be super, really quite awesome.
56:36 Yeah.
56:36 I think it will be too.
56:37 let's see.
56:39 Tushar also says loves that the --require V and V.
56:43 Yep.
56:43 As a thing.
56:44 he thinks it'll become the default and also points out for those who don't UV that
56:49 pip require virtual UV as an environment flag is in your RC files.
56:53 It's pretty nice.
56:54 I need to do that.
56:55 Yes.
56:55 The other day.
56:55 Yeah.
56:56 You can, you can.
56:56 Oh, I spelled that to the, to my, to the wrong spot.
57:00 Yeah.
57:00 So pip can be configured to require virtual ones.
57:03 Yes.
57:03 Yeah.
57:04 I do something weird.
57:05 I'm actually looking at my terminal behind our, our shared screen meeting here.
57:09 And my prompt says global V and V.
57:12 And so one of the things that I do is I have a, just, if I log it, if I open up my terminal,
57:16 it already has an activated virtual environment.
57:18 That's just for whatever.
57:19 Oh, interesting.
57:20 Just to avoid messing up your system Python.
57:22 Just to avoid messing up.
57:23 Or so I can have a, I can just make that virtual environment version of Python.
57:27 I want it to be, even if it's not the system one in general that I want to set, you know,
57:31 just like it's its own thing.
57:33 And so it wouldn't actually help me, but I still like that.
57:35 Cause that's smart.
57:36 Yeah.
57:37 That's smart.
57:37 Thanks.
57:38 Yeah.
57:39 I've learned a lot about like, oh my gosh.
57:41 I mean, I've learned a lot about packaging.
57:43 Like I didn't know like anything about packaging, you know, like six months ago.
57:47 I shouldn't, I should actually shouldn't admit that.
57:49 Cause it's really bad for my credibility, but like I've learned a lot about packaging.
57:53 And in the past, like two weeks, I've also learned a lot about like system pythons, like
58:00 how Python is installed and like how on like older versions of like Debian, like Python,
58:06 they do like a lot of customization to Python that makes it like really different from like
58:10 I learned like way more about this than I ever thought I would.
58:14 I think it's fine to say that.
58:16 I'm out on system pythons, but we do support them.
58:18 Yeah.
58:19 Awesome.
58:19 You know, someone asked me like, no, Michael, you must know all of the standard library.
58:24 I'm like, what are you crazy?
58:25 No.
58:25 Yeah.
58:26 Why don't I want to stop the standard library?
58:28 Yes, exactly.
58:29 And I think it's the same thing about packaging.
58:31 There's like so many edge cases.
58:32 If you never interact with an edge case and you don't care about that edge case, why would
58:36 you take the week or whatever to study it?
58:38 Like it's just, it's irrelevant to you until you need it.
58:40 And now you've dove in head first here.
58:44 So then you're in the deep end.
58:47 We spent so much time.
58:48 I shouldn't even bring this up, but we did.
58:51 Okay.
58:51 When we were, whatever.
58:53 I want to tell the whole story because I need to not, but like we did consider like lots
58:56 of different names for this tool and multiple times we considered a name and then it turned
59:01 out to be a standard library module that none of us had ever used.
59:05 Like we wanted to use wave W-A-V-E.
59:08 Okay.
59:09 But that's a standard library module.
59:10 Yeah.
59:10 Yeah.
59:11 I was like, oh, I had no idea.
59:12 Is that for working with a wave audio files?
59:14 Probably it is.
59:15 Yeah.
59:15 Like W-A-V files.
59:16 Yeah.
59:17 Yeah.
59:17 Interesting.
59:18 Yeah.
59:18 There's a bunch of stuff.
59:19 There's the whole dead batteries and removing certain things that like, you know, I know it's
59:23 like a library, but some of these things I had never seen.
59:27 Yeah.
59:28 Well, it's naming tools and packages is its own whole special deal.
59:33 And we have half a million packages in PyPI.
59:35 And so how are you going to not conflict with that?
59:38 Have an interesting name that's not for typo squatting.
59:42 Yeah.
59:42 Exactly.
59:42 Hard.
59:43 Yeah.
59:43 It's a hard problem.
59:44 Yeah.
59:44 I don't even get me started on the name stuff.
59:46 Someone actually donated this name to us, which is very kind of them.
59:49 Oh, that's actually very cool.
59:50 Very cool.
59:51 All right.
59:51 One other thing I do want to talk about here.
59:55 Padnish says, asks about, you know, is there a future where Rye, R-Y-E and UV go hand
01:00:01 in hand.
01:00:01 Also great work.
01:00:02 But maybe just talk a bit about Rye.
01:00:05 That was by Armin Roeniger.
01:00:06 And it kind of had a similar zen as UV, but really different.
01:00:10 Yeah.
01:00:11 So we, yeah.
01:00:12 So we're taking over like maintainership of Rye.
01:00:15 And we've just been like, I think I started talking to Armin like right after Rye got released,
01:00:23 which was PyCon last year.
01:00:25 I think it was during PyCon it got released.
01:00:27 And we talked like shortly after.
01:00:29 And we just found that like we were trying to do a lot of the, we were trying to solve a
01:00:33 lot of the same problems.
01:00:33 And we had like very similar vision for what we wanted packaging to be.
01:00:37 But like we were coming at it from very different angles.
01:00:40 Like Rye kind of came at it from, let's solve the Python bootstrapping problem.
01:00:44 So we're going to ship a Rust tool.
01:00:45 That seems like it's main focus.
01:00:46 Yeah.
01:00:46 Yeah, exactly.
01:00:47 And then internally it was actually using like pip-tools and pip to do installs and resolutions.
01:00:54 And then the thing that, I think the thing that Armin came to realize was like, if you want
01:00:58 to fulfill this whole vision, you kind of need to like reinvent a lot of those internals.
01:01:03 And meanwhile, like we were building UV, which was like basically those internals.
01:01:07 And I was like, we're going to put a lot of effort into like building this packaging stack.
01:01:13 And so we kind of found that like, it was just a really, we're trying to get to the same
01:01:17 place.
01:01:17 And we were putting in a lot of the engineering investment on building a lot of kind of building
01:01:22 blocks.
01:01:22 And we want UV to evolve into something that could like fully replace Rye.
01:01:28 So we want it to evolve in that direction.
01:01:30 And in the meantime, like we're going to keep maintaining Rye and kind of using it as like
01:01:36 a little bit of a test bed for like experimental things.
01:01:39 Like Armin added like pie test support to it, for example.
01:01:42 So we're like, we're kind of playing with like, you know, that's meant to be more of
01:01:45 an experimental test bed for like the future that we want to achieve.
01:01:49 And over time, we're going to kind of evolve UV up to the point that hopefully it can fully
01:01:52 replace it.
01:01:53 And then we can provide a clear migration path for it.
01:01:55 So we're going to keep maintaining it.
01:01:58 It is our intention for UV to like, to, you know, supplant it at some point in the future.
01:02:03 But it'll take us like time for it to get there and be able to do all the things.
01:02:07 But, but the visions were just so similar that it seemed like it made a lot of sense to
01:02:11 try and consolidate and kind of team up on it.
01:02:14 Yeah.
01:02:14 They do seem pretty similar.
01:02:16 And I can, I can see the direction that you're going in it.
01:02:19 It's going to make them more similar.
01:02:20 Yeah.
01:02:21 I know it'll take time.
01:02:22 And like, you know, this release of UV is like, it really is like the first release,
01:02:26 you know, it's like, like I kind of use some of this stuff as like pretty low level.
01:02:30 Like, like we want to build something that feels higher level and more, more automatic
01:02:34 in the future.
01:02:35 But this, these are kind of like the ability to install and uninstall and resolve packages.
01:02:40 These were like the fundamental things we needed and need for anything we were going to do.
01:02:44 And so this goal was really, let's take those and let's put them in a form that's like immediately
01:02:48 useful to people.
01:02:50 Yeah, for sure.
01:02:50 One more Rye question.
01:02:53 Then I have other questions.
01:02:54 So UV will replace Rye.
01:02:56 Do you recommend using Rye or UV or what's the, what's that side of the story, right?
01:03:01 Yeah.
01:03:01 Yeah.
01:03:02 Yeah.
01:03:02 It kind of depends on what you're doing.
01:03:04 So like, like Rye uses UV under the hood.
01:03:06 So like Rye uses UV for resolution and installation.
01:03:11 So if you're using Rye, you're using UV.
01:03:12 I, like I say, I consider UV to be like, especially if you're like a company or something, like I
01:03:19 would say UV is production ready for, for you.
01:03:22 Rye, you're buying into a little bit more of something that's a little bit more experimental.
01:03:28 Like I think Rye is a good fit for like professional projects, hobby projects, libraries, smaller
01:03:33 projects.
01:03:33 I don't know that I would like, you're just buying into more change, I think.
01:03:39 Yeah.
01:03:40 And so if you're already in a part of your monorepo, that's got a million lines of code
01:03:45 and a hundred people on it.
01:03:46 Yeah.
01:03:46 You can certainly, you can certainly try it, but you should know that you're buying into
01:03:49 something experimental is the way I'd put it.
01:03:51 Whereas UV, like you could also view UV as experimental if you want.
01:03:54 Like it's very new, right?
01:03:56 Like we've, we're like when we launched, we had, I mean, I think having issues is actually
01:03:59 good because it means people are using your project, but we had like hundreds of
01:04:02 issues.
01:04:03 And we closed and we closed, we've closed like hundreds and hundreds of issues since
01:04:07 we launched.
01:04:07 Yeah.
01:04:07 You guys have been super, yeah.
01:04:09 You've been super responsive on it.
01:04:10 Like we, you and I've had some exchanges there.
01:04:12 Yeah, we did.
01:04:13 And yeah.
01:04:14 Yeah.
01:04:14 That's some nice changes I saw going on, but like I said, almost every day.
01:04:19 It's getting like way better.
01:04:19 It's great.
01:04:20 Yeah.
01:04:20 And it's just getting way, way better.
01:04:22 Like that's the thing about developing in private is like, like we just, once we released
01:04:26 it, we finally, we actually had users who could use it and tell us all the things we missed,
01:04:30 also the things we didn't think about.
01:04:31 It's just like every week getting way better.
01:04:32 So like it's getting more and more stable.
01:04:34 And like, I would use it in production for my stuff for sure.
01:04:39 And I recommend it for production, but like Rye is just a little bit of a different story.
01:04:44 I think with Rye, you know, it's not like we're going to shut it down tomorrow or anything
01:04:48 like that.
01:04:48 Like it's going to be, it's going to continue to be supported for sure.
01:04:51 but you are, and I think it's branded this way, which is you are kind of buying into
01:04:57 a little bit of an experimental tool.
01:04:59 Yeah.
01:04:59 Also a bit of a workflow.
01:05:00 Yeah.
01:05:01 It's a very opinionated workflow.
01:05:02 Yeah.
01:05:03 Yeah.
01:05:03 Whereas UVs were designed to kind of slot into existing workflows.
01:05:07 Sure.
01:05:08 It's a little more foundational.
01:05:10 Speaking of which, I really like that, you know, so many of these tools have their own,
01:05:15 their complete own way.
01:05:17 Like, I know you're going to do that, but we're going to start up our shell and then
01:05:20 you're going to run these three commands and then we're going to have our own lock file
01:05:23 and we're going to have our own things.
01:05:24 And it's, it's amazing if you drink the Kool-Aid, if you go all in on the tool, but if you don't,
01:05:30 then it's like, ah, okay, well, what is this thing even doing?
01:05:33 It's more in my way than it's helping me, you know?
01:05:35 And so on.
01:05:35 So the fact that a lot of, a lot of this is kind of baking in the pip-tools way of there's
01:05:42 going to be this external tool that can manage some of your stuff for you, but it's not
01:05:46 prescribing a workflow.
01:05:48 A hundred percent props for that.
01:05:49 Love it.
01:05:50 Thanks.
01:05:50 Yeah.
01:05:51 I wanted, like, I wanted to build something that, again, I use the word like modular a
01:05:55 lot and I think it can mean different things, but like rough was kind of like this too.
01:05:58 Like in rough, you can use it as like just a linter or like just a formatter or both.
01:06:04 And like with UV, like you could use UV, like just to create virtual environments or just
01:06:08 to do dependency resolution, but use pip for your installer or something.
01:06:12 Like it's designed to be kind of flexible in how you choose to use it.
01:06:17 And I want to, I want to maintain that.
01:06:19 You know, I think, I think we'll start to introduce more opinionated workflows, but I think that
01:06:24 we'll continue to provide this kind of pick and choose model as well.
01:06:29 Yeah.
01:06:30 Yeah.
01:06:30 I think it's great.
01:06:31 It lines right up with the way I do things.
01:06:33 And also I really like it as both someone who might do presentations either at a conference
01:06:38 or in a course or teaching because you're not putting, you know, the whole virtual environment
01:06:43 stuff is already such a kind of a large barrier that comes a little early in people's learning
01:06:48 path, right?
01:06:49 They're like, I want to run Python.
01:06:50 I want to run this thing.
01:06:51 Whoa, you don't just install this.
01:06:53 You don't just use it.
01:06:54 We're going to talk about virtual environments.
01:06:56 Like I don't care about those.
01:06:57 I just want to run it.
01:06:58 Like, but you're going to need to install something.
01:06:59 So here we go.
01:07:00 We're adding more workflow and more specific ways of working there.
01:07:04 I think while trying to help a lot of times they end up just adding more friction at the
01:07:08 start.
01:07:09 Yeah.
01:07:09 Yeah.
01:07:10 And like, I guess my philosophy there is like, I want us to, I want us to like embrace virtual
01:07:16 environments.
01:07:16 Actually, Rai has this philosophy too, which is like Rai does use virtual environments and
01:07:20 like virtual environments actually have a lot of, there's a lot of benefits to embracing
01:07:24 them.
01:07:24 Like all the editors and such, they're all built around virtual, they all are all built around
01:07:28 virtual environment detection and stuff like that.
01:07:31 But I wanted to feel, I want to feel a little, honestly, like it has a really bad reputation,
01:07:36 but I wanted to feel more like node modules, you know, where it's like, it just kind of
01:07:40 works in your, it just kind of sits in your project and your project just does the right
01:07:43 thing.
01:07:43 and I know people make fun of node modules usually for being big.
01:07:47 but like, but that's the developer experience I want, which is you don't think, you don't
01:07:51 think of the virtual environment as this weird other thing.
01:07:53 It's just kind of like the project environment and it just kind of works.
01:07:56 And I think, I think you've got that by not like fielding people from it, but abstracting
01:08:01 some of it away for people that don't need to think about it.
01:08:04 Yeah.
01:08:04 There was a, there was an amazing, it's not a joke, but it's, I guess something that's
01:08:10 a prank that somebody, came up with here.
01:08:14 I'll put it on the screen.
01:08:15 It's called when everything becomes too much, the NPM package chaos of 2024.
01:08:20 And I was just, as you were talking about node modules, it's amazing.
01:08:26 So it's more of a statement of like, well, how super interdependent or how many combinatorial
01:08:33 or transitive dependencies does a couple of NPM things have?
01:08:37 Like, for example, I used tailwind, but there was maybe 50 things in my, my node module for
01:08:43 just using tailwind in my project.
01:08:45 Right.
01:08:45 So anyway, this one is some, this, an NPM username, Patrick JS launched a troll campaign
01:08:51 where a package called everything, it depended on every other NPM package.
01:08:55 So if you, you know, NPM install everything that literally tried to download the repository.
01:09:01 That's kind of, that's kind of amazing.
01:09:02 Wow.
01:09:03 I know it's, it's devious, but it's also kind of like, okay, that's, that's something else.
01:09:09 Yeah.
01:09:09 And Python independency trees tend to be much, like shorter, I guess, and like smaller, like you would tend to have way fewer dependencies.
01:09:17 Yeah.
01:09:18 they are sometimes like heavier, I guess.
01:09:21 Cause like in Python, it's very common to have lots of native code.
01:09:23 and like, I don't know, like PyTorch, like the PyTorch wheels that you download when
01:09:30 they're zipped are like between a hundred and 200 megabytes.
01:09:34 Wow.
01:09:34 Okay.
01:09:35 Yeah.
01:09:35 Yeah.
01:09:36 Like all the, all the ML stuff and all the native stuff, like those are like big, but,
01:09:40 but the dependent, but the number of dependencies tends to be a lot smaller.
01:09:42 Yeah.
01:09:43 I totally agree.
01:09:44 It's also very common to ship like foundational packages with like no dependencies or very few
01:09:49 dependencies, which is very hard to do in, in JavaScript.
01:09:52 Yeah, it is.
01:09:53 it definitely is.
01:09:55 All right.
01:09:55 I think we're getting short on time here.
01:09:56 I think I probably should let you go back and knock out another release of UV.
01:10:01 I do have to do a release today.
01:10:02 Okay.
01:10:02 Thank you.
01:10:03 Awesome.
01:10:03 Cool.
01:10:04 So Tony, the audience has been using UV in production for a couple of weeks now.
01:10:08 Awesome.
01:10:09 Seems very excited about it.
01:10:10 And also I have two.
01:10:12 It's an absolute delight.
01:10:14 It hasn't.
01:10:14 Oh, thank you so much.
01:10:16 Yeah.
01:10:16 I know there's certain things that it didn't do like right away, but then it, it came
01:10:21 out and you added them quickly.
01:10:23 I know there was some criticism for y'all for developing this in private and then releasing
01:10:28 it.
01:10:28 And I just want to say like, you know, thanks for doing that.
01:10:31 And what's the alternative?
01:10:32 You start with just a blank GitHub repo and people start to say, well, you should do this.
01:10:37 You should be doing that.
01:10:37 Like we have a vision.
01:10:38 Let us just like get it a little structure in place and then we'll open source it.
01:10:42 Like give us a month, you know?
01:10:44 Yeah.
01:10:45 I don't know.
01:10:45 I think it's, I think it's excellent work you're doing.
01:10:47 I appreciate it.
01:10:49 I appreciate it.
01:10:49 Yeah.
01:10:50 Yeah.
01:10:50 Yeah.
01:10:50 You know, like I said at the start, it was different.
01:10:52 It's different this time because anything we release, like, you know, you could work
01:10:58 on a rough for a month and nobody cares until it starts to catch some traction.
01:11:01 Right.
01:11:01 But this is the instant that it hits.
01:11:03 Yeah.
01:11:04 We knew people would at least, would at least look at it and at least try it.
01:11:07 And I think, you know, we wanted to make sure that whatever we released, first of all
01:11:10 was good.
01:11:11 And second of all, that we were ready to maintain it.
01:11:13 And then I think with packaging too, it's like, there's just a lot of, it's just such
01:11:18 a complex space that like, I wanted to make sure that we had a lot of clarity in the messaging
01:11:22 around what the tool is and what it's not and like what we want it to be and what it isn't
01:11:27 yet.
01:11:28 And so I'm really happy with how the launch went and I've really appreciated just all
01:11:32 the excitement, activity, engagement that we've had on the repo.
01:11:37 It's been like, I don't know.
01:11:39 I mean, honestly, it's been a lot of work, but it's like really, really, no, but it's awesome.
01:11:45 It's like so energizing for me and for the team.
01:11:48 And to see all the people picking it up and making it the foundation of their projects.
01:11:52 And yeah, it's really cool.
01:11:53 Yeah.
01:11:53 And it's cool.
01:11:54 You know, I guess another, like one other thing that's a little different this time is
01:11:57 like, I talk, I just talked to more people who work on Python tooling at companies now than
01:12:02 I did when I released Ruff, just because over the course of the past year, I've just met
01:12:07 a lot of people and we've just talked about how they're using Ruff, how they're not.
01:12:10 And so just hearing some of those stories too, of how like companies are starting to use
01:12:13 it and like what the blockers are and like how much of a speed of it's providing has been
01:12:17 pretty cool to see too.
01:12:18 So yeah, I appreciate, I appreciate it though.
01:12:20 Yeah, you're welcome.
01:12:21 All right.
01:12:21 We'll leave with this final thought from Juan.
01:12:23 I installed 94 libraries in around two seconds.
01:12:25 Incredible.
01:12:26 That's great.
01:12:26 All right.
01:12:26 Yeah.
01:12:27 All right.
01:12:29 Well, I'm excited to see where things go and, you know, we'll maybe do a follow-up when,
01:12:33 when you've got some more, more of the ideas in place.
01:12:36 Sounds great.
01:12:37 No, it's always, it's always a pleasure.
01:12:38 Thanks so much for having me on.
01:12:39 I really appreciate it.
01:12:40 Yeah.
01:12:41 Thanks, Charlie.
01:12:41 This has been another episode of Talk Python to Me.
01:12:45 Thank you to our sponsors.
01:12:47 Be sure to check out what they're offering.
01:12:48 It really helps support the show.
01:12:50 It's time to stop asking relational databases to do more than they were made for and simplify
01:12:56 complex data models with graphs.
01:12:58 Check out the sample FastAPI project and see what Neo4j, a native graph database, can do
01:13:05 for you.
01:13:05 Find out more at talkpython.fm/neo4j.
01:13:09 Want to level up your Python?
01:13:12 We have one of the largest catalogs of Python video courses over at Talk Python.
01:13:15 Our content ranges from true beginners to deeply advanced topics like memory and async.
01:13:21 And best of all, there's not a subscription in sight.
01:13:23 Check it out for yourself at training.talkpython.fm.
01:13:26 Be sure to subscribe to the show.
01:13:28 Open your favorite podcast app and search for Python.
01:13:31 We should be right at the top.
01:13:33 You can also find the iTunes feed at /itunes, the Google Play feed at /play,
01:13:38 and the direct RSS feed at /rss on talkpython.fm.
01:13:42 We're live streaming most of our recordings these days.
01:13:45 If you want to be part of the show and have your comments featured on the air, be sure to
01:13:49 subscribe to our YouTube channel at talkpython.fm/youtube.
01:13:53 This is your host, Michael Kennedy.
01:13:55 Thanks so much for listening.
01:13:56 I really appreciate it.
01:13:57 Now get out there and write some Python code.
01:13:59 I'll see you next time.