5 Python Web Frameworks to learn in 2017
This article is meant to take a look at some web frameworks you can and should use in 2017. I won't mention the well-known Django or Flask because you may already know them. I therefore chose 5 not-so-popular, but in my opinion, very promising frameworks.
The description of each framework will not be too thorough because my aim is to get you started if you want to take a closer look and try them out. For a closer look I can write follow-up articles, just let me know with a comment.
Full-stack and not
When you take a look at web frameworks you have to keep in mind what their capabilities are. There are two main kinds you can encounter: full-stack or not full-stack. What's the difference and does it matter?
The difference is really simple: in a full-stack you have everything included: back-end and front-end functionality. This means you do not have to look for other libraries to do some functionalities (like graphical representation, templating and so on). Some would say, that in a full-stack Python application you write everything in Python. This is not the most ideal because you can also choose different Python libraries to work together. Therefore this article "full-stack" means that one library is containing everything you will need from the back-end to the front-end and do not need to install/ combine other packages.
The first library we will look at is CherryPy. As their website states, it is a minimalistic web framework for Python. Installing it comes really easy:
pip install cherrypy
With this you get the minimalistic web framework which you can test right after installing without any code:
python -m cherrypy.tutorial.tut01_helloworld
This launches a web server listening for requests on port 8080 and if you visit the URL you get a response similar to this one:
Naturally this little hello world is not enough, let's dig a bit deeper to see how we can create a web application. For this we'll create a simple form to submit data.
class Greeter(object): @cherrypy.expose def index(self): return """<html> <head></head> <body> <form method="post" action="greet"> <input type="text" value="World" name="name" /> <button type="submit">Greet me!</button> </form> </body> </html>""" @cherrypy.expose def greet(self, name='World'): return 'Hello ' + name + ', from CherryPy!' if name == ' main ': cherrypy.quickstart(Greeter())
As you can see, this is the only thing you need to get a basic example up and running. The two methods of the Greeter class are exposed through CherryPy which means, you have access to those endpoints. The index method represents the index.html or the home page. This example hard-codes every HTML as strings but CherryPy plays well with template engines like Mako or Genshi.
Beside all this you can change the source code while you are running your script. After you save the Python file, CherryPy automatically exposes the changes and you can use the new script without restarting -- this is something I really find useful.
Pyramid is a small but fast web framework which is developed as a part of the Pylons project. Installing it is really simple:
pip install pyramid
Creating an example application (the same one I did with CherryPy) is easy too:
from wsgiref.simple_server import make_server from pyramid.config import Configurator
from pyramid.response import Response
def index(request): print('Incoming request') return Response("""<html> <head></head> <body> <form method="post" action="greet"> <input type="text" value="World" name="name" /> <button type="submit">Greet me!</button> </form> </body> </html>""") def greet(request): return Response('Hello ' + request.params.get('name') + ', from Pyramid!') if name == ' main ':
print('Serving on port 8080...') config = Configurator() config.add_route('index', '/') config.add_route('greet', '/greet') config.add_view(greet, route_name='greet') config.add_view(index, route_name='index') app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever()
Now we have the code in pyramid_example.py and to run it, simply execute the following command:
This results in a form where you can add your name and after hitting the button you will be greeted similar to this:
It takes a bit more configuration but it is really simple to get yourself up and running.
What I do not like in Pyramid is when I start my application I do not get any information on the console like port number and if it is actually running -- but this can be fixed with a simple print statement where I log out from the port that the server is listening on. The other drawback while running just a simple example is that your changes in the scripts do not get reloaded on-the-fly and you have to restart the application to see every change working. However if you switch to a real web based application then you won't follow this simple approach but use pserve which has the ability to automatically reload files.
TurboGears is a so called "mega-framework" which is based on already available parts and integrates the best of whats available -- naturally "best" is always opinionated. In the background it has CherryPy doing the basics so we already know how we can get started.
pip install turbogears2
It is essential to install TurboGears 2 for Python 3. The first version is using Python 2 so it won't install.
Because we already know that TurboGears is based on CherryPy, it will be easy to port the application to the new library:
from wsgiref.simple_server import make_server from tg import expose, TGController, AppConfig class RootController(TGController): @expose() def index(self): return """<html> <head></head> <body> <form method="post" action="greet"> <input type="text" value="World" name="name" /> <button type="submit">Greet me!</button> </form> </body> </html>""" @expose() def greet(self, name='World'): return 'Hello ' + name + ', from TurboGears!' config = AppConfig(minimal=True, root_controller=RootController()) print("Serving on port 8080...") httpd = make_server('', 8080, config.make_wsgi_app()) httpd.serve_forever()
To start this example application simply run:
The result is visible in your web browser and should be similar to this one:
Beside this you can start a simple project with the quickstart functionality of TurboGears which creates a base folder structure and a set-up with dependencies like SQLAlchemy. But this part is out of the scope of this article but feel free to take a deeper look.
If you know German, you already know that "klein" means "small". And so is Klein.
Because it’s a micro framework you can get started very easily. As the other tools mentioned previously, Klein can be installed through pip:
pip install klein
The sample application done throughout this article can be done with Klein too and it doesn’t take much effort:
from klein import run, route @route('/') def home(request): return """<html> <head></head> <body> <form method="post" action="greet"> <input type="text" value="World" name="name" /> <button type="submit">Greet me!</button> </form> </body> </html>""" @route('/greet', methods=['POST']) def greet(request): print(request.args) name = request.args.get('name'.encode('ascii'), [b'World']) print(name) return 'Hello ' + name.decode('ascii') + ', from Klein!' run("localhost", 8080)
As you can see, there is some string-conversion going on because request.args handles only binary strings. Fortunately there is already an open pull request which aims to solve this problem. It’s been open for just a short while, and needs some additional review, but I think with the next release this will be fixed and we do not need to do this "magic" with the strings.
Nevertheless if we run this example script:
we can see something like this:
Klein can be extended too and can be used with templating engines and databases too.
CubicWeb is a semantic web application framework. Because of this, it’s a prerequisite to understand what semantic web means before one tries to understand how CubicWeb works.
Instead of separate views and models, a cube includes both. And because a cube is a component that can be built from other components CubicWeb relies on component-reusing. One or more cubes can be assembled into an instance along with configuration files, a web server and a database.
The learning curve for CubicWeb is not as simple as for Python. Installing CubicWeb is as simple as the other listed frameworks, but getting it running takes a bit more time and coding. That's because of the complexity of the tool. There are tutorials which let you start but you have to decide if semantic web is really something you want or need to use. You should ask yourself if you can deliver the same solution with an alternative tool-set.
With Python 3 there are some problems which are claimed to be because of the Twisted library. However if I look at Klein which also uses Twisted, I do not see any problems. Perhaps the cause lies much deeper...
As we have seen, there are other libraries beside the popular ones which can keep up the pace of development and provide features you want to use even in a full-blown enterprise application.
I hope you’ve acquired some new inputs on web frameworks available in Python! For any comment or question, leave your thoughts below.