YouTube2Text

REST API Crash Course - Introduction + Full Python API Tutorial — Transcript

by Caleb Curry · 8,814 words · 1,239 segments · language en · Watch on YouTube

Full transcript

  1. 0:00Hey everyone, welcome to your REST API
  2. 0:02crash course. My name is Caleb. In this
  3. 0:04video, we're going to talk about
  4. 0:05everything you need to know to get
  5. 0:06started with REST APIs. We're going to
  6. 0:08first talk about the concepts, then
  7. 0:10we're going to talk about how to consume
  8. 0:12an API, and then we're going to build
  9. 0:13our very own API in Python. So, it's a
  10. 0:17lot of useless or it's a lot of useful
  11. 0:19information. So, if you need a reference
  12. 0:21of all this, I created a PDF that you
  13. 0:23guys can get for free with a link in the
  14. 0:25description. So go check that out if you
  15. 0:27just need to like, you know, look at the
  16. 0:28definitions and study or whatever. But
  17. 0:31anyways, we're going to jump in by first
  18. 0:33talking about what a REST API is, why
  19. 0:35you should care, and where this is used
  20. 0:38in software. And if you're watching this
  21. 0:40video and you're not really doing
  22. 0:41anything with software, not really sure
  23. 0:43why you're here, but you can probably
  24. 0:45move on to one of my other videos. So
  25. 0:48which all of my videos are about
  26. 0:49software. So anywh who, API stands for
  27. 0:52application programming interface.
  28. 0:56So, I tried talking and explaining this
  29. 0:59last time I recorded this and it just
  30. 1:01didn't go so well because I cannot talk
  31. 1:05and write very well at the same time.
  32. 1:08Application programming interface. It's
  33. 1:11basically a fancy way to say a way two
  34. 1:14pieces of software can communicate with
  35. 1:15one another. So, if we have this
  36. 1:18software over here, this is some really
  37. 1:21cool software system we built. And here
  38. 1:24is another one. And let's say these are
  39. 1:26built in different programming
  40. 1:28languages. That's where an API is going
  41. 1:30to come in and save the day. It allows
  42. 1:32different applications that aren't built
  43. 1:34exactly the same to communicate. So
  44. 1:37we'll say this one was built in
  45. 1:39Python and this one was built in
  46. 1:42JavaScript. Poor developer. I'm so
  47. 1:44sorry. Well, an API allows us to build
  48. 1:47functionality in this application to
  49. 1:50make a request to this other application
  50. 1:53and then this application can give a
  51. 1:56response back to this application. And
  52. 1:59that is where the API comes in. We're
  53. 2:02building this interface for these pieces
  54. 2:05of software to communicate with one
  55. 2:07another. Now, in general, it's a one-way
  56. 2:09thing. So this app is not going to
  57. 2:12request information from this app and
  58. 2:15get it back. Instead, it's always we
  59. 2:17have a a server and then a client. The
  60. 2:21client consumes information given from
  61. 2:24the server. So this is a very common
  62. 2:25setup you'll see in all of computing.
  63. 2:28The same way when you go to get a
  64. 2:30website, you know, you go to
  65. 2:32youtube.com, you're making a request and
  66. 2:35then that server gives back a response.
  67. 2:38It works exactly the same way with our
  68. 2:39REST API, although instead of getting
  69. 2:42HTML, you're going to get JSON.
  70. 2:46So, JSON is a language or a notation of
  71. 2:51describing information. It's just like
  72. 2:54text and it stands for JavaScript object
  73. 2:57notation. So, it's a way to notate what
  74. 3:00objects look like. But, it doesn't have
  75. 3:02to be done with JavaScript. It's
  76. 3:05actually supported in pretty much every
  77. 3:06language. And this is now the standard
  78. 3:09for APIs. You may run into APIs that use
  79. 3:14XML. However, this is kind of
  80. 3:17old-fashioned and probably not what you
  81. 3:19would want to use going forward. So, I
  82. 3:21would recommend even if you're more
  83. 3:22familiar with XML for some reason to
  84. 3:25learn JSON or JSON. You'll hear both.
  85. 3:28So, JSON's not complicated. Don't feel
  86. 3:30like you have to learn another
  87. 3:31programming language or something. It's
  88. 3:33just a series of key value pairs just
  89. 3:36like an object in JavaScript, hence the
  90. 3:39word JavaScript object notation or like
  91. 3:41a dictionary in Python where you have a
  92. 3:44key and then an associated value. So,
  93. 3:46it's pretty much just an associative
  94. 3:48array. We'll get into what JSON looks
  95. 3:51like and how to use it soon when we go
  96. 3:54build our own API, but don't worry too
  97. 3:57much about that. So JSON is basically
  98. 4:00the the language of communication and
  99. 4:03the API is you know what things we can
  100. 4:06communicate you know maybe you want to
  101. 4:08get a list of users or maybe you want to
  102. 4:11update some comments whatever you want
  103. 4:14to do that's all defined as API end
  104. 4:17points. So, you know, right here where
  105. 4:20we're making that request, that's an
  106. 4:23example of an end
  107. 4:26point. We're going to talk about the
  108. 4:28different types of endpoints that we can
  109. 4:30create. Now, what about this rest thing
  110. 4:33here? Well, that stands for um I think
  111. 4:36representational state transfer. I had
  112. 4:38to look that up a little bit ago because
  113. 4:40I was like represent what was it?
  114. 4:42Anyways, this is the means of
  115. 4:44communication. So, you know, I can talk
  116. 4:46to you in English, but how am I talking
  117. 4:49to you? Am I talking to you over the
  118. 4:51phone? Am I texting you? Am I talking to
  119. 4:54you face to face? Well, that is
  120. 4:57describing how we're communicating. And
  121. 5:00this REST aspect is communicating over
  122. 5:03the web or the
  123. 5:05internet. So, this is all going to be
  124. 5:08done by making requests similar to how
  125. 5:10you would request a website, but instead
  126. 5:13of HTML, you're requesting JSON. just as
  127. 5:15I mentioned earlier. So to make this a
  128. 5:17little bit more concrete, let's go over
  129. 5:18an example of an app I'm working on. So
  130. 5:21I have some software written in
  131. 5:24Python and this is the server software.
  132. 5:27You may also hear it as the backend
  133. 5:31software. And this is the software
  134. 5:33that's going to communicate with a
  135. 5:35database. That's where all of our
  136. 5:36information and data is going to be
  137. 5:38stored. So this talks to the
  138. 5:41database. Now, we want other pieces of
  139. 5:44software to be able to communicate to
  140. 5:46this back-end software, but we don't
  141. 5:48just want them to be able to access
  142. 5:49anything. We don't want to give direct
  143. 5:51access to this database. So, instead, we
  144. 5:54expose different API endpoints. So, an
  145. 5:58example of an API endpoint would be
  146. 6:01forward
  147. 6:01slash and this I haven't described what
  148. 6:05the actual app is for, but forward
  149. 6:07slashdrinks. Now, the actual app is to
  150. 6:11get a list of drinks and be able to rate
  151. 6:13these, you know, like zero to 10 or to
  152. 6:15put them in different categories of how
  153. 6:17good they are. And then you can
  154. 6:19basically keep track of all your
  155. 6:20favorite drinks. It's a little silly,
  156. 6:22but I thought it'd be a fun project. And
  157. 6:25um basically, I I like to drink I don't
  158. 6:28like to drink. I like to drink
  159. 6:29non-alcoholic beverages like LCroy or
  160. 6:33like stevia drinks and energy drinks or
  161. 6:36whatever, but there's so many of them I
  162. 6:37can't keep track of them all. So, I just
  163. 6:39wanted to build a little website to, you
  164. 6:41know, rank them, you know, and instead
  165. 6:43of just getting all of the drinks, you
  166. 6:45might want to get a specific drink. So,
  167. 6:48in this situation, we would pass in an
  168. 6:51ID. So, in this situation, we are
  169. 6:54getting data. And that's one of the
  170. 6:57different methods of APIs. We're going
  171. 6:58to talk about API methods here in a
  172. 7:00minute. But what this means is my
  173. 7:02software that I built over
  174. 7:04here. And in this situation, let's just
  175. 7:07say this is
  176. 7:08JavaScript. I can get all of the drinks
  177. 7:12or a specific drink from my backend
  178. 7:15software just by making a request to
  179. 7:18this web address. Now, you might be
  180. 7:20looking at this like, what? That doesn't
  181. 7:22look like a web address. Well, because
  182. 7:24this is a web server, this is going to
  183. 7:26have either an IP address or a domain
  184. 7:29name. So, let's say I put this up on a
  185. 7:31website, Caleb's favorite
  186. 7:34drinks.com, not a real website to the
  187. 7:36extent of my knowledge, and then forward
  188. 7:41slashdrinks forward slash and then you
  189. 7:43can pass in some ID such as five. Now,
  190. 7:46the actual structure for these URLs and
  191. 7:48what data you want to get that is
  192. 7:50totally up to you. However, there are
  193. 7:52some general standards and I will
  194. 7:54describe why I went with this coming up
  195. 7:57soon. But basically, we have the list of
  196. 8:00data we're trying to get from and then
  197. 8:01we pass in which specific element we
  198. 8:05want. And this will return JSON of all
  199. 8:08the information about that drink. Now,
  200. 8:10oftent times when you have a website,
  201. 8:13you're going to have web pages, you
  202. 8:15know, people can view on their web
  203. 8:16browser or you're going to have the API.
  204. 8:19And often these will be split out into
  205. 8:21two subset applications. So you might
  206. 8:24have calebs
  207. 8:31favoritedrinks.com/drinks5. Or another
  208. 8:33common thing is to have a different
  209. 8:35domain such as
  210. 8:39api.calebsfeddrinks.com. You don't have
  211. 8:41to. You can mix those together. However,
  212. 8:43just for organizational sake, often the
  213. 8:45API is in some separate section, either
  214. 8:48a subdirectory or a subdomain. Now, you
  215. 8:51might look at this setup, as I often do
  216. 8:53when I'm working on applications, and be
  217. 8:56like, why the complexity? Why do you
  218. 8:58need to have two applications and then
  219. 9:01the database? Why don't you just connect
  220. 9:03from this
  221. 9:04application all the way to the database,
  222. 9:07skipping all this junk? Well, obviously
  223. 9:10you can do that. You can do whatever you
  224. 9:12want but this is not always advisable
  225. 9:15for various reasons. The most biggest
  226. 9:18importantest reason of not going from
  227. 9:20the client application directly to the
  228. 9:23database is security specifically if you
  229. 9:27are using JavaScript. Now oftent times
  230. 9:30the client is going to be JavaScript
  231. 9:32because that's used for web pages.
  232. 9:34However, you could also make a console
  233. 9:35application or a mobile application. So,
  234. 9:38it's not always going to be JavaScript,
  235. 9:40but if you go to a website, you can go
  236. 9:43into the developer tools and you can see
  237. 9:46all of this JavaScript or you can
  238. 9:48rightclick and view source and it'll
  239. 9:50have the JavaScript files linked there
  240. 9:52and you can view all of that. So, you
  241. 9:54don't really want to put sensitive
  242. 9:58information on the client here because
  243. 10:00it's all viewable to the person using
  244. 10:03your software, which means they could
  245. 10:04then go to the database themselves
  246. 10:06directly, tinker around, you know, drop
  247. 10:09database, lol. We don't want them doing
  248. 10:12that. So instead, we just expose
  249. 10:15specific things that we want people to
  250. 10:17see, such as the list of drinks, but
  251. 10:20they can't go in there and see
  252. 10:22everybody's user information or people's
  253. 10:25address or any of that. Now, beyond
  254. 10:27security, the other big reason is
  255. 10:29versatility. So, right now, we have one
  256. 10:31front-end application in JavaScript, but
  257. 10:34with this setup, we could very easily
  258. 10:36build a mobile
  259. 10:38application, and yes, this is a cell
  260. 10:40phone. And we could also consume the
  261. 10:43same API. So what happens now is both of
  262. 10:47these front-end applications are sharing
  263. 10:50the same backend which means these are
  264. 10:53always going to have the same data.
  265. 10:55They're going to be
  266. 10:57synchronized. So that is how when you
  267. 10:59have applications on your phone, you can
  268. 11:02go in there and change data and then you
  269. 11:04can go log in on your computer and all
  270. 11:06of that stuff still exists. It's because
  271. 11:08they all share the same backend. So, you
  272. 11:11know, when you're messaging someone on
  273. 11:13social media, well, those messages are
  274. 11:15being sent to a back-end server that
  275. 11:18does all of the processing and all of
  276. 11:19the hard work of the application. And
  277. 11:22that website you're looking at is really
  278. 11:24just a pretty cover to this backend. So,
  279. 11:28you know, JavaScript, maybe your
  280. 11:30application here is in Swift, but
  281. 11:32ultimately we're hiding the back end of
  282. 11:35this application and separating those,
  283. 11:37which brings up the next good point,
  284. 11:39which is modularity. Because the front
  285. 11:42end and the back end are separated and
  286. 11:45we're just defining this consistent way
  287. 11:47to communicate, we can actually swap
  288. 11:49different things out and not necessarily
  289. 11:52break. I say necessarily because you
  290. 11:54know in practice it's it could be
  291. 11:56difficult but in theory you should be
  292. 11:58able to swap out different things
  293. 12:00without breaking other pieces of the
  294. 12:02application. So right now this is
  295. 12:04written in Python but I could be like eh
  296. 12:06I don't really feel like writing in
  297. 12:07Python you know and I decide to upgrade
  298. 12:10to something like Visual Basic and in
  299. 12:13this situation we can expose the same
  300. 12:16exact API endpoint. So, this website and
  301. 12:20this mobile phone app, they don't even
  302. 12:23need to know about those changes to the
  303. 12:26back end because they're still getting
  304. 12:28their list of drinks. That's all they
  305. 12:29care about. They just want their drinks.
  306. 12:32This is great because you can change the
  307. 12:33back end of software without requiring
  308. 12:36an update to the app or requiring a new
  309. 12:40deployment of the website as long as
  310. 12:43you're able to give a consistent
  311. 12:45interface to working with your backend.
  312. 12:47Last reason and then I promise I'll stop
  313. 12:50rambling. Okay, I got a little bit more
  314. 12:51rambling, but basically the last thing I
  315. 12:54wanted to share of why this setup is
  316. 12:56good is interoperability, which I think
  317. 12:58is a word. And basically what I'm saying
  318. 13:00here is that these front-end
  319. 13:02applications, they don't all have to be
  320. 13:05built by you or the front-end
  321. 13:08development team for your company. You
  322. 13:10can actually expose certain endpoints
  323. 13:12such as this one right here, and you
  324. 13:14could make this public.
  325. 13:17So if you make certain endpoints public,
  326. 13:20you don't have to worry about
  327. 13:21authentication or authorization. And in
  328. 13:24that situation, anybody could go ahead
  329. 13:26and create some new app, new and
  330. 13:29improved to consume your API. So you
  331. 13:33know, if I don't like the way Instagram
  332. 13:35looks, I can go create my very own
  333. 13:38Instagram viewer because they have an
  334. 13:41API that can be consumed. Now, sometimes
  335. 13:43you'll still need to get some kind of
  336. 13:45token or some way to authorize saying,
  337. 13:47"Hey, I'm okay to use this API." But a
  338. 13:50lot of the times these APIs are going to
  339. 13:52be publicly available. So, the API we're
  340. 13:55going to consume soon is just a public
  341. 13:57API that anybody can use and it's really
  342. 14:00cool honestly. So, many websites you
  343. 14:02might not even realize have APIs. So,
  344. 14:05for example, if you wanted to do
  345. 14:06something like create a trading bot or
  346. 14:09like a cryptocurrency trading bot, well,
  347. 14:11oftent times different exchanges are
  348. 14:14going to have APIs so you can automate
  349. 14:16different things in code. So, it's not
  350. 14:19always just about making a pretty
  351. 14:21interface, but it might be about
  352. 14:23automation. How can we connect these
  353. 14:24apps and make things happen
  354. 14:26automatically? So, if the thing's not
  355. 14:28public, it might be private, but you can
  356. 14:30still access it. You just need a way to
  357. 14:33verify that it's you and not just
  358. 14:35anybody's going on there and trading
  359. 14:38cryptocurrencies or spending your money.
  360. 14:40So there the authorization aspect of
  361. 14:43this is like a whole another beast. But
  362. 14:45a common thing you often see is OOTH 2.
  363. 14:47That is an authentication technique
  364. 14:49that's fairly common. So if you want to
  365. 14:51look into how to protect your API and
  366. 14:54make you basically have to log in, you
  367. 14:56can look into OOTH. That's o a u t
  368. 15:00h2. Now I want to take a moment to talk
  369. 15:02about the different methods of
  370. 15:04requesting data from the server. So
  371. 15:06we've talked about get and this one's
  372. 15:09pretty simple. It's what's used to
  373. 15:10retrieve data from the server. And these
  374. 15:13are often written in all uppercase
  375. 15:16letters. So you're just like screaming
  376. 15:19like get me this information. All right.
  377. 15:21So get is used to retrieve data.
  378. 15:26I could just say get data but fancy
  379. 15:29here. All right, so there's a few other
  380. 15:30ones you should know about and that is
  381. 15:34post. Post is used to write data. So
  382. 15:38anytime you want to write information to
  383. 15:40the server, you're going to use post.
  384. 15:42And then there is delete. Almost didn't
  385. 15:46use capitals there, but I fixed
  386. 15:48it. And this is used to, you know,
  387. 15:51delete stuff. Now there is another one
  388. 15:54that's pretty common. Why do I always
  389. 15:55write like this way? I don't know. And
  390. 15:58that is put. And this is actually fairly
  391. 16:01confusing if you're new. And the
  392. 16:04difference between post and put is
  393. 16:06pretty gray. And people will even argue
  394. 16:07about which you should use where. Here's
  395. 16:10my opinion. Post should be used to write
  396. 16:14new data. Put should be used to write
  397. 16:18but in this situation, we're going to
  398. 16:19update data.
  399. 16:22So now I want to show you how these
  400. 16:23things correlate to the most popular
  401. 16:25things you have to do with the database
  402. 16:27which is CRUD. So the different things
  403. 16:30you need to do, we need to be able to
  404. 16:32create data, post, read data, get,
  405. 16:36update data, put, and delete data,
  406. 16:39delete. Now, why exactly is there
  407. 16:42confusion between post and put? That's
  408. 16:44what I want to talk about now. Well,
  409. 16:46first let's talk about how post and put
  410. 16:48are generally used. Post is used to add
  411. 16:50a resource. Put is used to replace a
  412. 16:54resource. And that's why it's natural in
  413. 16:56my mind to say you can use put to update
  414. 16:59data and post to add new data. But
  415. 17:01replacing a resource requires some way
  416. 17:03to identify it. And often this is done
  417. 17:05with an ID. So my thoughts are if you're
  418. 17:09doing a post request, you want to add
  419. 17:11data. So you might have the
  420. 17:14address of drinks and you want to add a
  421. 17:17new drink. With put, you're probably
  422. 17:20going to need to identify what resource
  423. 17:22you want to replace. So it might look
  424. 17:24like drinks slash 6005 for an ID. Now,
  425. 17:30with the setup I tend to do, I usually
  426. 17:32don't have this ID value until that's
  427. 17:34that data is already inserted in the
  428. 17:36database with a post. So when you're
  429. 17:39adding new data, you don't know what
  430. 17:40that ID is going to be because that's
  431. 17:42auto incremented in the database. Then
  432. 17:44if you want to update that data, then
  433. 17:46you use the ID. But there's another
  434. 17:49difference and this is more defined in
  435. 17:51the spec of how an API is supposed to
  436. 17:53work and less about pure functionality
  437. 17:56because you're the one who defines the
  438. 17:58functionality. So if you want your API
  439. 18:00to work correctly then you need to make
  440. 18:02sure you implement it in this way and
  441. 18:05that is put is designed to give the same
  442. 18:09result every time if you make the same
  443. 18:12request. So for example if you're
  444. 18:15replacing this drink with a new drink
  445. 18:18you can replace this ID over and over
  446. 18:21again as long as that new one has the
  447. 18:24same exact ID. So, let's say you have a
  448. 18:26grape drink and you replace it with cola
  449. 18:31and then you replace cola again with
  450. 18:33cola and then cola again with cola. No
  451. 18:37matter how many times you do this, the
  452. 18:40same resource exists and it doesn't hurt
  453. 18:42if you accidentally put that request
  454. 18:44numerous times. Post is usually a little
  455. 18:46bit different because that feature or
  456. 18:48capability is not guaranteed. So, what
  457. 18:50that means is if you add a new drink,
  458. 18:53let's say you add cola
  459. 18:55and then you add cola again. Well, in
  460. 18:58this situation, you're not replacing
  461. 18:59anything. So each time you add cola,
  462. 19:02it's making a new record in that table.
  463. 19:04So put is guaranteed to be able to be
  464. 19:08executed numerous times without any kind
  465. 19:10of side effects. Post on the other hand
  466. 19:12is not guaranteed by the spec. And in
  467. 19:14that situation, you could actually have
  468. 19:16duplicate records in the database or you
  469. 19:19could get an error on that second one if
  470. 19:22the drink name is defined to be unique.
  471. 19:24Now, I'm probably going to mess this
  472. 19:25word up, but there's a word to describe
  473. 19:27this. Iden
  474. 19:28potent. It Yeah, I it potent. I don't
  475. 19:32know. So, put is said to be
  476. 19:35this. I'm not even going to try anymore.
  477. 19:37Just whatever that's called. Now, in
  478. 19:40general, I think there's a lot of
  479. 19:41confusion between post and put. And you
  480. 19:43can pretty much do the same behaviors
  481. 19:46with either one. So, I tend to just try
  482. 19:48to stick with post most of the time.
  483. 19:52Even if I'm updating a resource, it you
  484. 19:55can do it with post just the same. You
  485. 19:57can define it however you want. It's
  486. 19:58sort of how with modern HTML, you can
  487. 20:00make a section be a div or you can be a
  488. 20:03little bit more specific and say, "Oh,
  489. 20:05this is a footer." Both kind of give the
  490. 20:08same results. And if you're not using
  491. 20:09footer, right, then you might just make
  492. 20:11things worse. So, a lot of people still
  493. 20:13end up just using divs. So if you're
  494. 20:15using HTML, that's just maybe that kind
  495. 20:18of puts it in perspective. I don't know.
  496. 20:20There's another method, patch, which is
  497. 20:22used to replace different pieces of a
  498. 20:24resource. So maybe you just want to
  499. 20:25update one field. However, in our
  500. 20:28situation, the data we're working with
  501. 20:29is so small that it's pretty much just
  502. 20:32easier to replace it with a new version.
  503. 20:36So that way you don't have to keep track
  504. 20:37of individual changes. However, if
  505. 20:39you're working with very large data, you
  506. 20:41can definitely look into patch. So my
  507. 20:44theory is you basically keep the state
  508. 20:46of an object in the client side
  509. 20:49application and then once you save you
  510. 20:52just send that new state and replace the
  511. 20:53old state in the database. Hopefully
  512. 20:56that makes sense. All right. So let's
  513. 20:58get some practice with APIs by consuming
  514. 21:00an existing API. We're going to take a
  515. 21:02look at Stack Overflow. So all of the
  516. 21:06questions on here, you can get access to
  517. 21:08this information through an API. So we
  518. 21:11can build an application to work with
  519. 21:13Stack Overflow. So to do this, you
  520. 21:16actually go to
  521. 21:18api.stackchange.com and in here you can
  522. 21:20see the documentation for all of this.
  523. 21:23So here's the different API endpoints.
  524. 21:26So we can get the answers, badges,
  525. 21:29comments, posts, which is just a uh
  526. 21:32combination of questions and answers.
  527. 21:34And I'm going to take a look at the
  528. 21:35questions here. So we're going to get
  529. 21:37all of the questions. And here is an
  530. 21:39example of how you would invoke this. So
  531. 21:41you can hit run and you can see in this
  532. 21:44web address there's this question mark
  533. 21:46and then some variables with assigned
  534. 21:48values and then an and sign amperand and
  535. 21:52sort. These are known as query
  536. 21:54parameters and they can be used in this
  537. 21:56situation to modify the results of the
  538. 21:59API. Now, if you want to know how to
  539. 22:01actually invoke this without it running
  540. 22:03it in this little test window, you
  541. 22:05basically just take this address here
  542. 22:08and you would paste it after api.stack
  543. 22:11exchange.com
  544. 22:13uh like so. So, that's what it's going
  545. 22:15to look like. Hitting enter, you get a
  546. 22:18bunch of data here. Not exactly as
  547. 22:20pretty as this, which by the way, this
  548. 22:23is JSON format. So, it's just key value
  549. 22:25pairs. And in the pairs you can have
  550. 22:29arrays or uh you could consider them
  551. 22:31lists if you're more familiar with
  552. 22:32Python. So we have items right here
  553. 22:34which is a list of questions. Each
  554. 22:36question is surrounded by curly braces.
  555. 22:38So there's the opening curly brace and
  556. 22:40it has tags owner bunch of other stuff
  557. 22:43and then it ends. And then we have
  558. 22:44another question which has tags owner a
  559. 22:47bunch of other stuff and it just repeats
  560. 22:49in a list. So what we're going to do is
  561. 22:51we're going to work with this API. So, a
  562. 22:53tool I would recommend you get is called
  563. 22:56Postman. And in here, you can work with
  564. 22:59your APIs and it's just a little bit
  565. 23:01easier because you can customize the
  566. 23:03body and the different headers of your
  567. 23:05requests. And what we're going to do is
  568. 23:07we're just going to take this web
  569. 23:09address
  570. 23:11here and paste it on here. So, we're
  571. 23:14going to have httpapi.stackchange.com
  572. 23:17stack
  573. 23:19exchange.com and then forward
  574. 23:21slashquests and then all that other
  575. 23:23stuff. So hit send and we'll get a
  576. 23:25response sort of like this. So basically
  577. 23:28this is JSON here we have this items and
  578. 23:31then a list of the different questions.
  579. 23:34So let's go ahead and we'll come back to
  580. 23:37Postman later but for now let's take
  581. 23:38this URL and try to work with this in a
  582. 23:41Python script. So, if you need help
  583. 23:43setting up a Python environment, then
  584. 23:45you can check out my beginner Python
  585. 23:47programming all-in-one. However, I'm
  586. 23:50just going to assume you can at least
  587. 23:51get a Python environment set up. And
  588. 23:54we're in a Python file. What we're going
  589. 23:56to do is we're going to need a few
  590. 23:57tools. So, we're going to say import
  591. 24:00requests and import JSON. So, if this is
  592. 24:03your first time working with requests,
  593. 24:05you might need to install it. So what we
  594. 24:07can do is we can open a terminal and say
  595. 24:11pip 3 install requests. All right. So
  596. 24:14now we have requests installed and we
  597. 24:16should be able to make a request to a
  598. 24:19web page by saying
  599. 24:22requests.get and pasting in a web
  600. 24:24address inside of a string here. So
  601. 24:27let's just uh make sure this is nice and
  602. 24:29formatted properly like so. And that's
  603. 24:32going to return a response. So we can
  604. 24:34assign that to a response variable. And
  605. 24:37then what we'll do is we'll just print
  606. 24:38this response and see what we get. And
  607. 24:40you can see we get a response 200 which
  608. 24:43means okay. Now we can actually see the
  609. 24:46data that's returned by running.json as
  610. 24:49a method here. And that's going to give
  611. 24:51us all of the data exactly as we would
  612. 24:54if we requested it in the web browser or
  613. 24:56with Postman. So we got the items and
  614. 24:59then a list of all of the different
  615. 25:02questions. So we can basically zoom in
  616. 25:05on this and instead of just having one
  617. 25:08key value pair where we have items and
  618. 25:10then a giant list, we could actually
  619. 25:13explore items
  620. 25:15specifically by passing
  621. 25:17in items here. So we're going to index
  622. 25:21for items and then run this now. And we
  623. 25:25have just a list now. So we're no longer
  624. 25:28working with the items. we just have a
  625. 25:31list of
  626. 25:33questions. So then what we could do is
  627. 25:35we could iterate over these. So let's
  628. 25:38get rid of this print and we'll say for
  629. 25:43data in items. Or if you want to be more
  630. 25:46specific, you could say for question in
  631. 25:49items. This will be good for now. And
  632. 25:51then what we'll do is we'll just print
  633. 25:53data. And you can just print each one
  634. 25:54individually like so. Or you can be more
  635. 25:56specific and grab something like the
  636. 26:00title, which I know is an attribute of
  637. 26:02it. So running this and you can see here
  638. 26:04are all of the titles. So that's pretty
  639. 26:07cool. So basically that is
  640. 26:12right right here, the title. We're going
  641. 26:15to be grabbing each one of these. So
  642. 26:17every single item in this list. And you
  643. 26:20could also get something like the link
  644. 26:21if you wanted. So we can say print data
  645. 26:25link and now we got a series of question
  646. 26:28and answers and let's just print a space
  647. 26:30just to make it a little bit prettier.
  648. 26:32There we go. So here is the question and
  649. 26:36then here is the link which we can
  650. 26:38control-click to open. And there you go.
  651. 26:42So maybe you could build some kind of
  652. 26:44application to help you find good Stack
  653. 26:46Overflow questions to try to answer
  654. 26:49before anyone else does. So you can be a
  655. 26:52little bit more specific. You know, you
  656. 26:54could go in here and you could check to
  657. 26:56see the answer count. Answer count is
  658. 26:58like two for this one. So maybe maybe
  659. 27:02you only want to print the ones where
  660. 27:04the answer count is zero. So you could
  661. 27:07say if
  662. 27:09data and then ask for the answer
  663. 27:14count is zero, then we want to print the
  664. 27:18data. And just to show you guys that
  665. 27:20it's working, we'll say else print
  666. 27:24skipped. And also just print another
  667. 27:26space at the end. Actually, I'll just uh
  668. 27:28take that out of the loop. There we go.
  669. 27:31So this is our setup now. And we can run
  670. 27:33this. And you can see skipped. And then
  671. 27:36we got a question and then skipped and
  672. 27:37then a question, another question. And
  673. 27:40it seems to be working. So that's how
  674. 27:41you consume an API. Now I want to talk
  675. 27:43about how we can create our own API. So
  676. 27:46what I want to do is X out of this file
  677. 27:48here and we are in a folder API and open
  678. 27:53a terminal which I have one here and we
  679. 27:57can get the
  680. 27:58path. So just make sure you're in that
  681. 28:00directory and we're going to execute a
  682. 28:04sequence of commands in the terminal
  683. 28:05here. So the very first thing is we're
  684. 28:07going to create a virtual environment.
  685. 28:10So to do that you say python
  686. 28:133-m virtual environment venv and then
  687. 28:16give it a name such
  688. 28:18asveenv and that's going to create a new
  689. 28:22folder in here for your virtual
  690. 28:24directory which I talk about this in my
  691. 28:27uh previous video where we deployed a
  692. 28:29python web app but this is basically to
  693. 28:31isolate the dependencies for this
  694. 28:33specific application. Now what we can do
  695. 28:36is we can activate that by saying source
  696. 28:39and then traveling to it. So it's in the
  697. 28:42uh venv folder
  698. 28:46bin activate. So that is how you
  699. 28:48activate a virtual environment. Then we
  700. 28:51can install our dependencies. pip 3
  701. 28:53install flask and we're also going to
  702. 28:57install pip 3 install flask sql alchemy
  703. 29:03and that's going to be used to work with
  704. 29:06the database. So this is an example of
  705. 29:08an OM which I think is object relational
  706. 29:11mapper and we can output all of our
  707. 29:14dependencies in a file if we want. So we
  708. 29:16can say pip 3 freeze and put this in
  709. 29:20requirements.txt. So, anytime you uh add
  710. 29:23a new dependency, you'll want to do that
  711. 29:25just so all of our requirements are in
  712. 29:26this text file. So, uh whoever uses this
  713. 29:29project in the future can get the
  714. 29:31dependencies. Then we can just create
  715. 29:34our file. So, we'll say application. py
  716. 29:37and that's going to create this
  717. 29:40application. file, which is where we're
  718. 29:42going to do our coding. So, to start
  719. 29:45off, we'll just create a basic flask
  720. 29:47application. So we'll say from flask
  721. 29:51import flask and then we say app is
  722. 29:59flask_ame right there. So that's how we
  723. 30:01set up flask and what we can do now is
  724. 30:03we can make a simple route basically an
  725. 30:07endpoint by saying app.root and giving
  726. 30:10it a path and then we can define a
  727. 30:12method that we want hit when someone
  728. 30:15visits this route. So all we're going to
  729. 30:18do for right now is just return a string
  730. 30:20hello. All right. So let's just make
  731. 30:22sure this is working. So what we can do
  732. 30:24is run our application. To do this,
  733. 30:26we're going to create a few environment
  734. 30:29variables real quick. So flask
  735. 30:32app is application.
  736. 30:36py and the flask environment
  737. 30:42is development. And you're going to need
  738. 30:44to do that anytime you open up your
  739. 30:47terminal. So if you X out of your
  740. 30:49terminal and then reopen it, those are
  741. 30:51going to go away. So you'll need to do
  742. 30:53those again. And then you just say flask
  743. 30:55run. All right. So this is where our
  744. 30:57website's located. And we'll just open
  745. 31:01that. All right. Already made a stupid
  746. 31:03mistake. We don't put the colon here
  747. 31:05just after the uh method. So do a
  748. 31:08refresh. Now this needs to be uppercase.
  749. 31:11There we go. That should be everything.
  750. 31:12All right. All right, we got our app up
  751. 31:14and ready to go. So, the very first
  752. 31:16thing I want to do is make a get
  753. 31:18request. So, we're going to make an app
  754. 31:20to store drinks. So, we'll say app
  755. 31:23route. And the path for this is just
  756. 31:26going to be drinks and we'll say defaf
  757. 31:29get drinks and it's going to return
  758. 31:32something. We'll just say drinks for
  759. 31:34right now. But that's not a thing. So,
  760. 31:36what we need to do is we need to put
  761. 31:37some code here to make it a thing. If
  762. 31:40you want to just test it out for right
  763. 31:41now, what you could do is you could
  764. 31:42return a dictionary. And let's just say
  765. 31:46we got drinks and we'll just put drink
  766. 31:48data for right
  767. 31:49now. So we should be able to save that
  768. 31:52and it'll automatically refresh. And
  769. 31:54then when we refresh our page, well, we
  770. 31:56go to actually forward/drinks and we get
  771. 31:59some data back in JSON. So it's sort of
  772. 32:01working now. We just got to worry about
  773. 32:04connecting to a database. So to do this
  774. 32:07with the object relational mapper, we
  775. 32:09basically define all of the things we
  776. 32:11want to store in our database as models.
  777. 32:14So we're going to create a class. So we
  778. 32:17can do that up here. And all we're going
  779. 32:20to do is we're going to
  780. 32:21say class drink. And for SQL Alchemy, we
  781. 32:26just say DB domodel. So it's going to
  782. 32:28inherit from this. So it's already going
  783. 32:30to have various built-in
  784. 32:33functionalities. And that's how we can
  785. 32:35use it with SQL uh alchemy. So then we
  786. 32:39define the columns and we're going to
  787. 32:41put three of them in here. So we're
  788. 32:42going to have an ID and the way you
  789. 32:44create a column is by saying DB column
  790. 32:48and passing in any attributes of it. So
  791. 32:50it's going to be an
  792. 32:52integer and then we set it as the
  793. 32:55primary key by saying primary key is
  794. 32:58true. Next up we're going to have a name
  795. 33:01which is DB column. And this one is
  796. 33:04going to be a string. So to do that, you
  797. 33:06say db string and you can pass in a max
  798. 33:08length. We'll just say 80. And another
  799. 33:10attribute in here is unique true if you
  800. 33:13want the name to be unique. And you can
  801. 33:15also say nullable is false. So you can't
  802. 33:19have any nulls. And then the last one on
  803. 33:21here we're going to use is description.
  804. 33:24And we'll say dbc
  805. 33:26column. And this is going to be a string
  806. 33:28as well. And we'll just give this 120
  807. 33:31characters. However, I'm not going to
  808. 33:32put any other attributes on the
  809. 33:34description. Now, we want to override
  810. 33:36another method in here and that is
  811. 33:38called the rep re reper method repr for
  812. 33:42uh representation probably. And for this
  813. 33:45we we pass in self which refers to the
  814. 33:48object. So, we can grab the object's
  815. 33:50attributes by saying self dot something.
  816. 33:53So, we're just going to return a string
  817. 33:55and this will be invoked whenever we try
  818. 33:57to print out the the drink in the list.
  819. 34:00So you'll see what I mean here soon. So
  820. 34:02we'll say f to make a parameterized
  821. 34:05string and we can say
  822. 34:08self.name and then maybe you know a
  823. 34:10hyphen and then
  824. 34:13self.escription. All right, cool. So
  825. 34:15that is how we create a model. And what
  826. 34:17we're going to do is we're going to set
  827. 34:18up our database with a table for drinks.
  828. 34:22And to do that the easiest way is to use
  829. 34:24the Python terminal. So what I'm going
  830. 34:26to do is I'm going to quit our server.
  831. 34:28Crl + C and then I'm going to say Python
  832. 34:323. So that's going to open up the
  833. 34:34interactive mode in Python. And what you
  834. 34:36can do is you can say from application
  835. 34:39import DB. So what we do is we import
  836. 34:42our database from application import
  837. 34:44database. However, all we did is define
  838. 34:46the model. We need to actually make this
  839. 34:49connection to the database in our code
  840. 34:51first before we can reference it. So to
  841. 34:53do that, we're going to go up here and
  842. 34:55say from flasks SQL alchemy imports SQL
  843. 35:02alchemy. So all lowercase and then SQL
  844. 35:05is capital here. Then to get that DB
  845. 35:07variable, we just say DB is an instance
  846. 35:11of SQL Alchemy and we're going to pass
  847. 35:14in our Flask app. So that's the setup
  848. 35:16for SQL Alchemy. The last thing we have
  849. 35:18to do is we need to configure our
  850. 35:21database so we can connect to it. So we
  851. 35:23say
  852. 35:25app.config and we're going to pass in a
  853. 35:28string here. SQL
  854. 35:32alchemy
  855. 35:34database urri. And you don't have to
  856. 35:37have all of this stuff memorized. You
  857. 35:39can find this in the documentation for
  858. 35:42flask fairly uh simply. And then we're
  859. 35:44going to say
  860. 35:46SQLite and then three forward slashes
  861. 35:50data.
  862. 35:51DB. So that's how we say we're going to
  863. 35:54create an SQL light database called
  864. 35:56data. DB in the same directory. And then
  865. 35:59I think this DB variable actually will
  866. 36:02come after this config. So we'll paste
  867. 36:04that there. And there we go. So we
  868. 36:07should be able to X out of the Python
  869. 36:11interactive mode. Restart it. And now
  870. 36:14what we should be able to do is say from
  871. 36:16application which refers to our
  872. 36:18application because we named it
  873. 36:19application.
  874. 36:20py import
  875. 36:23db. Great. We didn't get any errors. We
  876. 36:26did get this warning here uh warning us
  877. 36:28about significant overhead and you can
  878. 36:30change some settings but you really
  879. 36:31don't have to worry about that. So to
  880. 36:32create our tables we say db.createall.
  881. 36:35create all hit enter and you can see it
  882. 36:39actually creates the database as well
  883. 36:41since we didn't have that. Now because
  884. 36:42this is what's known as an object
  885. 36:44relational mapper the way we work with
  886. 36:47our relational database is with objects.
  887. 36:50So if we want to create a new drink we
  888. 36:53create a drink object and we can assign
  889. 36:55it to a variable called drink. And the
  890. 36:58way we pass in data to create a drink is
  891. 37:01we do named parameters. So we can say
  892. 37:04name is grape soda and then a comma
  893. 37:08description
  894. 37:11uh I don't know tastes like grapes maybe
  895. 37:14seems pretty fitting. So that is how we
  896. 37:17create oh and you see when we do this
  897. 37:20name drink is not defined. So anytime we
  898. 37:23want to use something from our file we
  899. 37:26have to import it. So this class drink
  900. 37:28needs imported as well. So from
  901. 37:31application import drink and now we
  902. 37:34should be able to use the up arrow key
  903. 37:36to bring back our previous code. Hit
  904. 37:38enter. And now we have a drink object.
  905. 37:40And you can see it by typing in drink.
  906. 37:42And it says grape soda tastes like
  907. 37:44grapes. And that is where this repr
  908. 37:48method comes in. It basically the name
  909. 37:50hyphen in the description. Now to add it
  910. 37:52to our table, we say db session.add
  911. 37:56add drink and then
  912. 38:00db.ession.comit. And that's an important
  913. 38:02step. Yeah, we want
  914. 38:05DB.Comit, not
  915. 38:07doctor. So, db session
  916. 38:10commit. Now, we should be able to get
  917. 38:12all of our drinks by saying
  918. 38:17drink.query.all. Hit enter. And you can
  919. 38:19see it's a list now with just one
  920. 38:21element, grape soda. So if you wanted to
  921. 38:24add another drink, what we can do is
  922. 38:26just go through that process again. So
  923. 38:28we'll do this one in line. So we'll say
  924. 38:30db session add. And we'll create a
  925. 38:35drink. The name we'll call this one
  926. 38:38cherry. And we'll give it this
  927. 38:40description. And this cherry drink I
  928. 38:42drink tastes exactly like this cherry
  929. 38:44ice cream. So that I used to eat. So it
  930. 38:46tastes like that one ice cream. All
  931. 38:50right. Perfect. Hit enter. and then db
  932. 38:55session.comit. Now let's check
  933. 38:59drink.query.all. Hit enter. And now you
  934. 39:02can see we have multiple elements. We
  935. 39:03have grape soda and cherry. So then we
  936. 39:06can exit and go back to flask. Let's say
  937. 39:09flask run. So we got our server running.
  938. 39:12But now we need to create a way to get
  939. 39:15those drinks inside of this route right
  940. 39:18here. So, it's going to be pretty
  941. 39:20similar to what we did earlier. If I can
  942. 39:23scroll up just a little
  943. 39:26bit. We said
  944. 39:29drinks.query.all. So, let's go ahead and
  945. 39:31do that. In this code right here, we
  946. 39:33will say drinks is equal to
  947. 39:37drink
  948. 39:39query.all. And unfortunately, it's not
  949. 39:41something that we could just put right
  950. 39:44here by saying drinks. That'd be nice.
  951. 39:47Um, but I'll show you what happens. So,
  952. 39:50what we can do is if we refresh this
  953. 39:52page and it says object of type drink is
  954. 39:54not JSON serializable. Uh, I've worked
  955. 39:56around trying to figure out how to make
  956. 39:58this as easy as possible. Uh, I I really
  957. 40:01didn't come up with too many great
  958. 40:02ideas. Um, but here's basically what I
  959. 40:04decided. We're just going to build a
  960. 40:06list. Uh, so we're just going to
  961. 40:09basically write out what the JSON should
  962. 40:11look like. So, we're going to say output
  963. 40:12is just an empty list. From here, what
  964. 40:15we're going to do is we're going to
  965. 40:16iterate through the drinks. So, we'll
  966. 40:18say for drink in drinks and we're going
  967. 40:21to describe what it will look like
  968. 40:22inside of a dictionary. So, the end goal
  969. 40:24is to have a list of dictionaries. So,
  970. 40:27we'll just say drink data is a
  971. 40:29dictionary where name comes
  972. 40:33from
  973. 40:36drink.name and the
  974. 40:39description comes from drink.escription.
  975. 40:45like so. And then once we got that
  976. 40:47dictionary, all we have to do is say
  977. 40:51output.append and pass in drink data. So
  978. 40:54that's going to add that dictionary to
  979. 40:56this list right
  980. 40:57here. And it's going to do that twice.
  981. 41:00One for each drink that's currently in
  982. 41:01in the database. And then what it'll do
  983. 41:04is we'll just say
  984. 41:06drinks and pass in output instead. So
  985. 41:10now we have a nice list of dictionaries
  986. 41:13and that should be serializable. So what
  987. 41:16we can do is do a refresh over here and
  988. 41:19there we go. We have an outer object and
  989. 41:23then key value pairs one key with the
  990. 41:26pair of a list of dictionaries. So a
  991. 41:29very similar format to how the API for
  992. 41:31Stack Overflow looked. Now what I want
  993. 41:33to do is I want to create the ability to
  994. 41:35pass in an ID in here. So, let's say we
  995. 41:38passed in a one and we were able to get
  996. 41:41the first drink. So, let's go ahead and
  997. 41:44build that functionality. I'm going to
  998. 41:45clean up my screen just a little bit
  999. 41:47here because we're not going to need
  1000. 41:49this terminal right now. I'm just going
  1001. 41:50to shrink that. And I'm going to hide
  1002. 41:53our different files on the side there.
  1003. 41:58So, what we do now is we create a new
  1004. 42:00route. So,
  1005. 42:02app.oute. And this is also going to be
  1006. 42:05to drinks. and then forward slash and
  1007. 42:08you can use less than and greater than
  1008. 42:11signs to define a parameter here. So
  1009. 42:13that's going to be substituted for a
  1010. 42:15specific number. Now a lot of people
  1011. 42:18debate on whether this should be plural
  1012. 42:20or singular since we're grabbing one
  1013. 42:22drink. I decided to do it plural and
  1014. 42:25I'll show you why. So I found this stack
  1015. 42:28overflow question singular or plural
  1016. 42:30name of resource while creating it. And
  1017. 42:34this person talks in here and you know
  1018. 42:36there's a bunch of different thoughts in
  1019. 42:37here about the best way to do it. And as
  1020. 42:39I was reading this I looked up at the
  1021. 42:41web address and I saw questions plural
  1022. 42:44with the ID. So I was like I think I'm
  1023. 42:47sold. I'm just going to keep it plural.
  1024. 42:49So that is why I decided that. So let's
  1025. 42:52go back to our code in here and we're
  1026. 42:54going to create a new method. So we'll
  1027. 42:55say defaf get drink and this one's going
  1028. 42:58to have a parameter ID. So instead of
  1029. 43:01having a drinks variable, we're going to
  1030. 43:03have a drink variable. And now we're
  1031. 43:05just going to get a drink. So to do
  1032. 43:07that, we can say
  1033. 43:11drink.query.get or
  1034. 43:14404. It's kind of a tongue twister
  1035. 43:17there. And from here, we can pass in the
  1036. 43:20ID. That's going to give us a drink
  1037. 43:22object. And then we can just return that
  1038. 43:25and build a quick dictionary. So we'll
  1039. 43:28say jsonify and we're going to build out
  1040. 43:31the JSON. The key is going to be name.
  1041. 43:36That's going to come from
  1042. 43:38drink.name. And then the second key is
  1043. 43:40going to be description and that's going
  1044. 43:43to come from
  1045. 43:45drink.escription. So dictionaries are
  1046. 43:49serializable instantly. You actually
  1047. 43:52don't even have to call JSONify here. So
  1048. 43:55you can just return
  1049. 43:59uh dictionary like so. But sometimes
  1050. 44:02you'll need to call
  1051. 44:03jsonify if you're not working with a
  1052. 44:05dictionary. So I think that should work.
  1053. 44:07Let's save and let's go back to our web
  1054. 44:10page. And you can see we get one drink
  1055. 44:12back. And we can try it again with ID2.
  1056. 44:16We get that second drink. And then we
  1057. 44:18can try ID3. And we get not found
  1058. 44:20because there's not a third drink in
  1059. 44:21there. Now I wanted to show you real
  1060. 44:22quick. If you go back to ID2 here, you
  1061. 44:26can rightclick inspect and get a little
  1062. 44:28bit more information about this request.
  1063. 44:31So, hitting network and then do a little
  1064. 44:33refresh. You can see this request here
  1065. 44:36and it's a get request. The response was
  1066. 44:38200. Okay. And you can see the content
  1067. 44:40type is application JSON. It's a little
  1068. 44:43bit different than if you're on a web
  1069. 44:44page. What we can do is we can inspect
  1070. 44:46on here and go to
  1071. 44:50network. Get that first request on here.
  1072. 44:52And that's 200. Okay. Also a get, but
  1073. 44:54this time the content type is
  1074. 44:58text/html. So yeah, just want to call
  1075. 45:00that out for you guys. Let's go ahead
  1076. 45:01and go back. And now I want to talk a
  1077. 45:03little bit about adding a new drink. So
  1078. 45:06let's go ahead and create another route
  1079. 45:09on here. We'll say
  1080. 45:11app.oute. The path is going to be
  1081. 45:13drinks. And you can actually have
  1082. 45:16another parameter in here which is
  1083. 45:18methods and say post which is good to do
  1084. 45:22if you're defining for a post request.
  1085. 45:24You can put any of the methods in here.
  1086. 45:26You could put get or delete or whatever.
  1087. 45:28And you can actually condition. So you
  1088. 45:30could check to see what method the
  1089. 45:32person's requesting. So you could you
  1090. 45:35could in theory define all of this in
  1091. 45:38one
  1092. 45:39method and then you know check to see if
  1093. 45:43they're trying to get all the drinks or
  1094. 45:46add all of the drinks. However, I like
  1095. 45:48to just have a little bit more separate.
  1096. 45:50So I put them in separate methods here.
  1097. 45:53And we'll just create a separate method.
  1098. 45:54So add drink. Now this one's going to be
  1099. 45:58a little bit more complicated because we
  1100. 45:59actually have to get the request data.
  1101. 46:02So when the person calls this, they're
  1102. 46:03going to pass in the structure of what a
  1103. 46:06drink should look like. So we're going
  1104. 46:09to get this by creating a new
  1105. 46:13drink. And where are the attributes for
  1106. 46:16the drink going to come from? Well, the
  1107. 46:18name is going to come from
  1108. 46:21request.json. So that's how you can
  1109. 46:23access the JSON data that they send.
  1110. 46:26It's through
  1111. 46:27request.json. And we're going to be
  1112. 46:29looking for name. And we're going to do
  1113. 46:30the same exact thing for the
  1114. 46:33description. And that is going to come
  1115. 46:36from
  1116. 46:38request.json
  1117. 46:41description. There we
  1118. 46:43go. Now we can add these by saying
  1119. 46:47db.ession.add and pass in the drink
  1120. 46:53db.ession. Then what we could do, we can
  1121. 46:55return whatever we want. We could say
  1122. 46:57successfully added. Um, or you could do
  1123. 47:01the ID. So if you wanted to return the
  1124. 47:04ID, it's going to look like return ID
  1125. 47:09colon drink ID. So that ID attribute is
  1126. 47:13going to be added to this drink object.
  1127. 47:15So that's pretty convenient. Save that.
  1128. 47:18And now let's give it a try. So we'll go
  1129. 47:21over to here, but we can't really pass
  1130. 47:23in the data for our requests really
  1131. 47:25easily. So this is where Postman comes
  1132. 47:27in handy. So from here, what we can do
  1133. 47:30is we can
  1134. 47:32define what a drink should look like in
  1135. 47:35JSON inside of the body of our request.
  1136. 47:38And then we just set it to post. And
  1137. 47:40also, we'll want to update our web
  1138. 47:41address. So you can copy that from right
  1139. 47:44here. Paste that there. And what we're
  1140. 47:48going to do is we're going to give this
  1141. 47:49a
  1142. 47:50name. Let's zoom in a little bit. What's
  1143. 47:53the name going to
  1144. 47:54be? Uh we'll call it cola. And then the
  1145. 47:59description is
  1146. 48:01delicious. All right. So, just check
  1147. 48:03everything is right. We got body, raw,
  1148. 48:05JSON, post, and the correct web address.
  1149. 48:09Hit send. We got an error on line
  1150. 48:1342. Let's go back to our code real
  1151. 48:15quick. Looks like we might have some
  1152. 48:16kind of formatting issue here.
  1153. 48:18Unexpected name request. For request to
  1154. 48:22work, I think we need to do another
  1155. 48:24import from Flask. So, we'll say request
  1156. 48:28there. And hopefully that'll do the
  1157. 48:30trick. I'm also getting another warning
  1158. 48:32down here. I think we need to uh take
  1159. 48:35this and move it up a line. It wasn't
  1160. 48:38causing any issues, but best practice
  1161. 48:40there. All right, let's scroll back down
  1162. 48:42in our code. And it looks like we don't
  1163. 48:44have any more warnings. So, we will go
  1164. 48:47back to Postman and hit send. And it
  1165. 48:50looks like uh we're making progress.
  1166. 48:52Okay. So the issue here is that we're
  1167. 48:56not using the right web address. So we
  1168. 48:59need to go to drinks, no forward slash,
  1169. 49:03and hit send. So that was nice that that
  1170. 49:06worked. And in this situation, it
  1171. 49:08returns the ID of three. So now we can
  1172. 49:11get all of the drinks. We can still keep
  1173. 49:13this body here. We don't have to delete
  1174. 49:15that. Hit send. And you can see all the
  1175. 49:17drinks there. Or you could pass in the
  1176. 49:20ID of three. Hit send and you can get
  1177. 49:23that new one. Last thing I want to talk
  1178. 49:25about is how to delete a drink. So let's
  1179. 49:27go ahead and go back to our code and
  1180. 49:29create a new route. We'll say
  1181. 49:32app.oute. The path is going to be drinks
  1182. 49:35and we're going to take the
  1183. 49:38ID so that way we know which drink to
  1184. 49:41delete. And then for the methods, we're
  1185. 49:43going to say delete. There we go. and
  1186. 49:47we'll say defaf delete drink. So for
  1187. 49:51this to delete a drink we're going to
  1188. 49:54say db
  1189. 49:57session delete and pass in the drink
  1190. 50:00structure. The best way to get this
  1191. 50:03drink structure I thought would just be
  1192. 50:04to get it from the database. So we're
  1193. 50:07going to create a variable drink and say
  1194. 50:11drink.query.get and pass in the ID. So
  1195. 50:14I'll take the ID as a parameter from
  1196. 50:16this web address. And then after we
  1197. 50:18delete, we say
  1198. 50:21db.ession.comit. And I was having a
  1199. 50:23little bit of an issue. Now in general,
  1200. 50:24I haven't done a lot of like error
  1201. 50:26checking and different edge cases.
  1202. 50:29However, I was getting it where I would
  1203. 50:31delete a drink and it wouldn't exist and
  1204. 50:33I would get an issue. So I decided just
  1205. 50:35to add a little bit of extra casing
  1206. 50:37here. So, if drink is none, what we're
  1207. 50:40going to do is we're just going to
  1208. 50:41return and I'm just going to say
  1209. 50:44something like error not found or
  1210. 50:47something. Or you could return a 404.
  1211. 50:49Just showing some different options
  1212. 50:51here. And you know, if that doesn't
  1213. 50:53happen, then I'm just going to assume
  1214. 50:55everything's good. And we're just going
  1215. 50:56to return
  1216. 50:58uh we'll say message. And I don't know,
  1217. 51:01we'll just say something like yeet.
  1218. 51:04There we go. Okay, let's test this one
  1219. 51:06out. For this, what we're going to do is
  1220. 51:08we're going to do a delete. And we don't
  1221. 51:12have to pass in anything with the body
  1222. 51:14just to show you guys. I'll delete that
  1223. 51:16just to make sure it's clear. We do pass
  1224. 51:18in the ID here, however. Hit send and it
  1225. 51:21says yeet. If we hit send again, it says
  1226. 51:24error not found. So, that is how you do
  1227. 51:29the most basic API calls. We have the
  1228. 51:33ability to get all the drinks, a
  1229. 51:34specific drink, add a drink, or delete a
  1230. 51:38drink. I didn't really do anything for
  1231. 51:40updating a drink, but a drink is so
  1232. 51:42simple. Like, I feel like you could just
  1233. 51:44delete a drink and then read it. Or if
  1234. 51:46you want to practice, you could try some
  1235. 51:48uh put requests here. But that's all I
  1236. 51:50got for you guys for the basics of
  1237. 51:52creating an API in Python. It's a lot
  1238. 51:55more to it, but hopefully that'll get
  1239. 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.