A Beginners Introduction To Best Python Web Frameworks in 2022
A Beginners Introduction To Best Python Web Frameworks in 2022
Frameworks in 2022
stxnext.com/blog/beginners-introduction-python-frameworks
Wojciech Lichota
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.
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.
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.
1/22
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.
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?
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.
Is using a framework necessary when working with Python? The short answer is: no, it
is not necessary.
Of course, you can write in Python without a web development framework. However,
using one is extremely useful when building web apps and websites since Python wasn’t
written as a direct web scripting language, like PHP was, for example. So common things
like connecting to databases aren’t native to it, and frameworks come in handy.
The benefits of using a Python framework include—apart from obviously making it easier
to create web applications in Python—working with a more organized code, increased
productivity, and a simplified web development process.
Frameworks have libraries for handling common tasks and tools for debugging and
testing your apps. With a Python framework, the implementation and integration is easier,
the documentation is better, the efficiency increases, and the entire process is more
secure, because all the framework libraries are heavily tested.
2/22
What’s more, there are communities that develop software using the same code base, so
if you have questions, you can easily find help. In summary, if your language has a
good framework that’s well-supported by the community, there’s not much reason
against using it.
There are obviously some disadvantages to using a Python web framework. Firstly, you
are tied to a particular tool, which limits your options for switching to a different one. When
working on an existing project, you may also need to refactor your code to work with the
web development framework.
Additionally, some of the Python frameworks may not be suitable at all for smaller
projects, and others completely incomprehensible for beginners.
Finally, Python web frameworks can take some time to learn and be quite complex. That
way, you may not understand how to use individual components of the frameworks due to
the large size of some of them and spend too much time getting the hang of it.
Having said that, the disadvantages don’t outweigh the benefits of working with
Python web development frameworks. Let’s now consider a couple of things you
should know before you choose the right Python framework for you.
What should you know before you choose a Python web framework?
Before you make a move and choose a Python web development framework, keep in
mind the size and complexity—some can be quite large and significantly challenging to
learn.
You should also consider the features that the framework offers, as some offer more
extensions and tools than others.
Something that you should also take into account is the documentation available for the
framework and the license that it uses; some are open-source software (OSS), while
others are closed source software (CSS), which means the software uses proprietary
and closely guarded code.
1. Full-stack framework
If you’re planning to develop a large structure filled with lots of requirements and features,
a full-stack framework will be the best choice for you and your project.
3/22
Such frameworks are an all-in-one solution for all your requirements. Typically, form
generators, form validation, and template layouts, among others, are available within a
usual full-stack framework.
2. Microframework
On the other hand, if you’re creating a small and simple app, you should rather think
about choosing a microframework.
Microframeworks are lightweight and they don’t offer additional functionalities and
features, such as database abstraction layer, form validation, and specific tools and
libraries. So developers using them will need to add a lot of code and additional
requirements manually.
3. Asynchronous framework
Asynchronous (async) frameworks, which are becoming more and more popular, are a
type of microframework that allows handling a large set of concurrent connections.
Usually, an async framework built for Python uses the programming language’s asyncio
library.
Django
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.
4/22
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.
class Company(models.Model):
name = models.CharField(max_length=255)
date_founded = models.CharField(
@property
def urls(self):
return {
def __unicode__(self):
5/22
return self.name
web2py
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:
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.
6/22
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.
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 = {
self.validators = {
"title": IS_NOT_EMPTY(),
"picture": IS_IMAGE(),
Pyramid
7/22
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.
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.
8/22
from pyramid.config import Configurator
def hello_world(request):
if __name__ == ’__main__’:
config.add_route(’hello’, ’/’)
config.add_view(hello_world, route_name=’hello’)
app = config.make_wsgi_app()
server.serve_forever()
Twisted
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.
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.
9/22
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.
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
def getUsers(self):
try:
except ConnectionError:
returnValue([])
returnValue(json.loads(responseBody))
Masonite
10/22
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.
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.
...
post = Post.find(request.param(’id’))
Python microframeworks
11/22
Flask
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.
@image_view.route(
’/api/<string:version>/products/<int:prod_id>/images’,
methods=[’GET’],
12/22
)
@auth_required()
@documented(prod_id="ID of a product")
@output(ProductImagesSeq)
@errors(MissingProduct)
@jsonify
Bottle
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
13/22
@route(’/time/<continent>/<city>’)
tz_name = f’{continent}/{city}’
try:
time = datetime.now(tz=timezone(tz_name))
except pytz_exceptions.UnknownTimeZoneError:
run(host=’localhost’, port=8080)
Falcon
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.
14/22
If you’re thinking, “Sometimes the simplest solution is the best one,” you should definitely
consider Falcon.
import falcon
class QuoteResource:
quote = {
’quote’: (
),
resp.media = quote
api = falcon.API()
api.add_route(’/quote’, QuoteResource())
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.
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.
15/22
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.
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.
def hello(request):
app = Application()
app.router.add_route(’/’, hello)
app.run(debug=True)
FastAPI
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.
16/22
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.
app = FastAPI()
class Post(BaseModel):
title: str
contents: str
tags: List[str] = []
@app.post("/posts/")
return post
Sanic
17/22
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.
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.
@app.websocket(’/websocket’)
while True:
18/22
now = datetime.datetime.utcnow().isoformat() + ’Z’
await websocket.send(now)
await asyncio.sleep(random.random() * 3)
aiohttp
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.
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.
19/22
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.
if msg.type == aiohttp.WSMsgType.TEXT:
await ws.close()
break
else:
break
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.
20/22
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.
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. Python frameworks—including Django and Flask—
ranked quite high in the top 10!
We still haven’t answered one key question: which of these frameworks is the easiest for
beginners to learn? Well, in terms of ease of use, smaller frameworks like web2py, Bottle,
or Flask would be the best choice. The problem is that usually later on you’ll have to build
more of the supporting components by yourself.
So the framework that’s the easiest to set up and use might not be the best for the
particular task you have in mind. Depending on what you’re coding, the answer will
determine which framework is best for your task.
On top of that, if you’re new to Python, non-technical things like community size and
available resources should probably factor into your decision as well.
Which Python web framework has the best performance? The one you can finish the
project with.
21/22
Final thoughts on choosing the best web framework for Python
Thank you for reading our article on the best Python frameworks in 2022. We hope this
summary will help you decide which framework will help you the most and get you started
right away.
Python offers an extensive selection of web frameworks, all of which have their strengths
and weaknesses. At STX Next, we use whatever framework fits a project best, even
learning new ones on the go if needed.
STX Next has grown to become one of the largest Python software agencies in the world
with over 150 Python developers on board and over 18 years of experience under our
belt. We’re constantly looking for enthusiastic, talented developers who live and breathe
Python. If you’re interested in starting your journey with us, check out our current job
opportunities.
If you enjoyed this article and would like to learn more, we have a lot of free resources on
Python you may also find interesting, such as:
The Best Python IDEs and Code Editors (According to Our Developers and the
Python Community)
What Is Python Used for? Advantages and Examples Across 7 Industries
Python vs. Other Programming Languages: Go, JS, Node.js, Java, Ruby, PHP, R,
C++
Should you have any more questions, not only Python-related, don’t hesitate to contact
us directly—we’d be happy to help out!
22/22