Hello to the World in 8 Web Frameworks (micro, batteries included & async)
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Bassett, Aaron
Join us for a Phileas Fogg inspired whirlwind tour of eight Python web frameworks. "Had he programmed? It was likely, for no one seemed to know web frameworks more familiarly; there was no framework so obscure that he did not appear to have an intimate acquaintance with it. He must have developed in everything, at least in the spirit." We'll start with the current crop of microframeworks, showing how to achieve the same task in each, before progressing to "Batteries included" and the more specialised async frameworks. For developers who perhaps have only used a single framework, this talk gives them an opportunity to get out and explore the world (of web frameworks) and broaden their horizons, with plenty of Jules Verne inspired fun along the way.
 So yeah, thanks for coming along folks. Basically we're going to do a really quick look at different web frameworks. So we're going to start looking at some micro frameworks, we're going to look at some batteries included ones, and we're going to finish off with some async. So yeah, just a quick introduction to who I am. If I could remember to turn my clicker on, that would be good. Yeah, so I'm our ambassador. That's my Twitter handle. It's very imaginative. It's literally just my name. And I'm going to try and go for, because it's like eight web frameworks, we're going to do a whole little world. It kind of sounded a bit like, you know, around the world, 80 days, but Jules Vernezy. So I'm going to go for like a bit of a steampunk Victorian kind of aesthetic for the whole thing. So I probably should be a bit better on this image. Give him some of hats. Let's swap out those Rayvans. Got to have a bow tie if you're going Victorian and like that facial hair really needs an upgrade. So yes, this is me. I'm a developer advocate for people who don't know what that is. I literally get paid to wear branded t-shirts and hand out leaflets. I do that for a company called Nexmo. We're one of the sponsors here today. So we have a booth actually on this floor, I think. So if you haven't checked it out yet, you should. We may still have some t-shirts left, hopefully. Go grab some swag, talk to us about what we do. But essentially, we're just an API company. We do telecommunications APIs. We make it really easy to add the ability to kind of invite up an SMS or voice calls and things to your own applications. So I work with this team. We're kind of a bit different than most developer relations teams and that we don't come under sales and marketing. We actually come under product. We're all developers. We write all our own code. So all the client libraries and things that any of the developers interact with, they were all been written by the developer relations team. We still program an awful lot, to be honest. As well as programming, we write a lot as well. We want to make it as easy as possible for people to integrate our APIs. So we write a bunch of tutorials. So this one uses JavaScript and the Ionic framework. This one's Microsoft Bot. Android and Firebase. Flashing Google Cloud. The Dap peer-to-peer protocol and hug. Express deployed on the Glitch, Ionic, Django, Android, Swift, Angular Express. We go through a lot of different technologies at Next. Because, well, as we are an API company, we want to show people how they can integrate our products into whatever stack they're using. But also it's kind of fun. We enjoy trying out new technologies. We enjoy trying out new frameworks. I personally come from a background of Python and Django. I use Django for a very long time. So a lot of the stuff that I first arrived there was written in Django. Now I've started to branch out, like other kind of Python frameworks, like lots of JavaScript frameworks. And that's what I'm going to be talking about today, is the fact that over my last year doing developer relations, I've obviously worked with an awful lot of different frameworks, writing these blog posts and producing this content. And I'm going to look at some of those that I've used as we go through this. So what I'm going to build is essentially this. So in order to power a lot of our APIs, we use JSON. We call it a next-mo conversation control object, but it's a JSON file. It's essentially just a list of actions. So this one is telling a telephone call to use a synthesized voice to read out some text. You know, pretty straightforward. And that's what I'm going to build for each of these different frameworks today. So it's going to be one root that's just going to spit out some JSON. You know, so really kind of easy. So the first one we're going to look at is Flask. So Flask actually started off as an April Fool's joke. The offer of Flask was quite well known at the time for being incredibly critical of different frameworks. So as an April Fool's joke, he decided to write his own framework, a framework that did everything he hated about micro frameworks. And he released it. And he didn't tell anybody it was a joke. He just released it on the GitHub. He did a screencast. He actually got like a friend of his to record the voice and stuff for it. He wrote a couple of posts and things. And, you know, even, I think even the source code was actually obfuscated when he first released it before people started asking for the source. And it's now incredibly popular, probably one of the most popular micro frameworks. And this is something that I built with everything that he hated. So I think the April Fool's joke is really kind of on him. But getting up and running is very straightforward. It's a single file kind of micro framework, you know, so you just create a Python file. We can see here that I'm just importing kind of Flask. I'm starting a new Flask app. And then my root declaration is just a decorator on a function. And that function, using the JSONify Flask method, will set the headers correctly to say that it's actually JSON that we're returning. It'll properly encode it. And it'll then serve that up. And running it again is incredibly easy. You know, I've got it here telling it what the name of my file is, and then it's just Flask run. And we have that served up and ready to go. So that's the first one, kind of a teaser of what we're going to be looking at today. I'll put the URLs up for each of the different frameworks as we go through them. Don't worry too much about trying to write them down or anything. I'll be publishing all the slides on my Twitter anyway. So next one is Cherry. Cherry is a little bit older than Flask. It's been around for a little bit more. But it's very, very similar. It uses class-based views rather than function-based views. So here we can see I'm defining a class, just a regular kind of object. And I have, again, a couple of decorators on the methods. And I'm just returning, again, another Python object which is going to be quickly encoded and adjacent and served up on that route. So this one, rather than defining the actual route on the method like I was before, we're defining this, sorry, in our CherryPy QuickStart. We have our different routes and we're telling what handlers to use for those. There's no special way of running this. You know, you run it with Gunicorn or your Python file at it. There's no CherryPy run, et cetera, like we had for Flask. But it is very, very similar, again. So, again, URL for it. Falcon's kind of a bit new. It's really kind of geared more to where it's creating APIs. So it's really kind of easy to return JSON on it. That's what it's kind of expecting. You're going to want to be doing it anyway. We can see here it's very similar to what we have with CherryPy. We're declaring a class. We have an onGet. And then we're just returning this object. We don't even need to tell it that it's going to be JSON coded or anything. It expects it to be because it's built for APIs. Now, this is kind of where... Well, I'll leave it up for a moment first. So Falcon, you can kind of see some of this stuff. It's nice, but it's a little bit convoluted. So the people behind the next one, the hug, kind of agreed on that as well. And they tried to simplify it a little bit. Now, we can see with Hug, it's very similar to what we had with kind of Flask or what we had with CherryPy. You know, it's just a function that's returning a Python object that's going to get encoded into JSON. We have a decorator that's telling it what the root is. You know, it's very compact. It's very easy to run. You're not saving an awful lot of space compared to what you were or an awful lot of code compared to what Falcon provided. But that's only for the very simple example of Hug. Where it kind of gets more interesting is when we start looking at more complex examples. So in this example, you can see I've actually got two functions that are the same name. And each function is actually operating on the same URL. So they're both on this NCCO root. You know, they're both called NCCO, weirdly enough. But whenever we actually try to call any of these URLs, you can see it's got a versions in it. So the first one has got this versions equal one, and the next one's got this versions of a range of two to five. So whenever we call a URL now, we can just add the v1 or v2, v3 in the URL, and it automatically does the versioning for us. It also allows us to provide things like examples. So in the second example there, we can see I've got this f string that's going to substitute the who into our hello world that's returning. And we're showing in our decorator that this who, or sorry, we're providing an example of what who should be. So we've got who's in equal world. And we're also saying in our method there that we have this who parameter that's coming through, and we can actually type it as well. So we're saying that it's going to be a string. It's going to be a hug type of text. Now, if I try to access the URL, it doesn't exist, or I try to provide the wrong information to hug, we get this lovely kind of error output in the browser. So it's showing us what routes are available. It's showing us what those routes are going to return. It's showing us what the examples were that we provided. It gives a lot of really useful information from whenever you're trying to explore that API. And this is all kind of provided out of the box from hug. So it really builds upon what Falcon gives you, but then extends it with a lot of kind of useful things that you end up building time and time again yourself in Falcon anyway. So that's hug. So that's our first kind of just look at micro frameworks. It's not an awful lot to them. That's kind of the point of them. As you can see in the code, it's, you know, we're talking four or five lines each and you're up and you're running. They're really, really handy in that with the micro frameworks, a lot of the stuff that we do is obviously building demos. We want to get stuff up and running really fast. You know, we want just to be able to, people don't want to be wondering too long about the infrastructure or the code or the things that aren't the next way, PIs essentially. We just want something that we can show them a couple lines of code, have it running in the browser immediately and they can get to work. And that's where these really come in. And we can see the majority of them, they're looking really kind of similar. And the money code that's required, they're looking very similar in how in which they handle kind of five or class based views or function decorators. So we've done our quick look at the micro frameworks. I know there are not enough code to do them. That's kind of the point of them. So I'm going to move on then to these batteries included framework. And the term, term, that part is included really was kind of coined by Django. It was the first kind of batteries included, you know, everything's in there. With the micro frameworks, they just give you the littlest amount possible, you know, they're going to maybe give you rooting, they might give you template handling, and they're going to give you kind of views. And that's it. You know, everything beyond that point is up to you. But with your batteries included frameworks, they're going to specify an awful lot more, and they're going to provide an awful lot more. And for many of them, it's going to be kind of, you know, a convention over configuration, you know, so it's, they'll have a way in which they prefer you to do things. And if you stick to that, then it normally works out pretty well. So with Django, we have a few different commands. Once it's kind of installed, you've got your pip install, your pip install, et cetera. You've got this Django admin. And Django admin has a start project, which essentially is just going to build out your initial kind of template. Now, for anybody who used Django, probably not.9-ish to 1.4, maybe, whenever you did your original kind of start project, and then you would do your run server, it wasn't the greatest experience. It didn't set up your static files for you. Things were a little bit difficult, shall we say. Not anymore. With Django, now, as soon as you run your, do your start project and do your run server, you immediately get this lovely kind of webpage already up and running for you. It also has a start app. So here I'm creating a new conversation app. And it's going to create a bit of a file structure for you. So I've got just a print tree of that there. You see that it's going to create a new folder, and that folder is going to be things around for your migrations, for your database, for your models, for your views. It really gets an entire kind of structure. And that's normally in the structure most people continue to follow with Django, is the one that it kind of suggests. So once we have our app created, we need to add it to our settings. This is where you can kind of see these frameworks. They'll only provide a lot more. They need a lot more configuration as well. Whereas the micro frameworks, it's like a single page that you just wrote some code in, ran your Python, you're done with these. There's going to be multiple different files when you change. Lots of different bits need to be updated. So why we tend to avoid using these a lot in demos, because you end up having to explain an awful lot of boilerplate to people. But if you're using it for your own kind of major projects, it's probably what I would go for rather than micro. So anyway, here we're adding it to our installed apps. We then have our URLs. So you can put the URLs directly in the URLs file. What most people tend to do is have your URLs file lookal to each app, and then just reference that from your main URLs file. So here I'm looking at, including these conversation.urls. And then we create our view. Now Django does support function-based views. So you could just have a view that's going to return, take a request and return a response. They prefer to methodize these class-based views. They've been around for a while. They're still not, by some people, fully understood or fully utilized. I personally prefer them to make it a lot easier to test stuff. Trying to isolate things within one large function-based view for testing is problematic. If class-based views obviously makes the testing a lot easier, if people are having problems trying to get their heads wrapped around how class-based views actually work, there's a fantastic reference called ccbv.co.uk. It lists all the different views that are in there. It allows you to drill down into them, see exactly where they inherit from, what methods are available on them, what the code of those methods are, should you need to extend it yourself. It's incredibly useful. I probably spend more time on that site when I'm writing Django than on the actual Django documentation itself. I don't know if that says something about Django's documentation around class-based views or not, but it's still a wonderful reference, and I highly recommend it. The other thing that we have here is, I don't know if people spot it, is whenever I'm turning this JSON response, so I'm overwriting the regular kind of response that we have, I'm coming back up this get handler, and instead I'm returning JSON. I do have this cf equals false. That's always a major red flag. Whenever you're having to do cf equals false on any method, it's probably not something you want to be doing lightly, maybe want to be considering first. The reason for that is I'm actually returning an array as part of my JSON. Now, there is a vulnerability around returning a JSON file that has an array at the root. So if you return a JSON file, where essentially it's a dictionary at the root, so it's an object rather than both objects, but where it's a dictionary rather than an array, and you include that in a script tag on your own website. So kind of cross domain exploits. That won't render. It's not going to execute anything. You can't just include a JavaScript object on the page using an external tag. It's not going to actually run anything. However, if you have an array at the top level, well, you can then overwrite the array function in JavaScript and have that read out the contents of it. So essentially, the array becomes like your JSONP, your function wrapper around that code. So there's a great article that goes into this in a lot more detail, but why it's a really bad idea. It's also why things like Django, by default, if you try to return a JSON response that has an array as the root element, it's not going to let you do it. You're going to have to actually specify that, hey, I know what I'm doing. I'm a big person. I'm a professional. Please let me shoot myself in the foot. It's okay. But you're still going to have to let it to actually kind of go, this is my responsibility and I will handle any repercussions from it. Okay, so once we get a review, then we're going to reference that in our URL. So this is the actual URLs for the app itself. We can see we've got this app name equals conversation. We're naming the actual URL. It's a niceity. It allows you then if you reference that URL for your code, it doesn't happen to reference the URL itself or the root. You can just do conversation, colon, NCCO. And so if you change the root or your URLs change at any point, you don't need to go through all your coding and reach and change all your hard coded paths. So we've been all together. We've got our modifications to our settings file. We've got our two different URLs files that need to be updated. And then we've got our view itself, which is actually doing all the heavy lifting. So there's a bit more to it. The views are very similar to what we've seen before. It's just we now need to kind of place them within the structure provided from Django. So there's a lot more boilerplate to update. There's a lot more kind of configuration settings to set. There's obviously going to be a lot more code as well. When you look at all the generated code from Django's start project, you know, it's going to create an awful lot of stuff, a lot of things that it's going to require to run. But yeah, I'll give you the URL for it as well. Most people probably were familiar with Django anyway. The other one that we've got then a lot on our kind of, our bar is included is pyramid. So pyramids got a long history. I think actually the blown people might be done are like sponsoring. So they're probably going to give you a lot more of the background on it than I can. But their slogan is start small and finish big. You know, so and you really can. So with pyramids, it can act like a micro framework, you know, you can have it all in one page. You can define your views in there using your decorators to tell you want to render from JSON, configure your app, and you're done. You know, there's not an awful lot more code there than what we saw for the likes of Falcon, for example, or Cherrypie. You know, it's a single function per view that's just got a decorator on it. You know, it really can start that small if you want. But they've got this whole thing about finishing big. So if you need it just for doing really quick kind of micro framework stuff, you can do it that way. If you're starting off on a larger scale project, then they actually use cookie cutter for doing their templating. So rather than having like a built in kind of admin like Django does, and there's using cookie cutter, there's a bunch of different cookie cutters out there, depending upon the type of project went start. I'm just using their default permit starter. So you can see I've done my cookie cutter here. I've got this Pippin M install off all the dependencies. One of the things that I find a little bit strange, probably just my own way of approaching this, is the fact that permit actually packages everything as a Python package. So your project then becomes deployable as a Python package itself. You know, it's just going to have its own setup.py in there, which is going to list this kind of requirements, et cetera. And whenever you're doing your development, you can see that I've in Pippin installed that with dash e to show that, you know, I'm still actually in development on this. So I can still modify the code that's contained within there and have it executed. And then it comes with all the configuration is done in any files. You know, so you'll have a development, any production, any one for all your different environments. And we have this P serve to allow you then to start serving the files up. And once very similar to Django, once you've run this kind of P serve on your different configuration file, then it's going to stand up a server for you and present you with this lovely web, very red web page in this instance. Now, once if we're using it as a, and this finished big kind of way, so as a much larger kind of framework rather than using it as a micro framework on a single page, then we're very similar to what we had with Django. And we've got a couple of different configuration files to edit. And this one, they actually put it all in your init.py. And so we have this pyramid.config. We're telling you where to lift its settings from. We're setting up our roots. So we've got a separate URL to start pyre or anything like that for it, so I'm going to end this configuration. And then we're telling it just in this instance, just to scan our views file and find any views that are in there. So we switch from using just a single kind of function of a decorator in this one. And this instance now instead, we're actually switched to a class-based view. Again, it has the same kind of benefits as what I was outlining with Django. Makes it a lot easier to test. It makes it a lot easier to override different methods and to create mixins, et cetera. And we can see here that I have created a really simple kind of roots that, again, is just returning this Python object. It's going to be automatically encoded, form and adjacent, and returned with the correct application type. So a URL for a pyramid there. And if you look at the two kind of side-by-side, we can see even with pyramids kind of finished, baked mentality, there's not a huge amount of difference between it, too. So PyFins or Django's is a little bit more scattered for different files. Some of that's not really necessarily required. That's just my personal preference. Things like having an additional URLs.py is not actually needed. You could just put it all in your first URLs. In fact, there's actually a project out there that will turn Django into a single file framework, much the same as Flask or any other micro frameworks. It's disgusting. So the good thing about any of these kind of large frameworks over the micro frameworks is that there is conventions in there. There is ways you should follow to get things done. There's lots of books and things out there that explain, Django 2 Scoops is probably the main one. You know, go for all the best practices. And hopefully, if you approach one Django project, which would look very similar to any other Django project, they're going to be structured very much the same way. Your models are going to be using the same ORM in order to access a database. Your views are going to be structured in very similar ways. You might have some use-functional-based views rather than class-based views. But again, it should all be in a logical kind of place, and you should be able to navigate the directory structure and find what you need very quickly. Micro frameworks, they're slightly different in that, well, they just give you the very, very basics and leave the rest up to yourself. And for developers, sometimes that, even for larger projects, that seems like a great idea. We don't want to be constrained by other people's ways of doing things sometimes. We've got this grand plan of what we're going to build. We're going to pour a heart and soul into this project, and it's going to be fantastic, and we're not going to make any of the mistakes that Django made or any of the mistakes that pyramid made. Our use case is unique to us. So we're going to start with the most basic framework we can, and then we're going to start adding in all the different things that we need that are written exactly for us in just the way that we need them. We're not going to worry about the fact that, obviously, Django is a great framework. There's a lot of work to be put into it, but concessions have probably had to be made because it's not geared exactly to what we need. So instead, you start off a micro framework, and then you might add in SQL Alchemy, or you might start adding in some of your own ORM stuff. Of course, these are all interesting problems, and that's what developers like to do, so that's why we do it. Why would we use somebody else's ORM when it might not do exactly the way we want? So we write our own, and we integrate that instead, and, well, that's the interesting part. Documentation is not interesting, so it's all documentation. Nobody does documentation. So the next developer comes along, and maybe they like what you did, maybe they don't like what you did. They might invent it slightly differently, or they may not quite understand the way we should have invented it, and there's no documentation, so they might use it slightly differently to what you'd used it. They might not even see what you'd done previously, and they might start a completely new way of accessing the database. And then a third developer comes along, and they actually don't want to roll their own, so they just go and Google it and take the first Stack Overflow answer and start doing it that way instead. And suddenly, this lovely framework that you designed in your head starts to look a little bit different. And I've seen this happen as well in countless different places where they go, we're not going to use Django because we don't like the way in which it handles views, or we're not going to use Pyramid because we don't like the way in which it's packaged for deployment, or we're not going to use List Your Favorite Frameworks here. We're going to build it ourselves because we can do better. Probably not. Okay, so we're running for this really quickly, but we're now onto our async. So we're going to start off with probably the granddaddy of all async ones, which is tornado. The benefits of async, most people think of immediately as kind of speed. Tornado is actually slower than Django, considerably slower than Django. If you're talking about first response times to render a piece of JSON to the browser, it's considerably slower, like, I think, a factor of two. But where it really excels is in concurrency and also in accuracy. So whereas with Django, as your number of concurrent users increases, your error rate also increases. With tornado, it tends to stay pretty consistent and pretty low as well. So it's going to be able to handle requests might be slightly slower, but it's going to handle a lot more concurrent requests with a lot lower failure rate. So let's look at how tornado is kind of set up then. Again, it's going to be pretty straightforward. It's much the same as a lot of the micro frameworks. You can use kind of class-based views. You can structure it a lot differently. It doesn't really put a lot of kind of conventions around you. Here we can see I'm just defining a class with a get method. I'm configuring my roots again, and I'm starting my application. Now, this will work, but if we look at this section here, we can see it's not going to work for next month. Next month requires that to be a list. Even though there's only one action occurring in there, it has to be a list. Now, if I try turning that into a list and running it in tornado, we're going to get this. It's going to throw an exception because of that security vulnerability that we talked about earlier. It's a really nice exception actually, and it explains why it's going to do it, but it's trying to stop me from introducing security vulnerability in my code. But as we talked about earlier, I will find a way to ship myself into foo. Now, tornado doesn't have a way of me just to go see if equals false and allow me to do it. It just blocks it. It's saying that this is a security vulnerability. You should not be doing this. We're not going to let you do it. But it's a Python class. It's got all this lovely, we can go in, we can look at the actual code for it. We can see it's got all this error checking in there. It's looking to ensure that it's either bytes, a Unicode type, or a dictionary. It's making sure that it's not going to be an array. If it is an array, it's going to return that exception. But we're professionals. Error checking is for people who do not have confidence in their code. So we're going to get rid of all of that. And because it's a class-based view, we can just strip all that stuff out. We can overwrite their right method. We can remove all that error checking. We will be wholly and solely responsible for introducing all the security vulnerabilities we want in our code. It's our code. If we want to be insecure, we will be. So we remove all their error checking. It now doesn't even check to see what kind of thing we're passing it. Everything's going to be JSON from now on. That's fine. We're just going to always return JSON. And we run this now and it's going to work. So it's returning it home. Now the last kind of one that we're going to look at, and I know we've gone through seven already, I really wish I'd brought some of that water up on the desk. Yes, the last one we're going to look at is, oh, you're amazing. Is Sanic. So whenever I first came across Sanic, I actually completely and artfully dismissed it. Thank you so much. I thought it was a joke, to be honest. It came up in hacker news. I went to the GitHub page. This is their mascot. Very enterprise friendly. For people who don't wear it, it's just really bad drawing of Sonic. But yeah, it actually completely turned me off from the project. Even when you start off the terminal, you get this in the terminal. They've really gone all in on this mascot. I immediately assumed it was a joke. I thought, okay, so somebody's done basically a flask, but for async. And I completely dismissed it. I didn't really look into it anymore. I didn't go back to it for probably 18 months until at another conference, somebody was really thinking about this framework. I completely forgotten all about it. Whenever I went to look it up, I was like, seriously? This is still a thing? That's a long running joke. But no, it's actually great. I don't know if the moral here is I don't judge a book by its cover, or maybe branding matters, I'm not sure. I know people sometimes have a go at the whole Django, like Pegasus Unicorn type thing, and how it's not enterprise friendly, it's not very professional. Yeah, but it could be worse. So, Saniq came up basically because of UV loop. So in Python, from 3.4, I think, we've had async. There's now a drop in replacement for the built in async and Python called UV loop. It's a lot faster. And Saniq really just came as a way to take full advantage of that. Much like we have before, it's really simple to get up and running. We're just defining a function. We're going to add our decorator on that to say what the root should be. So it's always going to be this ncco for any of our calls here. And then we just run it from the command line with our Python hello.py thing called these. And we're going to get this similar, this output. Thankfully, this, I should say, this only appears if you've got debug set to true. We don't get the lovely mascot in your production when we're running it, so it's not quite so bad. But it can also support class-based views. So we can see here that it looks very similar to some of the ones we've had. You know, I'm defining our class. We have this, in this case, so we're using async. So we've got this async method that's going to return our JSON for us. And then we can just run that as we did before. So, got our Saniq one. Now, as I was going through writing the code for all eight of these different ones, by the way, that was a fantastic idea of mine. Let's do a conference talk where I need to write the same code eight bloody times. But as I was going through writing the code, I actually started to notice that it's really similar. So here is how we define our root in Flask. And here is in Saniq. And here is in Hug. You know, we've got very, very similar. Okay, so it's app.root, app.root, hug.get. But it's a very similar kind of structure. You know, and then I started noticing other things like in Pyramid. You know, so whenever we're defining our roots there, okay, it's not app.root, but it's again, it's, you know, view config in a root name. Or whenever we're looking at our class-based views, you know, we've just got these get methods. And then on Toneida, we've got a get method. And on Django, we've got a get method. And on Falcon, we've got an on get. You know, again, very similar. And then I started noticing things like someone, Falcon, there, we've got this API add root as well. Which kind of looks like tornadoes, you know, first configuring it. Which kind of looks like pyramids, configuring it. You know, for all these, like the actual similarities to many of them were, well, very similar. So it's kind of an odd one then of, you know, what's, how do you choose a trimer to use? Or which one's the better one? And to be honest, I've got very little kind of differentiation between them. Django would be probably my favorite to go for for batteries included because I know it best. If I had started out my career writing pyramid, I'd probably be up here like using pyramid for most of my examples instead. Whenever I come to use a micro framework, again, I'll normally use flask because that's the one I used first. You know, it's not because I couldn't articulate. So my reasoning for it, why I prefer flask over cherry pie or why I would use flask over hug or over Falcon. Because it's not a case of, oh, it's this particular feature is a killer feature or that particular way that does it is the way that I really enjoy. It's just, it's the one I use first. You know, and I probably should explore that myself a little bit more because I probably am missing out on better ways of doing things. Because I, you know, like most people I've stick with what's familiar and I stick with what I know. But what we're running at least is turns out that actually, you know, the examples of at least the basics of each one is so similar that re scaling or learning the different frameworks didn't take very long at all. But I guess that's kind of like the whole point of Python, you know, there should be one and hopefully only one way of doing things apart from if it's stringed and catamation. Then we should have lots of different ways apparently. Okay, so I've been our ambassador. This has been my talk on eight different web frameworks. Hopefully you got a chance to absorb a little bit of each one. I know there was an awful lot of code going through very, very quickly there. I will post the, I have a GitHub repository that has everything I went through all the code examples with like explanations how to run each one. And so that's all up on my GitHub. I'll tweet it out on our ambassador. I'll also put it on. I should probably go right back to the start. There was a lot of slides. And just one or two here. There we go. There we go. Keep going. Right. And on next most account as well. So we have a next with Dev account. I'll put all the links to the slides, links to GitHub repositories. Also the different blog posts that I went through earlier. So once Angular, Swift, Android, Django, Sanec, Express, peer-to-peer stuff, all that kind of blog posts all up on next one.com too. Again, they're going to be using all different frameworks I've talked about today. This is actually one from Mark. So Mark is one of my colleagues. You may have seen him. He's the other dude in the kill walking about. He doesn't wear it quite so well. So he's going to be talking actually later on today. But about half to. So I recommend catching that as well if you can. Other than that, we're going to be on the booth for the rest of the conference. Please come say hello. And if you've got any questions about any of the frameworks and things that I went through, I will try my best to answer them. But as I said, I love for a lot of them. I'm really just a beginner as well. I've just been using them because I thought they were interesting and trying to get some example code and stuff like that for people. But yeah, so again, that's my Twitter. Please follow along. I'll tweet out all links and things. And thank you very much for your time. Okay. Thank you. So we have time for a couple of questions. So anyone have a question? Okay. Thanks, Aaron. That was quite a nice overview. I mentioned at the end that you probably would just go for Flask or just go for Django because you got experience there. When you look at the frameworks from a more company or from a business decision, would you consider or have you looked into any security handling of those frameworks and how they compare to each other? Would that be a thing where you would make the decision based on? Yeah. So for me, really, the reason that I probably would pick Django again, and this was probably, people will be able to tell me that all the frameworks are this, I'm sure, but is their deprecation schedule? The way in which they handle releases and stability of the actual framework is in my mind crucial for really any kind of company. And that feeds into the security stuff. I've seen companies where they just feel to upgrade because there's too many breaking changes or the way in which the different frameworks have handled deprecation of APIs, etc. has been so bad in the past that they're really scared to do any kind of upgrades. And that means they end up not doing even security upgrades as well. So for me, the fact that they have a stable release schedule, a published deprecation schedule they stick to, and the handling of their actual releases, both security and feature, is probably why I would stick with Django. Hi. Thanks for talking. My question is, could you recommend some API over another, if you plan to have a JavaScript framework managing the front end and more the backend side handled by some Django Python API? And the other question, can you say again the website that you are using for Django reference, and cut that? Yeah, sure. I'll just put the, let's get that slide back up. Sit here somewhere. I have to remove the thing off. And show all this stuff back on my face. Let's just exit our list and just go directly to the slide. I kind of forgot just how many slides I actually had. That one. Yeah. So for anybody who can't read it, it's ccbv.co.uk. And it's a reference for Django's class piece views. It's incredibly useful. So the first part of your question is, so if you're essentially using the backend just as an API, so driving, I'm assuming like React or View or Angular, all of the ones we're looking at there had the ability built in to respond with JSON. For some of them like Flask, it required using JSONify rather than the regular response. Ones like Falcon are really built to be API kind of back ends. So you don't even need to specify that you're returning JSON. As soon as it detects that the object that you're returning from your view is a Python object like one of their response objects or just plain text, it's going to assume that you want that encoded as JSON anyway. So most of the modern frameworks will be geared towards that kind of way of working. Django obviously is slightly different in that in order to turn it into really an API kind of backend, you're going to need to use something like Django REST framework, which is really mature. We've used it successfully on several kind of large projects and things. So I would highly recommend that if you wanted to go kind of the Django REST. Again, even with the async ones, they're going to be geared towards being API back ends as well. So things like tornado again, if you just provide it with a Python object, it's going to assume that you want a JSON response. So I wouldn't worry too much about whether or not they're going to act as an API gateway. All of them are capable of doing that and they all handle it really well. Again, it's just looking for whichever one kind of suits your style or your requirements best. Thank you. You're welcome. So last question. Hello. Hi. Hi. Thank you for the talk. It's really nice having someone spending time to write API's the same thing. And as you say, there's a difference between the big frameworks like Pyramid and Django REST. They include batteries. And in most, because there is not real life code, you usually need some kind of authentication, at least some kind of authentication. And usually the ability to connect to some data, Tini, there are database or something. Do you know when you did the research for your talk, do you know if A, there are standard plugins for all the micro frameworks to do that kind of thing? And B, do you know if somebody maybe did the same thing as you, but with all that included, like how much code it would take for a Flask with a database and identification? So for Flask, I know that they do. Flask has got a very mature kind of plugin, kind of ecosystem around it. It's one of those ones as well that for things like database access, there tends to be a preferred method of doing it. So if you're going to find for Flask, it's going to be Flask. It's going to be SQL welcoming. And it's going to be Flask welcoming. Those things combined is normally the way most people do database access. But because the whole idea of it is it just does the minimum of mind required and allows you to configure the rest yourself, I have come across situations where people are using Flask and using SQL welcoming, but then they've written their own ORM and top of it rather than using Flask welcoming, et cetera. For Falcon and Hug, which is based upon Falcon, I'm not overly sure. I know they're fairly new. I've not done a lot of research into what's available for them at the moment. I do know for most of the different frameworks that went through, as well, they do have, like for Cherry Pie essentially, especially, they have a very mature kind of ecosystem around different extensions for it. So they will have a preferred method of doing it again. For the second-party question, have I seen any major comparisons between all of them? I haven't. Normally what you'll find is comparisons between maybe one or two. One will show you, like, okay, this is how you get database access in Flask, and this is how you do it in Cherry Pie. Or something I'll look at, like, okay, so here is how you will do the preferred method in Falcon. But I've not seen somebody do it for all of the micro frameworks. Thank you. No problem. Okay. Thank you very much. So, let's give it a round of applause.
 So yeah, thanks for coming along folks.  Basically we're going to do a really quick look at  different web frameworks. So we're going to start looking at some micro frameworks,  we're going to look at some batteries included ones, and we're going to finish off with some async.  So yeah, just a quick introduction to who I am.  If I could remember to turn my clicker on, that would be good.  Yeah, so I'm our ambassador. That's my Twitter handle.  It's very imaginative. It's literally just my name.  And I'm going to try and go for, because it's like eight web frameworks,  we're going to do a whole little world.  It kind of sounded a bit like, you know, around the world, 80 days, but Jules Vernezy.  So I'm going to go for like a bit of a steampunk Victorian kind of aesthetic for the whole thing.  So I probably should be a bit better on this image.  Give him some of hats. Let's swap out those Rayvans.  Got to have a bow tie if you're going Victorian and like that facial hair really needs an upgrade.  So yes, this is me. I'm a developer advocate for people who don't know what that is.  I literally get paid to wear branded t-shirts and hand out leaflets.  I do that for a company called Nexmo.  We're one of the sponsors here today. So we have a booth actually on this floor, I think.  So if you haven't checked it out yet, you should.  We may still have some t-shirts left, hopefully.  Go grab some swag, talk to us about what we do.  But essentially, we're just an API company.  We do telecommunications APIs.  We make it really easy to add the ability to kind of invite up an SMS or voice calls and things to your own applications.  So I work with this team.  We're kind of a bit different than most developer relations teams and that we don't come under sales and marketing.  We actually come under product. We're all developers.  We write all our own code.  So all the client libraries and things that any of the developers interact with,  they were all been written by the developer relations team.  We still program an awful lot, to be honest.  As well as programming, we write a lot as well.  We want to make it as easy as possible for people to integrate our APIs.  So we write a bunch of tutorials.  So this one uses JavaScript and the Ionic framework.  This one's Microsoft Bot.  Android and Firebase.  Flashing Google Cloud.  The Dap peer-to-peer protocol and hug.  Express deployed on the Glitch,  Ionic, Django, Android, Swift, Angular Express.  We go through a lot of different technologies at Next.  Because, well, as we are an API company,  we want to show people how they can integrate our products into whatever stack they're using.  But also it's kind of fun.  We enjoy trying out new technologies.  We enjoy trying out new frameworks.  I personally come from a background of Python and Django.  I use Django for a very long time.  So a lot of the stuff that I first arrived there was written in Django.  Now I've started to branch out, like other kind of Python frameworks,  like lots of JavaScript frameworks.  And that's what I'm going to be talking about today,  is the fact that over my last year doing developer relations,  I've obviously worked with an awful lot of different frameworks,  writing these blog posts and producing this content.  And I'm going to look at some of those that I've used as we go through this.  So what I'm going to build is essentially this.  So in order to power a lot of our APIs, we use JSON.  We call it a next-mo conversation control object,  but it's a JSON file.  It's essentially just a list of actions.  So this one is telling a telephone call to use a synthesized voice  to read out some text.  You know, pretty straightforward.  And that's what I'm going to build for each of these different frameworks today.  So it's going to be one root that's just going to spit out some JSON.  You know, so really kind of easy.  So the first one we're going to look at is Flask.  So Flask actually started off as an April Fool's joke.  The offer of Flask was quite well known at the time  for being incredibly critical of different frameworks.  So as an April Fool's joke, he decided to write his own framework,  a framework that did everything he hated about micro frameworks.  And he released it.  And he didn't tell anybody it was a joke.  He just released it on the GitHub.  He did a screencast.  He actually got like a friend of his to record the voice and stuff for it.  He wrote a couple of posts and things.  And, you know, even, I think even the source code was actually obfuscated  when he first released it before people started asking for the source.  And it's now incredibly popular, probably one of the most popular micro frameworks.  And this is something that I built with everything that he hated.  So I think the April Fool's joke is really kind of on him.  But getting up and running is very straightforward.  It's a single file kind of micro framework, you know,  so you just create a Python file.  We can see here that I'm just importing kind of Flask.  I'm starting a new Flask app.  And then my root declaration is just a decorator on a function.  And that function, using the JSONify Flask method,  will set the headers correctly to say that it's actually JSON that we're returning.  It'll properly encode it.  And it'll then serve that up.  And running it again is incredibly easy.  You know, I've got it here telling it what the name of my file is,  and then it's just Flask run.  And we have that served up and ready to go.  So that's the first one, kind of a teaser of what we're going to be looking at today.  I'll put the URLs up for each of the different frameworks as we go through them.  Don't worry too much about trying to write them down or anything.  I'll be publishing all the slides on my Twitter anyway.  So next one is Cherry.  Cherry is a little bit older than Flask.  It's been around for a little bit more.  But it's very, very similar.  It uses class-based views rather than function-based views.  So here we can see I'm defining a class, just a regular kind of object.  And I have, again, a couple of decorators on the methods.  And I'm just returning, again, another Python object which is going to be  quickly encoded and adjacent and served up on that route.  So this one, rather than defining the actual route on the method like I was before,  we're defining this, sorry, in our CherryPy QuickStart.  We have our different routes and we're telling what handlers to use for those.  There's no special way of running this.  You know, you run it with Gunicorn or your Python file at it.  There's no CherryPy run, et cetera, like we had for Flask.  But it is very, very similar, again.  So, again, URL for it.  Falcon's kind of a bit new.  It's really kind of geared more to where it's creating APIs.  So it's really kind of easy to return JSON on it.  That's what it's kind of expecting.  You're going to want to be doing it anyway.  We can see here it's very similar to what we have with CherryPy.  We're declaring a class.  We have an onGet.  And then we're just returning this object.  We don't even need to tell it that it's going to be JSON coded or anything.  It expects it to be because it's built for APIs.  Now, this is kind of where...  Well, I'll leave it up for a moment first.  So Falcon, you can kind of see some of this stuff.  It's nice, but it's a little bit convoluted.  So the people behind the next one, the hug, kind of agreed on that as well.  And they tried to simplify it a little bit.  Now, we can see with Hug, it's very similar to what we had with kind of Flask  or what we had with CherryPy.  You know, it's just a function that's returning a Python object  that's going to get encoded into JSON.  We have a decorator that's telling it what the root is.  You know, it's very compact.  It's very easy to run.  You're not saving an awful lot of space compared to what you were  or an awful lot of code compared to what Falcon provided.  But that's only for the very simple example of Hug.  Where it kind of gets more interesting is when we start looking at more complex examples.  So in this example, you can see I've actually got two functions that are the same name.  And each function is actually operating on the same URL.  So they're both on this NCCO root.  You know, they're both called NCCO, weirdly enough.  But whenever we actually try to call any of these URLs, you can see it's got a versions in it.  So the first one has got this versions equal one,  and the next one's got this versions of a range of two to five.  So whenever we call a URL now, we can just add the v1 or v2, v3 in the URL,  and it automatically does the versioning for us.  It also allows us to provide things like examples.  So in the second example there, we can see I've got this f string  that's going to substitute the who into our hello world that's returning.  And we're showing in our decorator that this who,  or sorry, we're providing an example of what who should be.  So we've got who's in equal world.  And we're also saying in our method there that we have this who parameter that's coming through,  and we can actually type it as well.  So we're saying that it's going to be a string.  It's going to be a hug type of text.  Now, if I try to access the URL, it doesn't exist,  or I try to provide the wrong information to hug,  we get this lovely kind of error output in the browser.  So it's showing us what routes are available.  It's showing us what those routes are going to return.  It's showing us what the examples were that we provided.  It gives a lot of really useful information  from whenever you're trying to explore that API.  And this is all kind of provided out of the box from hug.  So it really builds upon what Falcon gives you,  but then extends it with a lot of kind of useful things that you end up building time and time again yourself in Falcon anyway.  So that's hug.  So that's our first kind of just look at micro frameworks.  It's not an awful lot to them.  That's kind of the point of them.  As you can see in the code, it's, you know, we're talking four or five lines each and you're up and you're running.  They're really, really handy in that with the micro frameworks,  a lot of the stuff that we do is obviously building demos.  We want to get stuff up and running really fast.  You know, we want just to be able to,  people don't want to be wondering too long about the infrastructure or the code  or the things that aren't the next way, PIs essentially.  We just want something that we can show them a couple lines of code,  have it running in the browser immediately and they can get to work.  And that's where these really come in.  And we can see the majority of them, they're looking really kind of similar.  And the money code that's required, they're looking very similar in how in which they handle kind of five or class based views  or function decorators.  So we've done our quick look at the micro frameworks.  I know there are not enough code to do them.  That's kind of the point of them.  So I'm going to move on then to these batteries included framework.  And the term, term, that part is included really was kind of coined by Django.  It was the first kind of batteries included, you know, everything's in there.  With the micro frameworks, they just give you the littlest amount possible, you know,  they're going to maybe give you rooting, they might give you template handling,  and they're going to give you kind of views.  And that's it.  You know, everything beyond that point is up to you.  But with your batteries included frameworks, they're going to specify an awful lot more,  and they're going to provide an awful lot more.  And for many of them, it's going to be kind of, you know, a convention over configuration, you know,  so it's, they'll have a way in which they prefer you to do things.  And if you stick to that, then it normally works out pretty well.  So with Django, we have a few different commands.  Once it's kind of installed, you've got your pip install, your pip install, et cetera.  You've got this Django admin.  And Django admin has a start project, which essentially is just going to build out your initial kind of template.  Now, for anybody who used Django, probably not.9-ish to 1.4, maybe,  whenever you did your original kind of start project, and then you would do your run server,  it wasn't the greatest experience. It didn't set up your static files for you.  Things were a little bit difficult, shall we say.  Not anymore. With Django, now, as soon as you run your, do your start project and do your run server,  you immediately get this lovely kind of webpage already up and running for you.  It also has a start app.  So here I'm creating a new conversation app.  And it's going to create a bit of a file structure for you.  So I've got just a print tree of that there.  You see that it's going to create a new folder, and that folder is going to be things around for your migrations,  for your database, for your models, for your views.  It really gets an entire kind of structure.  And that's normally in the structure most people continue to follow with Django,  is the one that it kind of suggests.  So once we have our app created, we need to add it to our settings.  This is where you can kind of see these frameworks.  They'll only provide a lot more. They need a lot more configuration as well.  Whereas the micro frameworks, it's like a single page that you just wrote some code in,  ran your Python, you're done with these.  There's going to be multiple different files when you change.  Lots of different bits need to be updated.  So why we tend to avoid using these a lot in demos,  because you end up having to explain an awful lot of boilerplate to people.  But if you're using it for your own kind of major projects,  it's probably what I would go for rather than micro.  So anyway, here we're adding it to our installed apps.  We then have our URLs.  So you can put the URLs directly in the URLs file.  What most people tend to do is have your URLs file lookal to each app,  and then just reference that from your main URLs file.  So here I'm looking at, including these conversation.urls.  And then we create our view.  Now Django does support function-based views.  So you could just have a view that's going to return,  take a request and return a response.  They prefer to methodize these class-based views.  They've been around for a while.  They're still not, by some people, fully understood or fully utilized.  I personally prefer them to make it a lot easier to test stuff.  Trying to isolate things within one large function-based view for testing is problematic.  If class-based views obviously makes the testing a lot easier,  if people are having problems trying to get their heads wrapped around  how class-based views actually work,  there's a fantastic reference called ccbv.co.uk.  It lists all the different views that are in there.  It allows you to drill down into them, see exactly where they inherit from,  what methods are available on them, what the code of those methods are,  should you need to extend it yourself.  It's incredibly useful.  I probably spend more time on that site when I'm writing Django  than on the actual Django documentation itself.  I don't know if that says something about Django's documentation around class-based views or not,  but it's still a wonderful reference, and I highly recommend it.  The other thing that we have here is, I don't know if people spot it,  is whenever I'm turning this JSON response,  so I'm overwriting the regular kind of response that we have,  I'm coming back up this get handler, and instead I'm returning JSON.  I do have this cf equals false.  That's always a major red flag.  Whenever you're having to do cf equals false on any method,  it's probably not something you want to be doing lightly,  maybe want to be considering first.  The reason for that is I'm actually returning an array as part of my JSON.  Now, there is a vulnerability around returning a JSON file that has an array at the root.  So if you return a JSON file, where essentially it's a dictionary at the root,  so it's an object rather than both objects,  but where it's a dictionary rather than an array,  and you include that in a script tag on your own website.  So kind of cross domain exploits.  That won't render.  It's not going to execute anything.  You can't just include a JavaScript object on the page using an external tag.  It's not going to actually run anything.  However, if you have an array at the top level,  well, you can then overwrite the array function in JavaScript  and have that read out the contents of it.  So essentially, the array becomes like your JSONP,  your function wrapper around that code.  So there's a great article that goes into this in a lot more detail,  but why it's a really bad idea.  It's also why things like Django, by default,  if you try to return a JSON response that has an array as the root element,  it's not going to let you do it.  You're going to have to actually specify that, hey, I know what I'm doing.  I'm a big person. I'm a professional.  Please let me shoot myself in the foot. It's okay.  But you're still going to have to let it to actually kind of go,  this is my responsibility and I will handle any repercussions from it.  Okay, so once we get a review, then we're going to reference that in our URL.  So this is the actual URLs for the app itself.  We can see we've got this app name equals conversation.  We're naming the actual URL.  It's a niceity.  It allows you then if you reference that URL for your code,  it doesn't happen to reference the URL itself or the root.  You can just do conversation, colon, NCCO.  And so if you change the root or your URLs change at any point,  you don't need to go through all your coding and reach  and change all your hard coded paths.  So we've been all together.  We've got our modifications to our settings file.  We've got our two different URLs files that need to be updated.  And then we've got our view itself,  which is actually doing all the heavy lifting.  So there's a bit more to it.  The views are very similar to what we've seen before.  It's just we now need to kind of place them  within the structure provided from Django.  So there's a lot more boilerplate to update.  There's a lot more kind of configuration settings to set.  There's obviously going to be a lot more code as well.  When you look at all the generated code from Django's start project,  you know, it's going to create an awful lot of stuff,  a lot of things that it's going to require to run.  But yeah, I'll give you the URL for it as well.  Most people probably were familiar with Django anyway.  The other one that we've got then a lot on our kind of,  our bar is included is pyramid.  So pyramids got a long history.  I think actually the blown people might be done are like sponsoring.  So they're probably going to give you a lot more of the background on it than I can.  But their slogan is start small and finish big.  You know, so and you really can.  So with pyramids, it can act like a micro framework, you know,  you can have it all in one page.  You can define your views in there using your decorators  to tell you want to render from JSON, configure your app, and you're done.  You know, there's not an awful lot more code there than what we saw for the likes of Falcon,  for example, or Cherrypie.  You know, it's a single function per view that's just got a decorator on it.  You know, it really can start that small if you want.  But they've got this whole thing about finishing big.  So if you need it just for doing really quick kind of micro framework stuff,  you can do it that way.  If you're starting off on a larger scale project, then they actually use cookie cutter for doing their templating.  So rather than having like a built in kind of admin like Django does,  and there's using cookie cutter, there's a bunch of different cookie cutters out there,  depending upon the type of project went start.  I'm just using their default permit starter.  So you can see I've done my cookie cutter here.  I've got this Pippin M install off all the dependencies.  One of the things that I find a little bit strange, probably just my own way of approaching this,  is the fact that permit actually packages everything as a Python package.  So your project then becomes deployable as a Python package itself.  You know, it's just going to have its own setup.py in there,  which is going to list this kind of requirements, et cetera.  And whenever you're doing your development, you can see that I've in Pippin installed that with dash e  to show that, you know, I'm still actually in development on this.  So I can still modify the code that's contained within there and have it executed.  And then it comes with all the configuration is done in any files.  You know, so you'll have a development, any production, any one for all your different environments.  And we have this P serve to allow you then to start serving the files up.  And once very similar to Django, once you've run this kind of P serve on your different configuration file,  then it's going to stand up a server for you and present you with this lovely web,  very red web page in this instance.  Now, once if we're using it as a, and this finished big kind of way,  so as a much larger kind of framework rather than using it as a micro framework on a single page,  then we're very similar to what we had with Django.  And we've got a couple of different configuration files to edit.  And this one, they actually put it all in your init.py.  And so we have this pyramid.config.  We're telling you where to lift its settings from.  We're setting up our roots.  So we've got a separate URL to start pyre or anything like that for it, so I'm going to end this configuration.  And then we're telling it just in this instance, just to scan our views file and find any views that are in there.  So we switch from using just a single kind of function of a decorator in this one.  And this instance now instead, we're actually switched to a class-based view.  Again, it has the same kind of benefits as what I was outlining with Django.  Makes it a lot easier to test.  It makes it a lot easier to override different methods and to create mixins, et cetera.  And we can see here that I have created a really simple kind of roots that, again, is just returning this Python object.  It's going to be automatically encoded, form and adjacent, and returned with the correct application type.  So a URL for a pyramid there.  And if you look at the two kind of side-by-side, we can see even with pyramids kind of finished, baked mentality,  there's not a huge amount of difference between it, too.  So PyFins or Django's is a little bit more scattered for different files.  Some of that's not really necessarily required.  That's just my personal preference.  Things like having an additional URLs.py is not actually needed.  You could just put it all in your first URLs.  In fact, there's actually a project out there that will turn Django into a single file framework,  much the same as Flask or any other micro frameworks.  It's disgusting.  So the good thing about any of these kind of large frameworks over the micro frameworks is that there is conventions in there.  There is ways you should follow to get things done.  There's lots of books and things out there that explain,  Django 2 Scoops is probably the main one.  You know, go for all the best practices.  And hopefully, if you approach one Django project, which would look very similar to any other Django project,  they're going to be structured very much the same way. Your models are going to be using the same ORM in order to access a database.  Your views are going to be structured in very similar ways.  You might have some use-functional-based views rather than class-based views.  But again, it should all be in a logical kind of place,  and you should be able to navigate the directory structure and find what you need very quickly.  Micro frameworks, they're slightly different in that, well,  they just give you the very, very basics and leave the rest up to yourself.  And for developers, sometimes that, even for larger projects, that seems like a great idea.  We don't want to be constrained by other people's ways of doing things sometimes.  We've got this grand plan of what we're going to build.  We're going to pour a heart and soul into this project, and it's going to be fantastic,  and we're not going to make any of the mistakes that Django made or any of the mistakes that pyramid made.  Our use case is unique to us.  So we're going to start with the most basic framework we can,  and then we're going to start adding in all the different things that we need that are written exactly for us  in just the way that we need them.  We're not going to worry about the fact that, obviously, Django is a great framework.  There's a lot of work to be put into it, but concessions have probably had to be made  because it's not geared exactly to what we need.  So instead, you start off a micro framework, and then you might add in SQL Alchemy,  or you might start adding in some of your own ORM stuff.  Of course, these are all interesting problems, and that's what developers like to do, so that's why we do it.  Why would we use somebody else's ORM when it might not do exactly the way we want?  So we write our own, and we integrate that instead, and, well, that's the interesting part.  Documentation is not interesting, so it's all documentation. Nobody does documentation.  So the next developer comes along, and maybe they like what you did, maybe they don't like what you did.  They might invent it slightly differently, or they may not quite understand the way we should have invented it,  and there's no documentation, so they might use it slightly differently to what you'd used it.  They might not even see what you'd done previously, and they might start a completely new way of accessing the database.  And then a third developer comes along, and they actually don't want to roll their own,  so they just go and Google it and take the first Stack Overflow answer and start doing it that way instead.  And suddenly, this lovely framework that you designed in your head starts to look a little bit different.  And I've seen this happen as well in countless different places where they go, we're not going to use Django  because we don't like the way in which it handles views,  or we're not going to use Pyramid because we don't like the way in which it's packaged for deployment,  or we're not going to use List Your Favorite Frameworks here.  We're going to build it ourselves because we can do better. Probably not.  Okay, so we're running for this really quickly, but we're now onto our async.  So we're going to start off with probably the granddaddy of all async ones, which is tornado.  The benefits of async, most people think of immediately as kind of speed.  Tornado is actually slower than Django, considerably slower than Django.  If you're talking about first response times to render a piece of JSON to the browser,  it's considerably slower, like, I think, a factor of two.  But where it really excels is in concurrency and also in accuracy.  So whereas with Django, as your number of concurrent users increases, your error rate also increases.  With tornado, it tends to stay pretty consistent and pretty low as well.  So it's going to be able to handle requests might be slightly slower,  but it's going to handle a lot more concurrent requests with a lot lower failure rate.  So let's look at how tornado is kind of set up then.  Again, it's going to be pretty straightforward.  It's much the same as a lot of the micro frameworks.  You can use kind of class-based views.  You can structure it a lot differently.  It doesn't really put a lot of kind of conventions around you.  Here we can see I'm just defining a class with a get method.  I'm configuring my roots again, and I'm starting my application.  Now, this will work, but if we look at this section here,  we can see it's not going to work for next month.  Next month requires that to be a list.  Even though there's only one action occurring in there, it has to be a list.  Now, if I try turning that into a list and running it in tornado, we're going to get this.  It's going to throw an exception because of that security vulnerability that we talked about earlier.  It's a really nice exception actually, and it explains why it's going to do it,  but it's trying to stop me from introducing security vulnerability in my code.  But as we talked about earlier, I will find a way to ship myself into foo.  Now, tornado doesn't have a way of me just to go see if equals false and allow me to do it.  It just blocks it.  It's saying that this is a security vulnerability.  You should not be doing this.  We're not going to let you do it.  But it's a Python class.  It's got all this lovely, we can go in, we can look at the actual code for it.  We can see it's got all this error checking in there.  It's looking to ensure that it's either bytes, a Unicode type, or a dictionary.  It's making sure that it's not going to be an array.  If it is an array, it's going to return that exception.  But we're professionals.  Error checking is for people who do not have confidence in their code.  So we're going to get rid of all of that.  And because it's a class-based view, we can just strip all that stuff out.  We can overwrite their right method.  We can remove all that error checking.  We will be wholly and solely responsible for introducing all the security vulnerabilities  we want in our code.  It's our code.  If we want to be insecure, we will be.  So we remove all their error checking.  It now doesn't even check to see what kind of thing we're passing it.  Everything's going to be JSON from now on.  That's fine.  We're just going to always return JSON.  And we run this now and it's going to work.  So it's returning it home.  Now the last kind of one that we're going to look at, and I know we've gone through seven already,  I really wish I'd brought some of that water up on the desk.  Yes, the last one we're going to look at is, oh, you're amazing.  Is Sanic.  So whenever I first came across Sanic, I actually completely and artfully dismissed it.  Thank you so much.  I thought it was a joke, to be honest.  It came up in hacker news.  I went to the GitHub page.  This is their mascot.  Very enterprise friendly.  For people who don't wear it, it's just really bad drawing of Sonic.  But yeah, it actually completely turned me off from the project.  Even when you start off the terminal, you get this in the terminal.  They've really gone all in on this mascot.  I immediately assumed it was a joke.  I thought, okay, so somebody's done basically a flask, but for async.  And I completely dismissed it.  I didn't really look into it anymore.  I didn't go back to it for probably 18 months until at another conference,  somebody was really thinking about this framework.  I completely forgotten all about it.  Whenever I went to look it up, I was like, seriously?  This is still a thing?  That's a long running joke.  But no, it's actually great.  I don't know if the moral here is I don't judge a book by its cover,  or maybe branding matters, I'm not sure.  I know people sometimes have a go at the whole Django, like Pegasus Unicorn type thing,  and how it's not enterprise friendly, it's not very professional.  Yeah, but it could be worse.  So, Saniq came up basically because of UV loop.  So in Python, from 3.4, I think, we've had async.  There's now a drop in replacement for the built in async and Python called UV loop.  It's a lot faster.  And Saniq really just came as a way to take full advantage of that.  Much like we have before, it's really simple to get up and running.  We're just defining a function.  We're going to add our decorator on that to say what the root should be.  So it's always going to be this ncco for any of our calls here.  And then we just run it from the command line with our Python hello.py thing called these.  And we're going to get this similar, this output.  Thankfully, this, I should say, this only appears if you've got debug set to true.  We don't get the lovely mascot in your production when we're running it, so it's not quite so bad.  But it can also support class-based views.  So we can see here that it looks very similar to some of the ones we've had.  You know, I'm defining our class.  We have this, in this case, so we're using async.  So we've got this async method that's going to return our JSON for us.  And then we can just run that as we did before.  So, got our Saniq one.  Now, as I was going through writing the code for all eight of these different ones,  by the way, that was a fantastic idea of mine.  Let's do a conference talk where I need to write the same code eight bloody times.  But as I was going through writing the code, I actually started to notice that it's really similar.  So here is how we define our root in Flask.  And here is in Saniq.  And here is in Hug.  You know, we've got very, very similar.  Okay, so it's app.root, app.root, hug.get.  But it's a very similar kind of structure.  You know, and then I started noticing other things like in Pyramid.  You know, so whenever we're defining our roots there, okay, it's not app.root,  but it's again, it's, you know, view config in a root name.  Or whenever we're looking at our class-based views, you know, we've just got these get methods.  And then on Toneida, we've got a get method.  And on Django, we've got a get method.  And on Falcon, we've got an on get.  You know, again, very similar.  And then I started noticing things like someone, Falcon, there, we've got this API add root as well.  Which kind of looks like tornadoes, you know, first configuring it.  Which kind of looks like pyramids, configuring it.  You know, for all these, like the actual similarities to many of them were, well, very similar.  So it's kind of an odd one then of, you know, what's, how do you choose a trimer to use?  Or which one's the better one?  And to be honest, I've got very little kind of differentiation between them.  Django would be probably my favorite to go for for batteries included because I know it best.  If I had started out my career writing pyramid, I'd probably be up here like using pyramid for most of my examples instead.  Whenever I come to use a micro framework, again, I'll normally use flask because that's the one I used first.  You know, it's not because I couldn't articulate.  So my reasoning for it, why I prefer flask over cherry pie or why I would use flask over hug or over Falcon.  Because it's not a case of, oh, it's this particular feature is a killer feature or that particular way that does it is the way that I really enjoy.  It's just, it's the one I use first.  You know, and I probably should explore that myself a little bit more because I probably am missing out on better ways of doing things.  Because I, you know, like most people I've stick with what's familiar and I stick with what I know.  But what we're running at least is turns out that actually, you know, the examples of at least the basics of each one is so similar that re scaling or learning the different frameworks didn't take very long at all.  But I guess that's kind of like the whole point of Python, you know, there should be one and hopefully only one way of doing things apart from if it's stringed and catamation.  Then we should have lots of different ways apparently.  Okay, so I've been our ambassador. This has been my talk on eight different web frameworks.  Hopefully you got a chance to absorb a little bit of each one.  I know there was an awful lot of code going through very, very quickly there.  I will post the, I have a GitHub repository that has everything I went through all the code examples with like explanations how to run each one.  And so that's all up on my GitHub. I'll tweet it out on our ambassador.  I'll also put it on. I should probably go right back to the start. There was a lot of slides.  And just one or two here. There we go. There we go. Keep going.  Right. And on next most account as well. So we have a next with Dev account.  I'll put all the links to the slides, links to GitHub repositories.  Also the different blog posts that I went through earlier. So once Angular, Swift, Android, Django,  Sanec, Express, peer-to-peer stuff, all that kind of blog posts all up on next one.com too.  Again, they're going to be using all different frameworks I've talked about today.  This is actually one from Mark. So Mark is one of my colleagues.  You may have seen him. He's the other dude in the kill walking about.  He doesn't wear it quite so well.  So he's going to be talking actually later on today. But about half to.  So I recommend catching that as well if you can.  Other than that, we're going to be on the booth for the rest of the conference.  Please come say hello. And if you've got any questions about any of the frameworks and things that I went through,  I will try my best to answer them. But as I said, I love for a lot of them.  I'm really just a beginner as well. I've just been using them because I thought they were interesting  and trying to get some example code and stuff like that for people.  But yeah, so again, that's my Twitter. Please follow along.  I'll tweet out all links and things. And thank you very much for your time.  Okay. Thank you. So we have time for a couple of questions. So anyone have a question? Okay.  Thanks, Aaron. That was quite a nice overview.  I mentioned at the end that you probably would just go for Flask or just go for Django because you got experience there.  When you look at the frameworks from a more company or from a business decision,  would you consider or have you looked into any security handling of those frameworks  and how they compare to each other? Would that be a thing where you would make the decision based on?  Yeah. So for me, really, the reason that I probably would pick Django again,  and this was probably, people will be able to tell me that all the frameworks are this, I'm sure,  but is their deprecation schedule? The way in which they handle releases and stability of the actual framework  is in my mind crucial for really any kind of company. And that feeds into the security stuff.  I've seen companies where they just feel to upgrade because there's too many breaking changes  or the way in which the different frameworks have handled deprecation of APIs, etc.  has been so bad in the past that they're really scared to do any kind of upgrades.  And that means they end up not doing even security upgrades as well.  So for me, the fact that they have a stable release schedule, a published deprecation schedule they stick to,  and the handling of their actual releases, both security and feature, is probably why I would stick with Django.  Hi. Thanks for talking. My question is,  could you recommend some API over another, if you plan to have a JavaScript framework managing the front end  and more the backend side handled by some Django Python API?  And the other question, can you say again the website that you are using for Django reference,  and cut that? Yeah, sure. I'll just put the, let's get that slide back up.  Sit here somewhere. I have to remove the thing off.  And show all this stuff back on my face.  Let's just exit our list and just go directly to the slide.  I kind of forgot just how many slides I actually had.  That one. Yeah. So for anybody who can't read it, it's ccbv.co.uk.  And it's a reference for Django's class piece views. It's incredibly useful.  So the first part of your question is, so if you're essentially using the backend just as an API,  so driving, I'm assuming like React or View or Angular,  all of the ones we're looking at there had the ability built in to respond with JSON.  For some of them like Flask, it required using JSONify rather than the regular response.  Ones like Falcon are really built to be API kind of back ends.  So you don't even need to specify that you're returning JSON.  As soon as it detects that the object that you're returning from your view is a Python object  like one of their response objects or just plain text, it's going to assume that you want that encoded as JSON anyway.  So most of the modern frameworks will be geared towards that kind of way of working.  Django obviously is slightly different in that in order to turn it into really an API kind of backend,  you're going to need to use something like Django REST framework, which is really mature.  We've used it successfully on several kind of large projects and things.  So I would highly recommend that if you wanted to go kind of the Django REST.  Again, even with the async ones, they're going to be geared towards being API back ends as well.  So things like tornado again, if you just provide it with a Python object,  it's going to assume that you want a JSON response.  So I wouldn't worry too much about whether or not they're going to act as an API gateway.  All of them are capable of doing that and they all handle it really well.  Again, it's just looking for whichever one kind of suits your style or your requirements best.  Thank you.  You're welcome.  So last question.  Hello.  Hi.  Hi.  Thank you for the talk.  It's really nice having someone spending time to write API's the same thing.  And as you say, there's a difference between the big frameworks like Pyramid and Django  REST.  They include batteries.  And in most, because there is not real life code, you usually need some kind of authentication,  at least some kind of authentication.  And usually the ability to connect to some data, Tini, there are database or something.  Do you know when you did the research for your talk, do you know if A, there are standard  plugins for all the micro frameworks to do that kind of thing?  And B, do you know if somebody maybe did the same thing as you, but with all that included,  like how much code it would take for a Flask with a database and identification?  So for Flask, I know that they do.  Flask has got a very mature kind of plugin, kind of ecosystem around it.  It's one of those ones as well that for things like database access, there tends to be a  preferred method of doing it.  So if you're going to find for Flask, it's going to be Flask.  It's going to be SQL welcoming.  And it's going to be Flask welcoming.  Those things combined is normally the way most people do database access.  But because the whole idea of it is it just does the minimum of mind required and allows  you to configure the rest yourself, I have come across situations where people are using  Flask and using SQL welcoming, but then they've written their own ORM and top of it rather  than using Flask welcoming, et cetera.  For Falcon and Hug, which is based upon Falcon, I'm not overly sure.  I know they're fairly new.  I've not done a lot of research into what's available for them at the moment.  I do know for most of the different frameworks that went through, as well, they do have,  like for Cherry Pie essentially, especially, they have a very mature kind of ecosystem  around different extensions for it.  So they will have a preferred method of doing it again.  For the second-party question, have I seen any major comparisons between all of them?  I haven't.  Normally what you'll find is comparisons between maybe one or two.  One will show you, like, okay, this is how you get database access in Flask, and this  is how you do it in Cherry Pie.  Or something I'll look at, like, okay, so here is how you will do the preferred method  in Falcon.  But I've not seen somebody do it for all of the micro frameworks.  Thank you.  No problem.  Okay.  Thank you very much.  So, let's give it a round of applause.
Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_0_515.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_516_1595.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_1596_2279.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_2280_2567.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_2568_2999.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3000_3119.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3120_3179.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3180_3227.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3228_3323.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3324_3383.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3384_3431.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_3432_5399.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_5400_6683.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_6684_7943.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_7944_8063.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_8064_9263.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_9264_9443.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_9444_10307.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_10308_10811.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_10812_11087.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_11088_13667.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_13668_15059.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_15060_15263.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_15264_26447.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_26448_33827.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_33828_36779.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_36780_38207.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_38208_39119.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_39120_39983.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_39984_40775.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_40776_41579.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_41580_41891.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_41892_42347.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_42348_42863.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_42864_46631.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_46632_46787.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_46788_46871.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_46872_46979.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_46980_47471.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_47472_47531.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_47532_47579.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_47580_47843.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_47844_47939.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_47940_50411.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_50412_51143.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51144_51203.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51204_51251.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51252_51347.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51348_51395.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51396_51659.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51660_51707.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51708_51767.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51768_51839.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51840_51887.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51888_51935.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_51936_52991.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_52992_57479.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_57480_57527.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_57528_57575.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_57576_57623.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_57624_57755.png Aaron_Bassett_-_Hello_to_the_World_in_8_Web_Frameworks_micro__batterie_57756_64733.png