
A Beginner’s Introduction to Python Web Frameworks (2018) - rbanffy
https://stxnext.com/blog/2018/09/27/beginners-introduction-python-frameworks/
======
BerislavLopac
This is a short list I have compiled a few months ago, FWIW:

    
    
        New kids on the block:
        - Starlette https://www.starlette.io
        - Vibora https://vibora.io
        - Xweb https://github.com/gaojiuli/xweb
        - Storm https://github.com/jiajunhuang/storm
        - Responder http://python-responder.org
        - Quart https://pgjones.gitlab.io/quart/
        - Sanic https://sanic.readthedocs.io
        - Bocadillo https://bocadilloproject.github.io/
        - Japronto https://github.com/squeaky-pl/japronto
    
        The old guard:
        - Flask http://flask.pocoo.org
        - Tornado http://www.tornadoweb.org
        - Falcon https://falconframework.org/
        - Bottle https://bottlepy.org
        - Pyramid https://trypyramid.com/
        - CherryPy https://cherrypy.org/
    
        Less known older ones:
        - Wheezy Web https://pythonhosted.org/wheezy.web/
        - API Hour https://pythonhosted.org/api_hour/
        - Morepath https://morepath.readthedocs.io/en/latest/toc.html
        - Klein https://github.com/twisted/klein
        - Weppy http://weppy.org/

~~~
stephenSinniah
Is there any python framework that optimizes for developer productivity?

~~~
mkolodny
Django's tagline is "The Web framework for perfectionists with deadlines".

~~~
bunnybender
.. That comes with a brief documentation of 1941 pages (as of August 20,
2019)..

~~~
collyw
That's because it comes with a load of built in functionality.

I am sure Flasks documentation is a lot smaller but its essentially just a few
parts of Django (it doesn't have a built in ORM from what I understand). Start
adding in the documentation for SQL alchemy, documentation for an
authentication library and whatever else you need and you will probably start
getting something similar but without the guarantee that the pieces will play
nicely together.

(Djangos documentation is really good.)

------
andrewstuart
I started Python programming 8 or 9 years ago and went from bottle to flask to
Falcon to Django to Sanic.

Django is incredible - I wish I'd started with it. It's truly the most useful
framework I've ever used - a real workhorse for building applications.

Flask and bottle are minimalist and get the job done for focused tasks - for
example I hacked together various web examples into an mjpeg server recently
used Flask (based on Miguel Grinberg's webcam server). You can get a simple
web site up and running in 3 minutes with bottle or Flask. I'd recommend
against using them for anything bigger though - you'll just spend all your
time reinventing Django (badly).

I use Sanic for asynchronous web servers.

Falcon is great to use to build APIs - it's raw and minimal and built to task.

Indeed in my latest project I use Django for the main web application, Flask
for the mjpeg server and sanic as a long polling web server acting as a
message queue server.

~~~
dragonsh
I have used Django a lot for applications where front-end is server generated
HTML page with templates. For REST API or GraphQL minimalist framework like
CherryPy, flask, bottle and others combined with excellent Python libraries
will work great even for a large modular app.

It is not true when you recommend don't use flask or bottle for large apps. On
the contrary it will be good for large projects to use minimalist framework as
they will act more like library. Also you can write code yourself for the
parts in the system which outgrow the framework. My team has built large
production level application for machine learning service initially in Django
and then later ported completely to flask. Given we don't use templates and
jinja2 as most of the front-end is in SPA, flask has been wonderful to work
with. Django rest framework doesn't work that well when you just need to work
directly with request/responses. Blueprints made it so easy to write large
modular code that choice between monolith and micro-service, just a
configuration setting coupled with either gunicorn or uwsgi in emperor mode.

All Python framework under the hood are WSGI or ASGI, so a decent Python
programmer can use excellent marshmallow, sqlalchemy, alembic, celery and
flask (or others) with blueprints to write a performant large modular
application and a service layer.

------
hmcdona1
We need to write a lot of small APIs in Python for SPAs. We ended up going
with FastAPI which utilizes Starlette under the hood. I'm surprised neither of
them are mentioned here.

Starlette was developed by the same dev who wrote the Django RESTful package.
If you mostly just need REST APIs or even GraphQL, it feels far more light and
modern than anything in Django and forms some better opinions around things
than the usual roll your own stack in flask alternative. Not to mention it's
ASGI based instead of WSGI and naturally faster because of it.

FastAPI just builds on that by adding some nice features like minimal
dependency injection and really awesome integration with type hints via
Pydantic.

~~~
heyoni
Do frameworks need to be asynchronous or is it good enough to just spawn
threads for background tasks?

~~~
hmcdona1
async is more beneficial for when code is primarily network bound. WSGI is
thread based which comes with a higher overhead for task switching. So it’s
just not as efficient for most web server tasks.

~~~
heyoni
Ok I think I get it, but if your backend is say, making a single API call and
sending that result back to the user, then there's no advantage to going async
since the user has to wait for that network call anyways, right?

Would you use this async then in instances where some of the API calls don't
matter to your user?

~~~
cle
I don’t know about Starlette/FastAPI, but generally a true async server
_could_ still see a benefit, because while that downstream call is blocked
waiting on a response, the OS thread can switch to a different request. This
is in contrast to a more traditional one-OS-thread-per-request model, where
each thread spends the vast majority of its time waiting on I/O. If your work
is I/O bound you can use expensive OS threads much more efficiently. Depends
on your workload characteristics and requirements.

------
hathawsh
Of these frameworks, Pyramid is the only one I know of that uses the concept
of traversal. Traversal is an elegant way to tame big projects. Whenever I
look at a web framework, I look for traversal and I'm always a little
disappointed to see it's missing.

Traversal means the framework treats each path segment in the URL as a
possible branch in a tree of resources provided by the app. After completing
traversal, the framework looks up a context-dependent view and checks a
contextual access control list before calling the view. It feels right to
declare security restrictions and other conditions outside the view.

~~~
vonseel
Maybe a semi-realistic example would help us understand what you mean by the
path segment branch in tree of resources part? Is that like /api/<resource
type>/<resource make>/<resource model>/ would boil down to
/api/cars/ford/fusion/ with cars, ford, and fusion each being a branch in the
tree?

~~~
hathawsh
That's right, except that 'api' is probably a resource also. Your app provides
a root resource with a __getitem__ method. Pyramid tries `context =
root['api']`, then `context = context['cars']`, then `context =
context['ford']`, and so on, until it uses up all the path segments or a
__getitem__ raises KeyError. Then it looks up the view for the final context
and calls it if all the conditions are met for the view configuration.

That's traversal in a nutshell. Resources can be database objects or any
object with a __getitem__ method. Everything about traversal is customizable,
but it's rare to need much customization.

Also, if your resources have __parent__ and __name__ attributes, you can ask
Pyramid to generate the URL of any resource and view using
`request.resource_url(resource, view_name)`, which is really handy for
ensuring URLs don't break.

------
infecto
I started working with Python around 2013 and I still consider Django the best
framework to use. Yes Flask you can pick what you want to use but I have found
the supporting libraries to be a bit outdated. Everytime I have used it I feel
like I am just gluing together a lot of different pieces and it becomes messy.
Django is constantly updated and I have little to no worries about security
issues.

Edit: And I have been following new projects such as starlette which I have
really enjoyed but I have not bought into the idea of why I need async
database access.

~~~
some1else
We have a legacy Django app at work. Coming from Rails and living in the npm
eco-system for the past few years, Django to me seems like an anti-pattern
framework in a death-spiral.

~~~
mkolodny
Would you mind sharing reasons why you think that?

------
heydenberk
The post doesn't mention Django's migration system, which is a killer feature.
Of course, one should change their database infrequently and deliberately, but
it is nonetheless a delight to use, and a feature that is not matched by many
other web frameworks, Python-based or otherwise.

~~~
collyw
> Of course, one should change their database infrequently and deliberately,

I think this attitude leads to a lot of crappy code. It's "safer" just to add
a bit more to the application layer than to change the database, but do that
enough times and you end up with a mess to compensate for a database design
that doesn't model what it needs to. (Learned through experience).

------
sifer
Will chime in and mention aiohttp[1]. It's lightweight, fun, and the API is
very user-friendly for those willing to work on a slightly lower level. I use
it to build speedy APIs, and coupled with a good ORM (peewee? [2]) it's pretty
dope.

1\.
[https://aiohttp.readthedocs.io/en/stable/](https://aiohttp.readthedocs.io/en/stable/)

2\. [http://docs.peewee-orm.com/en/latest/](http://docs.peewee-
orm.com/en/latest/)

~~~
enz
aiohttp is indeed neat. No WSGI (async-based). The API is clean and HTTP-
level. Maybe comparable to Falcon in this regard.

------
foxhop
Each of my bootstrapped startups were written using Pyramid:

* [https://www.remarkbox.com](https://www.remarkbox.com)

* [https://linkpeek.com](https://linkpeek.com)

It's pretty powerful. LinkPeek uses MongoDB for storage, and Mako for
templates.

Remarkbox uses PostgreSQL with SQLAlchemy, and Jinja2 for templates.

------
jszymborski
This is a great resource, and there are some neat inclusions like Falcon, but
I find the main trouble when building python web apps is deployment. I always
feel like I've duct-taped my carefully written app to the web-server.

~~~
appleiigs
Where have you deployed? I'm looking to switch for my Django website. I'd like
something full-serve like Heroku, but Heroku doesn't work well with sqlite.

~~~
scwoodal
If you don't mind a little sysadmin work I've had good experiences with
Dokku[1]. I spin up a Digital Ocean droplet or AWS Lightsail instance and it's
my own mini Heroku.

It's great for side projects without the limitations of Heroku's free tier.
Lots of plugins (Postgres S3 backups, Lets Encrypt certificates) are icing on
the cake.

[1] [http://dokku.viewdocs.io/dokku/](http://dokku.viewdocs.io/dokku/)

~~~
52-6F-62
I’ll second this.

I work on a selection of internal applications and services and we run
everything with Dokku. I was skeptical at first because it made initial
[legacy code] deployments a bit of a pain, but I’ve been converted. Not sure
I’d run everything that way but for small-scale applications it’s a breeze.
And because you have to do the sysadmin work yourself it’s a bit more flexible
than Heroku.

------
pythonwutang
FastAPI is my new favorite python api framework. Pydantic and starlette are
such powerful combo.

[https://github.com/tiangolo/fastapi](https://github.com/tiangolo/fastapi)

------
acbart
I was forced to encounter Web2Py in an open-source project several years ago.
It was awful. Besides the fact that it's stuck in Python 2 (seriously, even
today?), it had a lot of bizarre design decisions. For instance, it loaded
controllers by concatenating files in a directory - alphabetically. I know
Python's import system can confuse some folks, but surely there was a better
way. The whole thing left a very sour taste in my mouth, so I rewrote the
application in Flask - unfortunately, the lead developers didn't seem
interested in my fork. I've moved far away from their project, but I'm not
sure what they're going to do come 2020.

~~~
pbreit
I LOVE Web2py! I use it for pretty much all of my projects. It is the only
Python framework that is super easy to use, has enough "batteries included"
but not too much, super simple and super powerful templating, decent
migrations, simple data access layer not complicated ORM, no import hell,
implicit routing.

Developer has a new effort underway that is a little more "pythonic":
[https://github.com/web2py/py4web](https://github.com/web2py/py4web)

~~~
tim333
I'm a fan but found it a bit lacking in add ons for new stuff so am learning
rails.

------
tsumnia
I primarily use Flask for my research project. It was quick to pick up and
honestly, I like a more barebones style - one of the reasons I use Sublime
Text over IDEs. Plus Miguel Grinberg's tutorial is fantastic at getting you on
your feet (though I'm still sour over changes compared to his original
tutorial, more because its made it difficult to onboard new developers).

However, Pyramid's made some of the coolest shirts.
[http://pylonsproject.storenvy.com/collections/56570-all-
prod...](http://pylonsproject.storenvy.com/collections/56570-all-products)

~~~
sus_007
For once I thought, you're bluffing, and the shirts were of some Rock band,
but it's indeed for the web framework "Pyramid" xD

~~~
tsumnia
I met them back in 2015 at PyCon and they said that they loved the art design
of Iron Maiden shirts and Eddie, so since it was their product, they decided
that'd make it how they wanted

------
caiocaiocaio
Are any of these extremely good compared to a framework not written in Python?
For example compared to Rails or Phoenix?

~~~
moksly
We’re mainly a C# shop with some JavaScript, but I’ve done my time with php,
ror and java, and, Django is still my favourite web-framework. Don’t get me
wrong I actually like .Net Core, but DB migrations, authentication, testing
and productivity is just better in Django (I do have an unnatural hatred for
entity framework). Django even had the best learning resource I’ve ever seen
with the testing goat book.

That being said, the job market for Django is non-existent in my area, and
most of my country, and that’s a rather vital issue.

~~~
ianamartin
Hating entity framework is _not_ unnatural.

------
piffey
Because it's missing from all of these lists and I respect the maintainer a
lot I'm going to throw Hug
([https://github.com/hugapi/hug](https://github.com/hugapi/hug)) into the mix.

Really easy to build fast, versioned, testable, documented, async APIs with
Hug. If you're making a quick project would highly recommend giving it a spin.

------
bayesian_horse
Beginner's guide to choose a Python web framework: Django.

~~~
andrewstuart
Don't know why this is downvoted - it's crystal clear advice for beginners -
"just use Django".

~~~
rbanffy
Django brings a lot of concepts with it. It may be simpler to start teaching
with Flask and build up from there until the need for something like Django
becomes obvious.

~~~
goobynight
Right. With Flask, I can simply get to the point where I'm rendering
templates, styling with CSS, adding assets and populating template variables
with data from simple (or complex) functions I've written.

You can take care of a lot with just that.

~~~
rbanffy
Eventually, when the application reaches production, you'll have cobbled
together a unique subset of Django.

That's the downside of Flask.

~~~
bayesian_horse
And good luck with auditing upstream versions and security in general.

------
rglullis
For such a comprehensive list, no mention of tornado?

~~~
jbarham
That surprised me too. IMHO Tornado should be #3 after Django and Flask since
AFAIK it has the best built-in support for writing hybrid HTTP/WebSocket
servers in Python.

I use Tornado to serve the WebSocket backend for
[https://www.slickdns.com/live/](https://www.slickdns.com/live/). I've also
used Django Channels to add WebSocket support to a Django app and found it
very cumbersome compared to Tornado.

~~~
no_wizard
+1 For Tornado.

I'm curious if you care for their templates or not, though.

~~~
jbarham
Sorry, I haven't used Tornado's templates enough to compare them with e.g.
Django's.

Essentially all I use Tornado for is to publish a WebSocket endpoint, and for
that specific purpose it's great. For building conventional web apps I'm very
happy with Django and its templates.

------
BeetleB
I know some may not consider the category as part of web frameworks, but one
significant omission is the category of static site generators (e.g. Pelican).

If you want a fairly simple site that you'll use/modify only occasionally
(e.g. blog), save yourself some headaches and just use something like Pelican.
No need to worry about databases, and no need to worry about how to deploy. I
used Django for some years, but the hosting provider kept making changes to
the libraries resulting in my web site going down frequently.

------
jangid
Japronto looks promising but the lack of community support is discouraging.
Another alternate could be Sanic if you are going to use Python 3.5+. Support
for asyncio is essential if you want to serve a million requests per sec.

------
bckygldstn
I love using webapp2 on Google App Engine. Using objects and inheritance for
request handlers really clicks for me, in a way that Flask’s decorators and
magic imports never does.

------
jcroll
Anyone have any experience with getting an ioc container going in your python
project? What route did you go?

