« Return to show page
Transcript for Episode #121:
Microservices in Python
0:00 Michael Kennedy: Do you have a big monolithic web application or service that's hard to manage, hard to change, and hard to scale? Well, maybe breaking them into microservices would give you many more options to evolve and grow that app. This week, we'll meet again with Miguel Grinberg to discuss the trade-offs and advantages of microservices. It's Talk Python to Me, episode 121, recorded June 2nd, 2017. Welcome to Talk Python to Me, a weekly podcast on Python, the language, the library, the ecosystem, and the personalities. This is your host Michael Kennedy. Follow me on Twitter where I'm @mkennedy. Keep up with a show and listen to past episodes at talkpython.fm and follow the show on Twitter via @talkpython. This episode is brought to you by Datadog and us here at Talk Python Training. Be sure to check out what we're offered during the segments. It really helps support the show. Miguel, welcome back to Talk Python.
1:16 Miguel Grinberg: Thank you, thank you to be here a second time.
1:18 Michael Kennedy: Yeah. It's great to have you back. Previously, we talked about building Flask web applications and web services and that was really fun. And I think we're going to take it up a notch in terms of abstraction and talk about a more general idea, which obviously is frequently done in Flask but could be done in Pyramid, could be done in Django or NodeJS, microservices.
1:40 Miguel Grinberg: Yes.
1:42 Michael Kennedy: So microservices are really interesting and there's a couple of ideas vying for this, like how do we decompose our big applications and we'll dig into that but first, just want to let people know if they want to hear your previous episode, that was episode 48 and maybe we can quickly talk about PyCon. We were just both their, right, you have a good time there?
2:02 Miguel Grinberg: Yeah, yeah, I had a lot of fun. It always surprises me that people recognize me and they stop me and they say, "Thank you. Your tutorials, your blog it's what got me into programming or helped me advance," so I've always end up with a smile.
2:19 Michael Kennedy: It's really amazing how many people I was around who were like, wow, people actually really appreciate what I do and
2:27 Miguel Grinberg: Yeah, yeah, likewise, I mean I just do it because I enjoy, it, need to be honest, I do it for myself.
2:33 Michael Kennedy: Yeah, but it's really great to see that you make a difference, like some of the other podcasters that are podcasters, we're like, wow, people really appreciate what we do. You do this work often really very much in isolation. I don't mean it in a bad way but like you sit down to write your book or you write your series of blog posts or you record a course or even the podcast is kind of just two people, right? And then you go to one of these events, you're like, wow, there's a lot of people who this actually affects, how cool it is that I'm doing this.
3:04 Miguel Grinberg: Yeah. That's something that I really enjoy, so yeah.
3:07 Michael Kennedy: Yeah, and you do a tutorial, right, on microservices, right?
3:10 Miguel Grinberg: I did a tutorial so these are the three-hour-long tutorials that happened before the main conference, so, yeah, this year, this is the fourth consecutive year that I do a tutorial and this one was on microservices.
3:22 Michael Kennedy: Yeah, excellent, so we'll definitely have to put that into the show notes.
3:25 Miguel Grinberg: Sure, yeah, it's been on YouTube, the day after I gave it, they put it, they're very efficient.
3:31 Michael Kennedy: It's amazing they really seem to have the AV work down at PyCon these days.
3:36 Miguel Grinberg: They're very good, yes.
3:38 Michael Kennedy: I think it's also part of their outreach mission, I would guess. There's 3,300 people that came to PyCon but there's, already I think some of those videos have more people watching online than actually attended the conference.
3:49 Miguel Grinberg: Right, yeah.
3:51 Michael Kennedy: Yeah, so what were some of your favorite sessions, some talks or experiences?
3:56 Miguel Grinberg: Always dictionaries, those are always interesting, for example, there were a few this year so and I always end up learning something new that I didn't know.
4:03 Michael Kennedy: It's amazing, right?
4:05 Miguel Grinberg: But dictionaries I always go to. Those are all really nice, of course, I enjoyed the closing keynote by Kelsey Hightower because it was about microservices.
4:17 Michael Kennedy: Yeah, very much was, yeah, yeah, that's definitely a great follow on to this as well using Kubernetes and Docker an whatnot. All right, so, yeah, before we get into microservices, maybe just tell everyone, some people know you, some people don't, what do you do day-to-day? Where are you coming from, what's your perspective?
4:36 Miguel Grinberg: In the last few years, I have been working, well, actually for a very long time, I've been working as a software engineer. In the last few years, I've been building cloud applications, right now I'm working for Rackspace and I am helping build some of the services that our customers use when they go to the Rackspace control panel, more specifically, the services that I work on are ones that allow customers to deploy applications that then we manage. They deploy applications very easily by clicking and dragging stuff, basically, we do all the magic. Of course, we use microservices for all of this.
5:14 Michael Kennedy: Yeah, that's really cool and you have a book, right, the way we talked about just a little bit in the previous podcast.
5:20 Miguel Grinberg: Right and then I have a book. The book is called Flask Web Development. It's now, I think, a little bit over three years old and I'm currently working on the second edition so probably later this year, hopefully before Christmas, we'll see, the second edition will be out. That's going to basically refresh, the book's largely going to be the same. It's going to update a few things that changed in Flask or some of the extensions and related projects that I referenced.
5:51 Michael Kennedy: Yeah, progress is great but when you create things like books or video courses
5:55 Miguel Grinberg: Right.
5:57 Michael Kennedy: It's really frustrated when they change actually.
6:00 Miguel Grinberg: Yeah, I mean, it's really amazing, to be honest, that after three years or a little bit more, large parts of the book are still updated. Flask, thanks God, is not framework that likes to change things in big ways.
6:16 Michael Kennedy: Yeah, that's right, it was a pretty mature framework when you got to it. If you did Japronto or Sanic right now, you might be rewriting that thing in a year.
6:24 Miguel Grinberg: Right, yeah, and actually I do have one of my open-source projects, I have support for Sanic and aiohttp, as well as Flask and Django and many others. It's a SocketIO server, it's called Python SocketIO and I find that aiohttp and Sanic require more attention than the old friends from the WSGI world.
6:49 Michael Kennedy: Yeah, absolutely, yeah, but it's good, those things are changing. Those things are growing, those are the frameworks that are pushing the web forward in the Python space.
6:58 Miguel Grinberg: Yes, absolutely.
6:59 Michael Kennedy: It makes living around their orbit more work but I think it's going to make it all better for everyone in the end.
7:04 Miguel Grinberg: Yeah.
7:05 Michael Kennedy: All right, so let's start with what are microservices, like if I wanted to take and create like a, keep it on Flask, since that's where if I were to create a Flask app, I could just put everything in there, right? I could do my user management, I could do my data access. I could do my reporting, all that stuff I could just stick into like one big Flask app and ship it, right?
7:27 Miguel Grinberg: Correct and I cover many times. It's in the book and in tutorials that I've done in previous years, with Flask, you have a way to organize your application when it starts to become large. It gives people some trouble, there something issues with circular dependencies but you can do it. You can end up with a single application. In the context of microservices, we call these types of applications monoliths because they're one big thing.
7:55 Michael Kennedy: Yeah, yeah, so maybe compare and contrast with that what are microservices relatively?
8:01 Miguel Grinberg: I can draw a parallel so we all know that if you write your application in a single big function, that that's really not good, it's hard to maintain.
8:10 Michael Kennedy: Yeah, you should at least use two, two functions.
8:13 Miguel Grinberg: You usually use two or three, right. So basically what you do when you're talking about functions is you write small functions, each function at least you should try that it does one thing and then the functions call each other and that's how you achieve the big problem, the solution to the big problem, right?
8:32 Michael Kennedy: Right, and functions though, I think of it as if I can't give it just a simple name that says what it does, it's wrong. There's something wrong with it. I need to change the function so I can name it better, right?
8:43 Miguel Grinberg: Correct, right, so microservices, it's basically the same idea but applied to a web service so the traditional way in which you develop a web application in Python, say, using Flask, Bottle or Django or anything, Pyramid, basically, like you said before, you put all the contents in one application and then without realizing it, you have coupling between the different subsystems. You have a users' subsystem that keeps track of your users and then you have many others and they all use the same database models and you don't realize it but you're basically making it harder for that application to grow and maintain because of all these references that one subsystem into the outer so solution that microservices bring is that you take all these separate, conceptually separate subsystems and you create a separate web service with each one right.
9:45 Michael Kennedy: Right, so maybe you've got a front-end web app. It still does the back-end server-side stuff but instead of going straight to the database or straight to some submodules in your web app, it calls these related microservices that sort of implement the functionality, right?
10:01 Miguel Grinberg: Correct, right, so that gives you a number of advantages, some disadvantages too but the clear advantage is that each service can be very simple, we're going back to very small code basis for each service. For example, with Flask, you can easily write an entire microservice in a single file.
10:20 Michael Kennedy: Right, so give us some examples of microservices that would be reasonable to create, like would there be a blogging microservice? Would there be an authentication? How have you can decomposed this before?
11:48 Michael Kennedy: Okay, that makes a lot of sense. It definitely adds some a complexity, right? You're no longer maintaining the configuration for one app but you're maintaining five or four and then the the interplay between them, right?
12:01 Miguel Grinberg: Correct, so the complexity, I did mention this in the class, the complexity doesn't go away. Basically, you're shifting the complexity to a different place and now we have an ops.
12:11 Michael Kennedy: Yeah.
12:11 Miguel Grinberg: It's more complicated to deploy an application that's based on five and this was a relatively small app. Normally, you have dozens or maybe even hundreds of microservices, so yeah, definitely the complexity goes somewhere else, what I find that I like to shift the complexity into those places because I'm a software developer, so from my point of view, I really like clear code that's easy to maintain, for example, something that I see done with microservices is if you have a team where you have a beginner, usually if you have a big complex application, you're going to be afraid that this person that doesn't have a lot of experience may inadvertently break something.
12:57 Michael Kennedy: Right, and they could break it entirely, right?
12:59 Miguel Grinberg: Correct.
13:00 Michael Kennedy: They could be
13:00 Miguel Grinberg: Unknowingly, right? It's because of all this coupling that from, over time, keeps increasing in these types of applications.
13:10 Michael Kennedy: Right, the slightest little problem in like even a trivial part of app, if it makes it fail to start, you've taken the entire site down for everyone and for everything, right?
13:21 Miguel Grinberg: It's gone for everybody, right, so with microservices, however, you can have a beginner work on one microservice, even own it and if there are any problems with that microservice, that's not going to affect the overall application. All the other microservices will continue to run so this is in general, not only when a beginner makes a mistake but in general, if one microservice is sick, it goes down or has problems, that doesn't mean that the whole application goes down, it's just that system. And many times if you kill that microservice and start a new instance, then you back up running and you have more time to fix the problem.
14:01 Michael Kennedy: Yeah, that's really an interesting way to think about it, and you could probably even just force a rollback to the previous deploy and run that.
14:08 Miguel Grinberg: Correct.
14:10 Michael Kennedy: That could be super hard to do in your regular application 'cause maybe the UI's changed, maybe the database schema in some little part has changed and SQL Alchemy freaks out or whatever, right?
14:20 Miguel Grinberg: Right, yeah, databases are one of the big reasons why deployments for monolithic applications, it's so hard once you migrate the database, I mean ES Migration frameworks have downgrades but very few people use them and even those that use them, many times, they don't test them so they're usually broken.
14:40 Michael Kennedy: Yeah, and they could be remove this column, which had data in it .
14:43 Miguel Grinberg: Correct, right, so yes, the idea with microservices, in particular, to databases is that each microservice has its own database so if you migrate one database for, say, for the messages service, that has nothing to do with the users so it's a much smaller problem if you end up having problems.
15:02 Michael Kennedy: Yeah, that's really cool, there's a ton of advantages to that, I like the way, gosh, who was it? Martin Fowler was referring to these databases as the one from the monoliths and the bigger ones, he called those integration databases and these called application databases. I'm not sure if that's quite the right term but I really like to think of it as like you can take this one big complex database that's trying to represent everything from every part of the app or multiple apps so the users' table is as complicated as it could possibly be, right? The order history tables as complicated as it could be 'cause it has to support every single possible option but if you break it into these little microservices, you could have a really simple like here's the microservice that handles orders, it has a database that handles orders.
15:47 Miguel Grinberg: Right, it's just that, correct. Now there's a problem with that. You lose the ability to run joins because now you don't have everything in one database, right?
15:59 Michael Kennedy: Yes.
15:59 Miguel Grinberg: So if you need to correlate users or customers with orders, you have to do it in the application.
16:05 Michael Kennedy: Yeah, exactly, you can't join across HTTP requests.
16:09 Miguel Grinberg: Correct, that doesn't work. You have to do it in the Python space in our case.
16:14 Michael Kennedy: Yeah.
16:14 Miguel Grinberg: I don't find that terrible. That's my first observation, my second observation is that even though people that know me know that I'm a big fan of relational databases, when you're working with microservices and your databases are usually one table or two tables, the reason to use relational databases sort of lessens and now it's starting to make more sense to go to a NoSQL database.
16:43 Michael Kennedy: Yeah especially a document database
16:45 Miguel Grinberg: Yes.
16:45 Michael Kennedy: Where you, the one thing that you get kind of contains the pre-joined data as a hierarchy anyway. Yeah, that's really interesting so I can definitely see how that makes rolling back one of these services if it gets sick much, much easier and the chance that it gets sick is smaller as well, right? 'Cause it's simpler.
17:04 Miguel Grinberg: There's a lot less chances of making mistakes because you're working with a much simpler code base.
17:10 Michael Kennedy: How about scalability?
17:11 Miguel Grinberg: Well, right, so if you have a big monolithic app, you need to scale it, you need to scale the whole thing, maybe going back to the chat example, you're probably going to have a lot more activity around messages than around users, even less on tokens so if you were to scale a monolith, you're going to have to provision for the entire thing, if you need
17:35 Michael Kennedy: Right, you have aim for the worst-case scenario
17:39 Miguel Grinberg: Correct.
17:40 Michael Kennedy: Basically across any part of it, right?
17:42 Miguel Grinberg: Say you decide that to handle the load on messages from users, you need to run 10 instances. You're going to have to provision 10 instances for everything because it's all one piece. Now, when you are doing microservices, you can scale each service independently
18:00 Michael Kennedy: That's right, really cool.
18:02 Miguel Grinberg: It's super exciting, you can scale, if you use something like Kubernetes, for example, you can scale across different hosts. If you have a cluster of container hosts, automatically it does it for you so you can have not only scalability but reliability by having your instances of the same service distributed across multiple hosts.
18:23 Michael Kennedy: Yeah, that's really, really neat to think that, okay, I might have two or three of the straight-up web front ends, maybe five of the orders, servers, three of the message senders and is to be able to configure those independently is really cool.
18:41 Miguel Grinberg: And then dynamically as well, right?
18:43 Michael Kennedy: Yeah.
18:44 Miguel Grinberg: I mean those, the concept of auto-scaling also applies to this so the messages can, or orders or whatever, anything that's very active, you can decide, okay, I'm going to start one more, and some other components we haven't discussed yet help with that dynamicity.
19:01 Michael Kennedy: Sure, one of the things that was striking about the Instagram keynote, which is really cool story of moving Django from Python 2 to Python 3 while you have millions and millions of users and doing it on a single branch without going down was super interesting. One of the things they were really obsessing about was how can we get basically, being very aggressive with how they work with memory so they can get the best memory usage out of each server that they work with, like, for example, they went so far as disabling garbage collection in their Python apps, period which is just crazy.
19:41 Miguel Grinberg: That sounds scary.
19:43 Michael Kennedy: Yeah, yeah, they have a really interesting blog post they wrote up about it, that they were able to get much better memory sharing across processes if they did that, like dramatically better, it made it
19:55 Miguel Grinberg: Right, it probably makes for a cleaner use of memory, memory's not coming and going.
20:00 Michael Kennedy: Exactly, and apparently the cycles that were leaked were not sufficiently bad, surprisingly, it worked so the point is they're really, really focused on this and when you scale the monolith over and over and over, maybe it takes 200 megs per worker process, if you want 10 of them, that's a gig but you could get these other ones much, much smaller and only scale the parts that are really hot, right?
20:23 Miguel Grinberg: Correct, right, it's also a big savings. If you need to buy hosting for 100 instances of the monolith, that's going to be very expensive. That's going to be a lot of cloud instances. Now, if you're using microservices, you're scaling up very little things and only the ones that you need, so you have a lot more knobs and you end up saving a lot of money.
20:47 Michael Kennedy: Yeah, and this was not the case with Instagram because they were already in this monolith space but had they been in microservices, they could've done their migration from Python 2 to Python 3 and Django 1.3 to modern they could've done that microservice by microservice and it probably would've been dramatically easier.
21:07 Miguel Grinberg: One at a time, and so that's one of the other benefits you get, say, I don't know if this is true, probably not, but say one of the services that in this example, if they had microservices, if one of them could not be upgraded to Python 3 due to some lay-time dependency that hasn't been upgraded, that's not a problem. You can keep that one running Python 2, it doesn't matter so you're not constrained to use the same platform in all your services, if you find that some service can be benefited if you write it in Go or in Ruby or in NodeJS, that's totally fine. You can pick the best tool for each service.
21:49 Michael Kennedy: Yeah, that's really cool that you can break it up and it also means, like I said, the data level, like you talked about relational versus NoSQL. You could do MySQL on some pieces and MongoDB on others.
22:00 Miguel Grinberg: Absolutely.
22:01 Michael Kennedy: And you don't have to say, well, this part's going to have to fit into Mongo or that part's going to have to fit in MySQL when it would more naturally live somewhere else.
22:08 Miguel Grinberg: Yeah, so basically, you can pick the best tools for each service and each service is completely independent from the others, basically you are encouraged to keep this coupling that's always bad, under control by having these hard boundaries between services.
22:29 Michael Kennedy: Hey, everyone, this is Michael. Let me tell you about Datadog. They're sponsoring this episode. Performance and bottlenecks don't exist just in your application code. Modern applications are systems built upon systems and Datadog lets you view the system as a whole. Let's say you have a Python web app running Flask. It's built upon MongoDB and hosted and scaled out a set of Ubuntu servers running nginx and micro WSGI, at Datadog, and you can view and monitor even get alerts across all of these systems. Datadog has a great getting started tutorial that takes just a few moments and if you complete it, they'll send you a sweet Datadog T-shirt for free. Don't hesitate, visit talkpython.fm/datadog and see what you've been missing, that's talkpython.fm/datadog. There are some companies that basically have rules that say you're not allowed to create a web app that has more than 10,000 lines of code in it. What you have to do is create a service and then maybe multiple services and then you can construct your app out of these services, almost like creating these guidelines that just naturally leads to microservices. So we compared against monoliths. The other thing that I feel is like really strongly working in this space, trying to achieve the same thing, has some benefit, some trade-off is serverless architecture, AWS Lambda, Azure Functions things like this, right?
23:51 Miguel Grinberg: Yes.
23:52 Michael Kennedy: What do you think about those relevant to this?
23:54 Miguel Grinberg: Right, so glad that you asked because that's actually how we at Rackspace, in my team, that's how we deploy our microservices. So we haven't discussed this but one of the main components in a microservices platform is the load balancer. To achieve all these scalability and no downtime upgrades, another benefit that you get, you need to have all the services load balanced, even if you run one instance, it needs to be behind a load balancer so what you when you go to a serverless platform like Lambda on AWS is that AWS manages the load-balancing for you, so all you need to do is, you don't even need to have a WSGI server. All you need to do is write your microservice as a function and then you just upload the function with all its dependencies to AWS and then anytime, the function gets called, AWS will somehow figure out how to run it. It'll start a container, put the coding it and then run it. If you, in a burst, you make 100 calls, then AWS is running the load balancer. It'll run 100 containers for you. You don't have to worry about it, which is really nice and then if you make an upgrade, the moment you make the upgrade, any any calls from then on will use the new code, so you got immediate no downtime upgrades as well.
25:22 Michael Kennedy: Yeah, that's really neat, do you think that there's good situations to have a combination? Seems to me like there's certain things that would be really well-suited for a serverless Lambda type of thing and others may be more stateful, sort of a bigger microservice that would much better fit somewhere else so I'm thinking like if you wanted to, say, charge someone's credit card with Stripe, to do that as a single Lambda function, that's really stateless, really straightforward, maybe that would make perfect sense. Maybe something more complex like, for example, your message push stuff wouldn't necessarily be appropriate there.
26:02 Miguel Grinberg: Right, so here's one very important thing that Lambda does not support. It does not support WebSocket services so server push, exactly what you just mentioned. Basically for that, you need to have a permanent connection with the client so when you have a WebSocket connection, all the clients have permanent connection to the server. The server needs to handle a lot of connections. Now that Lambda services, or functions I should say, really ephemeral, they'd run and then they exit and they don't exist anymore until you make another call so that there's no way to have a permanent presence in Lambda so in that case, you will have to host that in a container or something like an instance, a cloud instance, for example.
26:48 Michael Kennedy: Sure, do you get maybe better response time if you run in, say, your own container that's more permanent, so there's probably a little startup to infrequently called Lambda functions or something, right?
27:02 Miguel Grinberg: In general, if you're looking for performance, you will not be using Lambda, that's my experience. It's, in general, slower so I can give you an example from work. We don't have anything that's extremely complex but typically, we see the REST API call that's posted on Lambda and it gets to Lambda through another AWS service called API Gateway and what we're seeing that nothing takes less than half a second, so 500 milliseconds for a simple call, there's really, we found no way to bring it below that, no matter how simple the actual endpoint is.
27:43 Michael Kennedy: There's that much overhead just to get to your function basically, get it up and running and so on.
27:48 Miguel Grinberg: Right, yeah, there are so many layers that I go through AWS before your code gets to run that really, you can optimize all you want, you're still not going to make a difference.
27:58 Michael Kennedy: Yeah, whereas in a Flask or other Python WSGI app, like 10 millisecond response time would be totally reasonable.
28:04 Miguel Grinberg: Correct, right, you can see much faster times and then you have the option to go Async if you want something that's very, very fast and can tolerate a lot of clients.
28:15 Michael Kennedy: Yeah, so I guess the takeaway probably is these serverless components of microservices, these serverless building blocks are cool but you can't just, in general, it wouldn't make sense to just go, I'm only doing that for the most part probably.
28:29 Miguel Grinberg: It makes sense in many cases, not every case and you have to keep performance in mind. Typically, the kinds of services that we do, these are all requested by average client application, something like Angular or React and those are background requests, so, yeah, if it takes half a second, that's fine, usually not a big deal. We actually, we had one of the services that we wanted to build at some point was a auto completion.
28:59 Michael Kennedy: Yeah.
28:59 Miguel Grinberg: It does not work on that.
29:01 Michael Kennedy: Now, was that frustrating on Lambda? Yes, exactly.
29:04 Miguel Grinberg: You cannot host that on Lambda.
29:06 Michael Kennedy: That's the typing equivalent of hearing your own voice echo back in a call.
29:09 Miguel Grinberg: Right, yeah.
29:09 Michael Kennedy: It's not good.
29:11 Miguel Grinberg: So yeah, that didn't go well, that was
29:13 Michael Kennedy: Yeah, so one of the challenges I can certainly see, especially if you start throwing containers into this as well is like if I have a monolith, it knows how to find the user interaction bit and the credit card bit and so on, it just imports and it works but if you break it across all these different servers, how do you keep it connected without hard wiring every bit of deployment into the code?
29:40 Miguel Grinberg: There's a component that all microservices platform have that's called the service registry so basically, each platform does it in a slightly different way but, in general, the idea is that when you start a service or an instance of a service, the first thing that the service does is talk to the service registry, which is in a known address so everybody knows where to find the service registry.
30:07 Michael Kennedy: That when you basically hard-code the domain or something
30:10 Miguel Grinberg: Right, it's hard-coded, it's usually in production deployments, it's highly available so you are not going to have a single point of contact. Probably you hardcode a few addresses to talk to the service and if one of them is down, you try the next one, so you want to make sure that this piece of code is always running. Basically, this service starts and then it reports itself to the registry, it says, hey, I'm here. I'm at this address, if you're running containers, the address is going to be basically, Docker, for example, it's going to come up with some port for you so you find out what port you're running on and then you tell the service, okay, I'm running on this address and this port so I'm ready to start taking jobs.
30:52 Michael Kennedy: Yeah, yeah and that service registry can be very simple code, it could almost just store
30:57 Miguel Grinberg: It's just simple.
30:58 Michael Kennedy: A dictionary in memory or something, right?
31:00 Miguel Grinberg: Right, essentially it's a dictionary, right, if you think about it, the complications that you want that to be super robust if the server where the registry's running goes down then nothing can find, there's no way for microservers to communicate so it's very important that you host it multiple locations and that that there is a redundancy.
31:25 Michael Kennedy: Do people sometimes use things like S3, just like I'm going to write to this bucket and
31:31 Miguel Grinberg: That's actually an interesting idea. I haven't seen that, it might be complicated with multiple accesses, you would need to implement some sort of locking mechanism, I would think, to keep the file that has all the list of services robust and never get corrupted.
31:50 Michael Kennedy: Yeah, maybe each service could have its own file.
31:53 Miguel Grinberg: Or, right, you could write different files. That actually could work, yeah, I think that could work.
31:59 Michael Kennedy: Interesting, but basically, here's a really simple thing that just every server can go, I'm here the things, the things I need, where are they, right?
32:06 Miguel Grinberg: Right, so then just to complete this, one of the simplest service registry options that the one that I like is called etcd. It's an open source project from CoreOS and basically, yeah, you send a request, you can even do it in a batch script with code, just it's a key-value database basically that's very fast. So then etcd, in this example, will have the list of all the services that are running, and we have the load balancer, and the load balancer will go periodically check the contents of this service registry and refresh its own configuration based on that so a service starts, it writes itself to the service registry, then on the other side, the loan balancer says, oh, there's a new service. I'm going to add it.
32:54 Michael Kennedy: Yeah, oh, that's cool. I didn't think of using the service registry to drive the load balancer but that's cool.
33:00 Miguel Grinberg: Yeah, that's very nice, there's actually, I know of one load balancer that has this functionality embedded, it's called Traffic. If you go with a more traditional one like nginx or HAProxy, which are the ones that I've used a lot of time, with those, you need to add a piece to the side that does the watching the service registry and then updating the configuration and restarting the load balancer.
33:25 Michael Kennedy: Right, right.
33:27 Miguel Grinberg: The one that I know about, which is actually written by Kelsey, it's called confd, that's one that I showed in the class.
33:35 Michael Kennedy: Okay, yeah, that's cool and nginx recharged pretty quickly so it's pretty good.
33:40 Miguel Grinberg: Yes, right, nginx is pretty good about reloading itself cleanly when you update the configuration, HAProxy is getting there. It's getting better, it's a little bit clunky but basically, it starts a new process when you want to update the configuration process and process by which all the connections are passed from the old process to the new process, has been for many years has been problematic. It costs some downtime, it's much better these days.
34:07 Michael Kennedy: Okay, that's great, another challenge I can imagine is if I just start using logging in my monolith app. It will all go to the same file, it will go always in order unless I'm doing threading.
34:22 Miguel Grinberg: It's a piece of cake, right.
34:23 Michael Kennedy: It's a piece of cake, if I have 20 little microservices, how do I trace through the steps?
34:28 Miguel Grinberg: Right, you need help. You really can't now manage 20 log files, sometimes it gets insane so basically, you use, you find another piece that basically, a log consolidator. There's one that's pretty good for, if you're doing Docker containers, it's called logspout.
34:49 Michael Kennedy: Logspout, okay.
34:50 Miguel Grinberg: It's also open source, logspout, so basically what this does is it grabs all the logs from all the containers in a host, the host where logspout is running and then basically it outputs a stream that you can watch over, for example, you can connect with the web browser that does web socket, for example. So you can connect on WebSocket and then watch the stream of logs in real time or you can connect logspout to something more more useful in a production environment, which will be, for example, an ELK stack or Elasticsearch, Logstash, and Kibana, which is three open-source apps that basically create a very powerful log storage and search solution.
35:35 Michael Kennedy: Yeah, okay, so basically, you put in something that basically brings it back into one place.
35:39 Miguel Grinberg: Yes, you usually want to have everything in one stream and then you can filter if you want but imagine if you have five instances of the same microservice, you may, even though it's five different ones, you may want to see the entire thing because if a client is sending requests to the service, requests are going to randomly arrive to any of those five.
36:01 Michael Kennedy: Right. It's hitting the load balancer, yeah.
36:05 Miguel Grinberg: Right, through the load balancer, of course, so you probably want to see the sequence, regardless of which which of the instances get a specific request.
36:12 Michael Kennedy: Yeah, yeah. Do you do or do people do things where they somehow identify a request so flag it with some kind of unique ID at the top and then flow that through so that you can say, this is the steps that this request went through?
36:32 Miguel Grinberg: Yeah, that's pretty common. Some platforms offer that, I implement it by hand in some cases myself but basically, yes, the entry point request so the first, the service app that receives a request from the outside world assigns on ID to that request and then in any communications that service has with other microservices, it will pass that ID so you always preserve a log, the initial ID, and then you get a trace of all the services that worked on a single client request.
37:07 Michael Kennedy: Right, and the infrastructure to actually do the communication between my microservices, is that typically requests?
37:13 Miguel Grinberg: There are different ways so the easiest would be to use HTTP as an interface, a REST API for each service, and then, yeah, you use Python requests. Some people prefer something that's less chatty so HTTP, as you know, you have all these requests, the headers, all that stuff. When you are talking to a client, that make sense and besides, that's the only way the browser or an HTTP client can talk to the server but when you're talking among services, you may say, well, okay I want something quicker so some people implement RPC schemes where a service can say to the other server, hey, I need you to do this and it's, for example, passing messages through a message queue, which could be a Redis Queue or SQS if you're on AWS.
38:01 Michael Kennedy: Do people set up socket servers, maybe?
38:03 Miguel Grinberg: You can do s socket server too, sure.
38:05 Michael Kennedy: Yeah, yeah, if you're looking for really low latency, low traffic.
38:07 Miguel Grinberg: The main idea, what I would you consider a good design point when thinking about how microservices communicate, so you want to leave the door open to having different tech stacks on different services. You don't want to go with something that, let me give you an example, I will probably not use a Celery worker for this because that will basically restrict me to use Python.
38:31 Michael Kennedy: Right, and you probably wouldn't ship data across the wire as Pickle.
38:34 Miguel Grinberg: Right.
38:34 Michael Kennedy: Yeah. As versioning issues, not just Python but even within Python
38:41 Miguel Grinberg: Python to Python it could be a big problem too, right, so the way Celery works, I think it's not friendly to the microservices ideas, the ideas that microservices trying to push so, yeah, I would go HTTP, maybe messages are JSON formatted over a queue, things that you are sure that any technology can easily communicate over.
39:06 Michael Kennedy: Yeah, makes a lot of sense, I imagine there's a lot JSON happening back in the data center
39:10 Miguel Grinberg: Oh, yeah, definitely, yes, absolutely.
39:13 Michael Kennedy: Yeah, nice, so that maybe brings us to an interesting place to talk about the tools. We talked about requests and some of the other tools that work and don't work but what are the other Python tools that you might involve here?
39:24 Miguel Grinberg: Well, of course, you need a framework, right? I mean we discussed, I like, no surprise, I like to use Flask, but really, you can use any web framework that you like, as long as it knows how to communicate with the other services. As far as other Python tools, there are many packages that talk to service registries, for example, so if you want your Flask-based or Python-based microservice to be able to talk to the service registry, there's packages for, certainly for etcd, if you use another one like Console, for example, this is one from HashiCorp, there's packages, so you're going to find a lot of support for these tasks that you need to do that are specific to microservices in the Python ecosystem.
40:11 Michael Kennedy: Sure.
40:13 Miguel Grinberg: Besides that, you're going to be doing things, and this is something that I really like, in the same way like you work with a monolith but you're going to be working with a much smaller code basis so you're going to see, you're going to be doing unit tests the usual way but you're going to be testing each service separately and then you're going to have integration tests if you need, and you probably do, but, yeah, nothing really changes, it just that the scale goes, you know, you doing your work on a much smaller scale. You're working with smaller applications.
40:44 Michael Kennedy: Yeah, it sounds to me like they're easier to work on and maintain and deploy but maybe more difficult to initially set up the infrastructure that wires them together.
40:52 Miguel Grinberg: Yes.
40:54 Michael Kennedy: You have more servers to set up. You've got the load balancer, you've got the service registry, these things you have to add but once that is in place, it kind of sounds like life gets easier so there's like a like a bar to cross but once you cross it, you're good.
41:06 Miguel Grinberg: Yeah, right, I agree with that. Yes, it's difficult to set up the platform and, of course, you can go, if you use Kubernetes, for example, or AWS Lambda, a lot of all those pieces are done for you. You don't have to worry about load balancers and service registries, they do it for you.
41:29 Michael Kennedy: This portion of Talk Python to Me is brought to you by us, as many of you know, I have a growing set of courses to help you go from Python beginner to novice to Python expert and there are many more courses in the works so please consider Talk Python training for you and your team's training needs. If you're just get started, I've built a course to teach you Python the way professional developers learn, by building applications, check out my Python Jumpstart by Building 10 Apps at talkpython.fm/course. Are you looking to start adding services to your app? Try my brand-new Consuming HTTP Services in Python. You'll learn to work with RESTful HTTP services as well as SOAP, JSON, and XML data formats. Do you want to launch an online business? Well, Matt Makai and I built an entrepreneur's playbook with Python for Entrepreneurs. This 16-hour course will teach you everything you need to launch your web-based business with Python. And finally, there's a couple of new course announcements coming really soon so if you don't already have an account, be sure to create one at training.talkpython.fm to get notified, and for all of you who have bought my courses, thank you so much. It really, really helps support the show.
42:34 Miguel Grinberg: In this class that I gave at PyCon, I didn't want to just tell, okay, install Kubernetes and be done, I wanted to teach what microservices are so I built my own platform, which was a lot of fun and I thank the PSF for approving my tutorial ideas and let me let me work on this. It was a lot of fun and I wanted to demonstrate that really it's not as hard as it sounds. You can go pick the best tools for each of the different tasks in a very Flask fashion, where everything is done, you pick the best tool for each task.
43:12 Michael Kennedy: Yeah, it sounds like people who like micro frameworks for their web frameworks might like this as well 'cause you kind of get to pick
43:19 Miguel Grinberg: Yes, they're going to find that there's a lot of affinity, so I built a platform using using Bash, so it's all Bash scripts, you can do a, you've seen Kelsey Hightower do a supercool, voice-operated demo of a no downtime upgrade, right? So take away the voice thing and then do that. But during class, I showed how, with a Bash script, you can deploy your upgrades without the service ever going down. Your application keeps running while you do the deployment.
43:51 Michael Kennedy: Sure.
43:51 Miguel Grinberg: So yeah.
43:52 Michael Kennedy: Yeah, so is there a roadmap or some guidance on how to take maybe a 50,000-line monolith web app and turn it into a number of services?
44:03 Miguel Grinberg: That's really difficult. I think the best advice I can give you is you probably cannot do it all in one go, you're going to have to find a strategy to do a phased migration to microservices. You need to have a very good unit tests in place because the task of, basically what you're going to do, in most cases, is take the monolith and put it inside a microservices platform as a big piece and then over time, you're going to start taking little pieces out of it and write microservices so the task of writing microservices, when you have the monolith is basically involves a lot of copying and pasting, you have to move endpoints that are in the monolith to a standalone application.
44:50 Michael Kennedy: Sure, and that's pretty easy in some aspect but breaking the tight coupling and the dependencies of code that you're moving around, that sounds to me like it could be pretty challenging.
45:01 Miguel Grinberg: Yes, it's difficult, it's actually hard. Basically, when you work on a monolith, you accumulate technical debt, that's pretty common. You're going to find that many times that technical debt is going to inform your decisions. You're going to take less-than-ideal decisions when you design your microservices to keep things the same way, I can give you an example. In this is, the program that I showed during the Python class, I was actually migrating this chat application to microservices and I started and I migrated the UI first. That was very easy and then I migrated users and then I went to migrate tokens and I realized that I could do a much better job with tokens. The tokens in the old application were sort of inefficient, were random strings. When you're working with microservices, you want tokens that can be verified without calling the token service and when you need that, you usually use JSON Web Tokens, which you can verify with cryptography so I had to decide, I mean, do I keep this and make it an efficient or do I say, okay, I'm going to draw a line in the sand and I'm going to change the token format but then everything is going to break. I'm going to have to migrate all the services to the new token style, right?
46:18 Michael Kennedy: Right.
46:19 Miguel Grinberg: And those decisions on a real application, they're going to be much harder to make.
46:24 Michael Kennedy: Yeah, I can imagine that but so one thing I was thinking of while you were speaking, of how you might break this apart. It seemed like you could almost do the partition in the web tier and then the data, like for example, if you have a database that, obviously, the monolith talks to the database, all of it to the same connections. If you could break this out into services, they theoretically could go back and just continue talking to the same database and you could get the service decomposition piece working and then you could say, okay, now how do we move this into the application database that's dedicated to each one of the services.
47:00 Miguel Grinberg: So that that can be a valid approach so when you do it that way, if you're sharing the database, then the zero downtime upgrades are still difficult.
47:09 Michael Kennedy: Yeah. I'm just taking a transitional thing.
47:11 Miguel Grinberg: So it's going to be a transition, right. You want to go all the way eventually but yeah, yeah, definitely, yeah, you have to figure it out, depends on the application what's the best route but yeah, it's difficult. What I've seen some people do is they say, okay, I'm not going to migrate to microservices but only from now on, I'm not going to change what I have. So basically they grandfather this big piece. They think of it as a microservice, even though it's not.
47:36 Michael Kennedy: It's a big microservice.
47:37 Miguel Grinberg: Right, it's a big one but then from then on, any new functionality, they start writing in microservices and that's actually had a very valid approach. In many cases, it's the only viable way, right?
47:48 Michael Kennedy: Sure, sure, sure, how does software development change for a team when they're transitioning to microservices, how does their world get different?
47:57 Miguel Grinberg: Well, they don't have to all work in the same code right so that's a big plus.
48:03 Michael Kennedy: Fewer merge conflicts.
48:04 Miguel Grinberg: Right, you basically merge conflicts. For me, I don't remember when I had a merge conflict last. Yeah, you don't usually see that so usually, you're find that your team, that the members will get specialized in specific services. For example, at Rackspace, I've been doing a lot of authentication microservices so when there's a new need for authentication, I do it usually. Some people may not like that, may prefer to be generalists so, yeah, it depends but you'll find that some people, it's more basically has affinity to certain parts of the system, certain microservices.
48:49 Michael Kennedy: Sure, and now they can focus more on it now because it's more explicit
48:52 Miguel Grinberg: Right, and they can do a much better job at that specific task because they don't have all the baggage of the remaining, the rest of the system that basically that needs to be, that you have to make sure that you don't break.
49:08 Michael Kennedy: Right, so one thing it seems like it might make sense would be to rotate the team around to the different services potentially. If you want to make sure, like there's many people that know the same thing, you could say this month, you're on this service, that month, you're on
49:23 Miguel Grinberg: Yeah, that's actually a good idea. You can find a way for the person that's experienced with microservice to mentor a new member and basically code review the changes that the new person makes, for example. There are a lot of different ways to make sure that everybody gets a little bit of everything, sure, so yeah, overall, I find that if you like to code, we could talk about the ops side, if you like to code, then you're going to be coding more and fixing bugs a lot less. You're going to find that you're going to be working on small code basis and that leads to less mistakes and errors.
50:04 Michael Kennedy: Yeah, that's great.
50:07 Miguel Grinberg: You don't have time for unit tests that a lot of people don't because it's too complicated and now you're back to a simple application that's very easy to unit test.
50:15 Michael Kennedy: Yeah, to be more careful on the boundaries though 'cause they all talk to each other, right?
50:19 Miguel Grinberg: And then you need, right, this app will probably put an experienced person. You need someone that overviews what are the interfaces that all the microservices expose to the rest of the, to the other microservices and sometimes to the clients. But you need to make sure that, especially with the public endpoints that are consistent, so you need at least one person that's experienced in API design to make sure that you get good APIs.
50:48 Michael Kennedy: Yeah, of course.
50:48 Miguel Grinberg: That's the only thing. It's a difficult change them once they're out there. This is if you want to have no downtime deployments, you cannot really introduce breaking changes so you cannot remove an API, you cannot remove a column in the database, there are some rules that you need to follow.
51:03 Michael Kennedy: Right.
51:05 Miguel Grinberg: So when you design databases and when you design APIs, you need to have people review that very well, make sure that you like what you are designing because you're going to have to be with those decisions for a long time.
51:17 Michael Kennedy: Yeah, that's a good point. Some of the HEP frameworks for building services have even built in versioning into them. I'm thinking of hug and some of the things but obviously, you can add it to your own apps pretty easily. Just set up a second endpoint rather than calling the same one, is this something that you have to do that?
51:39 Miguel Grinberg: You have to do that, basically you're forced so imagine you have five instances running of this one microservice and now you want to introduce a breaking change in one endpoint and, of course, you don't want to go down for the upgrade, so you cannot stop the five instances at the same time. You're going to have to do a rolling upgrade so during a window of time, you have a bunch of instances on the old API and a bunch on the new and then the rest of the system knows nothing of this, and then they're going to start sending requests probably, assuming that the old API is in place.
52:13 Michael Kennedy: Yeah, until you agree that part, which then will go to the new one, but it'll be sort of moving around through these services as that process happens, right?
52:20 Miguel Grinberg: Right, you so you need to create a new endpoint for the breaking change, keep the old one working and then once you're sure that the whole system is upgraded, it's on the new one, only then, you can go ahead and basically deprecate or remove the endpoint that you don't want to use anymore.
52:36 Michael Kennedy: Right, that's probably important as well to eliminate the cruft building up as well.
52:40 Miguel Grinberg: Yeah, yeah, I think that this platform encourages you to be clean and to keep things clean, to think about these important decisions very carefully.
52:52 Michael Kennedy: Yeah, excellent, so we talked about how AWS Lambda has this built-in latency and when you think about performance, a lot of times, there's really two sides to it, right? One is if I go and I hit that endpoint, how quick does he get back to me? And then the other one is if a million people hit it, how much does it degrade from that one person hit it, like how scalable is it? And how single request high-performance is it? So I can certainly see how this generates better scalability, you can very carefully tune the individual parts of your app and scale those up but it also seems like it might add some latency for an individual quest, so how much slower, like what's the typical changes? Would I add 10 milliseconds to a request? Would I add 100 milliseconds, what
53:42 Miguel Grinberg: Yeah that that's a good question so even if we take serverless out of the equation so
53:46 Michael Kennedy: Yeah, 'cause it's really bad, yeah.
53:48 Miguel Grinberg: Right, so the performance is not the same as in a monolith just by the mere fact that, in many cases, the client's going to send the request and the service that receives that request cannot carry out the request alone, it will have to talk to a bunch of other microservices, so there are a lot of communications among the microservices that, of course, will take time as well, so latencies increase no matter what, so microservices is not, if you're looking for performance, it's not really.
54:19 Michael Kennedy: And it doesn't actually have to be microservices versus monolithic, it could be more coarse-grained microservices, more fine-grained ones potentially, right?
54:28 Miguel Grinberg: Right, the times that I've seen, they're not really that terrible, I mean, we are talking like tenths of a millisecond.
54:36 Michael Kennedy: Yeah, you're making a request over the internet, maybe across the country, it might be 100-millisecond ping time so if it's 100, 110, who cares?
54:43 Miguel Grinberg: It could be in the noise, right, yeah.
54:45 Michael Kennedy: Right, exactly.
54:45 Miguel Grinberg: Right, yeah, absolutely. In many cases, it's going to be in the noise, yeah. So compared to all the benefits that we already discussed, I think, in my view, it's a no-brainer. It makes a lot of sense in many cases but yeah, it's all this complication of services talking to each other, and you might find that in some cases, you need to go Async, so you can certainly have an asynchronous microservice so you tell it you need something and the service says, yeah, okay I'll do it on my time but keep going, don't mind me. That's totally fine.
55:19 Michael Kennedy: Yeah, for example, send this email. You don't have to wait for the email to acknowledged to be sent, right?
55:22 Miguel Grinberg: Absolutely. That's a great example, right.
55:25 Michael Kennedy: Yeah, yeah, email can be pretty slow actually, given all the stuff that it does
55:31 Miguel Grinberg: Email, yeah, you count it in seconds.
55:33 Michael Kennedy: Yes, exactly.
55:33 Miguel Grinberg: In microseconds.
55:35 Michael Kennedy: And if you got to mail a group, like I want to send this mail to 2,000 people in my class on my platform like, okay, that needs to be Asynced just let me tell you, I've learned that.
55:45 Miguel Grinberg: Yeah, and that's actually, that's a good example in which you may, in many cases, you're not interested if the email bounces.
55:52 Michael Kennedy: Yeah, what are you going to do about it anyway, right?
55:54 Miguel Grinberg: Right, exactly if it bounces, there's nothing to do, if you are, you can have that service that's asynchronous record addresses that are bouncing in a database that's going to be owned by that service and then later on, in a cron job or whatever, you can clean up the addresses that are bad, so some of the service can send a request to the email service and ask, what are the bad addresses that you know, and that will be another endpoint. Return the addresses and then they can be cleaned up or the accounts can be canceled or whatever.
56:25 Michael Kennedy: It sounds really promising.
56:28 Miguel Grinberg: It's a great way to think about problems. It's solves little pieces so it's a lot easier to think about solutions and at the beginning, it's hard to start thinking this way but then you get used to it and all the problems become easier.
56:44 Michael Kennedy: Yeah, I can definitely see how that would happen, it might be difficult to think, how am I going to build this huge app? But if I can build, well, could you build 10 small apps and then have them help each other out, right?
56:56 Miguel Grinberg: Right, exactly.
56:57 Michael Kennedy: Right, very cool, all right, Miguel, I think we're going to leave it there, that's, I think, a great conversation on microservices so let me ask you the two questions. So if you're going to work on your microservices in Python, what editor do you use?
57:11 Miguel Grinberg: So. It's complicated. Yeah, that's a great answer for me. I usually iterate over a few editors so Vim it's my go-to editor, many times I need to edit files on remote hosts so Vim works anywhere so that's the one that I use most of the time. Sometimes I need to debug and for that, sometimes I use and IDE and the two that I've been using, I can't even decide on one, the two that I'm using is PyCharm and lately, Visual Studio Code, which is surprisingly good.
57:48 Michael Kennedy: Yeah, the Python plug-in there is doing really quite a bit.
57:52 Miguel Grinberg: Python plug-in, it's not an official plug-in but, yeah, this person that wrote it, he did an awesome job. It's very, very good.
57:59 Michael Kennedy: Yeah, he did a great job. I actually had him on an episode maybe 20 shows back or something, it's very cool how he took like 10 different open-source projects and brought them altogether and turned it into the plug-in for Visual Studio Code, it was cool.
58:13 Miguel Grinberg: Well, he did a great job. It's super powerful and in particular, I like the way that you set your configuration for a project, which basically it opens up a text file and you write JSON.
58:27 Michael Kennedy: Yeah, it is quite interesting for sure.
58:29 Miguel Grinberg: That's contrasting to PyCharm, where you have to enter a dialog, a window and find the setting that you want.
58:36 Michael Kennedy: Well, it also make the very source friendly, like source control friendly.
58:41 Miguel Grinberg: Source control friendly and you can copy configs from one project to the next, it all becomes much easier.
58:48 Michael Kennedy: Yeah, great, and PyPI package?
58:52 Miguel Grinberg: So one package that I'm sort of ashamed I didn't know and I learned about it from my colleagues at Rackspace, it's called Arrow and so this is a package that it is a drop-in replacement for the daytime package in the Python library but it implements all the holes in support that the daytime has, for example
59:14 Michael Kennedy: Yeah, I would definitely second that one. Arrow is awesome.
59:16 Miguel Grinberg: Yeah. I only know it for a few months since I've been working with this team and, yeah, I use it all the time now, so for example, it has, you know, daytime starts with this naive time zone approach where there's no time zone so by default, Arrow will use UTC, which is what you always want anyway, Right?
59:36 Michael Kennedy: Yeah.
59:37 Miguel Grinberg: So you work UTC
59:39 Michael Kennedy: Especially if you're working on servers.
59:41 Miguel Grinberg: Right, yeah, you want to have common units so that's what everybody uses and then support to convert to and from the ISO 8601, which is daytime can output ISO 8601 but cannot import from it so if something very common, so another thing that I tend to work on is the billing microservices in my team and you want to know, you have a date and you want to know the first of the month and the last of the month, it's like in one line you can get it, you don't have to do strange aerobics or acrobatics
1:00:16 Michael Kennedy: Yeah.
1:00:18 Miguel Grinberg: To get the first and last of a given month so yes.
1:00:22 Michael Kennedy: Yeah, people should definitely check that out. All right, so people heard this conversation. They're probably excited about microservices. How do they get started, what do they do?
1:00:31 Miguel Grinberg: So what I recommend, if you have three hours to waste, you can check out the YouTube video of my tutorial. I think I made it very approachable. If you're experienced developing either Django, it doesn't need to be Flask, any monolithic web application, I think you're going to pick up the tutorial really well. The code that comes with the tutorial, which is on GitHub, includes a Vagrant setup so you can deploy the system that I show in the class to your machine, to your laptop on a Vagrant VM and then you can play with it. Even at the end of the class, I listed a list of things that would be great ideas to, if you want to practice, so you take the project that I built and then extend it in many different ways, that would be my recommendation. You can look into Kubernetes, which is it's something that you can also deploy to your laptop if you want to use it for testing. I include it in the GitHub repositories for this class, the scripting required to deploy the same application to Kubernetes if you're into that and then the other valid option would be to look into AWS Lambda and API Gateway.
1:01:44 Michael Kennedy: Have you seen Zappo?
1:01:46 Miguel Grinberg: You mean Zappa, yes.
1:01:47 Michael Kennedy: Zappa, Zappa, yeah, which is a framework that just uses Lambda as a back end.
1:01:52 Miguel Grinberg: Yes, I've seen it, I even wrote a clone of it, which is called Slam, which is in my GitHub account as well but, yes, the idea is that you take a WISGE application, which is really a function if you think about it. WISGE is a callable, not a function but a callable.
1:02:09 Michael Kennedy: The is quite simple, yes.
1:02:12 Miguel Grinberg: You can think about it as a function and then Lambda requires a function so there's really a match, the only problem is that the way Lambda expects the function is not in the way WISGE applications are formatted so then Zappa comes in or my Slam also and basically, it's an adapter that sits in between Lambda and your application and it makes the conversion between the two formats.
1:02:34 Michael Kennedy: I see, all right, well, that's really cool.
1:02:37 Miguel Grinberg: That's a really easy way to deploy your, any Python web application that's WISGE, so Django, Flask, Pyramid, Bottle, all those, you get it deployed to AWS, yeah.
1:02:49 Michael Kennedy: All right, well, very, very cool so I definitely recommend people check out your tutorial, which I'll put in the show notes and I'm also going to put Kelsey Hightower's talk as well 'cause those go well together, I think.
1:03:01 Miguel Grinberg: That's actually a good thing to watch first. If you like that, then you can learn how those things work by watching the tutorial.
1:03:08 Michael Kennedy: Yeah, Kelsey's is high-level and flashy and interesting and then yours is the detail, yeah.
1:03:13 Miguel Grinberg: Right, I wish I could be as good a speaker as he is.
1:03:16 Michael Kennedy: Yeah, that was really great.
1:03:18 Miguel Grinberg: Yeah.
1:03:18 Michael Kennedy: All right, well, Miguel, thank you so much for being on the show once again. It was great to chat with you.
1:03:23 Miguel Grinberg: Thank you for inviting me.
1:03:23 Michael Kennedy: You bet, bye. This has been another episode of Talk Python to Me, Our guest was Miguel Grinberg and this episode has been brought to by Datadog and Talk Python Training. Datadog gives you visibility into the whole system running your code, visit talkpython.fm/datadog and see what you've been missing. They'll even throw in a free T-shirt for doing the tutorial. Are you or a colleague trying to learn Python? Have you tried books and videos that just left you bored by covering topics point by point? Well, check on my online course Python Jump Start by Building 10 Apps at talkpython.fm/course to experience a more engaging way to learn Python. And if you're looking for something a little more advanced, try my Write Pythonic Code course at talkpython.fm/pythonic. Be sure to subscribe to the show. Open your favor podcatcher and search for Python. We should be right at the top. You can also find the iTunes feed at /iTunes, Google Play feed at /play and direct RSS feed at /rss on talkpython.fm, our theme music is Developers, Developers, Developers by Corey Smith, who goes by Smixx, Corey just recently started selling his tracks on iTunes so I recommend you check it out at talkpython.fm/music, you can browse his tracks he has for sale on iTunes and listen to the full-length version of the theme song. This is your host Michael Kennedy. Thanks so much for listening, I really appreciate it. Smixx, let's get out of here.