<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NTQX69F" height="0" width="0" style="display:none;visibility:hidden">
Estimate project

A Beginner’s Introduction to Python Web Frameworks

Time to read
26 mins
Category
Table of contents
  • What are web frameworks?
  • 12+ best Python web frameworks
    • 1. Django
    • 2. Flask
    • 3. Pyramid
    • 4. web2py
    • 5. Sanic
    • 6. Japronto
    • 7. aiohttp
    • 8. Twisted
    • 9. Falcon
    • 10. Bottle
    • 11. FastAPI
    • 12. Masonite
    • 13. Other Python web development frameworks
  • Which web frameworks are the most popular?
  • Top Python web frameworks—an infographic
  • Final thoughts

Since you’re reading this, it’s safe to assume you’re interested in taking up Python—or maybe you’ve already started learning this awesome language.

It doesn’t seem too daunting, right? You can code, after all, so it’s just a matter of grasping the differences in syntax.

So let’s take it up a notch and talk about collecting proper experience in Python.

Let’s discuss creating your first Python project.

Where do you start?

With an idea, obviously, but that won’t be a problem. Surely you already have several great concepts safely locked away in the vault of your mind, just waiting for some of that precious spare time and attention.

What’s next, then? The choice of a framework.

And that’s where the real conundrum starts, because the ecosystem of Python frameworks is quite extensive and varied.

In this article, we’re going to describe the best and most popular Python frameworks. It should be more than enough for you to pick the right one and get started.

Be warned, though, that this list is rather subjective. It came together mainly as a result of our collective experience of using the following frameworks in commercial projects.

Read or download as PDF

What are web frameworks?

Before you decide on a particular framework, let’s make sure we’re on the same page when it comes to definitions.

What exactly do we have in mind when we talk about a web application framework?

In short, a web framework is a package of generic functionalities that makes creating web apps easier for the developer. It serves as a shortcut that removes the need to write unnecessary code by reusing existing solutions. As a result, it reduces the time your developers need to spend on writing code and makes their work more effective.

Web frameworks can be divided into two categories: frontend and backend. The former, also known as CSS frameworks, is all about the parts of the web app the users see and interact with. The latter relates to the behind-the-scenes aspects of creating a web app.

The crucial benefit of using Python frameworks is that you can mix and match frontend and backend elements within each framework to achieve the desired result. You can either focus on one or merge several of them, depending on the scope of your project.

By offering ready-made solutions, web app frameworks help developers add complex and dynamic elements that would otherwise be very difficult or time-consuming to develop from scratch.

12+ best Python web frameworks

1. Django

django.png__730x250_q85_crop_subsampling-2_upscale

Django is one of the most popular Python frameworks. Offering all the tools you need to build a web application within a single package, from low- to high-end, is its trademark.

Django applications are based on a design pattern similar to MVC, the so-called MVT (Model-View-Template) pattern. Models are defined using the Django ORM, while SQL databases are mainly used as storage.

The framework has a built-in admin panel, allowing for easy management of the database content. With minimal configuration, this panel is generated automatically based on the defined models.

Views can include both functions and classes, and the assignment of URLs to views is done in one location (the urls.py file), so that after reviewing that single file you can learn which URLs are supported. Templates are created using a fairly simple Django Templates system.

Django is praised for strong community support and detailed documentation describing the functionality of the framework. This documentation coupled with getting a comprehensive environment after the installation makes the entry threshold rather low. Once you go through the official tutorial, you’ll be able to do most of the things required to build an application.

Unfortunately, Django’s monolithism also has its drawbacks. It is difficult, though not impossible, to replace one of the built-in elements with another implementation. For example, using some other ORM (like SQLAlchemy) requires abandoning or completely rebuilding such items as the admin panel, authorization, session handling, or generating forms.

Because Django is complete but inflexible, it is suitable for standard applications (i.e. the vast majority of software projects). However, if you need to implement some unconventional design, it leads to struggling with the framework, rather than pleasant programming.

Sample model in Django

Sample model in Django

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Company(models.Model):
    name = models.CharField(max_length=255)
    email = models.EmailField(max_length=75, null=True, blank=True)
    website_url = models.URLField(blank=True, null=True)
    city = models.CharField(max_length=100, null=True, blank=True)
    street = models.CharField(max_length=100, null=True, blank=True)
    size = models.IntegerField(null=True, blank=True)
    date_founded = models.CharField(
        help_text='MM/YYYY', null=True, blank=True, max_length=7,
    )
    @property
    def urls(self):
        return {
            'view': reverse('view-company', args=(self.pk,)),
            'edit': reverse('edit-company', args=(self.pk,)),
        }
    def __unicode__(self):
        return self.name
2. Flask

flask.png__730x250_q85_crop_subsampling-2_upscale

Flask is considered a microframework. It comes with basic functionality, while also allowing for easy expansion. Therefore, Flask works more as the glue that allows you to join libraries with each other.

For example, “pure Flask” does not provide support for any storage, yet there are many different implementations that you can install and use interchangeably for that purpose (such as Flask-SQLAlchemy, Flask-MongoAlchemy, and Flask-Redis). Similarly, the basic template system is Jinja2, but you can use a replacement (like Mako).

The motto of this framework is “one drop at a time,” and this is reflected in its comprehensive documentation. The knowledge of how to build an application is acquired in portions here; after reading a few paragraphs, you will be able to perform basic tasks.

You don’t have to know the more advanced stuff right away—you’ll learn it once you actually need it. Thanks to this, students of Flask can gather knowledge smoothly and avoid boredom, making Flask suitable for learning.

A large number of Flask extensions, unfortunately, are not supported as well as the framework itself. It happens quite often that the plug-ins are no longer being developed or their documentation is outdated. In cases like these, you need to spend some time googling a replacement that offers similar functionality and is still actively supported.

When building your application with packages from different authors, you might have to put quite a bit of sweat into integrating them with each other. You will rarely find ready-made instructions on how to do this in the plug-ins’ documentation, but in such situations the Flask community and websites such as Stack Overflow should be of help.

Sample view in Flask
Sample view in Flask
1 2 3 4 5 6 7 8 9 10 11 12
@image_view.route(
    '/api/<string:version>/products/<int:prod_id>/images',
    methods=['GET'],
)
@auth_required()
@documented(prod_id="ID of a product")
@output(ProductImagesSeq)
@errors(MissingProduct)
@jsonify
def images_get(version, prod_id):
    """Retrieves a list of product images."""
    return [i.serialize() for i in find_product(prod_id).images]
3. Pyramid

pyramid.png__730x250_q85_crop_subsampling-2_upscale

Pyramid, the third noteworthy Python web framework, is rooted in two other products that are no longer developed: Pylons and repoze.bfg. The legacy left by its predecessors caused Pyramid to evolve into a very mature and stable project.

The philosophies of Pyramid and Django differ substantially. Unlike Django, Pyramid is trivial to customize, allowing you to create features in ways that the authors of the framework themselves hadn’t foreseen. It does not force the programmer to use framework’s idioms; it’s meant to be a solid scaffolding for complex or highly non-standard projects.

Pyramid strives to be persistence-agnostic. While there is no bundled database access module, a common practice is to combine Pyramid with the powerful, mature SQLAlchemy ORM. Of course, that’s only the most popular way to go. Programmers are free to choose whatever practices suit them best, such as using the peewee ORM, writing raw SQL queries, or integrating with a NoSQL database, just to name a few.

All options are open, though this approach requires a bit of experience to smoothly add the desired persistence mechanisms to the project. The same goes for other components, such as templating.

Openness and freedom are what Pyramid is all about. Modules bundled with it relate to the web layer only and users are encouraged to freely pick third-party packages that will support other aspects of their projects.

However, this model causes a noticeable overhead at the beginning of any new project, because you have to spend some time choosing and integrating the tools your team is comfortable with. Still, once you put the effort into making additional decisions during the early stages of the work, you are rewarded with a setup that makes it easy and comfortable to start a new project and develop it further.

Pyramid is a self-proclaimed “start small, finish big, stay finished framework.” This makes it an appropriate tool for experienced developers who are not afraid of playing the long game and working extra hard in the beginning, without shipping a single feature within the first few days. Less experienced programmers may feel a bit intimidated.

Sample “Hello world” app in Pyramid
Sample “Hello world” app in Pyramid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response


def hello_world(request):
   return Response('Hello, world!')


if __name__ == '__main__':
   with Configurator() as config:
       config.add_route('hello', '/')
       config.add_view(hello_world, route_name='hello')
       app = config.make_wsgi_app()

   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()
4. web2py

web2py.png__730x250_q85_crop_subsampling-2_upscale

Created in 2007, web2py is a framework originally designed as a teaching tool for students, so the main concern for its authors was ease of development and deployment.

Web2py is strongly inspired by Django and Ruby on Rails, sharing the idea of convention over configuration. In other words, web2py provides many sensible defaults that allow developers to get off the ground quickly.

This approach also means there are a lot of goodies bundled with web2py. You will find everything you’d expect from a web framework in it, including a built-in server, HTML-generating helpers, forms, validators, and many more—nothing unusual thus far, one could argue. Support for multiple database engines is neat, though it’s a pretty common asset among current web frameworks.

However, some other bundled features may surprise you, since they are not present in other frameworks:

  • helpers for creating JavaScript-enabled sites with jQuery and Ajax;
  • scheduler and cron;
  • 2-factor authentication helpers;
  • text message sender;
  • an event-ticketing system, allowing for automatic assignment of problems that have occurred in the production environment to developers.

The framework proudly claims to be a full-stack solution, providing everything you could ever need.

Web2py has extensive documentation available online. It guides newcomers step by step, starting with a short introduction to the Python language. The introduction is seamlessly linked with the rest of the manual, demonstrating different aspects of web2py in a friendly manner, with lots of code snippets and screenshots.

Despite all its competitive advantages, web2py’s community is significantly smaller than Django’s, or even Pyramid’s. Fewer developers using it means your chances of getting help and support are lower. The official mailing list is mostly inactive.

Sample model in web2p
Sample model in web2py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
class Ads(BaseModel):
    tablename = "ads"

    def set_properties(self):
        T = self.db.T
        self.fields = [
            # main
            Field("title", "string"),
            Field("description", "text"),
            Field("picture", "upload"),
            Field("thumbnail", "upload"),
            Field("link", "string"),
            Field("place", "string")
        ]

        self.computations = {
            "thumbnail": lambda r: THUMB2(r['picture'], gae=self.db.request.env.web2py_runtime_gae)
    }

        self.validators = {
            "title": IS_NOT_EMPTY(),
            "description": IS_LENGTH(255, 10),
            "picture": IS_IMAGE(),
            "place": IS_IN_SET(["top_slider", "top_banner", "bottom_banner", "left_sidebar", "right_sidebar", "inside_article", "user_profile"], zero=None)
        }

Get your free ebook

5. Sanic

sanic.jpg__730x250_q85_crop_subsampling-2_upscale

Sanic differs considerably from the aforementioned frameworks because unlike them, it is based on asyncio—Python’s toolbox for asynchronous programming, bundled with the standard library starting from version 3.4.

In order to develop projects based on Sanic, you have to grasp the ideas behind asyncio first. This involves a lot of theoretical knowledge about coroutines, concurrent programming caveats, and careful reasoning about the data flow in the application.

Once you get your head around Sanic/asyncio and applies the framework to an appropriate problem, the effort pays off. Sanic is especially useful when it comes to handling long-living connections, such as WebSockets. If your project requires support for WebSockets or making a lot of long-lasting external API calls, Sanic is a great choice.

Another use case of Sanic is writing a “glue-web application” that can serve as a mediator between two subsystems with incompatible APIs. Note that it requires at least Python 3.5, though.

The framework is meant to be very fast. One of its dependencies is uvloop—an alternative, drop-in replacement for asyncio’s not-so-good built-in event loop. Uvloop is a wrapper around libuv, the same engine that powers Node.js. According to the uvloop documentation, this makes asyncio work 2–4 times faster.

Sanic is a microframework, just like Flask. Apart from routing and other basic web-related goodies like utilities for handling cookies and streaming responses, there’s not much inside. Sanic imitates Flask, for instance by sharing the concept of Blueprints—tiny sub-applications that allow developers to split and organize their code in bigger applications.

Sanic also won’t be a good choice for simple CRUD applications that only perform basic database operations. It would just make them more complicated with no visible benefit.

Handling WebSockets in Sanic
Handling WebSockets in Sanic
1 2 3 4 5 6
@app.websocket('/websocket')
async def time(websocket, path):
   while True:
      now = datetime.datetime.utcnow().isoformat() + 'Z'
      await websocket.send(now)
      await asyncio.sleep(random.random() * 3)
6. Japronto

Have you ever imagined handling 1,000,000 requests per second with Python?

It seems unreal, since Python isn’t the fastest programming language out there. But when a brilliant move was made to add asyncio to the standard library, it opened up countless possibilities.

Japronto is a microframework that leverages some of them. As a result, this Python framework was able to cross the magical barrier of 1 million requests handled per second.

You may still be at a loss as to how that is possible, exactly.

It all comes down to 2 aces up Japronto’s sleeve: uvloop and PicoHTTPParser. Uvloop is an asyncio backend based on libuv, while PicoHTTPParser is a lightweight HTTP headers parser written in C. All core components of the framework are also implemented in C. A wide variety of low-level optimizations and tricks are used to tweak performance.

Japronto is designed for special tasks that could not be accomplished with bloated mainstream frameworks. It is a perfect fit for problems where every nanosecond counts. Knowledgeable developers, obsessed with optimization, will reap all of its possible benefits.

Additionally, Japronto is meant to provide a solid foundation for microservices using REST APIs with minimal overhead. In other words, there’s not much in the box. Developers only need to set up routing and decide which routes should use synchronous or asynchronous handlers.

It might seem counterintuitive, but if a request can be handled in a synchronous way, you shouldn’t try to do it asynchronously, as the overhead of switching between coroutines will limit performance.

What is quite unfortunate is that Japronto is not being actively developed. On the other hand, the project is licensed under MIT, and the author claims he is willing to accept any contributions. Like Sanic, the framework is meant to work with Python 3.5+ versions.

Sample “Hello world” app in Japronto
Sample “Hello world” app in Japronto
1 2 3 4 5 6 7 8
from japronto import Application

def hello(request):
    return request.Response(text='Hello world!')

app = Application()
app.router.add_route('/', hello)
app.run(debug=True)
7. aiohttp

aiohttp.png__730x250_q85_crop_subsampling-2_upscale

Aiohttp is another library based on asyncio, the modern Python toolkit for writing asynchronous code. Not meant to be a framework in a strict sense, aiohttp is more of a toolbox, supplementing the async arsenal with everything related to HTTP.

This means aiohttp is helpful not only for writing server applications, but also to clients. Both will benefit from asyncio’s goodies, most of all the ability to handle thousands of connections at the same time, provided the majority of operations involves I/O calls.

Such powerful clients are great when you have to issue many API calls at once, for example for scraping web pages. Without asyncio, you would have to use threading or multiprocessing, which are harder to get right and require much more memory.

Apart from building standalone applications, aiohttp’s clients are a great supplement to any asyncio-based application that needs to issue non-blocking HTTP calls. The same is true for WebSockets. Since they are part of the HTTP specification, you can connect to WebSocket servers and easily exchange messages with them.

When it comes to servers, aiohttp gives you everything you can expect from a microframework. The features available out-of-the-box include routing, middleware, and signals. It may seem like it’s very little, but it will suffice for a web server.

“What about the remaining functionalities?” you may ask.

As far as those are concerned, you can build the rest of the functionalities using one or many asyncio-compatible libraries. You will find plenty of them using sources like this one.

Aiohttp is built with testing in mind. Developers who want to test an aiohttp-based application will find it extremely easy, especially with the aid of pytest.

Even though aiohttp offers satisfactory performance by default, there are a few low-hanging fruits you can pick. For example, you can install additional libraries: cchardet and aiodns. Aiohttp will detect them automatically. You can also utilize the same uvloop that powers Sanic.

Last but not least: one definite advantage of aiohttp is that it is being actively maintained and developed. Choosing aiohttp when you build your next application will certainly be a good call.

WebSocket client using aiohttp
WebSocket client using aiohttp
1 2 3 4 5 6 7 8 9 10
async with session.ws_connect('http://example.org/ws') as ws:
    async for msg in ws:
        if msg.type == aiohttp.WSMsgType.TEXT:
            if msg.data == 'close cmd':
                await ws.close()
                break
            else:
                await ws.send_str(msg.data + '/answer')
        elif msg.type == aiohttp.WSMsgType.ERROR:
            break
8. Twisted

twisted.png__730x250_q85_crop_subsampling-2_upscale

With Twisted, Python developers were able to do async programming long before it was cool. Twisted is one of the oldest and most mature Python projects around.

Originally released in 2002, Twisted predates even PEP8, so the code of the project does not follow the famous code style guide recommendations. Admittedly, this may somewhat discourage people from using it these days.

Twisted’s heart is an event-driven networking engine called reactor. It is used for scheduling and calling user-defined callbacks.

In the beginning, developers had to use explicit callbacks by defining functions and passing them around separately for cases when an operation succeeded and when it failed.

Although this technique was compelling, it could also lead to what we know from early JavaScript: callback hell. In other words, the resultant code was tough to read and analyze.

At some point, Twisted introduced inlineCallbacks—the notation for writing asynchronous code that was as simple to read as regular, synchronous code. This solution played very well with Python’s syntax and greatly influenced modern async toolkit from the standard library, asyncio.

The greatest advantage of this framework is that although Twisted itself is just an engine with few bundled extensions, there are many additional extensions available to expand its functionality. They allow for both low-level network programming (TCP/USP) and high, application-level work (HTTP, IMAP, SHH, etc).

This makes Twisted a perfect choice for writing specialized services; however, it is not a good candidate for regular web applications. Developers would have to write a lot of things on their own to get the functionality they take for granted with Django.

Twisted is being actively maintained. There is an undergoing effort to migrate all of its code to be compatible with Python 3. The core functionality was rewritten some time ago, but many third-party modules are still incompatible with newer versions of the interpreter.

This may raise some concerns whether Twisted is the best choice for new projects. On the other hand, though, it is more mature than some asyncio-based solutions. Also, Twisted has been around for quite some time now, which means it will undoubtedly be maintained at least for a good while.

inlineCallbacks code in Twisted
inlineCallbacks code in Twisted
1 2 3 4 5 6 7 8 9
@inlineCallbacks
def getUsers(self):
    try:
        responseBody = yield makeRequest("GET", "/users")
    except ConnectionError:
        log.failure("makeRequest failed due to connection error")
        returnValue([])

    returnValue(json.loads(responseBody))

Read or download as PDF

9. Falcon

falcon.png__730x250_q85_crop_subsampling-2_upscale

Falcon is another microframework on our list. The goal of the Falcon project is to create a minimalist foundation for building web apps where the slightest overhead matters.

Authors of the framework claim it is a bare-metal, bloat-free toolkit for building very fast backend code and microservices. Plus, it is compatible with both Python 2 and 3.

A big advantage of Falcon is that it is indeed very fast. Benchmarks published on its website show an incredible advantage over mainstream solutions like Django or Flask.

The downside, though, is that Falcon offers very little to start with. There’s routing, middlewares, hooks—and that’s basically everything. There are no extras: no validation, no authentication, etc. It is up to the developer to extend functionality as needed.

Falcon assumes it will be used for building REST APIs that talk JSON. If that is the case, you really need literally zero configuration. You can just sit down and code.

This microframework might be an exciting proposition for implementing highly-customized services that demand the highest performance possible. Falcon is an excellent choice when you don’t want or can’t invest in asyncio-based solutions.

If you’re thinking, “Sometimes the simplest solution is the best one,” you should definitely consider Falcon.

Sample “Hello world” app in Falcon
Sample “Hello world” app in Falcon
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import falcon

class QuoteResource:
def on_get(self, req, resp):
    quote = {
        'quote': (
            "I've always been more interested in "
            "the future than in the past."
        ),
        'author': 'Grace Hopper'
    }
    resp.media = quote

api = falcon.API()
api.add_route('/quote', QuoteResource())
10. Bottle

bottle.png__730x250_q85_crop_subsampling-2_upscale

Bottle is a WSGI-compliant microframework that is fast and lightweight.

One of its main advantages is the single-file distribution process, which makes it easy to share and upload the app. To start coding, all you need to do is download bottle.py into the project directory.

Conveniently, the whole framework fits into one file. And since Bottle doesn’t depend on any external libraries, there is no need to install anything else to access it.

By design, Bottle is flexible, easy to use, and it makes web application development a breeze. However, due to its single-file distribution pattern, the framework is best suited for smaller apps, rather than larger projects.

A simple service in Bottle to get the current time in a requested time zone
A simple service in Bottle to get the current time in a requested time zone
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
from datetime import datetime
 
from bottle import abort, route, run
from pytz import timezone, exceptions as pytz_exceptions
 
 
@route('/time/<continent>/<city>')
def index(continent, city):
    tz_name = f'{continent}/{city}'
    try:
        time = datetime.now(tz=timezone(tz_name))
    except pytz_exceptions.UnknownTimeZoneError:
        abort(404, f'Unknown timezone: "{tz_name}"')
 
    return {'time': time.strftime('%Y-%m-%d %H:%M:%S'), 'tz': tz_name}
 
 
run(host='localhost', port=8080)
11. FastAPI

fastapi.png__730x250_q85_crop_subsampling-2_upscale

FastAPI allows you to build APIs with Python 3.6 or newer, based on standard Python type hints. As its name suggests, the framework is one of the fastest and most efficient Python web frameworks out there.

Based on Starlette, FastAPI comes with all of its features, including GraphQL support, templates, and others. Since Starlette uses ASGI—the newer standard for asynchronous web frameworks—it also offers some features not available in WSGI frameworks, such as WebSockets or background tasks.

One of the key advantages of FastAPI, besides the development speed, is that it helps minimize code duplication and bugs. The framework is very intuitive; editor support and autocompletion mean less time spent debugging.

FastAPI is also based on and fully compatible with OpenAPI and JSON Schema, the open standards for APIs.

Sample code demonstrating quick validation in FastAPI
Sample code demonstrating quick validation in FastAPI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from typing import List
 
from fastapi import FastAPI
from pydantic import BaseModel
 
app = FastAPI()
 
 
class Post(BaseModel):
    title: str
    excerpt: str = None
    contents: str
    tags: List[str] = []
 
 
@app.post("/posts/")
async def create_item(post: Post):
    # save post somewhere
    return post
12. Masonite

masonite.png__730x250_q85_crop_subsampling-2_upscale

Masonite is a relatively new framework that has been steadily gaining traction among developers. Since its first release in December 2017, it’s amassed over 1,300 stars on GitHub.

It comes with plenty of out-of-the-box functionalities and a highly extendable architecture. Fast and easy to install, Masonite is an MVC and batteries-included framework compatible with Python 3.4+. It’s similar to Django in that it strives to provide everything a web developer might need.

To increase the adoption of the framework among developers, its creator has prioritized ease of use and access to high-quality training materials. Masonite boasts an extensive documentation and plenty of tutorials for both beginner and experienced developers, as well as an active Slack channel.

The framework features over a dozen time-saving commands that allow developers to create views, controllers, job queues, models, and others from the command line.

Other key benefits include Orator, an Active Record-style ORM, as well as a simple routing engine and migration system.

Single Masonite controller viewed in the nomenclature of other frameworks
Single Masonite controller viewed in the nomenclature of other frameworks
1 2 3 4 5 6 7 8 9
from app.Post import Post
from masonite.request import Request
from masonite.view import View
...
 
def single(self, view: View, request: Request):
    post = Post.find(request.param('id'))
 
    return view.render('single', {'post': post})
13. Other Python web development frameworks

There are many more Python web frameworks out there you might find interesting and useful. Each of them focuses on a different issue, was built for distinct tasks, or has a particular history.

The first that comes to mind is Zope2, one of the oldest frameworks, still used mainly as part of the Plone CMS. Zope3 (later renamed BlueBream) was created as Zope2’s successor. The framework was supposed to allow for easier creation of large applications, but hasn’t won too much popularity, mainly because of the need to master fairly complex concepts (e.g. Zope Component Architecture) very early in the learning process.

Also noteworthy is the Google App Engine, which allows you to run applications written in Python, among others. This platform lets you create applications in any framework compatible with WSGI. The SDK for the App Engine includes a simple framework called webapp2, and this exact approach is often used in web applications adapted to this environment.

Another interesting example is Tornado, developed by FriendFeed and made available by Facebook. This framework includes libraries supporting asynchronicity, so you can build applications that support multiple simultaneous connections (like long polling or WebSocket).

Other libraries similar to Tornado include Pulsar (async) and Gevent (greenlet). These libraries allow you to build any network applications (multiplayer games and chat rooms, for example). They also perform well at handling HTTP requests.

Developing applications using these frameworks and libraries is more difficult and requires you to explore some harder-to-grasp concepts. We recommend getting to them later on, as you venture deeper into the wonderful world of Python.

Software development

Which web frameworks are the most popular?

Stack Overflow, a leading Q&A site for the global developer community, runs an annual Developer Survey that asks its 90,000-strong pool of followers comprehensive questions about their professional lives.

The survey is interesting for many reasons, not least its statistics highlighting the increasing popularity of Python among developers worldwide.

In one of the questions, developers were asked to rate their most loved web frameworks in various programming languages. As you can see, Python frameworks—including Django and Flask—rank pretty high:

most_loved_web_frameworks_stackoverflow.png__693x467_q85_crop_subsampling-2_upscale
Source: https://insights.stackoverflow.com/survey/2019#most-loved-dreaded-and-wanted

Top Python web frameworks—an infographic

Wouldn’t it be nice if you could get a summary of all the frameworks we’ve listed here in one tidy infographic?

Well, that is exactly what we’ve prepared for you!

python_web_frameworks_infographic.png__1250x4318_q85_crop_subsampling-2_upscale

Top Python frameworks

Click here to view the infographic in high resolution

Final thoughts

Python offers an extensive selection of web frameworks, all of which have their own strengths and weaknesses. At STX Next, we use whatever framework fits a given project best, even learning new ones on the go if need be.

We hope this summary will help you decide which framework you like the most and delve into that one first.

And now, it’s time for you to make a move. Read a guide or watch a tutorial. Write some practice code. Get started on your first Python project.

If you have any more Python-related questions, don’t hesitate to leave us a comment or contact us directly—we’d be happy to help out.

Get a project estimate

Get your free ebook

Download the ebook
Download the ebook
Senior Python Developer
Head of Service Delivery
Share this post