REST API Crash Course - Introduction + Full Python API Tutorial — Transcript
Full transcript
- 0:00Hey everyone, welcome to your REST API
- 0:02crash course. My name is Caleb. In this
- 0:04video, we're going to talk about
- 0:05everything you need to know to get
- 0:06started with REST APIs. We're going to
- 0:08first talk about the concepts, then
- 0:10we're going to talk about how to consume
- 0:12an API, and then we're going to build
- 0:13our very own API in Python. So, it's a
- 0:17lot of useless or it's a lot of useful
- 0:19information. So, if you need a reference
- 0:21of all this, I created a PDF that you
- 0:23guys can get for free with a link in the
- 0:25description. So go check that out if you
- 0:27just need to like, you know, look at the
- 0:28definitions and study or whatever. But
- 0:31anyways, we're going to jump in by first
- 0:33talking about what a REST API is, why
- 0:35you should care, and where this is used
- 0:38in software. And if you're watching this
- 0:40video and you're not really doing
- 0:41anything with software, not really sure
- 0:43why you're here, but you can probably
- 0:45move on to one of my other videos. So
- 0:48which all of my videos are about
- 0:49software. So anywh who, API stands for
- 0:52application programming interface.
- 0:56So, I tried talking and explaining this
- 0:59last time I recorded this and it just
- 1:01didn't go so well because I cannot talk
- 1:05and write very well at the same time.
- 1:08Application programming interface. It's
- 1:11basically a fancy way to say a way two
- 1:14pieces of software can communicate with
- 1:15one another. So, if we have this
- 1:18software over here, this is some really
- 1:21cool software system we built. And here
- 1:24is another one. And let's say these are
- 1:26built in different programming
- 1:28languages. That's where an API is going
- 1:30to come in and save the day. It allows
- 1:32different applications that aren't built
- 1:34exactly the same to communicate. So
- 1:37we'll say this one was built in
- 1:39Python and this one was built in
- 1:42JavaScript. Poor developer. I'm so
- 1:44sorry. Well, an API allows us to build
- 1:47functionality in this application to
- 1:50make a request to this other application
- 1:53and then this application can give a
- 1:56response back to this application. And
- 1:59that is where the API comes in. We're
- 2:02building this interface for these pieces
- 2:05of software to communicate with one
- 2:07another. Now, in general, it's a one-way
- 2:09thing. So this app is not going to
- 2:12request information from this app and
- 2:15get it back. Instead, it's always we
- 2:17have a a server and then a client. The
- 2:21client consumes information given from
- 2:24the server. So this is a very common
- 2:25setup you'll see in all of computing.
- 2:28The same way when you go to get a
- 2:30website, you know, you go to
- 2:32youtube.com, you're making a request and
- 2:35then that server gives back a response.
- 2:38It works exactly the same way with our
- 2:39REST API, although instead of getting
- 2:42HTML, you're going to get JSON.
- 2:46So, JSON is a language or a notation of
- 2:51describing information. It's just like
- 2:54text and it stands for JavaScript object
- 2:57notation. So, it's a way to notate what
- 3:00objects look like. But, it doesn't have
- 3:02to be done with JavaScript. It's
- 3:05actually supported in pretty much every
- 3:06language. And this is now the standard
- 3:09for APIs. You may run into APIs that use
- 3:14XML. However, this is kind of
- 3:17old-fashioned and probably not what you
- 3:19would want to use going forward. So, I
- 3:21would recommend even if you're more
- 3:22familiar with XML for some reason to
- 3:25learn JSON or JSON. You'll hear both.
- 3:28So, JSON's not complicated. Don't feel
- 3:30like you have to learn another
- 3:31programming language or something. It's
- 3:33just a series of key value pairs just
- 3:36like an object in JavaScript, hence the
- 3:39word JavaScript object notation or like
- 3:41a dictionary in Python where you have a
- 3:44key and then an associated value. So,
- 3:46it's pretty much just an associative
- 3:48array. We'll get into what JSON looks
- 3:51like and how to use it soon when we go
- 3:54build our own API, but don't worry too
- 3:57much about that. So JSON is basically
- 4:00the the language of communication and
- 4:03the API is you know what things we can
- 4:06communicate you know maybe you want to
- 4:08get a list of users or maybe you want to
- 4:11update some comments whatever you want
- 4:14to do that's all defined as API end
- 4:17points. So, you know, right here where
- 4:20we're making that request, that's an
- 4:23example of an end
- 4:26point. We're going to talk about the
- 4:28different types of endpoints that we can
- 4:30create. Now, what about this rest thing
- 4:33here? Well, that stands for um I think
- 4:36representational state transfer. I had
- 4:38to look that up a little bit ago because
- 4:40I was like represent what was it?
- 4:42Anyways, this is the means of
- 4:44communication. So, you know, I can talk
- 4:46to you in English, but how am I talking
- 4:49to you? Am I talking to you over the
- 4:51phone? Am I texting you? Am I talking to
- 4:54you face to face? Well, that is
- 4:57describing how we're communicating. And
- 5:00this REST aspect is communicating over
- 5:03the web or the
- 5:05internet. So, this is all going to be
- 5:08done by making requests similar to how
- 5:10you would request a website, but instead
- 5:13of HTML, you're requesting JSON. just as
- 5:15I mentioned earlier. So to make this a
- 5:17little bit more concrete, let's go over
- 5:18an example of an app I'm working on. So
- 5:21I have some software written in
- 5:24Python and this is the server software.
- 5:27You may also hear it as the backend
- 5:31software. And this is the software
- 5:33that's going to communicate with a
- 5:35database. That's where all of our
- 5:36information and data is going to be
- 5:38stored. So this talks to the
- 5:41database. Now, we want other pieces of
- 5:44software to be able to communicate to
- 5:46this back-end software, but we don't
- 5:48just want them to be able to access
- 5:49anything. We don't want to give direct
- 5:51access to this database. So, instead, we
- 5:54expose different API endpoints. So, an
- 5:58example of an API endpoint would be
- 6:01forward
- 6:01slash and this I haven't described what
- 6:05the actual app is for, but forward
- 6:07slashdrinks. Now, the actual app is to
- 6:11get a list of drinks and be able to rate
- 6:13these, you know, like zero to 10 or to
- 6:15put them in different categories of how
- 6:17good they are. And then you can
- 6:19basically keep track of all your
- 6:20favorite drinks. It's a little silly,
- 6:22but I thought it'd be a fun project. And
- 6:25um basically, I I like to drink I don't
- 6:28like to drink. I like to drink
- 6:29non-alcoholic beverages like LCroy or
- 6:33like stevia drinks and energy drinks or
- 6:36whatever, but there's so many of them I
- 6:37can't keep track of them all. So, I just
- 6:39wanted to build a little website to, you
- 6:41know, rank them, you know, and instead
- 6:43of just getting all of the drinks, you
- 6:45might want to get a specific drink. So,
- 6:48in this situation, we would pass in an
- 6:51ID. So, in this situation, we are
- 6:54getting data. And that's one of the
- 6:57different methods of APIs. We're going
- 6:58to talk about API methods here in a
- 7:00minute. But what this means is my
- 7:02software that I built over
- 7:04here. And in this situation, let's just
- 7:07say this is
- 7:08JavaScript. I can get all of the drinks
- 7:12or a specific drink from my backend
- 7:15software just by making a request to
- 7:18this web address. Now, you might be
- 7:20looking at this like, what? That doesn't
- 7:22look like a web address. Well, because
- 7:24this is a web server, this is going to
- 7:26have either an IP address or a domain
- 7:29name. So, let's say I put this up on a
- 7:31website, Caleb's favorite
- 7:34drinks.com, not a real website to the
- 7:36extent of my knowledge, and then forward
- 7:41slashdrinks forward slash and then you
- 7:43can pass in some ID such as five. Now,
- 7:46the actual structure for these URLs and
- 7:48what data you want to get that is
- 7:50totally up to you. However, there are
- 7:52some general standards and I will
- 7:54describe why I went with this coming up
- 7:57soon. But basically, we have the list of
- 8:00data we're trying to get from and then
- 8:01we pass in which specific element we
- 8:05want. And this will return JSON of all
- 8:08the information about that drink. Now,
- 8:10oftent times when you have a website,
- 8:13you're going to have web pages, you
- 8:15know, people can view on their web
- 8:16browser or you're going to have the API.
- 8:19And often these will be split out into
- 8:21two subset applications. So you might
- 8:24have calebs
- 8:31favoritedrinks.com/drinks5. Or another
- 8:33common thing is to have a different
- 8:35domain such as
- 8:39api.calebsfeddrinks.com. You don't have
- 8:41to. You can mix those together. However,
- 8:43just for organizational sake, often the
- 8:45API is in some separate section, either
- 8:48a subdirectory or a subdomain. Now, you
- 8:51might look at this setup, as I often do
- 8:53when I'm working on applications, and be
- 8:56like, why the complexity? Why do you
- 8:58need to have two applications and then
- 9:01the database? Why don't you just connect
- 9:03from this
- 9:04application all the way to the database,
- 9:07skipping all this junk? Well, obviously
- 9:10you can do that. You can do whatever you
- 9:12want but this is not always advisable
- 9:15for various reasons. The most biggest
- 9:18importantest reason of not going from
- 9:20the client application directly to the
- 9:23database is security specifically if you
- 9:27are using JavaScript. Now oftent times
- 9:30the client is going to be JavaScript
- 9:32because that's used for web pages.
- 9:34However, you could also make a console
- 9:35application or a mobile application. So,
- 9:38it's not always going to be JavaScript,
- 9:40but if you go to a website, you can go
- 9:43into the developer tools and you can see
- 9:46all of this JavaScript or you can
- 9:48rightclick and view source and it'll
- 9:50have the JavaScript files linked there
- 9:52and you can view all of that. So, you
- 9:54don't really want to put sensitive
- 9:58information on the client here because
- 10:00it's all viewable to the person using
- 10:03your software, which means they could
- 10:04then go to the database themselves
- 10:06directly, tinker around, you know, drop
- 10:09database, lol. We don't want them doing
- 10:12that. So instead, we just expose
- 10:15specific things that we want people to
- 10:17see, such as the list of drinks, but
- 10:20they can't go in there and see
- 10:22everybody's user information or people's
- 10:25address or any of that. Now, beyond
- 10:27security, the other big reason is
- 10:29versatility. So, right now, we have one
- 10:31front-end application in JavaScript, but
- 10:34with this setup, we could very easily
- 10:36build a mobile
- 10:38application, and yes, this is a cell
- 10:40phone. And we could also consume the
- 10:43same API. So what happens now is both of
- 10:47these front-end applications are sharing
- 10:50the same backend which means these are
- 10:53always going to have the same data.
- 10:55They're going to be
- 10:57synchronized. So that is how when you
- 10:59have applications on your phone, you can
- 11:02go in there and change data and then you
- 11:04can go log in on your computer and all
- 11:06of that stuff still exists. It's because
- 11:08they all share the same backend. So, you
- 11:11know, when you're messaging someone on
- 11:13social media, well, those messages are
- 11:15being sent to a back-end server that
- 11:18does all of the processing and all of
- 11:19the hard work of the application. And
- 11:22that website you're looking at is really
- 11:24just a pretty cover to this backend. So,
- 11:28you know, JavaScript, maybe your
- 11:30application here is in Swift, but
- 11:32ultimately we're hiding the back end of
- 11:35this application and separating those,
- 11:37which brings up the next good point,
- 11:39which is modularity. Because the front
- 11:42end and the back end are separated and
- 11:45we're just defining this consistent way
- 11:47to communicate, we can actually swap
- 11:49different things out and not necessarily
- 11:52break. I say necessarily because you
- 11:54know in practice it's it could be
- 11:56difficult but in theory you should be
- 11:58able to swap out different things
- 12:00without breaking other pieces of the
- 12:02application. So right now this is
- 12:04written in Python but I could be like eh
- 12:06I don't really feel like writing in
- 12:07Python you know and I decide to upgrade
- 12:10to something like Visual Basic and in
- 12:13this situation we can expose the same
- 12:16exact API endpoint. So, this website and
- 12:20this mobile phone app, they don't even
- 12:23need to know about those changes to the
- 12:26back end because they're still getting
- 12:28their list of drinks. That's all they
- 12:29care about. They just want their drinks.
- 12:32This is great because you can change the
- 12:33back end of software without requiring
- 12:36an update to the app or requiring a new
- 12:40deployment of the website as long as
- 12:43you're able to give a consistent
- 12:45interface to working with your backend.
- 12:47Last reason and then I promise I'll stop
- 12:50rambling. Okay, I got a little bit more
- 12:51rambling, but basically the last thing I
- 12:54wanted to share of why this setup is
- 12:56good is interoperability, which I think
- 12:58is a word. And basically what I'm saying
- 13:00here is that these front-end
- 13:02applications, they don't all have to be
- 13:05built by you or the front-end
- 13:08development team for your company. You
- 13:10can actually expose certain endpoints
- 13:12such as this one right here, and you
- 13:14could make this public.
- 13:17So if you make certain endpoints public,
- 13:20you don't have to worry about
- 13:21authentication or authorization. And in
- 13:24that situation, anybody could go ahead
- 13:26and create some new app, new and
- 13:29improved to consume your API. So you
- 13:33know, if I don't like the way Instagram
- 13:35looks, I can go create my very own
- 13:38Instagram viewer because they have an
- 13:41API that can be consumed. Now, sometimes
- 13:43you'll still need to get some kind of
- 13:45token or some way to authorize saying,
- 13:47"Hey, I'm okay to use this API." But a
- 13:50lot of the times these APIs are going to
- 13:52be publicly available. So, the API we're
- 13:55going to consume soon is just a public
- 13:57API that anybody can use and it's really
- 14:00cool honestly. So, many websites you
- 14:02might not even realize have APIs. So,
- 14:05for example, if you wanted to do
- 14:06something like create a trading bot or
- 14:09like a cryptocurrency trading bot, well,
- 14:11oftent times different exchanges are
- 14:14going to have APIs so you can automate
- 14:16different things in code. So, it's not
- 14:19always just about making a pretty
- 14:21interface, but it might be about
- 14:23automation. How can we connect these
- 14:24apps and make things happen
- 14:26automatically? So, if the thing's not
- 14:28public, it might be private, but you can
- 14:30still access it. You just need a way to
- 14:33verify that it's you and not just
- 14:35anybody's going on there and trading
- 14:38cryptocurrencies or spending your money.
- 14:40So there the authorization aspect of
- 14:43this is like a whole another beast. But
- 14:45a common thing you often see is OOTH 2.
- 14:47That is an authentication technique
- 14:49that's fairly common. So if you want to
- 14:51look into how to protect your API and
- 14:54make you basically have to log in, you
- 14:56can look into OOTH. That's o a u t
- 15:00h2. Now I want to take a moment to talk
- 15:02about the different methods of
- 15:04requesting data from the server. So
- 15:06we've talked about get and this one's
- 15:09pretty simple. It's what's used to
- 15:10retrieve data from the server. And these
- 15:13are often written in all uppercase
- 15:16letters. So you're just like screaming
- 15:19like get me this information. All right.
- 15:21So get is used to retrieve data.
- 15:26I could just say get data but fancy
- 15:29here. All right, so there's a few other
- 15:30ones you should know about and that is
- 15:34post. Post is used to write data. So
- 15:38anytime you want to write information to
- 15:40the server, you're going to use post.
- 15:42And then there is delete. Almost didn't
- 15:46use capitals there, but I fixed
- 15:48it. And this is used to, you know,
- 15:51delete stuff. Now there is another one
- 15:54that's pretty common. Why do I always
- 15:55write like this way? I don't know. And
- 15:58that is put. And this is actually fairly
- 16:01confusing if you're new. And the
- 16:04difference between post and put is
- 16:06pretty gray. And people will even argue
- 16:07about which you should use where. Here's
- 16:10my opinion. Post should be used to write
- 16:14new data. Put should be used to write
- 16:18but in this situation, we're going to
- 16:19update data.
- 16:22So now I want to show you how these
- 16:23things correlate to the most popular
- 16:25things you have to do with the database
- 16:27which is CRUD. So the different things
- 16:30you need to do, we need to be able to
- 16:32create data, post, read data, get,
- 16:36update data, put, and delete data,
- 16:39delete. Now, why exactly is there
- 16:42confusion between post and put? That's
- 16:44what I want to talk about now. Well,
- 16:46first let's talk about how post and put
- 16:48are generally used. Post is used to add
- 16:50a resource. Put is used to replace a
- 16:54resource. And that's why it's natural in
- 16:56my mind to say you can use put to update
- 16:59data and post to add new data. But
- 17:01replacing a resource requires some way
- 17:03to identify it. And often this is done
- 17:05with an ID. So my thoughts are if you're
- 17:09doing a post request, you want to add
- 17:11data. So you might have the
- 17:14address of drinks and you want to add a
- 17:17new drink. With put, you're probably
- 17:20going to need to identify what resource
- 17:22you want to replace. So it might look
- 17:24like drinks slash 6005 for an ID. Now,
- 17:30with the setup I tend to do, I usually
- 17:32don't have this ID value until that's
- 17:34that data is already inserted in the
- 17:36database with a post. So when you're
- 17:39adding new data, you don't know what
- 17:40that ID is going to be because that's
- 17:42auto incremented in the database. Then
- 17:44if you want to update that data, then
- 17:46you use the ID. But there's another
- 17:49difference and this is more defined in
- 17:51the spec of how an API is supposed to
- 17:53work and less about pure functionality
- 17:56because you're the one who defines the
- 17:58functionality. So if you want your API
- 18:00to work correctly then you need to make
- 18:02sure you implement it in this way and
- 18:05that is put is designed to give the same
- 18:09result every time if you make the same
- 18:12request. So for example if you're
- 18:15replacing this drink with a new drink
- 18:18you can replace this ID over and over
- 18:21again as long as that new one has the
- 18:24same exact ID. So, let's say you have a
- 18:26grape drink and you replace it with cola
- 18:31and then you replace cola again with
- 18:33cola and then cola again with cola. No
- 18:37matter how many times you do this, the
- 18:40same resource exists and it doesn't hurt
- 18:42if you accidentally put that request
- 18:44numerous times. Post is usually a little
- 18:46bit different because that feature or
- 18:48capability is not guaranteed. So, what
- 18:50that means is if you add a new drink,
- 18:53let's say you add cola
- 18:55and then you add cola again. Well, in
- 18:58this situation, you're not replacing
- 18:59anything. So each time you add cola,
- 19:02it's making a new record in that table.
- 19:04So put is guaranteed to be able to be
- 19:08executed numerous times without any kind
- 19:10of side effects. Post on the other hand
- 19:12is not guaranteed by the spec. And in
- 19:14that situation, you could actually have
- 19:16duplicate records in the database or you
- 19:19could get an error on that second one if
- 19:22the drink name is defined to be unique.
- 19:24Now, I'm probably going to mess this
- 19:25word up, but there's a word to describe
- 19:27this. Iden
- 19:28potent. It Yeah, I it potent. I don't
- 19:32know. So, put is said to be
- 19:35this. I'm not even going to try anymore.
- 19:37Just whatever that's called. Now, in
- 19:40general, I think there's a lot of
- 19:41confusion between post and put. And you
- 19:43can pretty much do the same behaviors
- 19:46with either one. So, I tend to just try
- 19:48to stick with post most of the time.
- 19:52Even if I'm updating a resource, it you
- 19:55can do it with post just the same. You
- 19:57can define it however you want. It's
- 19:58sort of how with modern HTML, you can
- 20:00make a section be a div or you can be a
- 20:03little bit more specific and say, "Oh,
- 20:05this is a footer." Both kind of give the
- 20:08same results. And if you're not using
- 20:09footer, right, then you might just make
- 20:11things worse. So, a lot of people still
- 20:13end up just using divs. So if you're
- 20:15using HTML, that's just maybe that kind
- 20:18of puts it in perspective. I don't know.
- 20:20There's another method, patch, which is
- 20:22used to replace different pieces of a
- 20:24resource. So maybe you just want to
- 20:25update one field. However, in our
- 20:28situation, the data we're working with
- 20:29is so small that it's pretty much just
- 20:32easier to replace it with a new version.
- 20:36So that way you don't have to keep track
- 20:37of individual changes. However, if
- 20:39you're working with very large data, you
- 20:41can definitely look into patch. So my
- 20:44theory is you basically keep the state
- 20:46of an object in the client side
- 20:49application and then once you save you
- 20:52just send that new state and replace the
- 20:53old state in the database. Hopefully
- 20:56that makes sense. All right. So let's
- 20:58get some practice with APIs by consuming
- 21:00an existing API. We're going to take a
- 21:02look at Stack Overflow. So all of the
- 21:06questions on here, you can get access to
- 21:08this information through an API. So we
- 21:11can build an application to work with
- 21:13Stack Overflow. So to do this, you
- 21:16actually go to
- 21:18api.stackchange.com and in here you can
- 21:20see the documentation for all of this.
- 21:23So here's the different API endpoints.
- 21:26So we can get the answers, badges,
- 21:29comments, posts, which is just a uh
- 21:32combination of questions and answers.
- 21:34And I'm going to take a look at the
- 21:35questions here. So we're going to get
- 21:37all of the questions. And here is an
- 21:39example of how you would invoke this. So
- 21:41you can hit run and you can see in this
- 21:44web address there's this question mark
- 21:46and then some variables with assigned
- 21:48values and then an and sign amperand and
- 21:52sort. These are known as query
- 21:54parameters and they can be used in this
- 21:56situation to modify the results of the
- 21:59API. Now, if you want to know how to
- 22:01actually invoke this without it running
- 22:03it in this little test window, you
- 22:05basically just take this address here
- 22:08and you would paste it after api.stack
- 22:11exchange.com
- 22:13uh like so. So, that's what it's going
- 22:15to look like. Hitting enter, you get a
- 22:18bunch of data here. Not exactly as
- 22:20pretty as this, which by the way, this
- 22:23is JSON format. So, it's just key value
- 22:25pairs. And in the pairs you can have
- 22:29arrays or uh you could consider them
- 22:31lists if you're more familiar with
- 22:32Python. So we have items right here
- 22:34which is a list of questions. Each
- 22:36question is surrounded by curly braces.
- 22:38So there's the opening curly brace and
- 22:40it has tags owner bunch of other stuff
- 22:43and then it ends. And then we have
- 22:44another question which has tags owner a
- 22:47bunch of other stuff and it just repeats
- 22:49in a list. So what we're going to do is
- 22:51we're going to work with this API. So, a
- 22:53tool I would recommend you get is called
- 22:56Postman. And in here, you can work with
- 22:59your APIs and it's just a little bit
- 23:01easier because you can customize the
- 23:03body and the different headers of your
- 23:05requests. And what we're going to do is
- 23:07we're just going to take this web
- 23:09address
- 23:11here and paste it on here. So, we're
- 23:14going to have httpapi.stackchange.com
- 23:17stack
- 23:19exchange.com and then forward
- 23:21slashquests and then all that other
- 23:23stuff. So hit send and we'll get a
- 23:25response sort of like this. So basically
- 23:28this is JSON here we have this items and
- 23:31then a list of the different questions.
- 23:34So let's go ahead and we'll come back to
- 23:37Postman later but for now let's take
- 23:38this URL and try to work with this in a
- 23:41Python script. So, if you need help
- 23:43setting up a Python environment, then
- 23:45you can check out my beginner Python
- 23:47programming all-in-one. However, I'm
- 23:50just going to assume you can at least
- 23:51get a Python environment set up. And
- 23:54we're in a Python file. What we're going
- 23:56to do is we're going to need a few
- 23:57tools. So, we're going to say import
- 24:00requests and import JSON. So, if this is
- 24:03your first time working with requests,
- 24:05you might need to install it. So what we
- 24:07can do is we can open a terminal and say
- 24:11pip 3 install requests. All right. So
- 24:14now we have requests installed and we
- 24:16should be able to make a request to a
- 24:19web page by saying
- 24:22requests.get and pasting in a web
- 24:24address inside of a string here. So
- 24:27let's just uh make sure this is nice and
- 24:29formatted properly like so. And that's
- 24:32going to return a response. So we can
- 24:34assign that to a response variable. And
- 24:37then what we'll do is we'll just print
- 24:38this response and see what we get. And
- 24:40you can see we get a response 200 which
- 24:43means okay. Now we can actually see the
- 24:46data that's returned by running.json as
- 24:49a method here. And that's going to give
- 24:51us all of the data exactly as we would
- 24:54if we requested it in the web browser or
- 24:56with Postman. So we got the items and
- 24:59then a list of all of the different
- 25:02questions. So we can basically zoom in
- 25:05on this and instead of just having one
- 25:08key value pair where we have items and
- 25:10then a giant list, we could actually
- 25:13explore items
- 25:15specifically by passing
- 25:17in items here. So we're going to index
- 25:21for items and then run this now. And we
- 25:25have just a list now. So we're no longer
- 25:28working with the items. we just have a
- 25:31list of
- 25:33questions. So then what we could do is
- 25:35we could iterate over these. So let's
- 25:38get rid of this print and we'll say for
- 25:43data in items. Or if you want to be more
- 25:46specific, you could say for question in
- 25:49items. This will be good for now. And
- 25:51then what we'll do is we'll just print
- 25:53data. And you can just print each one
- 25:54individually like so. Or you can be more
- 25:56specific and grab something like the
- 26:00title, which I know is an attribute of
- 26:02it. So running this and you can see here
- 26:04are all of the titles. So that's pretty
- 26:07cool. So basically that is
- 26:12right right here, the title. We're going
- 26:15to be grabbing each one of these. So
- 26:17every single item in this list. And you
- 26:20could also get something like the link
- 26:21if you wanted. So we can say print data
- 26:25link and now we got a series of question
- 26:28and answers and let's just print a space
- 26:30just to make it a little bit prettier.
- 26:32There we go. So here is the question and
- 26:36then here is the link which we can
- 26:38control-click to open. And there you go.
- 26:42So maybe you could build some kind of
- 26:44application to help you find good Stack
- 26:46Overflow questions to try to answer
- 26:49before anyone else does. So you can be a
- 26:52little bit more specific. You know, you
- 26:54could go in here and you could check to
- 26:56see the answer count. Answer count is
- 26:58like two for this one. So maybe maybe
- 27:02you only want to print the ones where
- 27:04the answer count is zero. So you could
- 27:07say if
- 27:09data and then ask for the answer
- 27:14count is zero, then we want to print the
- 27:18data. And just to show you guys that
- 27:20it's working, we'll say else print
- 27:24skipped. And also just print another
- 27:26space at the end. Actually, I'll just uh
- 27:28take that out of the loop. There we go.
- 27:31So this is our setup now. And we can run
- 27:33this. And you can see skipped. And then
- 27:36we got a question and then skipped and
- 27:37then a question, another question. And
- 27:40it seems to be working. So that's how
- 27:41you consume an API. Now I want to talk
- 27:43about how we can create our own API. So
- 27:46what I want to do is X out of this file
- 27:48here and we are in a folder API and open
- 27:53a terminal which I have one here and we
- 27:57can get the
- 27:58path. So just make sure you're in that
- 28:00directory and we're going to execute a
- 28:04sequence of commands in the terminal
- 28:05here. So the very first thing is we're
- 28:07going to create a virtual environment.
- 28:10So to do that you say python
- 28:133-m virtual environment venv and then
- 28:16give it a name such
- 28:18asveenv and that's going to create a new
- 28:22folder in here for your virtual
- 28:24directory which I talk about this in my
- 28:27uh previous video where we deployed a
- 28:29python web app but this is basically to
- 28:31isolate the dependencies for this
- 28:33specific application. Now what we can do
- 28:36is we can activate that by saying source
- 28:39and then traveling to it. So it's in the
- 28:42uh venv folder
- 28:46bin activate. So that is how you
- 28:48activate a virtual environment. Then we
- 28:51can install our dependencies. pip 3
- 28:53install flask and we're also going to
- 28:57install pip 3 install flask sql alchemy
- 29:03and that's going to be used to work with
- 29:06the database. So this is an example of
- 29:08an OM which I think is object relational
- 29:11mapper and we can output all of our
- 29:14dependencies in a file if we want. So we
- 29:16can say pip 3 freeze and put this in
- 29:20requirements.txt. So, anytime you uh add
- 29:23a new dependency, you'll want to do that
- 29:25just so all of our requirements are in
- 29:26this text file. So, uh whoever uses this
- 29:29project in the future can get the
- 29:31dependencies. Then we can just create
- 29:34our file. So, we'll say application. py
- 29:37and that's going to create this
- 29:40application. file, which is where we're
- 29:42going to do our coding. So, to start
- 29:45off, we'll just create a basic flask
- 29:47application. So we'll say from flask
- 29:51import flask and then we say app is
- 29:59flask_ame right there. So that's how we
- 30:01set up flask and what we can do now is
- 30:03we can make a simple route basically an
- 30:07endpoint by saying app.root and giving
- 30:10it a path and then we can define a
- 30:12method that we want hit when someone
- 30:15visits this route. So all we're going to
- 30:18do for right now is just return a string
- 30:20hello. All right. So let's just make
- 30:22sure this is working. So what we can do
- 30:24is run our application. To do this,
- 30:26we're going to create a few environment
- 30:29variables real quick. So flask
- 30:32app is application.
- 30:36py and the flask environment
- 30:42is development. And you're going to need
- 30:44to do that anytime you open up your
- 30:47terminal. So if you X out of your
- 30:49terminal and then reopen it, those are
- 30:51going to go away. So you'll need to do
- 30:53those again. And then you just say flask
- 30:55run. All right. So this is where our
- 30:57website's located. And we'll just open
- 31:01that. All right. Already made a stupid
- 31:03mistake. We don't put the colon here
- 31:05just after the uh method. So do a
- 31:08refresh. Now this needs to be uppercase.
- 31:11There we go. That should be everything.
- 31:12All right. All right, we got our app up
- 31:14and ready to go. So, the very first
- 31:16thing I want to do is make a get
- 31:18request. So, we're going to make an app
- 31:20to store drinks. So, we'll say app
- 31:23route. And the path for this is just
- 31:26going to be drinks and we'll say defaf
- 31:29get drinks and it's going to return
- 31:32something. We'll just say drinks for
- 31:34right now. But that's not a thing. So,
- 31:36what we need to do is we need to put
- 31:37some code here to make it a thing. If
- 31:40you want to just test it out for right
- 31:41now, what you could do is you could
- 31:42return a dictionary. And let's just say
- 31:46we got drinks and we'll just put drink
- 31:48data for right
- 31:49now. So we should be able to save that
- 31:52and it'll automatically refresh. And
- 31:54then when we refresh our page, well, we
- 31:56go to actually forward/drinks and we get
- 31:59some data back in JSON. So it's sort of
- 32:01working now. We just got to worry about
- 32:04connecting to a database. So to do this
- 32:07with the object relational mapper, we
- 32:09basically define all of the things we
- 32:11want to store in our database as models.
- 32:14So we're going to create a class. So we
- 32:17can do that up here. And all we're going
- 32:20to do is we're going to
- 32:21say class drink. And for SQL Alchemy, we
- 32:26just say DB domodel. So it's going to
- 32:28inherit from this. So it's already going
- 32:30to have various built-in
- 32:33functionalities. And that's how we can
- 32:35use it with SQL uh alchemy. So then we
- 32:39define the columns and we're going to
- 32:41put three of them in here. So we're
- 32:42going to have an ID and the way you
- 32:44create a column is by saying DB column
- 32:48and passing in any attributes of it. So
- 32:50it's going to be an
- 32:52integer and then we set it as the
- 32:55primary key by saying primary key is
- 32:58true. Next up we're going to have a name
- 33:01which is DB column. And this one is
- 33:04going to be a string. So to do that, you
- 33:06say db string and you can pass in a max
- 33:08length. We'll just say 80. And another
- 33:10attribute in here is unique true if you
- 33:13want the name to be unique. And you can
- 33:15also say nullable is false. So you can't
- 33:19have any nulls. And then the last one on
- 33:21here we're going to use is description.
- 33:24And we'll say dbc
- 33:26column. And this is going to be a string
- 33:28as well. And we'll just give this 120
- 33:31characters. However, I'm not going to
- 33:32put any other attributes on the
- 33:34description. Now, we want to override
- 33:36another method in here and that is
- 33:38called the rep re reper method repr for
- 33:42uh representation probably. And for this
- 33:45we we pass in self which refers to the
- 33:48object. So, we can grab the object's
- 33:50attributes by saying self dot something.
- 33:53So, we're just going to return a string
- 33:55and this will be invoked whenever we try
- 33:57to print out the the drink in the list.
- 34:00So you'll see what I mean here soon. So
- 34:02we'll say f to make a parameterized
- 34:05string and we can say
- 34:08self.name and then maybe you know a
- 34:10hyphen and then
- 34:13self.escription. All right, cool. So
- 34:15that is how we create a model. And what
- 34:17we're going to do is we're going to set
- 34:18up our database with a table for drinks.
- 34:22And to do that the easiest way is to use
- 34:24the Python terminal. So what I'm going
- 34:26to do is I'm going to quit our server.
- 34:28Crl + C and then I'm going to say Python
- 34:323. So that's going to open up the
- 34:34interactive mode in Python. And what you
- 34:36can do is you can say from application
- 34:39import DB. So what we do is we import
- 34:42our database from application import
- 34:44database. However, all we did is define
- 34:46the model. We need to actually make this
- 34:49connection to the database in our code
- 34:51first before we can reference it. So to
- 34:53do that, we're going to go up here and
- 34:55say from flasks SQL alchemy imports SQL
- 35:02alchemy. So all lowercase and then SQL
- 35:05is capital here. Then to get that DB
- 35:07variable, we just say DB is an instance
- 35:11of SQL Alchemy and we're going to pass
- 35:14in our Flask app. So that's the setup
- 35:16for SQL Alchemy. The last thing we have
- 35:18to do is we need to configure our
- 35:21database so we can connect to it. So we
- 35:23say
- 35:25app.config and we're going to pass in a
- 35:28string here. SQL
- 35:32alchemy
- 35:34database urri. And you don't have to
- 35:37have all of this stuff memorized. You
- 35:39can find this in the documentation for
- 35:42flask fairly uh simply. And then we're
- 35:44going to say
- 35:46SQLite and then three forward slashes
- 35:50data.
- 35:51DB. So that's how we say we're going to
- 35:54create an SQL light database called
- 35:56data. DB in the same directory. And then
- 35:59I think this DB variable actually will
- 36:02come after this config. So we'll paste
- 36:04that there. And there we go. So we
- 36:07should be able to X out of the Python
- 36:11interactive mode. Restart it. And now
- 36:14what we should be able to do is say from
- 36:16application which refers to our
- 36:18application because we named it
- 36:19application.
- 36:20py import
- 36:23db. Great. We didn't get any errors. We
- 36:26did get this warning here uh warning us
- 36:28about significant overhead and you can
- 36:30change some settings but you really
- 36:31don't have to worry about that. So to
- 36:32create our tables we say db.createall.
- 36:35create all hit enter and you can see it
- 36:39actually creates the database as well
- 36:41since we didn't have that. Now because
- 36:42this is what's known as an object
- 36:44relational mapper the way we work with
- 36:47our relational database is with objects.
- 36:50So if we want to create a new drink we
- 36:53create a drink object and we can assign
- 36:55it to a variable called drink. And the
- 36:58way we pass in data to create a drink is
- 37:01we do named parameters. So we can say
- 37:04name is grape soda and then a comma
- 37:08description
- 37:11uh I don't know tastes like grapes maybe
- 37:14seems pretty fitting. So that is how we
- 37:17create oh and you see when we do this
- 37:20name drink is not defined. So anytime we
- 37:23want to use something from our file we
- 37:26have to import it. So this class drink
- 37:28needs imported as well. So from
- 37:31application import drink and now we
- 37:34should be able to use the up arrow key
- 37:36to bring back our previous code. Hit
- 37:38enter. And now we have a drink object.
- 37:40And you can see it by typing in drink.
- 37:42And it says grape soda tastes like
- 37:44grapes. And that is where this repr
- 37:48method comes in. It basically the name
- 37:50hyphen in the description. Now to add it
- 37:52to our table, we say db session.add
- 37:56add drink and then
- 38:00db.ession.comit. And that's an important
- 38:02step. Yeah, we want
- 38:05DB.Comit, not
- 38:07doctor. So, db session
- 38:10commit. Now, we should be able to get
- 38:12all of our drinks by saying
- 38:17drink.query.all. Hit enter. And you can
- 38:19see it's a list now with just one
- 38:21element, grape soda. So if you wanted to
- 38:24add another drink, what we can do is
- 38:26just go through that process again. So
- 38:28we'll do this one in line. So we'll say
- 38:30db session add. And we'll create a
- 38:35drink. The name we'll call this one
- 38:38cherry. And we'll give it this
- 38:40description. And this cherry drink I
- 38:42drink tastes exactly like this cherry
- 38:44ice cream. So that I used to eat. So it
- 38:46tastes like that one ice cream. All
- 38:50right. Perfect. Hit enter. and then db
- 38:55session.comit. Now let's check
- 38:59drink.query.all. Hit enter. And now you
- 39:02can see we have multiple elements. We
- 39:03have grape soda and cherry. So then we
- 39:06can exit and go back to flask. Let's say
- 39:09flask run. So we got our server running.
- 39:12But now we need to create a way to get
- 39:15those drinks inside of this route right
- 39:18here. So, it's going to be pretty
- 39:20similar to what we did earlier. If I can
- 39:23scroll up just a little
- 39:26bit. We said
- 39:29drinks.query.all. So, let's go ahead and
- 39:31do that. In this code right here, we
- 39:33will say drinks is equal to
- 39:37drink
- 39:39query.all. And unfortunately, it's not
- 39:41something that we could just put right
- 39:44here by saying drinks. That'd be nice.
- 39:47Um, but I'll show you what happens. So,
- 39:50what we can do is if we refresh this
- 39:52page and it says object of type drink is
- 39:54not JSON serializable. Uh, I've worked
- 39:56around trying to figure out how to make
- 39:58this as easy as possible. Uh, I I really
- 40:01didn't come up with too many great
- 40:02ideas. Um, but here's basically what I
- 40:04decided. We're just going to build a
- 40:06list. Uh, so we're just going to
- 40:09basically write out what the JSON should
- 40:11look like. So, we're going to say output
- 40:12is just an empty list. From here, what
- 40:15we're going to do is we're going to
- 40:16iterate through the drinks. So, we'll
- 40:18say for drink in drinks and we're going
- 40:21to describe what it will look like
- 40:22inside of a dictionary. So, the end goal
- 40:24is to have a list of dictionaries. So,
- 40:27we'll just say drink data is a
- 40:29dictionary where name comes
- 40:33from
- 40:36drink.name and the
- 40:39description comes from drink.escription.
- 40:45like so. And then once we got that
- 40:47dictionary, all we have to do is say
- 40:51output.append and pass in drink data. So
- 40:54that's going to add that dictionary to
- 40:56this list right
- 40:57here. And it's going to do that twice.
- 41:00One for each drink that's currently in
- 41:01in the database. And then what it'll do
- 41:04is we'll just say
- 41:06drinks and pass in output instead. So
- 41:10now we have a nice list of dictionaries
- 41:13and that should be serializable. So what
- 41:16we can do is do a refresh over here and
- 41:19there we go. We have an outer object and
- 41:23then key value pairs one key with the
- 41:26pair of a list of dictionaries. So a
- 41:29very similar format to how the API for
- 41:31Stack Overflow looked. Now what I want
- 41:33to do is I want to create the ability to
- 41:35pass in an ID in here. So, let's say we
- 41:38passed in a one and we were able to get
- 41:41the first drink. So, let's go ahead and
- 41:44build that functionality. I'm going to
- 41:45clean up my screen just a little bit
- 41:47here because we're not going to need
- 41:49this terminal right now. I'm just going
- 41:50to shrink that. And I'm going to hide
- 41:53our different files on the side there.
- 41:58So, what we do now is we create a new
- 42:00route. So,
- 42:02app.oute. And this is also going to be
- 42:05to drinks. and then forward slash and
- 42:08you can use less than and greater than
- 42:11signs to define a parameter here. So
- 42:13that's going to be substituted for a
- 42:15specific number. Now a lot of people
- 42:18debate on whether this should be plural
- 42:20or singular since we're grabbing one
- 42:22drink. I decided to do it plural and
- 42:25I'll show you why. So I found this stack
- 42:28overflow question singular or plural
- 42:30name of resource while creating it. And
- 42:34this person talks in here and you know
- 42:36there's a bunch of different thoughts in
- 42:37here about the best way to do it. And as
- 42:39I was reading this I looked up at the
- 42:41web address and I saw questions plural
- 42:44with the ID. So I was like I think I'm
- 42:47sold. I'm just going to keep it plural.
- 42:49So that is why I decided that. So let's
- 42:52go back to our code in here and we're
- 42:54going to create a new method. So we'll
- 42:55say defaf get drink and this one's going
- 42:58to have a parameter ID. So instead of
- 43:01having a drinks variable, we're going to
- 43:03have a drink variable. And now we're
- 43:05just going to get a drink. So to do
- 43:07that, we can say
- 43:11drink.query.get or
- 43:14404. It's kind of a tongue twister
- 43:17there. And from here, we can pass in the
- 43:20ID. That's going to give us a drink
- 43:22object. And then we can just return that
- 43:25and build a quick dictionary. So we'll
- 43:28say jsonify and we're going to build out
- 43:31the JSON. The key is going to be name.
- 43:36That's going to come from
- 43:38drink.name. And then the second key is
- 43:40going to be description and that's going
- 43:43to come from
- 43:45drink.escription. So dictionaries are
- 43:49serializable instantly. You actually
- 43:52don't even have to call JSONify here. So
- 43:55you can just return
- 43:59uh dictionary like so. But sometimes
- 44:02you'll need to call
- 44:03jsonify if you're not working with a
- 44:05dictionary. So I think that should work.
- 44:07Let's save and let's go back to our web
- 44:10page. And you can see we get one drink
- 44:12back. And we can try it again with ID2.
- 44:16We get that second drink. And then we
- 44:18can try ID3. And we get not found
- 44:20because there's not a third drink in
- 44:21there. Now I wanted to show you real
- 44:22quick. If you go back to ID2 here, you
- 44:26can rightclick inspect and get a little
- 44:28bit more information about this request.
- 44:31So, hitting network and then do a little
- 44:33refresh. You can see this request here
- 44:36and it's a get request. The response was
- 44:38200. Okay. And you can see the content
- 44:40type is application JSON. It's a little
- 44:43bit different than if you're on a web
- 44:44page. What we can do is we can inspect
- 44:46on here and go to
- 44:50network. Get that first request on here.
- 44:52And that's 200. Okay. Also a get, but
- 44:54this time the content type is
- 44:58text/html. So yeah, just want to call
- 45:00that out for you guys. Let's go ahead
- 45:01and go back. And now I want to talk a
- 45:03little bit about adding a new drink. So
- 45:06let's go ahead and create another route
- 45:09on here. We'll say
- 45:11app.oute. The path is going to be
- 45:13drinks. And you can actually have
- 45:16another parameter in here which is
- 45:18methods and say post which is good to do
- 45:22if you're defining for a post request.
- 45:24You can put any of the methods in here.
- 45:26You could put get or delete or whatever.
- 45:28And you can actually condition. So you
- 45:30could check to see what method the
- 45:32person's requesting. So you could you
- 45:35could in theory define all of this in
- 45:38one
- 45:39method and then you know check to see if
- 45:43they're trying to get all the drinks or
- 45:46add all of the drinks. However, I like
- 45:48to just have a little bit more separate.
- 45:50So I put them in separate methods here.
- 45:53And we'll just create a separate method.
- 45:54So add drink. Now this one's going to be
- 45:58a little bit more complicated because we
- 45:59actually have to get the request data.
- 46:02So when the person calls this, they're
- 46:03going to pass in the structure of what a
- 46:06drink should look like. So we're going
- 46:09to get this by creating a new
- 46:13drink. And where are the attributes for
- 46:16the drink going to come from? Well, the
- 46:18name is going to come from
- 46:21request.json. So that's how you can
- 46:23access the JSON data that they send.
- 46:26It's through
- 46:27request.json. And we're going to be
- 46:29looking for name. And we're going to do
- 46:30the same exact thing for the
- 46:33description. And that is going to come
- 46:36from
- 46:38request.json
- 46:41description. There we
- 46:43go. Now we can add these by saying
- 46:47db.ession.add and pass in the drink
- 46:53db.ession. Then what we could do, we can
- 46:55return whatever we want. We could say
- 46:57successfully added. Um, or you could do
- 47:01the ID. So if you wanted to return the
- 47:04ID, it's going to look like return ID
- 47:09colon drink ID. So that ID attribute is
- 47:13going to be added to this drink object.
- 47:15So that's pretty convenient. Save that.
- 47:18And now let's give it a try. So we'll go
- 47:21over to here, but we can't really pass
- 47:23in the data for our requests really
- 47:25easily. So this is where Postman comes
- 47:27in handy. So from here, what we can do
- 47:30is we can
- 47:32define what a drink should look like in
- 47:35JSON inside of the body of our request.
- 47:38And then we just set it to post. And
- 47:40also, we'll want to update our web
- 47:41address. So you can copy that from right
- 47:44here. Paste that there. And what we're
- 47:48going to do is we're going to give this
- 47:49a
- 47:50name. Let's zoom in a little bit. What's
- 47:53the name going to
- 47:54be? Uh we'll call it cola. And then the
- 47:59description is
- 48:01delicious. All right. So, just check
- 48:03everything is right. We got body, raw,
- 48:05JSON, post, and the correct web address.
- 48:09Hit send. We got an error on line
- 48:1342. Let's go back to our code real
- 48:15quick. Looks like we might have some
- 48:16kind of formatting issue here.
- 48:18Unexpected name request. For request to
- 48:22work, I think we need to do another
- 48:24import from Flask. So, we'll say request
- 48:28there. And hopefully that'll do the
- 48:30trick. I'm also getting another warning
- 48:32down here. I think we need to uh take
- 48:35this and move it up a line. It wasn't
- 48:38causing any issues, but best practice
- 48:40there. All right, let's scroll back down
- 48:42in our code. And it looks like we don't
- 48:44have any more warnings. So, we will go
- 48:47back to Postman and hit send. And it
- 48:50looks like uh we're making progress.
- 48:52Okay. So the issue here is that we're
- 48:56not using the right web address. So we
- 48:59need to go to drinks, no forward slash,
- 49:03and hit send. So that was nice that that
- 49:06worked. And in this situation, it
- 49:08returns the ID of three. So now we can
- 49:11get all of the drinks. We can still keep
- 49:13this body here. We don't have to delete
- 49:15that. Hit send. And you can see all the
- 49:17drinks there. Or you could pass in the
- 49:20ID of three. Hit send and you can get
- 49:23that new one. Last thing I want to talk
- 49:25about is how to delete a drink. So let's
- 49:27go ahead and go back to our code and
- 49:29create a new route. We'll say
- 49:32app.oute. The path is going to be drinks
- 49:35and we're going to take the
- 49:38ID so that way we know which drink to
- 49:41delete. And then for the methods, we're
- 49:43going to say delete. There we go. and
- 49:47we'll say defaf delete drink. So for
- 49:51this to delete a drink we're going to
- 49:54say db
- 49:57session delete and pass in the drink
- 50:00structure. The best way to get this
- 50:03drink structure I thought would just be
- 50:04to get it from the database. So we're
- 50:07going to create a variable drink and say
- 50:11drink.query.get and pass in the ID. So
- 50:14I'll take the ID as a parameter from
- 50:16this web address. And then after we
- 50:18delete, we say
- 50:21db.ession.comit. And I was having a
- 50:23little bit of an issue. Now in general,
- 50:24I haven't done a lot of like error
- 50:26checking and different edge cases.
- 50:29However, I was getting it where I would
- 50:31delete a drink and it wouldn't exist and
- 50:33I would get an issue. So I decided just
- 50:35to add a little bit of extra casing
- 50:37here. So, if drink is none, what we're
- 50:40going to do is we're just going to
- 50:41return and I'm just going to say
- 50:44something like error not found or
- 50:47something. Or you could return a 404.
- 50:49Just showing some different options
- 50:51here. And you know, if that doesn't
- 50:53happen, then I'm just going to assume
- 50:55everything's good. And we're just going
- 50:56to return
- 50:58uh we'll say message. And I don't know,
- 51:01we'll just say something like yeet.
- 51:04There we go. Okay, let's test this one
- 51:06out. For this, what we're going to do is
- 51:08we're going to do a delete. And we don't
- 51:12have to pass in anything with the body
- 51:14just to show you guys. I'll delete that
- 51:16just to make sure it's clear. We do pass
- 51:18in the ID here, however. Hit send and it
- 51:21says yeet. If we hit send again, it says
- 51:24error not found. So, that is how you do
- 51:29the most basic API calls. We have the
- 51:33ability to get all the drinks, a
- 51:34specific drink, add a drink, or delete a
- 51:38drink. I didn't really do anything for
- 51:40updating a drink, but a drink is so
- 51:42simple. Like, I feel like you could just
- 51:44delete a drink and then read it. Or if
- 51:46you want to practice, you could try some
- 51:48uh put requests here. But that's all I
- 51:50got for you guys for the basics of
- 51:52creating an API in Python. It's a lot
- 51:55more to it, but hopefully that'll get
- 51:56you started.
About this transcript
This page contains the full transcript of REST API Crash Course - Introduction + Full Python API Tutorial by Caleb Curry, generated from the public captions YouTube serves with the video. The transcript has 8,814 words across 1,239 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.