#383: Textinator and Building macOS Apps with Python Transcript
00:00 For all the amazing powers of Python. Deploying packaged apps that leverage native OS.
00:04 Level capabilities isn't really one of them, but it can be done.
00:09 We have a great guest, Rhett Turnbull, here to tell us how he built his Distributable Mac OS app, Textinator
00:15 that uses macOS native vision recognition framework through Python. This is talk Python to Me.
00:22 Episode 338 recorded September 25, 2022.
00:39 Welcome to talk Python to Me.
00:41 A weekly podcast on Python.
00:42 This is your host, Michael Kennedy. Follow me on Twitter where I'm @mkennedy, and keep up with the show and listen to past episodes at Talkpython.FM and follow the show on.
00:51 Twitter via @talkpython.
00:54 We've started streaming most of our episodes.
00:56 Live on YouTube, subscribe to our YouTube.
00:58 Channel over at Talkpython.fm/YouTube to get notified about upcoming shows and.
01:03 Be part of that episode.
01:05 Brett welcome to talk python to me.
01:07 Thanks, Michael. Glad to be here.
01:08 I'm glad to have you here. So many interesting things to cover on the show. I'm really excited. Let's start with the excitement, I guess, of saying we're both excited about Mac computers. It's about, I guess, one third split, maybe not quite that many for Mac developers in the Python space, but there's a lot of people who write code either on a Mac or for people who use a Mac, and it would be nice to make a little bit more of a native thing with Python. So we're going to talk about this really awesome app that you wrote. And here we are because of a tweet follow up for the Python Bytes show. You sent a really cool tweet, and I'm like, this is amazing. We have to talk about this. And so we're talking about building Mac apps with Python, like native apps that go into the dock, not just something that could run a script, but a thing you could get a regular user to believe as an app, and they would call it an app. And the other is, you also happen to work for the US. Space Force, which is very interesting. So we'll touch on that maybe a little bit at the end. There's some programming tie ins as well, right?
02:11 Yeah, definitely sounds good.
02:14 Well, again, happy to have you here. Before we get into that, though, let's start with your story. How do you get a programming Python?
02:21 I'm a hobbyist programmer, self taught, but I've been programming since I was eight years old. And roughly around 1981, my dad brought home a TRS 80 model three from Radio Shack. It was one of those all in one. It's a twelve inch black and white screen, built in keyboard, and it had a five and a quarter inch floppy, which was a pretty big deal for those.
02:41 That is a big deal.
02:42 I was going to ask, did it have a cassette player or did it have a floppy?
02:45 It did not. It had the floppy actually built into the consoles and all in one.
02:49 It must have been jealous.
02:51 Where's your cassette player now? Let me show you. It's this huge thing.
02:55 I don't remember how much it was, but the floppy disk held, but it was like 80K or something. It was a lot for back then. He had it for work, but I just was fascinated by it. I loved the idea that this machine can respond to what I tell it to do and do something completely different. And so I got into programming. He taught me a little bit of Basic. It came with Basic handy Basic install on there. I got into that a little bit. And then from there, I moved into Commodore 64 later and IBM PC, and then eventually found my way to the Mac. And I've been using the Mac for a long time. I found Python about four years ago. I've used a number of different languages through the years. Probably most of the work I've done was in Perl, a lot of Fortran in college. I'm an engineer by trade, and back then we used Fortran. In fact, that program Fortran on the backs back in the day.
03:47 Cool. What type of engineering?
03:49 Astronautical engineering. So everything dealing with space satellites, rockets.
03:54 Space engineering, it sounds like.
03:57 Yeah, that's a lot of fun. But we did a lot of Fortran. But I taught myself Perl along the way, and I used that for years. That was sort of my go to any time I need to get something done. And then I remember a few years ago, I read an article about Python. It was the up and coming thing. And so I thought, well, let me give this a try. So I started playing around with it, and I've done almost exclusively Python since then. It's been a lot of fun.
04:19 Oh, so once you found it, you're like, all right, this place, I feel comfortable in this place, in this language, and I want to do more and just stuck with it.
04:26 Yeah, it's an easy language to learn, right. But it grows with you, is what I found with Python.
04:33 You can obviously build industrial grade apps with Python, but it's really easy to start out, too. And I will say I actually first came across Python quite a few years ago, in the late 90s when I discovered Perl. And I'd come from a C and Fortran background, and I remember looking at this whole white space thing and thinking, there's no way that I can program with that. I need the curly braces, I need the semicolon. And now, to be fair, back then on a Windows PC programming, it was literally with notepad. There wasn't black, there weren't any formatters, any of that kind of stuff. Right. So white space was hard, actually getting it right. But once I got over that, I actually really liked the white space. Now I think it makes the code a lot easier to read and cleaner, and I really have enjoyed working with Python.
05:22 Yeah, the white space. I do feel like there's a certain number of people that just look at it and go, nope, next language.
05:28 What else might I learn today? Because that one is out, but it really is something that it seems like it's a big deal, and then you kind of work with it. You're like, oh, especially now. The tools are just auto inventing for you.
05:41 Oh, yeah.
05:41 It's just omnipresent. But you don't have to think about it so much if you're cool and you hit enter and like, oh, I'm indented already.
05:48 That's cool.
05:48 Just keep typing.
05:50 How about now? What are you doing these days? I mentioned something about the Space Force.
05:54 So I work for the Space Force. I'm actually an officer in the Space Force. I've been a career Air Force officer. I've been in the Air Force since 1995, is an astronautical engineer, and then last year had an opportunity to transfer from the Air Force into the Space Force. And being an astronomical engineer and a guy who's worked in space my whole career, that was a no brainer.
06:14 Yeah, it seems like exactly.
06:15 That's exactly where I should be. And so today I'm an officer in the Space Force, and my day job is I'm a chief engineer for an organization called Space Systems Command, which is part of the Space Force that develops and acquires all of our new satellite systems, rocket systems, ground systems, all of our networks and infrastructure, that kind of thing. So that's a lot of fun. I get to do a lot of fun engineering in my day job and get to do Python on the weekend.
06:42 Do you get to run any Python on any of the satellites? I know that some of the satellites are controlled with Python or API, not necessarily for the Space Force, but some of the scientific ones.
06:53 So none of the systems that I've used are using Python to actually directly interact with the satellite, but we are using Python in a number of different places. Some of the apps that we run to help process data or analyze display data to those kinds of things, the.
07:09 Data science dashboard thing that happens to data after it gets out of space. Yeah, exactly.
07:15 Well, that sounds like a super fun job. And I was talking to somebody get together just earlier this week. Everyone's kind of fascinating that I can have a job that is podcasting. They're like, okay, well, who are you interviewing this week? Well, I'm going to interview the guy who does cool Python stuff, and he works at the Space Force. And someone else like, oh, that's amazing. And then someone else is what's? The Space Force? So maybe for those of us who don't know, we know what the Air Force is.
07:42 The Space Force.
07:42 Yeah, sure. The Space Force is the newest of the military services. We were established just in December of 2019 and birthed out of the Air Force. And so the initial people that came over to Space Force came from the Air Force, although we've now brought in people from all the other services army, Marines, Navy to be part of Space Force, people who transfer just like I did. And the job of the Space Force is to organize, train and equip guardians, what we call people in the Space Force to do space operations for the nation. And so things like GPS for example, which I know everybody's familiar with, if you pull out your phone and use waves or a maps app or even do banking, which all relies on GPS, timing signals, those kinds of things.
08:28 We've used GPS and a corn maze recently.
08:31 Yeah, so all of that is coming from a signal from a satellite in space that is run by the Space Force. We do a lot of other things too weather, missile warning, communications, remote sensing, all sorts of different missions that the Space Force does. But we do all of the space systems that support the rest of the services communications, navigation, location, all those kinds of things.
08:55 It sounds fascinating and I suspect that many of these things were happening often under the Air Force banner or some other banner. Right, and now it's just more formalized. Right, exactly.
09:06 So the Air Force has been doing this mission for a long time. In fact, the Air Force originally designed and launched the GPS Constellation that is still operations today and is now run by the Space Force. But what we found was that space was becoming more and more important. Certainly everybody is familiar with what SpaceX and a lot of the other commercial space companies are doing a lot of really exciting things going on, but a lot more happening in space. The importance of space to our economy and our nation is increasing and quite frankly, the threat to all of that is increasing. A number of other countries have pay a lot of attention to what we're doing in space and they are actively working on ways to deny the US the ability to use some of those capabilities if they want to. We've seen some of that play out in things going on in Europe right now, in Ukraine for example. So because of the increased threat and the increase of importance of space to our economy and our nation, we decided that we really wanted a team that was focused only on space. And that's all we did because for the Air Force it was always an extra job in addition to everything else that they're doing. And so the only job Space Force has is doing space operations for the country. And so we have guardians, as I mentioned, focused on doing that job day in and day out.
10:24 Very cool. It strikes me that this is one of the areas of the defense and military industry that is the least hands on, the most you almost never get to interact with things in space directly, even with cameras, necessarily.
10:41 It's a little bit different than running over a hill or something.
10:44 Well, it is different. And first, I just want to add that I'm excited about Space Force and happy to talk about it, but anything I say is my opinion and not necessarily the opinion of the Space Force at the Department of Defense.
10:57 Absolutely. Thanks for saying that.
10:59 But I will tell you, you're right, Michael, that people that interact with the space domain as part of the Space Force, except for the very small number of astronauts we have that work with NASA, we largely do that through a computer screen. We do that through a piece of glass, a keyboard, and a network. And that makes the Space Force different than the other services, as you alluded to. But that also means that we really want a workforce that really understands that right. That understands the technical domain, that's really digitally fluent. Space Force is really focused on building digital service and having a digitally native workforce that really understands computers, understands coding, understands cloud infrastructure and those kinds of things, all the underlying technologies that we need to do our job. We're really focused on building a workforce that understands those things.
11:50 Yes, that's what I was hinting at. I feel like a lot of the coding skills are somewhat in the same realm as the kind of things that you all need to do. Probably a ton of custom software as well.
12:02 Yeah, definitely.
12:03 We use a lot of commercial software, but we also do a lot of our own custom software. We have a couple of software factories where we've got people from the Space Force guardians who actually write code for other guardians to use as part of their day job.
12:17 Well, if we have some extra time at the end, we'll come back to that. But let's switch over to our main topic, I guess, and let's start with the genesis of this idea. And you created this project called Textinator, and it's open source and Python, obviously, which is why we're talking about it. And I'll link to the GitHub repo and it says the about where it says simple Mac OS status bar menu bar app to automatically detect text and screenshots, which is pretty awesome. So it's one of those apps that are just an icon in the upper right by the clock, would be in the task bar little hidden down there if it was a Windows app. But it's a Mac app, so it lives up in the menu bar alone. And what does it do?
13:02 So it's really simple.
13:04 If textinator is running and you take a screenshot, it will search that screenshot for any text that it finds in the screenshot and copy that text to the clipboard. That's all it does. Super simple, but a useful thing if you've got text on the screen, like on a link on a video or something, and you can't copy and paste it. All you got to do is screenshot it and test it in a row, pick it up and stick it on your clipboard.
13:28 That's fantastic. Does it automatically capture? Is it just constantly looking for screenshots and then clipboard, doing text recognition and then clipboarding that? Or do you have to trigger it?
13:39 No, it'll do it all automatically. And what it's doing is it's using this Mac built in Spotlight feature behind the scenes and basically it sets up a query that's running in the background all the time and the query says, anytime there's a new screenshot, send me an alert. And then so when it gets an alert from the operating system that there's a new screenshot, then it does the processing and copies everything to the clipboard. Otherwise it's just sitting there waiting for an alert to pop up.
14:06 Yeah, fantastic. I said this show originated from a tweet. Just as a user, I talked about this app called Text Sniper, which I thought was pretty cool on the Mac App Store that lets you kind of screenshot an area of text and will capture it. It costs money and you got to get it at the App Store and so on. And you said in your tweet, that's a really cool idea. And it inspired me to create texting. I love the name as well and I just think it's fascinating. You're able to knock us out pretty quickly in Python.
14:39 Yeah, it's growing a little bit because I've tried to put a few bells and whistles on it, but the initial I knocked it out on Saturday afternoon. The initial capability, it was like 300 lines of code. It's fairly simple and it was fairly simple because I don't have to do all the hard work. I'm calling Mac Framework API, calls that are built into the Mac to do the do the hard work of hey, find a screenshot, detect the text with the text on the clipboard, those kinds of things. And so it was actually fairly easy to throw together. And then I'm using another Python package called ROPS that does all the heavy lifting of actually putting an app into the menu bar with an icon and all those kinds of things.
15:22 Rumps is fantastic. It has such a ridiculous name, but it's so easy to build MacBooks with.
15:29 Yeah, I've used it for quite a few different things. I've got a couple of apps running right now on my Mac that I use every day that I built out of Python and Rops. That's a really useful tool.
15:39 That's cool. I'm starting to think of more that maybe I should create, but I have one as well and maybe I'll talk about it a bit when we compare notes on yours. But yeah, super cool. This is so useful.
15:51 There's all these different times. I really just want that text. And in Mac OS, you hit Command Shift Four, and you can select just a region of the screen. You don't have to screenshot the whole screen, which you'd get, like, the menu bar and the navigation. You can just say, I want this section, and it will grab that and then turn it into text, which is just amazing. I've used it for watching a video course or some kind of presentation. I want that URL. They said, Go to the huge long URL, just select Snape, paste the text of the URL and go right?
16:27 Yes, exactly. It's so useful for those kinds of things. And I do want to add, this was inspired by you mentioning Text Sniper, I think, on the Python Bites podcast. Right. Tech Sniper is a great app.
16:39 It's only like $10, so you should definitely check it out. But when you mention that I had already been working with playing around with the Vision Framework, which is the Max ML powered computer vision framework for you, I've been playing around with that. And I knew that it was fairly easy to do this optical characteristic recognition and grab the text from a picture. So I thought, well, I bet you I can recreate that. And I did play around a little bit to try to be able to actually draw the crosshairs on the screen myself and let you do that in Python. That was actually kind of hard to do. But then it dawned on me, well, the Mac already comes with the ability to do that, the screenshot. Then I just had to figure out, okay, how do I grab that screenshot when it happens?
17:24 Right. You know, there was a screenshot, and then, how do you get the text right?
17:27 And it turns out that that's super easy to do. If you tell the Mac, tell me when there's a new screenshot, you set up a query that basically runs just like you would if you use Spotlight on the Mac and it runs in the background. Anytime there's some new thing that matches your query, it lets you know, and then it runs your code.
17:46 That's amazing how easy it was to knock out the Vision Framework and some of the ML tools. They're probably using the Neural engine that's built into the latest chips as well. They're probably taking advantage of that.
17:58 Yeah, I'm sure they are. I've got an older MacBook, and they run fine on there, too, but they're using the GPU on that. So they use whatever hardware you have. But I'm sure if you've got an M, one more, the newer Max that's using the Neural engine, and it's really surprising how accurate it is and how fast it is that. They've done a really good job with that.
18:19 As we look at this, we also see people talk about, well, Python is slow, so how could you use Python to do this thing.
18:27 I think that's always a funny statement to say python is slow because it's slow until it's as fast as C or as fast as it lives in this weird bimodal world.
18:37 It's like really slow all of a sudden, just as fast. Right.
18:42 I've never found Python to be slow, but I guess it depends what you're doing with it. I'm not doing really big, heavy data crunching, but just in this example, it's a Python app that's doing the text detection, but the text detection is not running in Python. That's running exactly Objective C or Swift or whatever native language that Apple wrote it in. And we're just calling that from Python. So the only slow part of that is actually setting up that call to translate between Python types and Objective C types and go back and forth.
19:13 There's a really great bridge for it called Py ObjC, which is short for Py.
19:19 Objectivec is one of the languages that has been around the Mac for a long time, that Apple has used a long time, though they're migrating a lot more to Swift now. But Py ObjC does all that sort of translation across the bridge between Python and Objective C for the most part. Don't really even really have to think about it.
19:37 Yeah, exactly. So what you did is you basically saw there was a screenshot and you say, send that information off to the Objective C platform layer, and it just goes natively and does its thing.
19:49 It's a pretty interesting bit of coordination. You've got Rumps coordinating, working with the menu bar API, and you've got these various low level OS platforms that you're talking to through Py Objective C. And yeah, we'll see how you built it up, but there's a lot of neat moving pieces there.
20:07 This portion of Talk Python to Me it's brought to you by Sentry. How would you like to remove a little stress from your life?
20:13 Do you worry that users may be.
20:15 Encountering errors, slowdowns, or crashes with your app right now? Would you even know it until they sent you that support email?
20:22 How much better would it be to.
20:24 Have the error or performance details immediately sent to you, including the call stack and values of local variables and the active user recorded in the report? With Sentry, this is not only possible, it's simple. In fact, we use Sentry on all the Talk Python web properties. We've actually fixed a bug triggered by a user and had the upgrade ready to roll out as we got the support email. And that was a great email to write back. Hey, we already saw your error and have already rolled out the fix. Imagine their surprise, surprise and delight your users. Create your Sentry account at Talk Python.FM/sentry. And if you sign up with the code, Talkpython all one word, it's good for two free months of Sentry's business plan, which will give you up to 20 times as many monthly events, as well as other features. Create better software, delight your users and support the podcast. Visit Talkpython.Fm/sentry and use the coupon code talk python.
21:22 Let's start with Python on the Mac, because I know you have some opinions on how to get started there.
21:28 Yeah, it's a good experience on the Mac, but it does take a little bit of finagling, I think, to get Python right. And the first thing you got to start with is, hey, which Python do I put on? How do I install it? And there's a number of different ways. There's a thing called home brew for the Mac, which is a package manager that installs apps and command line tools on the Mac. And that's great.
21:49 If any kind of command line tool you need in the terminal, homebrew can install it pretty fast. And so what I've seen is a lot of people are tempted just to install Python that way. Unfortunately, that can run into a number of different problems because home brew also uses that same Python to manage a lot of the other packages and things that it's installing. And so it might change that Python, update it, change something and you don't realize it. And then now all of your stuff stops working. So after a few false starts with that, I decided, just don't use the homebrew Python for the Mac. And what I recommend for most people is just download it from Python.org and you get the Mac installer, install it and run it. Because I developed a bunch of different open source packages and want to test them on different versions of Python, I build my own Python and I use PyEnv to manage that, and that way I can run a number of different versions of it. Anaconda is also another great one for the Mac, but you really need to understand sort of the ins and outs of which Python you picked and what it's good for.
22:49 Yeah, there's an article that you link to talking about this is Homebrew Python is not for you. We can do you as a developer. This is by Justin Mayor. It's interesting. Basically, fundamental problem he talks about is that Homebrew might change the underlying Python version even if you don't ask it to, because you might brew, install Glances or some other thing that needs Python, and then it goes, well, great, we got a good new Python for that. Right. And that could potentially break your virtual environments, which is not amazing anyway. People can check this out and see what they think about this.
23:26 Yeah, I recommend that you don't use home brew for developing. Right. Home brew is great for everything. I use it every day. But if you want to develop Python, get your own Python. That is only going to get updated if you decide to update it.
23:39 Yeah, that makes a lot of sense for me. I'm okay.
23:42 If my virtual environments change, I have a whole bunch of hotkeys and shortcuts and aliases that I can just recreate and reset up those things. So if something changed, I'll just drop into the terminal and throw it away and recreate it. But that's because I've been doing it for a long time. I know a lot of people, whether or not a virtual environment is active, where is Python, what is installed, all those things become very frustrating to people. So this could help potentially avoid those troubles. Out of curiosity, I did a Brew list, see what I got installed here. Probably got about 120 different things installed.
24:20 Like Rich in the audience, which says Brew is my go to.
24:24 I'm there with it as well. The article, by the way, mention this thing which I have not used Asdf, which is I know what to make of the name. It's just like I just hit left, fingers just go down right. But apparently this is about installing. You use this to install different tools and frameworks. Basically it's for CLI, for managing different run times of ruby and perl. And there's a plug in for Python.
24:55 Have you played with this? I have not. It looks really cool, but I've got my Mac to the point where it works and I just don't mess with it.
25:02 Mine is so janky, honestly, just as a sidebar, talking about this is, this is a Mac Mini M one, and I ordered it right when it came out, basically a week after, and so I got it right away. And many of the things that you would pip install, or certainly Brew install, it would say, well, we don't have that for your platform.
25:23 It took about a month before I could reliably pip install everything I needed, because the wheel didn't exist for the Arm 64 or whatever. And so I've got the intel version of Brew put on here, and then I've got the C++ tools for Apple silicon. And so when I try to do certain things that drop down to the compiler, like PyEnv, which I've tried, I can't get it to work. There's some mismatch about the compiler flags on what platform it thinks it's on. I'm tempted to just reformat the whole computer now that everything is stabilized, but I'm waiting until October because if they ship a new, much better one, I might not even go through that process. But yes, I would love to use PyEnv. I haven't been able to get it to work. Maybe Asdf is the thing to do.
26:10 Yeah, maybe worth trying.
26:12 Certainly worth trying, I would say. Now that's great for creating and getting your Python. There one of the first things, I guess, that came to mind when I thought about what your app does. I'm like, oh, this is going to be really tricky because I can get, say, a little rumps app to run when you really. Get down to it. There's a lot of things about is it from assigned developer? What permissions does it request? Like, does it request the be a server or access your file system or look at the clipboard. All these different things can get a little bit tricky. You want to talk about this permissions a bit?
26:48 Yeah, sure. And that's a tricky thing for every back app, whether it's in Python or not. Right.
26:55 I guess it's a good thing and a bad thing there. From a user's perspective, Apple's done a really good job locking down the computer and privacy make sure that apps cannot access your data unless you explicitly allow them to access your data. From a developer's perspective, that means apps can't access your data unless you explicitly allow it. So you've got to keep that in mind as a developer that you've got to make sure that your app has the right permissions. And so there's a couple of different ways to do that. Every app bundle that ships on the Mac has info plist, a property list file that's basically just a dictionary of key values that tell the app various settings for the app. A couple of those things are permissions or entitlements that you need to request and say, hey, I want my app to be able to do this. For example, for Textinator, one of the things it does is request access to the desktop and it'll pop up and then you can grant access to the desktop.
27:51 Until then, it won't be able to.
27:52 See the desktop, presumably because the default behavior of taking a screenshot is to drop the file onto the desktop.
27:58 So exactly.
27:59 Go hunt for those files.
28:00 Yeah. In fact, when I first got the first version of Textinator working, it wasn't doing that properly and so I was taking screenshots and I never found them and because it just couldn't see the disk that the screenshots were happening. But the whole query system is smart enough to say, hey, you don't have permission to see the screenshots, so I'm not even going to tell you about them. So it was never even getting alerted that it was getting a screenshot, I'm sorry to get that sorted out. And then if you can change the default location of a screenshot and put it somewhere else. And if you do that, you actually have to go into the system settings, the privacy settings, and actually give textinator a full disk access so that they can see where those screenshots are if they're outside of your home directory.
28:43 Yeah, there's a screenshot application and if you run it, basically that's like your preferences a hotkey. But you can go and change your preferences for the screenshots.
28:52 Yeah, there's a property list setting, you can do it from the command line as well. But yeah, the screenshot app is the easiest way to do that.
28:59 Okay, so basically you go through the info plist and you just express, I need access to the disk, or do you try to get there and then Mac OS says, hey, this thing is trying to do it. Do you want to let it?
29:12 So what I did in Textinator, in the info plist you put in, what you actually put in there is the message that gets shown to the user when they actually try to access the desktop or whatever it is that you're trying to do.
29:24 And so what I have textinator do is when it first fires up, it tries to access the desktop to force that message to pop up so that you grant right away. Otherwise you'll never see the screenshots. So that's an easy way to just force the user. That way, as soon as they start, it already got their attention. It'll pop up a dialog box and say, hey, Textinator wants to access a desktop Allow, and then now it has access.
29:47 I'm always suspicious of apps that pop up these little enter your admin password for whatever reason, but they do it just out of the blue.
29:57 It's one thing, like if I launch new app and it says there's an update, do you want to update? You say yes and it'll pop up.
30:03 This is trying to update itself, but if it's running just behind the scenes, doesn't update or something, oh, we need your password. You're like, yeah, I don't know what's going on here. So I think anyway, the reason I bring this up is I think it's a good idea to like, as they're interacting with it, just get those out of the way straight away.
30:20 Yeah, exactly. Otherwise you're right. Well, textinator. If it pops up later on and you've forgotten all about it, it does definitely look suspicious.
30:30 I'm sure I should have gone and installed this if it's a timely one.
30:36 Okay. The other thing about installing apps is that they have to be signed. And you get this really scary when you try to open it, you'll get a really scary warning saying, hey, this is signed by an unknown developer. It will destroy your computer. Don't open right?
30:51 Kind of thing.
30:51 And you actually have to right click and say open, and then say, yes, I really want to open this thing. And you only have to do that once. But the first time you do it, it does give you kind of the scary warning. So you do need to know where is this code coming from that I'm going to try to run.
31:05 So you build it with the ultimate you built the app bundle with Py2app, right?
31:10 Yes, that's right.
31:11 I wonder if there's a way to sign if you have a developer account. If there's a way to sign?
31:16 Yeah, I think you could. I don't have an Apple developer account. That's something you have to pay for.
31:22 I just tinker around so I don't have it bothered with that. So it's mine is self signed. But yes, you can. Or you could do it after the fact. You could resign the app using the Apple signing tools, which you can run from the command line and then resign the app with your developer signature. And you could even do that and notarize it as well.
31:40 Then it would just run with no.
31:42 It would just run.
31:43 Because sometimes, depending on how you run it, it won't give you the option to run anyway. Like if it's in the little download section and you just pop up that little fan and you click it, sometimes it'll just go, this is from an item developer. We won't run it. But if you right click and say run it'll, say, oh, are you sure you want to run it?
31:59 So it can be annoying, it can be a bit of a roadblock.
32:06 That's something to keep in mind.
32:08 A lot of things that Python developers do sometimes I know I do. This is whip out a little tool to help a family member or a friend or something, right. So if you're going to send them something to run, you've got to make sure you walk them through. Okay. You've got a right click and then say Open, and then click Allow access to the desktop or whatever it is that you're trying to do.
32:27 Exactly. Or if you're building this app for your club or your kids football team or soccer team or whatever.
32:34 Then you're handing it off to people who don't necessarily know that it's trustworthy or how to make it go, but you kind of got to talk them through it. Probably if you have a developer account, it probably would be cool to do. I say that as somebody who has an Apple developer account and a Romps app, and it's not signed, so you should probably figure it out.
32:54 In theory, I think it would be cool. I'm intrigued on how I might go about doing that now.
32:58 Yeah, I don't think it's that hard. I think you can just run the signing tools and add your signature on there.
33:05 Well, it just has to be trusted from something that Apple trusts, right?
33:09 So let's talk about Py2app really quick.
33:12 To me, there's a bit of a danger that I might get into some ranty side tracks here on this show, but to me, I think it's really a big hole in Python capabilities, let's put it that way. There's not a way to say, press a button or run a command, and then I have a binary thing I give to people that from their perspective is an application with an icon that goes into their Start menu or their dock, that they click it and it comes out.
33:40 They even just run the command line and it does things right. The ability to send somebody an application that was created with Python is super lacking. If they're not a developer on the other end receiving it or not a server admin receiving it.
33:57 That's very true. I'll add one caveat to that, Michael. If it's a command line, tool. What I found is I've defaulted now just to use pipX. They brew install pip and then they can pip install and they're good to go and it's super easy. And it just works. And then inside the terminal. All your permissions are owned by the terminal. So once you've granted the terminal access to your desktop or your photos or whatever, any Python app you run will have access. No problem.
34:25 That's an absolutely good point.
34:26 But for a Gui app yeah, it's just way harder than it ought to be.
34:29 It is way harder not to be in. I would love to see something built into Python right now. It Seems like The Big Focus of So Many Of The people doing High End Work on Python is about Making it faster, do More, take more advantage of hardware. And I would not say sidetrack. That work. But once that's kind of done, the low hanging fruit is how do I get a shippable thing?
34:54 Because after that, you start to open up things like, well, if I could send out a binary, maybe I could send out a binary for iOS or Android.
35:01 And then all of a sudden, we have mobile and it unlocks so much.
35:07 Talk Python to me is partially supported by our training courses. Do you want to learn Python? But you can't bear to subscribe to yet another service and talk python training. We hate subscriptions, too.
35:18 That's why our course bundle gives you.
35:20 Full access to the entire library of courses for just one fair price.
35:24 That's Right.
35:25 With the Everything bundle, you save over 80% off the full price of our courses, and you own them all forever. That includes the courses published at the time of purchase, as well as courses released within about a year after the bundle.
35:38 Stop subscribing and start learning at Talkpython.Fm
35:45 Even that said, what we have now are a couple of programs and tools that will bundle up the Python runtime, and we're just going to scratch the surface. There's a bunch of attempts on this, like PyOxidizer, which we won't touch on. But if you're building a mac app, probably the way to go is Py2 app because it's specifically about making macOS apps.
36:05 Right? Yeah.
36:07 I've used Py installer for command line tools. It'll. Bundle up. Basically. It's a zip file with all your Python code in it. That unzips at runtime and runs. And then Py2app for GUI apps. There's another one called Beware, the Beware Project that's really trying to solve that problem of, hey, I want to be able to run on Android, iOS and Mac OS and Windows. I've tried it a couple of times. It looks really promising, but I keep running into problems and I go back to Py2 app because I know how to make it work.
36:37 Yeah, the briefcase project from them, I think is what it's called, is very interesting.
36:42 But I'm holding out hope that they'll be able to solve some of these things. They seem to be doing a lot of work on it. But Py2app will you run it and it will create basically an app bundle, which is how apps are distributed on your Mac. One thing you'll notice if you go to the text repo is that there's a setup.py. And on all my other projects, I've switched to Poetry and Py project Yaml.
37:05 But I have not figured out how to make Py2app work with that. So Py2app needs a setup.py, and so I use setup.py anytime I have to use Py2app.
37:15 Okay, how cool. I'm looking at your setup py on the Textinator.
37:21 You've got these options here, and one of the things it has is icons, the various icons which for your app, you actually need all these different sizes of icons, which is kind of a bit of a hassle. But then you give that file and it makes that the right it does the right thing with it. And then you also have a Plist which has things like Lsui element is True or NS names in the desktop folder usage description. That's what you're talking about, right?
37:49 Those things in the P list settings, there are the things that are going to go into that info.plist for the app and Py2App, stick them in there. The Lsui element basically says, I want to run headless without being in the dock. And so that's how the Rumps apps works. You'll get the little icon up in the status bar, but you won't see it in the dock. And then the desktop folder usage description. That's the little message that will pop up when texting it or tries to access the desktop the first time.
38:16 Right, okay. So this is one of the ways in which you configure the actual creation of the Mac side of things, not just the bundling of the python.
38:26 Exactly. So that stuff, those settings there will actually go into the app and Py2app, stick them in there.
38:31 Cool. I just want to give a quick shout out to this app here as well. I've had to create these icon sets for different apps, and there's this thing called the icon set Studio, and you just give it one icon and it will just not have very good reviews, but it worked well for me.
38:46 Okay, good.
38:49 But you basically give it one large icon and it'll create all the different variations and one of those icon files and stuff for you. So anyway, that's a pretty cool one. All right, so then you just give it a command line to build your application, right?
39:06 You run Py2app and it will create it'll take reading your Setup.py, read in all the files associated with your app and then bundle it up into the app file.
39:17 Yeah, it takes a little bit of time and then there's a build and a Disk folder. And miraculously it's really delightful, actually. In the Disk folder, I think it is there's whatever you call your application app. It has the icon. It looks like an app thing. You can drag it to your Applications folder, you can put it in the dock if it's that kind of app. For the Rumps one, I'm not sure it makes a lot of sense to actually put it in the dock. But it's as much an app as far as Mac OS is concerned as all the other ones, right, exactly.
39:48 It's a native app and it'll run and for something like textinator, I just put it in the Applications folder and then add it to the startup items or my login items, so that it just starts running when I log into the computer. One thing to keep in mind is you might be tempted. You get that first time you build that app in your dist folder. If you run that, at least for Textinator, it won't work because that version of the app won't have the permissions to see your desktop because I guess the privacy settings are going to look at hey, which app and which signature was signed? And it's going to look for hey, that version of it's got permission. That also means that if you upgrade Textinator, you may have to go back into your settings and give it permission again.
40:33 Okay, yeah, permissions are always tricky, but pretty cool. My experience is this has worked and it's been really nice. You can build app files and it's like those smart bundles, right? They're really folders, but they look like a single file. Yeah, it's a great way to handle I don't know if I agreed sufficiently enthusiastically with you, but Pipx is absolutely the way to hand out mainline tools these days. People can get Pip X by just reinstalling it, which brings in Python that Pipx needs. So that already is set. Then if you just type Pip X, like for example, Pip X install Pls, right, for example. That's a really nice one. It's LS replacement. I think I've talked about it before, but it's like sort of a developer focused LS type of experience and you can get like little icons for READMEs or license files or whatever. But if you want this, you could go through the way of setting up and running on Python, or you could just pipx install Pls or Glances or HTTPie http.
41:40 All of those things should just come in with Pipx. They get automatically upgraded if you ask for it. There's a lot of good stuff going on there, but if you need to hand out an executable thing for Mac people, this Py2app is really nice.
41:54 Yeah, it works great.
41:57 There's a few quirks to get it set up. Like, you have to use the setup PY, and you have to make sure you get the right things in that Plist dictionary, but once you figure those out, it's super easy.
42:08 It's also, I guess, worth pointing out. There's a Py2exe for doing this for Windows folks, right? Windows people are like, wow, the Python app doesn't do me any good, but there's a Py2exe, and maybe more broadly, there's Py Installer, and honestly, I don't have enough experience between Py2exe versus Py Installer, which also make Windows apps to say which you should choose. But Pyinstaller has been pretty solid too.
42:33 Yeah, I use Pyinstaller for a different project of mine. It's a command line tool, and it works great. I've got to build that one. I think that Pyinstaller doesn't sign it. The Py2App automatically signs it. So you have to sign it yourself whether you use an ad hoc signature or a developer signature. But you can do that. I just have a shell script that does that for me.
42:55 Okay, interesting. I've used Py installer for GUI. Have you checked out? Gooey G-O-O-E-Y-I have, yeah.
43:05 I don't know what to make of it. It's super interesting, and it lets you take any command line tool and turn it into well, as the name says, like a Gui, where it takes the command line arguments and turns them into Widget inputs. Like a file might be a browser for a new file, or yes or no might be a check on or off type of thing. What's your thoughts on gooey before we go off?
43:27 I think for simple CLI, it's a great tool.
43:30 I haven't used it, but I have played around with it a little bit, and it's definitely less scary, I guess, in the command line. For users that aren't really comfortable in the command line. I have one app, that command line app that I use, PyInstaller for, that is fairly complex. It's got over 150 command line options, and it's a beast. So something like that would not work. I actually tried it because I was just curious to see how it would work, and it just kind of blew.
43:56 Up, but it wasn't having it just.
44:00 Like, no, I'm not going to do this, and I need a lot of.
44:02 Tabs, please, for your simple command line apps. I think it's super useful because I'm sure a lot of listeners it'd be fantastic to build a little Python app that just does a thing that my coworkers need instead of some manual process that they do. But then soon as you start to say and then you open up terminal and you start to type there's just like, no.
44:24 If you give them a Gui, it's pretty nice.
44:26 So one thing I would love to see. And since we can't do an episode without mentioning Will McGugan is aTUI version of GUI that would just automatically create a two week interface for you from your command line app.
44:39 Now, you're right.
44:40 We can't do a show without mentioning him.
44:42 The textual stuff, it's coming along.
44:47 It's really impressive what he's been doing. So I have a couple of projects in mind that when I actually get to sit down and have time to learn textual a little bit, that I would love to play around with. Absolutely.
44:57 I think it would be you're right that that would be a pretty nice way to sort of a more terminal native way of going. We're going to build this UI for you, but here's how you get to it. But the one that you and I both use to create apps for real, and the one that you got to create Textinator with is Rumps, which stands for Ridiculously Uncomplicated Mac OS python status Bar Apps.
45:25 That's probably the most complicated thing about Rumps. Is that right? It's amazing to use. Tell people about rumps.
45:31 Yeah, it's super easy. Rumps does all the heavy lifting of creating the status bar app, which you can see if you're watching the video on the screen there. You get either your name of your app or an icon in the status bar. Then you can click on it and you get some menus.
45:47 And you can do that in ten lines of code with Rumps. It's just ridiculously easy.
45:53 The name is accurate.
45:54 It is ridiculously uncomplicated, as you point out. So they've got a Hello World type of thing that has four options on the menu bar. When you click on the thing in the menu bar, it drops down four options. And one of the things that it does is also post a toast notification, native Mac OS notification as well. And in order to make that happen, that really is like ten lines of Python.
46:20 It's super simple, so that notification code isn't really hard to do, but you'd have to set it up. You'd have to set up a notification handler and register it.
46:31 It's quite several steps to do that. And rumps does it. You just one line, Rumps notification, and boom, you can post a notification.
46:39 So the basic idea is you create a class. It derives from Rumpstart Apps app, and then you use a bunch of decorators, like, clicked to say when a menu item is selected. And then there's a few other calls you can do. You can say, Rumps Alert, and that pops out a notification.
46:58 You can say, I guess that doesn't pop out.
47:01 That's like a modal dialogue. You could say, Rumps Notification, and it pops out the toast, and then you just say, App run. And that's pretty much it.
47:08 Yeah. And you've got a full blown native Mac app written in Python that's up and running.
47:15 Yes. The one missing element, which we've already given people the key to is this is still just a PY file and if you try to give this to your friends or distribute on the internet, it's going to go very badly. Right. There's no App bundle, there's no app file package thing, there's no Python Runtime.
47:36 And so that's why you need Py2app as you take your Rumps app and then you Py2app it and then you have something to give out.
47:42 Right, exactly. And once they get that, they don't even need Python on their machine because it comes bundled with that. And so it's really nice. It actually Py2Apple, bundle up your Python and all the libraries packages you need in the app folder so that it got its own copy.
47:58 How do you make it auto start with system start. And I ask that as somebody who created a runs app, and it is clearly Auto starting, I just don't remember how I did it.
48:09 I don't know how to do it automatically. But if you go to your system settings and go to your login items, you can add it there. Right. So it's a couple of extra steps that you've got to do as a user and just say you click the plus next to your login items and it will pop up a file dialog and you can pick your app to run and it will run that when you log in.
48:29 Yeah, I'm pretty sure that that's what I did to get it to Auto Start. I was just wondering if there might be some other clever way, but probably not.
48:36 Yeah, I know it's possible for an app to do that because I have apps that you run them and it says, hey, do you want me to run a login?
48:44 And it does it. And so I just have not explored doing that myself because that's something I'm doing all the time. But there probably is a way whether you can do that from Python, if the permissions will work, I'm not really sure of it. It might be something worth looking into.
49:00 This Rumps project is super cool, but it feels like it's not quite super active these days.
49:08 Yeah, that is one downside. There's a fair amount of activity on the repo, but if you look at the issues, there's a number of issues that have been open a long time or PRS that haven't been merged in. And it doesn't run on Python 310, for example. So you'll need to install Python 39 or earlier to use it. So there are a few downsides to it, but it's a great app and I hope that it continues to get a little bit of love, because it really is super useful.
49:37 It really is useful. I totally agree. And I'm just thinking there could be like a startup set, some preferences right, where you just say, I would like to request to run at startup. If that's permission not already set, then just set it through whatever Objective C OS level thing you got to do. There's just little things like that that would be really nice.
49:58 The menu bar, the drop downs to be able to associate a hotkey with them. There's just a few things like dividers and menus. Right.
50:07 They seem like such low hanging fruit that I think this could get a big upgrade. It's pretty popular. It has 2.8 thousand stars but not a ton of traffic recently. And it'd be awesome if people either Jared KS, who originally created keeps going, or if they've lost interest, then someone else could pick it up and run with it. That'd be fun.
50:28 Yeah, definitely.
50:29 Oh, Richie in the audience says creating the plist to execute your script is just having it in tilde library launch agents. So maybe if you just copy script to start your app over to there, and it just launches.
50:42 Okay. Yeah, I'll look at that. You'll have to request access to the library folder as well, so I'll have to look into that. But I've done that before. The old fashioned way of actually creating a P list by hand and sticking it in there to get something to start. Thanks, Richie. I'll take a look at that.
51:01 Yeah, that's excellent advice. This is in your user profile, so maybe you don't have to ask, but maybe you do. All right, so Rumps is very important building block here for Texnator Py2app. Also super important, but the one that I created called URL Fi, and it just does a bunch of stuff like creates your own slugs and transforms text that might end up doing all that. That's my little app.
51:27 We've got the ability to build the app with Py2app. We've got a way to kind of create a shell that runs in the menu bar and constantly runs in the background.
51:37 As long as nobody closes the app.
51:39 It's just out of the way. So that's really fantastic. And now you need to start working with some of the OS level APIs like you talked about, hooking the event for the screenshot. And those are Objective C type things, right?
51:53 So for those, I use Py ObjC, Py Objective C, which is a bridge between Python and objective C.
52:02 It's an amazing package. If you're a Python programmer and you use a Mac, you really ought to get familiar with PyO bjC, because what that does is exposes everything that Apple's built in all the native capabilities, like vision and machine learning. The most recent update to Textinator, I added QR code detection. So if you screenshot QR code, it will tell you what the URL is.
52:25 Oh, wow.
52:28 Decode the QR code and stick it on your clipboard. But all that's built in to the Apple frameworks and PyobjC gives you access to all those fairly easily.
52:38 There's some quirks to it. Because Objective C itself is kind of a quirky language. And so you've got to do the translation between Python and Objective C. You'll see a lot of camel case that you don't normally see in Python, but once you figure those things out, it's super useful.
52:55 Yeah, there's no attempt to Python Five or make objective C low level run time supporting classes to make them pythonic.
53:07 Because when you have to go Google, what does this function do? Or what's this NS file handle and how do I use it? It's a lot easier if you can.
53:15 Just cut and paste.
53:16 Yeah, for sure. One of the things I'm looking at some of these examples, maybe there's some hints in here, but one of the things that's super odd to me about Objective C, it is one of those languages I'm like, I'm going to try to learn this. And after I'm like, no, it's too weird.
53:33 And how you have these named, these really oddly named methods and then variables, right? Like you can't just say string lower. You've got to get like I forget what the API is called, but there's like a weird set of incantations to sort of invoke a lower case type of behavior.
53:53 So how does that I see like in the example here, it looks like there's a string specifying maybe one of the arguments or something like file handle, read, completed colon is one of the strings last year.
54:07 What's the deal with that?
54:08 Yeah, I'm not super familiar with this notification Center API, but looking at what you have on the screen there, you've got the notification centre, addobserver underscore selector, underscore name underscore object underscore, which if you use my Objective C, you're going to see a lot of underscores like that, including the trailing underscore. And what that does is the way Objective C work. And let me caveat. I am not an objective c programmer. I tried a couple of times to learn and it just did not grocer. But I've gotten pretty good at interpreting Objective C through the Python lens so that I can use it in Python because I've got quite a few apps that Python apps that use Objective C calls. So Objective C has this concept of selectors which are basically sending messages to an object to call specific functions on that object.
54:56 I see.
54:57 And a method on an object could have different signatures. And so you might sometimes call it with a different value, a different value, a different number of parameters than you would a different time. And so the selectors handle doing that. And so what this is doing is each of those underscores is think of it as every time you see an underscore in a Py Objective C method call, you need to have a variable. You need to have an argument to that method call because it's passing that selector the value that you want for that particular selector. So that's why there's four underscores in this example you've got on the screen and four different values you're passing in arguments, you're passing in.
55:35 So if I say add observer, underscore selector, underscore name, underscore object, I've got to give it a selector, the name of the object and also itself.
55:43 And if you went and looked that up on the Apple docs, instead of underscores, you'd see colon. So you'd see add observer, colon, selector, name, colon, object. And so that's the decoder ring there. If you're trying to translate the Python is replace the colons with underscores and then add a trailing underscore. And then you got to figure out, okay, well, for that number of arguments, what are those arguments and what type do they need to be?
56:09 Very interesting. Okay, so it's weird, but it's kind of weird in the sense of just it's mirroring objective C, which is itself a bit of a unique language.
56:18 But that said, this is a cool library that gives you direct access to much of the operating system, right?
56:26 Yeah, exactly.
56:26 So Apple has built some really great frameworks, like the Vision that does the text detection for Textinator, which literally takes a few lines.
56:35 Tell us quick about the Vision one here, because this is one of the core building blocks used, right?
56:39 Exactly. Yeah.
56:40 So Vision does a number of different computer vision type tasks for you and really only takes a few lines. It does text detection, find barcodes or QR codes. It'll find faces in an image, detect different objects and images, those kinds of things. And it does it really well. It runs on the neural engine, as you said at the beginning of the show. So it's super fast. And you get access to that all from Python. If you use Objective C, you can directly access that power with just a handful of lines of code. And there are a number of Python packages for doing that. There's several different Python image to text packages out there, for example, but they're all fairly compute intensive. Or you've got to download these big models or whatever, and if you're on a Mac, you can just use them. What's already built into your Mac?
57:27 Yeah, absolutely.
57:29 For example, in texting, you just say Vision V and recognize text request with completion Android. Give us a call back.
57:40 There was an alloc, and it is something you got to do. And objectively, you've got to allocate your memory. And then there's a whole memory management piece of this you've got to keep in mind for the most part, PyObjC handles that for you. But every now and then I can bite you. If you have got a you're allocating a bunch of things and never dealocating them, you can have a memory like.
58:03 That back to memory management, something you.
58:06 Normally don't have to think about in Python.
58:08 And then maybe some of the other you've got the natural language ML APIs as well, right?
58:14 There's natural language processing built in.
58:16 All the things that the Mac does to do all those neat Mac things are, for the most part, available to the developer through these frameworks.
58:25 All right.
58:26 Very cool. Yeah, I guess that's probably it for the building blocks and stuff. Now that you've got this built, would you have done anything different or you're happy with the way it's coming together?
58:35 I think I was pretty happy with the way it came together. It works pretty good. The most current version will immediately ask for desktop access. Like, we were talking about that. I didn't do that in the first version.
58:48 I left it up to the user to go add that manually. But when I realized, hey, that the default location for screenshots is the desktop and 99% of people are going to have it there, just let's just ask right away for the desktop access and then it just works out the box. But yeah, again, it was a fun little project. The initial version took a weekend, and it's grown a little bit since then. But the whole thing is still only about 500 lines of code, and it's a fully functional, useful app that I use every day. And so it was really fun to be able to build that in Python.
59:19 There's something very satisfying about having your app do the thing.
59:24 Right. Yeah.
59:24 You can, of course, download everyone downloads apps from the App Store in various places, but to go but that's my code writing. My thing caught that text out of there, or whatever it is. Right, yeah, exactly.
59:35 Excellent. I hope this is an inspiration as well as a roadmap for people that want to build interesting things, maybe for themselves, but also for end users in Python on the Mac. Right.
59:48 Rumps, if you want a menu bar app, high objective C to get access to the framework and platform, high to app to build it in a way that you can hand it out.
59:58 Very cool. Yeah.
59:59 A few basic building blocks and you can put something pretty slick together fairly quickly.
01:00:05 Yeah, I totally agree. The little one that I built with Romps came together surprisingly well, and it does way less than what yours does. I'm really impressed with you. This is great.
01:00:15 I've got another romps one that I use every day. That all it does, is tell me when to plug in or unplug my laptop just to try to keep the battery percentage.
01:00:25 And it has an icon of a plug, and it changes color depending on whether I should plug in it's charging or discharging, and whether I should. And then it pops up an alert to say, plug in your laptop now. It's super simple, but really useful.
01:00:39 Absolutely. Keep it in the range, not always 100% charged, but don't let it go dead.
01:00:44 That's super simple. Those kinds of things are really easy to write with rumps and the various tools we talked about so definitely check that out. All right, well, I think we are out of time, but super cool work on Texanator and like I said, a great road map for people to follow if they want to build things like that. So, Rhett, before you get out of here, final two questions. If you're going to work on Texting it or other Python things, what editor are you using these days?
01:01:09 I use Vs code.
01:01:10 On Extensions plugins that you're fan of, obviously Python if you don't hate yourself or pieces on your own.
01:01:18 So I use GitHub Copilot.
01:01:21 Which I really enjoy is the solo hobbyist developer who only gets a few hours a week to write code.
01:01:28 It's kind of like having a peer programmer, and it's really helpful that knowledgeable.
01:01:32 Friend you're like, how do you connect SQL Alchemy to a database again?
01:01:35 Exactly. Yeah, it just does it for you. It's really useful. And the other one that I really like is Git Lens.
01:01:42 Yeah, git lens is cool.
01:01:45 It'll put the Git history right in.
01:01:50 Line with the code and you can see what changed. And when using that yesterday to try to debug a problem and try, when did I change this code? And that was really useful.
01:02:00 I was looking at the CPython source code with Vs code and I had Git Lens installed and I was going through some section this changed from 1994 from Guido.
01:02:14 That line was changed. I'm like, okay, this is like a bit of archaeology or some history going on here.
01:02:21 Yeah, that's neat.
01:02:22 Very neat. Okay, well, definitely a good choice there. And then notable PyPI package. I mean, Rumps is an obvious choice, but if you got something else that you want to throw out, go for it.
01:02:31 Yeah. I've got two for you. One we talked about Py ObjC. If you're a Mac developer or you're a Python developer who uses a Mac, definitely take the time to learn that because it'll give your Python superpowers. And then the other one, completely unrelated, that I really like is called Text X, and it's basically a parser generator for Python. Peg creates a parsing expression grammar for you out of its own little modeling language. But basically, if you find that you're writing more than two regions to parse some code, textX can might be able to help you out because it will build a parser for you out of its own sort of specification language that then gives you a Python class that parses your text for you. And I've used it in some other projects to actually create my own language to solve a specific domain problem. And it's super useful. It's fairly easy to create a fairly powerful parser.
01:03:27 When I hear I don't have to write regular expressions, that already makes me happy. Yeah, it's great. Their description here is, in a nutshell, text X will help you build a textual language in an easy way. You could invent your own language or build support for an already existing one. That sounds fantastic. Yeah, great recommendation. Alright, well, final call to action. Before we go, people are interested maybe in building apps, Mac apps with Python and a broad sense. What advice you got for it's?
01:03:56 A learn PyobjC play with Rumps and Py2app and go. There's a lot of great projects already out there on GitHub. Go look at the text native source code or search for some others.
01:04:08 For me, the easiest way to get started is always to look at what somebody else has done, then reading through a whole bunch of documents. So I'd say go find a project that peaks your interest and go build something for your Mac.
01:04:18 Yeah, absolutely. All right, well, it's been great to get a look inside what you're doing with this app and how you build it for a Mac, and also a bit of a peek inside the Space Force. So thanks for being here.
01:04:29 Thanks, Michael. It was a lot of fun.
01:04:30 You bet. Bye.
01:04:32 This has been another episode of Talk Python to me. Thank you to our sponsors. Be sure to check out what they're offering.
01:04:38 It really helps support the show.
01:04:40 Take some stress out of your life. Get notified immediately about errors and performance issues in your web or mobile applications with Sentry. Just visit Talkpython.Fm/sentry and get started for free. And be sure to use the promo code Talk Python all one word when.
01:04:57 You level up your Python.
01:04:58 We have one of the largest catalogs of Python video courses over at Talk Python. Our content ranges from true beginners to deeply advanced topics like memory and Async. And best of all, there's not a subscription in site. Check it out for yourself at training.talkpython FM. Be sure to subscribe to the show, open your favorite podcast app and search for Python.
01:05:17 We should be right at the top.
01:05:19 You can also find the itunes feed at /itunes, the Google Play feed at /Play, and the Direct RSS feed at /RSS on Talk Python FM.
01:05:29 We're live streaming most of our recordings these days. If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at Talk Python FM/YouTube. This is your host, Michael Kennedy. Thanks so much for listening.
01:05:42 I really appreciate it.
01:05:44 Get out there and write some Python code.