Python Bytes - #147 Mocking out AWS APIs

Episode Date: September 11, 2019

Topics covered in this episode: rapidtables Quick and dirty mock service with Starlette Mocking out AWS APIs Single Responsibility Principle in Python Extras Joke See the full show notes for thi...s episode on the website at pythonbytes.fm/147

Transcript
Discussion (0)
Starting point is 00:00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to earbuds. This is episode 147, recorded September 4th, 2019. I'm Michael Kennedy. I am Brian Ocken. And this episode is brought to you by DigitalOcean. Tell you more about some cool stuff they got coming up later. Right now, I want to talk about tables. Okay. And really quick, what's 147 in hex?
Starting point is 00:00:22 No, just, I couldn't do that. I don't expect you. Anyway. No, but one of the things I do need to do occasionally, I need to do really fast is generate tables. And I know it's not something that everybody needs to do. But if I've got a whole bunch of data, like in this case, some dictionaries list, and I want to be able to just print that stuff out. They're all the same type of dictionary. They just hold some data. I want to print them out. How do I do that quickly? And for test reports or whatever, I found this called rapid tables and it's really kind of awesome.
Starting point is 00:00:56 Oh, that is so cool. Wow. Yeah. So you just basically, you've got a list of dictionaries and then you want to print them out and you want it to look like a good ASCII table. It shows you how to do it. And it also shows you how to do it with a thing called termcolor.colored. I didn't know this was around. So you can do colored tables if you want. I probably won't do that.
Starting point is 00:01:19 It also converts stuff to markdown and restructured text. That's kind of neat. I might use that. But right away, I just need the just really easy tables. And it says it's super fast in speed, like speed wise, it goes fast. But what I like is that it's not a lot of extra code gunk in your code. You just kind of say, I want this table and you can print it out easily. Yeah, that's super cool because a lot of times like this kind of formatting, it's a lot of Z fill and pad these strings and L pad,
Starting point is 00:01:51 like just like trying to get the spacing and you're putting tabs, but every now and then the tab, like the word is too big. And so the tab will shoot it to the next column. It's a lot of work. And this is not you doing that work. Right. So for all the columns,
Starting point is 00:02:02 you have to go through each of the elements to find the longest one, to figure out how long you, how wide you need to make the column. And it's, and yeah, there's other libraries to do this, but this one I think is pretty cool. Yeah. It's pretty cool. I also like the markdown and restructure text output option. Yeah. Very cool. Yeah. So if you think about what is like one of the most popular packages, what would you say? Take some guesses. Requests. It's gotta be requests. I don't know if it's the most popular packages, what would you say? Take some guesses. Requests. It's got to be requests. I don't know if it's the most used one, but it's certainly the one that has people's
Starting point is 00:02:30 attention and imagination. So what would you think if I told you here is a competitor to request called HTTPX? Ooh, I like the X. It's extra cool. Absolutely. What's really interesting about HTTPX, though, is it's not a from scratch, like throw away the ideas of requests. It's compatible with the request API. So what you can do with requests, you can do with this. So you can kind of drop it in. But it has all these other cool features. And in fact, it comes from this project called ENCODE, E-N-C-O-D-E, ENCODE. And over there, they have a ton of cool things, including Django REST Framework, Starlet, uveacorn, HTTPX,
Starting point is 00:03:10 and also some other async stuff. And a lot of the things happening around here, uveacorn databases, ORM, HTTPX, is all about adding the asynchronous capabilities to these various things, right? And that's one of the shortcomings of Request is it doesn't support an async option. But this HTTP, it does a bunch of cool things around the async space to kind of let you gradually go up the stack of complexity. So you can just be straight
Starting point is 00:03:36 synchronous stuff doing what request does. It has this concept of parallel requests. So you can issue a bunch of requests in parallel, but you don't have to think about actually creating the async event loop and stuff. You just say, I want to run these things all in parallel. And you could even ask it, say, like, I want to process the responses as they come in. So I can say, like, while parallel.hasPendingResponses, the response is parallel.nextResponse. So I can kick off like 20 requests and just process them as they come back in like four lines of code or something.
Starting point is 00:04:10 Oh, that's so cool. I like it. Yeah. Or if you really want, if you're in something like Starlet, where it has actual async support for the method, you do want that to be async. So you can actually flip into like an async mode where those happen the same way I described, but also on the async IO event loop. So it's really cool. It also has some other neat features. So like I said, a request compatible API.
Starting point is 00:04:32 It does HTTP2, which like I could do a request for a page. And as I pull down like, say, five CS style sheets and a JavaScript and an image, you can go get those all in one request. So it has support for that, which is cool. It has a standard synchronous interface, but also async and await if you want it. And Brian, you'll like this one, it allows you to make direct requests to WSGI or ASGI, the asynchronous variant of that apps. So imagine I'm creating a flask app, I don't want to test it, I can actually inside of my flask app, provide HTTP, the app, right creating a Flask app. I don't want to test it. I can actually, inside of my Flask app, provide HTTPS the app, right?
Starting point is 00:05:08 The Flask app object. And then I can issue requests that don't go through the network layer. They just go through this test app instance that I've created. Oh, that's cool. Isn't that cool? So if I want to mock out some behavior or interact with it as if I were externally, I don't have to start a server and talk to it i'd literally just like use the same api here but like directly skipping all the infrastructure oh that sounds fun yeah in like you know a nerdy kind of fun yeah that sounds like
Starting point is 00:05:35 really fun but yeah it is also fully type annotated so it's very like python 3 friendly uh has 100 test coverage and yeah it has support for mocking out things a lot of cool nice features and the fact it's built all this is built on top of requests means if you're already using requests it's like you can adopt it pretty easily because you don't have to change anything but if you want to bring in some of these cool new features it's just you know you start using nice now one caveat i does say that this is in some of these cool new features it's just you know you start using nice now one caveat i does say that this is in some form of alpha it's like pretty early days for this project but yeah it says this this project should be considered an alpha release it's substantially api complete but some areas need to work well you know people start using it people start contributing to it
Starting point is 00:06:20 all of a sudden it becomes not alpha so anyway it, it's out there for people to use. This is sort of the same umbrella area as Tom Christie and the Django rest framework area. So I think it's a pretty good place. Cool. Okay. Neat. Speaking of stuff under the encode GitHub project. So Starlet is part of that as also? Yeah. Okay. So interesting that we did not plan this. The universe planned it to line it up for us. Oh, my gosh. We're wearing the same color shirt also. Oh, my gosh. It's black, so that's not that weird of a coincidence. But anyway, so the article I wanted to highlight was Quick and Dirty Mock Services with Starlet.
Starting point is 00:06:58 This is by a friend of the show, Matt Lehman. Hey, Matt. It's kind of a neat thing. So one of the ideas, I don't know if we've talked about this on the show, but the idea of testing. So if you've got something that you're part of your application or the thing you want to test talks to a third-party service, sometimes you might not actually want to call that third-party service. You can mock or stub out the calls to the service, or one of the ideas is to create a fake service to talk to.
Starting point is 00:07:27 And so that's what this article is about, is how to create a fake service so that you can use it for testing. And Matt writes a really quick one using Starlet. And I think you could use other frameworks too, but I like how simple this is. One of the needs he had was that he didn't want the service to like just come back right away. He wanted some delay because there were some of the service calls that were taking up to a minute or longer, and he wanted to be able to simulate that within his fake service so that you can test the code under test to make sure it is working correct with a big delay. Anyway, like it was a really easy to read write up, easy way to
Starting point is 00:08:06 do that. And I know that that's a, it's a recommended practice for a lot of instances. And this is, but there aren't any very many write ups of how to do it. And so congrats, Matt. I like it. Yeah, that's, that's really cool. You know, when you think of dependencies, you think of, well, my database layer or Stripe API or something, but time is one of those dependencies that's really tricky. Most of the time, one of the reasons why we try to do a mock-a-service is to eliminate that time. You want to make sure that the flow of the data goes quickly, but you don't want to wait for the service during your test. But at the same time, you kind of want to make sure that you're... And in most case test cases, maybe that's the right thing,
Starting point is 00:08:45 but you also want to make sure that your, your application deals with long latencies if that's the normal situation. Yeah, for sure. You might want to shrink it from five minutes to five seconds or something. So the tests don't run super long, but yeah. Or even like, I want to start something and then see in an hour if it's done, you could like, you know,
Starting point is 00:09:05 have to fake out like, you know, daytime dot now. So the next time you ask it, it's like two hours from now, but it's one millisecond, you know? Yeah. Well, and you, you know, make sure your parameterization of that test doesn't make it so that you're running 50 different versions of the hour long wait. Yeah, for sure. All right right, now before we get to the next item, let me tell you about some new services from DigitalOcean. So they've traditionally had recently added Postgres as a service. So now hosted database, which is really cool, but maybe you don't use Postgres.
Starting point is 00:09:37 Maybe you want to use Redis. We just talked about queuing and stuff. So Redis is now a service that you can get over at DigitalOcean, Redis as a service, and also MySQL as a service. So check that out over at pythonbytes.fm slash DigitalOcean, get $50 credit for a new user. They've got all sorts of good stuff coming your way. And of course, all of our infrastructure runs on it as well, which is fun and very good. All right, the next thing I want to talk about is that other larger cloud provider. Have you heard of something? It's some people started using this,
Starting point is 00:10:11 Brian. It's called AWS. Have you heard of this? I think so. Yeah. Yeah. I think like a quarter of the internet at least runs on it. So the Python API, the Python package that used to talk to things like S3 and EC2 and AMI and all the stuff over at AWS is called Bodo. Yeah. Okay. So there's a project brought to our attention by Giuseppe Consolo. Thank you for that, Giuseppe. Called Mocking Out AWS APIs with Modo. So if you're going to mock out Bodo, what would you call it?
Starting point is 00:10:47 Modo. Oh, nice. Now, it lets you do all sorts of stuff. Like if you say, want to mock out an S3 bucket, right? So S3 is like file blob storage. You can mock it out and then like save, quote, save a file to it and then see if it's there or preload it with data and then interact with it. And it's got all sorts of interesting stuff. But if you start to dig through this library, it turns out it's got both some really interesting ways to test stuff. And it's also super comprehensive. So for example, if I want to test working with S3, I can say from Modo import mock S3. And then I just put an app mock S3 on my method and my test method. And now all of my true S3 calls with Bodo actually don't go to Bodo. They go to this Modo mock version. Oh, that's neat.
Starting point is 00:11:33 Yeah. But apparently it doesn't really end there because if I wanted to work with like EC2, I could import mock EC2 and put that on there and say Bodo dot working with, you know, do all the Bodo client EC2, whatever. It's like, I don't know why Bodo is so terribly complicated. It's like super overloaded, but anyway, that's a different time for a different story. You can go and like, ask for your reserved instances and it'll use your mocked out ones and things like that. So just like if you were to go flip through all the stuff that it supports, ACM, API gateway, auto-scaling, cloudM, API Gateway, autoscaling, cloud formation, CloudWatch, CloudWatch events,
Starting point is 00:12:08 Cognito Identity, Data Pipeline, DynamoDB, et cetera, et cetera. And we're only into the Ds, right? It just goes on and on and on of all the different AWS things that it mocks out. So if you got to test AWS, this is pretty killer. Like you can mock out Glacier, IoT, Kinesis, whatever, you name it. One of the notes you added was that it can run as a standalone server mode so that you can even test non-Python code. That's right.
Starting point is 00:12:34 That's right. So apparently I can, yeah, there's a way to run it as a server and then talk to it as if it were some of these services as well, which is pretty wild. It is incredible. And I guess good that Bodo is all of the interface so that it's one point to mock it. Yeah. Yeah, Bodo, the reason I don't like it is you say Bodo and you create a client and then you pass it a string. The string could be like EC2 or S3.
Starting point is 00:13:01 And then how you interact with it has to do with what factory that string drove it to to dry to create a different like you it's really hard to discover what can I do with this thing because it's it's like a generic blob that that can be converted into something more real I don't know it's it's funky but yes in this regard it's definitely very nice apparently your life is more complicated than mine I guess I've worked with S3 and Elastic Transcoder and all that stuff too much. Yeah. Okay, cool. What's next? I was just thinking that maybe we should have done a testing code episode with all this testing stuff. Yeah. But one of the things that we have, I think we've
Starting point is 00:13:35 talked about Mongo Engine before. And I know that you've used Mongo Engine in some of your courses, right? Yeah, for sure. And on and on the sites yeah and it's like a mappers um they don't say orm because object relational mapping because it's not really the r so they say odm for object document mapper that's like the okay the adapted acronym so i didn't know that there were so i knew about mongo engine because of you but i didn't know about others and here's a project called micro mongo or muewMongo? Not sure. Yeah, I think MicroMongo is the way you would say it. I think that's the Greek. Yeah. It's a Python MongoDB ODM. And it comes because the people that made it had two needs. They wanted an asynchronous ODM. And for some reason, they felt like it was difficult to
Starting point is 00:14:22 do serialization and un-serialization of documents with existing ODMs. And so this one does it. So it's an asynchronous sort of thing. It works directly with some of the popular Mongo drivers like PyMongo, TxMongo, that's for Twisted, MotorAsyncIO, and MongoMock. And I'm kind of excited about MongoMock. Yeah, for sure. I got to say, this is probably the most interesting aspect of this because something like Mongo engine, it just works with PyMongo. But this one says, you know what, we actually can work with all these different foundations, which gives it like fundamentally different behaviors and features, right? If you pointed at the twisted one,, it can now integrate with Twisted's Async or its model. MotorAsyncIO now lets it plug into true AsyncIO stuff. Like you could plug it into
Starting point is 00:15:11 Scarlet like you discussed before and those Async methods there. And then the mocking as well, like we're just going to take the foundation and make it a mock version. All those are super cool. Yeah. And then also because of this, I learned about MongoMock, which is a cool way to mock out your Mongo database. So kind of neat. Definitely want to try this sometime. Yeah, it definitely looks interesting. I don't remember exactly when this got created. Do you know what GitHub needs? Is it needs a, this project was created on this day, right? Because you can go back to the commits, but if there's thousands of commits, you've got to like infinite scroll your way back to the origins. But anyway, yeah, it's really cool. I think if I had known about this at first, I might've even chosen this over Mongo Engine,
Starting point is 00:15:54 but yeah, it's really nice. It's nice. It has a 90% plus test coverage. I really like the different foundations, which means you learn like one odm style of programming but then you can use it in these different situations yeah super cool i like it and also i didn't know about manga mock either but now i'm excited about it that looks cool nice all right so let me hit you with um an opinionated piece here and you can give me some feedback let me know what you think about it some parts of it... Okay, I got my tomatoes ready. Yeah, perfect.
Starting point is 00:16:27 Get ready to throw them. I'll get ready to dodge them. So this article was sent over by Tyler Madison. Listener, thanks for sending that over. Now, it's called the Single Responsibility Principle in Python. And the Single Responsibility Principle, or SRP, comes out of this larger group of design principles, coding principles, architecture principles, something like that, called SOLID. So S is the Single Responsibility Principle. O is the Open-Close Principle.
Starting point is 00:16:55 L is Liskov's Substitution Principle. And these even come in really interesting demotivator-style posters. I don't know if you're all familiar with demotivators. You're probably familiar with motivators. Like you will see this probably in the entryway, like kind of near the CEO office. It's like probably got a giant eagle soaring above clouds, like together we can fly higher than you ever dreamed or something stupid like that. Well, the demotivators take pictures like that, but put like negative captions and connotations. So these are really interesting things. For example, the Lisskov substitution one has a duck and a rubber duck in the water. And it says, if it looks like a duck and quacks like a duck, but it needs batteries, you probably have the wrong abstraction, right? So there's all these, there's all these really cool demotivator style posters around the solid principles. And I think the solid principles are pretty neat. Like you can go overboard with them,
Starting point is 00:17:49 but they are pretty powerful. So, this article focuses specifically on the single responsibility principle. And I think talking about it is really interesting. I think the solution is unexpected and it made me think. And at first I'm like, Oh, I don't like it. But after a while, but it is pretty creative and things that make me think I like to share with people. So I guess that's why I chose it. And it starts out by saying this article will guide you through the complex process of writing simple code. And it talks about stuff that you would expect, right? So there's, there's some kind of super long function says this is terrible, you can't test it, you can't reason about it because it's doing five things.
Starting point is 00:18:29 How do you know whether you're doing too much? You can look at measures like the cyclamatic complexity, the Halstead complexity thing, the number of arguments, the number of statements, body length, all that kind of stuff. And that'll help you condense down into, say, reasonable classes or functions. And this is really mostly focusing on functions. So all right, well, let's think of another simple example. I want to calculate the price of a bunch of products given a list of products. And it seems all well and good, except for that it also happens to use some kind of logger object and log out the price. Well, now this thing is doing two things.
Starting point is 00:19:04 It's one calculating and logging it out. What if you want to test it or work with it with its computation bits, but not the logging bit or something like that? So how do you go around dealing with these types of dependencies, right? This kind of goes back to the testing side of things, Brian. How do you deal with things like files and database connections and or database connection objects and you know loggers and whatnot so this guy takes us through this whole sort of thought process which is really good and says you know what we're going to do we're going to come up with callable classes and the callable the callable classes will be given the dependencies and then
Starting point is 00:19:48 you call them like functions allowing you to pass different dependencies or other dependencies and now that seems like a really bad idea but he's using they're using a lot of it and my first thought was okay well that's you know, that's like a curvy shaped weird hammer that I guess you could hit it with. But it's using a lot of interesting Python features. So if you create a class that has, it's a data class, you set frozen equal to true, slots equal to true. It means all of its variables become internal and private only. You said it'd be private or final rather, so it can't be derived from, and you give it a call function.
Starting point is 00:20:28 It turns out to be pretty interesting. And then they talk about some dependency injection frameworks that work with these types of classes. In the end, it comes up with a pretty interesting way to create these things and then call them. I'm not sure that I love it, but it definitely made me think, and I was a little bit surprised by it, so I thought you all might enjoy it.
Starting point is 00:20:49 Yeah, it's an entertaining read to give you that. Look at the very last code fragment in that article, Brian. Okay. The last code fragment that says, like, send postcards equals container dot resolve. Send to these postcards. Yes, exactly. And a little bit above it.
Starting point is 00:21:08 Yeah. Yeah, yeah. So, it is powerful in that you can create these objects. You can pass in mock objects without actually using mock dot patch and stuff. It's interesting. I don't think that I would go write software using this today. But I might use some of the concepts of it, maybe. My opinion is that it is possible to do this, and it might make sure that you don't get fired because nobody else can edit your code.
Starting point is 00:21:37 Yeah. Okay, so I do like the single responsibility part of solid. I am not a fan of the Liskov substitution principle or the open-closed or dependency injection is something that frightens me. These are things that were put in place to work around limitations of other languages like Java and C. And I'm going to get tomatoes thrown at me for coming up with saying this, but some problems are complex. And you can remove the complexity out of one part of your code, but it moves to somewhere else. And maybe it makes your unit tests better, but your system tests are just the same.
Starting point is 00:22:20 Or it makes writing regular code super hard because you're like, where did this database connection come from? I have no idea how I got here. Right? Yeah. It is a thing. It's an interesting article. I'm not a fan.
Starting point is 00:22:32 Yeah, I submit this to everyone as a thought piece, not necessarily as guidance. Yeah, but I'm not willing to say that it's wrong. It's just my opinion. All right. Well, I think we should leave it there for our main topics. Got anything you want to share with folks this week? I've got one quick one. Oh, you'd share it with us then. right the dot es extension i just go challenges put the period between g and es and that's a place where you can go do like practice exercises and it's a cool platform they've created and they
Starting point is 00:23:11 just came out with byte 220 where they walk people through analyzing the python bytes rss feed oh cool yeah so you can go in there and it shows you how to use feed Parser, which is a really cool way to parse RSS feeds. Go in there and actually answer questions. What were they looking at? It was things like, what is the average duration of an episode in seconds? What are the number of episodes with special guests? Like Trey was on the show last week, for example. What are the most common domain names we mentioned?
Starting point is 00:23:42 Like GitHub probably is right up near the top and things like that. So it's pretty cool that there's like this guided challenge to get through our platform, at least our platform's data. Yeah, I'll have to come up with ways in our show notes to break their challenge. No. Yeah, that sounds good. So that's all fun.
Starting point is 00:24:00 People can check that out if they're interested. You ready for some jokes? Definitely. These come from Web Boss's Dad Jokes GitHub repo. So they're pretty short and sweet, but they're in the dad joke style, which is kind of bad jokes that are hopefully funny. So what do you get when you cross a computer and a lifeguard? I don't know. What?
Starting point is 00:24:20 A screensaver. What do you get when you cross a computer with an elephant? Lots of memory. Lots of elephant? Lots of memory. Lots of memory. Lots of memory. Okay. Nice. So I'm going to share this because I made it up and I thought it was funny, but it's
Starting point is 00:24:36 an anti-joke. So a Python developer, a PHP developer, a C Sharp developer, and a Go developer all went to lunch together. Oh my gosh, what happened? They had a nice lunch and all got along fine. Perfect. Of course they should. They're all developers.
Starting point is 00:24:51 Anyway, thanks. Awesome. Yeah, well, thanks as always, Brian. See you later. Thank you for listening to Python Bytes. Follow the show on Twitter via at Python Bytes. That's Python Bytes as in B-Y-T-E-S. And get the full show notes at pythonbytes.fm. If you have a news
Starting point is 00:25:06 item you want featured, just visit Pythonbytes.fm and send it our way. We're always on the lookout for sharing something cool. On behalf of myself and Brian Auchin, this is Michael Kennedy. Thank you for listening and sharing this podcast with your friends and colleagues.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.