Hacker News new | comments | ask | show | jobs | submit login
Flask 1.0 Released (palletsprojects.com)
548 points by JonoBB 9 months ago | hide | past | web | favorite | 179 comments

Flask has a stigma for not being that good when building larger apps, but honestly Flask scales really well for that type of use case (coming from a development / maintenance point of view).

I have some pretty large Flask apps with dozens of top level dependencies and models spanning across many thousands of lines of code. Even if I don't touch the code base for a few months, it's easy to jump back into it.

I'm also a huge fan of Rails, but truthfully I find Flask apps to be easier to reason about and hack on once they grow to a decent size, simply because Blueprints make it really straight forward and intuitive to modularize your application without increasing the complexity of everything by using micro-services.

If anyone wants to jump into Flask and start building real world apps, you may want to check out https://buildasaasappwithflask.com/. It's a full blown course where we build a SAAS application using Flask and Docker. I recently added a free RESTful API bonus section to the course and now that Flask 1.0 out, I'll be adding another free update which will cover updating all of the packages in the main app. Just going to wait for the dust to settle on the 1.0 release first.

> Flask has a stigma for not being that good when building larger apps

Not sure how to quantify that "large" but I've worked on some api backend services written in Flask with a quarter million lines of python code and not feeling "outgrowing" Flask. Granted, it took some good design and effort to make all piece s work together. These days, horizontally scale apps is the way to go.

In my experience, Django is less suitable for large projects than Flask.

The nature of Django encourages tight coupling between unrelated parts of the system - Models intertwine database operations and business logic, ModelViews intertwine db operations, business logic and the interface layer.

This is manageable in the small, but when you hit scale, this tight coupling adds a whole bunch of unnecessary complexity to your system. Good luck trying to tune your database when any template can trigger hundreds of db calls!

Django is great for building Django apps. That is, if you're starting a greenfield project and don't have to integration with an existing database schema, and you like the Django ORM, and you like Django templates, and your data model maps cleanly onto a relational DB, and you can use the admin site more or less as-is without having to customize much, then it's lovely! I'm not being sarcastic: it really is. We've successfully rolled out several CRUD apps so that our internal employees can tweak settings and update stuff without waiting for engineering to get around to it.

That said, I'd rather gnaw off my own ankle than develop a production, customer-facing website that breaks any of the preconditions I listed above. Every time I've needed to deviate from the Django Way of doing things, it's felt like I'm swimming upstream against a rapids. For those kinds of projects, I love Flask very, very much.

You don't need Django's ORM, templates, and admin section to build a Django app. Check out this example of a single-file Django project:


It's from a good book called Lightweight Django.

But if you’re not using those things, why Django?

You can use what you need and replace the rest. Or use Flask or something else. I'm not arguing for one or the other, but just mentioning that you don't need all of those mentioned conditions for Django.

> Every time I've needed to deviate from the Django Way of doing things, it's felt like I'm swimming upstream against a rapids.

I agree -- if you use Django, you have to do it the Django way. Flask is more flexible.

This is a false statement that Django is unsuitable for large projects. I have been working on a fairly large Django Project for 5 years now and it has been a pleasure using Django to build good and stable features that actually scale.

> The nature of Django encourages tight coupling between unrelated parts of the system - Models intertwine database operations and business logic, ModelViews intertwine db operations, business logic and the interface layer.

It totally depends how your architect your application and how you write code.

Any framework you choose, you need to write good code, keep an eye on db operations, enable caching where it is required and you will survive the scale just fine. All the arguments are exactly same in the favor of slack.

Do not spread the FUD that using a framework can magically make your application scale. I have seen very bad and very good code in both Django and flask. If you want your application to scale, you need to carefully work on it there is no silver bullet.


I agree some frameworks enforce good design decision but none can guarantee it. That's my argument here.

There are good frameworks in PHP too and not all PHP code is garbage.

PHP is a language, not a framework.

A language is a framework, just even bigger ;)

Hell, some frameworks even come with their own (DS)Language

If you want something similar to Flask component wise that scales well and allows for nice structuring patterns try Pyramid (https://trypyramid.com/). It it is really well thought out framework, you can use it to build single file applications if you want but it really shines when you use Pyramids mechanisms that allow for extending applications and their composition.

That being said when you are careful you can probably end up with reasonably structured applications in either Django, Pyramid or Flask.

Newly released version of PyPi is built in Pyramid.

I was about to post something similar, but this nicely summarizes my feelings. Even with DRF (for REST APIs) the extreme coupling at all layers makes things painful, though it's possible to reduce that pain a little with some carefully enforced rules.

(I would like to see a way of disabling QuerySet traversing, so that if you try to access something that you didn't already prefetch_related/select_related then you just hit an error (and therefore fix it before you go live). The behaviour of just happily issuing hundreds of DB queries in a single request really hides a bunch of architectural and performance issues.)

That said, as the sibling comment says, if you need a simple- to moderate-complexity, mostly CRUD API, and particularly if you need it fast, then Django is a great tool.

Your should look into the django-seal package which enforces this sort of constraint that you're asking for

Yes, yes I should. Many thanks!

Might want to tell instagram


Instagram is using jinja for templates (also used by Flask) and does not use the Django ORM.

I mean Facebook uses PHP and that doesn't mean it's any more scalable.

I suppose they call it hack now though.

>template can trigger hundreds of db calls

I'll take what is caching for 500, Alex

That sounds like a helleva large codebase, especially for Python.

What did the application do? How large was the dev team?

I have worked on several Python code bases exceeding 500k lines. Not sure why you think that's uncommon.

I've worked on a couple codebases approaching that a few hundred k. But at that point we've usually done major refactor, usually resulting in a codebase with a level of magnitude less lines.

I'm not saying exceeding 500k lines is impossible, but it seems like a very large system for a well written codebase with low duplicity. I would love to see what the codebase looks like for such a system written with Flask.

There are a lot of different types of software being made in python.

I've managed to do python for 10 years only working on one codebase that size, and I'm not sure it counts - it was made by low skilled devs (we were encouraged not to do anything "clever", like use the language features) mostly cutting and pasting existing code.

You've got to love companies that have the don't be "clever" attitude... Whats the point of hiring skilled workers to just dumb them down. I've stopped counting the companies that openly stated, "we don't pay you to think," only to see them stuck in an endless loop of mediocrity.

Our policy is to avoid cleverness - think "code golf" - that is going to be opaque and hard to reason about at 2AM when things are on fire. We don't shy away from language features, but if you have a PR with multiply-nested generator expressions, for instance, someone will usually ask you to unroll that into a set of explicit loops.

A company that doesn't pay it's engineers to think is surely doomed from achieving any significant innovation.

Doesn't seem like viable strategy at all, I'd run the other way if I were approach by such a company.

I think that's more because Flask is a micro web framework whereas Rails is a macro web framework. Sinatra, Express, and Compojure are micro frameworks in the same vein as Flask, and they encourage simplicity of mental model over batteries-included comprehensiveness of features that you find in Rails, Sails, and Django. In general I prefer some kind of a middle ground but I don't think there's middle-ground frameworks actually out there, I think you have to kind of build on top of Flask/Sinatra/Express by throwing some-batteries-included libraries on top of them to get there. But yeah I also find it easier to reason about than having a whole lot of convention-over-configuration rules memorized.

Tornado fits that middle ground sweet spot for me, in a lot of ways. Its lightweight to learn, but includes a surprisingly good number of really helpful stuff for web apps.

One of those things is its wonderfully simple oath2 helpers (the simplest I've seen, really).

You'll still have to bring your own model layer though. And its ecosystem isn't as rich as flask. That is a shame, because its a wonderful little framework.

It's bizarre there are few or no offerings in that elusive middle ground. Rails & Django seems a little heavy. Flask & Express a little lite.

I've never written an app that did not need user management, sessions, admin, db access, form processing, views/templating. Web2py is the best I've found (python).

Will the needs not be satisfied with flask ext, approved or not[0]? For example: user management, sessions, admin(flask-admin), db access(SQLAlchemy), form processing(wtforms), views/templating(jinja).

[0]: http://flask.pocoo.org/extensions/

Yes, I think you could definitely piece something together. And I suspect there's a starter-kit/cookiecutter somewhere that I'll look for.

This is one of the reasons I liked Silex back when I was a PHP dev. It’s a simple micro framework, but built on the same underlying components as Symfony, so porting libraries from one to the other is simple.

Add a tiny bit of structure to take the guesswork out of how to lay out your app (or module — it’s very easy to load one Silex app into another), and it nicely meets that “in between” you’re talking about!


In the Python world, Pyramid seems to fit the bill of a middle-ground framework.

My employer made me switch from Flask to Django providing non-scalability reason. I asked around on a few online forums and they told me that flask has no such issues. There was an article where somebody from DISQUS explained how they were able to use flask in production without much hassel and there's no reason to switch to django. My employer told me to not use flask as it is not production grade. The problem was to implement a few web APIs. I switched, reluctantly. I am still not convinced though, given that I have very recently started using Flask/Django, it may come to me at a later time.

I've been developing with Django since the 0.90 days and, to be honest, I've seen a lot of scalability issues with Django itself once you get big enough.

Those issues all relate to how Django is an all-in-one solution with a lot of modules, which you start dropping one by one as you use different solutions.

For example, Django's cache layer is great, but as you scale you'll want to use Redis clients directly rather than the memcached abstraction.

The ORM is fantastic (and much more intuitive than SQLAlchemy). But as you scale, you'll want to use Postgres' more powerful features without worrying about compatibility with MySQL / SQLite. (Django has made progress in that area with contrib.postgres, but it's still only scratching the surface)

Forms? Templates? Staticfiles? If you're using a JS (Webpack and the like) frontend, forget about this stuff. You're better off not serving the frontend with Django at all, it'll only cause more trouble than is worth.

URL routing... again, nowadays even that is done in Javascript. And doing it in two places at the same time is a pain. Long term, you might drop that too.

What's left? The model layer, and the admin that accompanies it. I wouldn't trade the Django admin for the world but it also has a lot of scalability issues and although it's very declaratively customizable, it's much harder to customize specific models.

The auth layer is also probably something you'll keep for a long time, but it's littered with things you will probably not use such as the whole groups/permissions system, or the adminlogs auditing system (which is super cool but the API is very hard to use outside the Admin).

The problem with Flask is it's missing in the "what's left" parts. And if you use Flask, you're missing out on the entire Django ecosystem of apps that make heavy use of the model layer.

But you dear reader statistically will most likely not hit any of these scalability issues (aside from the frontend ones). So don't feel bad picking Django, it's an excellent framework regardless.

> ORM is fantastic (and much more intuitive than SQLAlchemy)

Any articles or blog posts you can recommend to give some examples or comparison?

> entire Django ecosystem of apps that make heavy use of the model layer.

Exactly why I don't want to use the django system. I'm happy with the python ecosystem and have yet to find a django only module where no other alternative exist.

Its not that django is a bad web framework; on the contrary, to be honest. I'm just already invested in other modules that django decided to re-invent/design to fit their needs better.

> Any articles or blog posts you can recommend to give some examples or comparison?

Not really sorry, it's all personal experience.

> I'm happy with the python ecosystem and have yet to find a django only module where no other alternative exist.

What about all the cases where you need support from database schemas? For example let's say you want to have access to Stripe subscriptions from Python and cache them to your database, you'll need something like dj-stripe. There's nothing "in Python" other than an API client because the Python stdlib doesn't have a model ORM.

> For example let's say you want to have access to Stripe subscriptions from Python

I will use the official stripe flask checkout example[0].

> and cache them to your database, you'll need something like dj-stripe. There's nothing "in Python" other than an API client because the Python stdlib doesn't have a model ORM.

With their OpenAPI definitions[1] to create the needed sqla model boilerplate, which creates the needed pgsql tables. For change log of my models it is kept in my py model files and xml with sql diff using a cheat where I implemented a Liquibase python wrapper[3].

I'm lucky where I work in a not to enterprise env so self-rolled solutions is sometimes acceptable and we try to keep it sane.

[0]: https://stripe.com/docs/checkout/flask

[1]: https://github.com/stripe/openapi

[3]: https://github.com/Morabaraba/python-liquibase

> I will use the official stripe flask checkout example[0]. [...] to create the needed sqla model boilerplate, which creates the needed pgsql tables

Ok, so let's say someone else wants to apply this pattern (it's extremely common after all). Should they do the same thing as you did?

Should the next guy as well? Where does it stop? At some point, you write a library right?

Well that library will end up containing the ORM models. So your choice ends up being between "I will roll my own models" (whether they're autogen'd from openapi or not doesn't matter) and "I will use someone else's models". You're back at exactly the same point as earlier, none of this actually achieved anything, other than give you extra work.

The point I was trying to originally make is that saying you'll do it "in pure Python" instead of "in Django" doesn't actually work. If by "Python" you mean "SQLAlchemy" that makes more sense.

At the end of the day, I wish the Django ORM were ripped out of Django so we could have libraries that depend on Django's ORM without them depending on the entire Django stack. There's also a lot of demand for the other side of this, which is having Django's ORM be replaceable by SQLAlchemy. Then you're no longer talking about "Django vs Flask", but "djangorm vs sqlalchemy".

The final step after this would be to have the Django ORM support SQLAlchemy's model declarations. The Django and SQLA model declarations are already very similar. Then we live in a world where you can swap out the ORM API at the application layer, but have libraries that are compatible with both and don't need to be reimplemented for both Django and SQLAlchemy. (I strongly believe the distinction between the two model APIs is not useful right now due to how similar they are)

> Should they do the same thing as you did?

They can, I recommend they look at the swagger-codegen[0] api stub templates. There clients as well.

[0]: https://github.com/swagger-api/swagger-codegen/tree/master/m...

> At some point, you write a library right?

Normally a flask-ext forms around a established python library. Yes now we are back at the tight integration problem, but at-least your knowledge of the py library will not be lost in another eco-system.

> I wish the Django ORM were ripped out of Django so we could have libraries that depend on Django's ORM without them depending on the entire Django stack... Django ORM support SQLAlchemy's model declarations... Then we live in a world where you can swap out the ORM API at the application layer, but have libraries that are compatible with both and don't need to be reimplemented for both Django and SQLAlchemy.

Amen Brother!

This is sad. Flask is a very nice microframework that does not have any of these scalability limitations for which your employer asked you to switch to Django.

I have used both Flask and Django for a long time, so I think I could contribute a couple of points in this regard.

- Django with a very good documentation and batteries included helps to build a lot of functionality in less time without having to look anywhere else. In the same time, flask being a microframework, you need to look for the batteries yourself and it takes experience and knowledge to know which components to use and which to avoid.

- None of these two frameworks will magically fix the scaling issues or are free to scaling issues.When you hit issues with scaling, you need to find the bottleneck and fix it. There is no other magic bullet here. I would suggest do not be religious about things and try both of them without any bias in your personal projects and then evaluate. Do not form an opinion without knowing something yourself.

Disqus is built with Django, isn't it? I've always read that and I've seen articles about it last year. Or do they use a chimera between Django and Flask? It's easy to find Django's "csrfmiddlewaretoken" input hidden in some of their forms, such as the authentication ones.

Ah, "hit and run management"...

> Flask has a stigma for not being that good when building larger apps

I've never heard that before. It's been the go-to backend server at the last few companies I've worked for, and it's the first Python web framework I reach for when I need to roll out a new service. I think its explicitness is hugely wonderful for maintenance: given a route, it's straightforward to figure out exactly what code is being called.

    I think its explicitness is hugely wonderful for maintenance
I find all the magic really off-putting in Flask…

I thought what the parent comment meant was that there's little to no magic in Flask compared to some macro-framework like Django/Spring. Can you get any more explicit than Flask and still be called a framework, without hitting the socket levels?

There's a bit of magic in Flask - the global object is an example.

This one trips up every podcast host and blogger. It is not a global object, it just pretends to be with some wrapper magic. Like an attribute method it is not a simple variable.

Which is even more magic... I don't get why the request and context isn't just passed as parameters. Explicit is better than implicit!

> Explicit is better than implicit!

Only if you want DRY to mean "Do repeat yourself".

Agree: passing the request with the full context as parameters to the handler function seems like a more explicit approach.

Which is hardly unique to flask. A scoped bean in Spring is the same concept, if expressed in a much more verbose manner.

Well flask did evolve of Werkzeug a utility wrapper around wsgi, in response to bottlepy.

I also find a lot of the "magic" is found in flask extensions.

Flask _does_ scale really well with lines of codes. However the limitations of Python w.r.t. async log really start to show once you step beyond simple CRUD apps.

This was my experience. Just exited a startup that relied on Python heavily. Built a flask-restful based back end with SQL Alchemy.. Never had any issues with flask per say, but it made me happy I know languages with far better tooling and concurrency experience/performance :)

Did you ever attempt to use PyPy? Flask works with it, and in my experience the handful of times I've needed Python to be more performant, PyPy got me there easily.

My use-case was I was doing a heavy part of an ETL pipeline out of MySQL and it was taking an unreasonable amount of time. PyPy was a roughly ~8x speedup, which ended up being faster than doing direct manipulation with MySQL via the cli (!!!).

For interest sake, can SQLAlchemy run on PyPy; pgsql driver support? thanks,

I haven't used it in production (only made some benchmarks), but the recommended approach is to use the pg8000 driver (https://github.com/mfenniak/pg8000) with pypy, instead of psycopg.

SQLAlchemy can run on PyPy, but you have to use pg8000 (pure Python) or psycopg2cffi (cffi port) instead of psycopg2 for pg.

Just use sanic. It's a mostly drop in replacement for flask that is async first and runs on uvloop.

The unfortunate bit is you lose out on so much of the ecosystem going hard on asyncio right now though (like sqlalchemy orm).

aiohttp + pee wee async is the best combination available right now IMO. A fully asyncio app with pleasant non-blocking ORM and migrations.

I'll have to give that a shot sometime. :) Haven't used peewee before, as sqlalchemy has mostly been tremendous.

That said, if I'm starting a new project where I'm pretty sure I need async io, I'm not sure Python is my first choice. It's got decent facilities but compared to other ecosystems it's not as mature there

Quart is another option. Even more of a "drop-in replacement" than sanic.

Can you elaborate a little more on `limitations of Python w.r.t. async log`? I have switched to Django + Gunicorn which seems to be handling requests just fine.

I meant async logic. So that means things like worker threads and messaging. It's more of a limitation of Python as a language than anything else. As bad as NodeJS is, the fact that it's underpinned by an event loop makes it more powerful with async stuff. Golang is better, though a little funkier.

>Flask has a stigma for not being that good when building larger apps

If it has such a stigma, I've never heard or read about it.

How do other users of Flask handle async calls to third party APIs? I use celery which works okay but it still feels quite clunky.

Both the solutions I use is mq and py based: mqttwarn[0] and celery.

What feels clunky about celery? The third party broker? Bunch of "magic" code you feel can be simpler as a couple of pika modules? While I like pika it needs a bunch of boiler plate[1] where celery is just multi-broker batteries included solution... which might feel a bit clunky.

I see a lot of zmq solutions in the wild. But I'm happy with my current setup.

[0]: https://github.com/jpmens/mqttwarn [1]: https://github.com/pika/pika/blob/master/examples/asynchrono...

This reference to buildasaasappwithflask.com deserves a disclaimer (I assume you're the author - the initials match)

The sentences immediately following the URL makes it pretty clear the commenter's relationship with the site:

> "It's a full blown course where we build a SAAS application using Flask and Docker. I recently added a free RESTful API bonus section to the course and now that Flask 1.0 out, I'll be adding another free update which will cover updating all of the packages in the main app."

I'm sorry, it's been a long day and I apparently can't read anymore.

I understand that Flask has become popular because it is easy to learn, but my experience is that as your knowledge progresses it just keeps getting in your way. I particularly dislike some design choices which look like afterthought hacks, such as global variables for current request and using abort() functions instead of raising exceptions directly.

EDIT: To avoid hollow naysaying, here are some alternatives to Flask I find much better designed:

    - Tornado Web Framework [0]
    - Falcon [1]
[0] http://www.tornadoweb.org/en/stable/webframework.html

[1] https://falconframework.org/

The real value of Flask is that it makes you appreciate what Django does by default.

When I first started learning Python / web frameworks, I went with Flask because it was smaller and "simpler". As my project grew however, I had to organize it. I was basically imitating what Django gives you by default, though less cleanly.

"The real value of Flask is that it makes you appreciate what Django does by default"

I have exactly the opposite experience: Flask is nicer than Django; SQLAlchemy is better than Django ORM. Love a bit of Flask.

Django has nicely integrated components, but each of flask components are better (jinja2, sqlalchemy, migrations, etc).

Those aren’t Flask components. They just work well with Flask. And Jinja, SQLAlchemy, and Alembic just happen to be the largest and best of them.

Many of these independent components pale in comparison to their Django counterparts in glaring ways—they are often a pain to use, with some pretty questionable internal code choices. They remain used because they are often the only choice out there, even though their implementations are inferior to Django’s.

I say this as someone who has used Flask for over 5 years, as well as nearly 5 years of Django.

They are flask components cause they work well with flask and work bad with django.

Parts that I mentioned are (or were when I compared) light years ahead (especially sqlalchemy).

I totally agree on SQLAlchemy. It’s very good. As is Alembic.

I feel like most using Flask would consider “Flask components” to be equivalent to Flask extensions—e.g., Flask-SQLAlchemy vs SQLAlchemy proper. Maybe it’s a pedantic nitpick, but I’ve never heard anyone refer to SQLAlchemy as a Flask component in 5+ years, hence my comment about the distinction. But yes, many of the Flask-compatible Python packages you mentioned are quite a joy to use.

I have the exact opposite opinion. Flask just gets out of my way and allows me to design my app just the way I want it.

this only applies if your project can be organised within Django's requirements though right? I use Flask and Django a bit but it usually depends on how "cookie cutter" the project scope is

That is a fair point. Since I was doing something kind of CMS focused, Django fit the bill. I suppose if you were doing something orthogonal to that, it would be better to have the flexibility of Flask.

Especially when you then go to maintain a Flask project where they have re-implemented Django, except you don't know where anything is or how it works.

Exactly. I have used Django quite a bit over the years and have maintained a few prebuilt (by previous developers) Flask apps for clients. Recently I had a need for a small web service so I thought I'd use Flask. After days of trying to get something simple running and installing numerous packages, I gave up on Flask. I had a server with everything I needed in less than a day with Django.

Some of the design decisions of Flask just don't seem logical, such as using the db instance when defining model parent classes. Makes for strange contortions when defining multiple model files to prevent circular references or db not found errors.

  db = SQLAlchemy(app)
  class User(db.Model):

I disagree. With any sufficiently complex project, Django's batteries included got in the way whereas scaling Flask felt smooth.

Can you elaborate? In all the dozens of Django projects I've worked with, I've never felt like Django got in the way, mainly because everything is pluggable and you can just not use it if you don't want to.

Both Django and Flask make me yearn for Rails :(

i learned to program with python and flask and promptly started hammering out my project. flask was great for learning piece by piece what goes into a web app but eventually it grew to a point where i was relying on all these extensions that were no longer maintained and i was spending alot of time to configure and setup every last bit of functionality i needed and every extension was like a new DSL to learn.

The obvious move at the time was to move to django and I spent some time familiarizing myself with it's own DSL. But boy was i struggling all along the way to do things how I liked in Flask with django. The Django Templates were extremely limiting (no modules) and couldn't even do regular python things and I came to find that extensions for Django were in no better shape than flask's. There was no clear solution for rate limiting and various other things I was looking for.

I've followed rails from a distance for a long time but, coming from python, ruby seemed so abstract to me i could just never figure it out but towards the end of my django time, i was finding that rails did/had everything i wanted and it all worked just the way i wanted it to and it was calling to me really hard. i took a big leap and spent a couple months diving fully into ruby, doing all the tutorials, reading all the books. at this point i am officially converted and my project app with it is already further along than i ever got with flask or django. when they say "ruby/rails is built for programmer happiness", they really mean it. and i can really feel/appreciate it. it's extremely fun to use and to see real progress without having to rack my brain and figure out some internals before i can proceed every so many hours. i'm just getting shit done and things work just how you'd intuitively think they should. rails ftw

+1 You nailed it, this mirrors my experience.

Pyramid is great, lacks the problems (magic) you mentioned, and is now what pypi.org is built on: https://docs.pylonsproject.org/projects/pyramid/en/latest/in...

I’ve used it off and on since 2010 (as Pylons) and have been happy with it.

Wow, I didn't make the connection until now that pypi.org is built on Pyramid. That's cool. :-)

Some more links for anyone interested:



>global variables for current request

Not really global variables. I would analogize it to dynamic variables from Lisp, which are a feature I wish every language had. I strongly disagree it's a hack or gets in the way. Having access to the request from anywhere without explicitly passing it around is really useful.

OK, fair point, I used a wrong term here. So instead of global variables we have dynamic modules that represent a stateful context object which is different depending on where they are imported and when. Very un-Pythonic, and honestly I'd prefer global variables here. :-/

>different depending on where they are imported and when

Er, no. Their value depends on where in the callstack you read it, not on where/how they're imported. They're like global variables but with thread locality, and with a stack of values.

The context local request object is nice (once you accept it), but it definitely complicates the testing story. Whether that is a worthwhile trade-off depends on how many tests you write I suppose.

Another interesting API framework from the DRF author:


Uses Python3 type annotations to do serialization. Not sure it's ready for production, but it has some very interesting new concepts.

Also worth mentioning Sanic which is fast and I believe dispenses with Flask warts like the thread-local Request object (though it does bill itself as "Flask-like").

Yeah, Apistar has an interesting approach, but that's just more unpredictable magic.

I've never seen Falcon, thanks.

Flask is still one of the most approachable frameworks I've used. It's great for getting something hacked out really quickly, but for asynchronous requests Tornado is where it's at.

That being said, when I really want performance I usually reach for Golang.

Check out Sanic if you want an async python framework with a similar API to flask

Its pretty hard to beat Tornado's api, IMHO. Its a really rich api for how simple and quick it is to learn. Flask is a definite downgrade to me, when it comes to the api.

But Flask wins hands down on the richness of its ecosystem.

Most of the "Flask ecosystem" are wrappers for some generic Python libraries which can easily be introduced to any other framework: SQLAlchemy for RDBMS abstraction and ORM, Jinja2 for templating, and so on.

Do you find Golang to be that much harder to develop in, or is it that Python has libraries whose equivalents are missing in Golang? When would you actually choose one over the other?

Python is generally less to type. Go isn't hard, per se, but it is statically typed and tends to be a bit more verbose.

For me: Python if there's a specific library I want to use, I'm just hacking out a proof of concept, or I'm working with text.

Golang for higher performance, concurrency, stream processing, and cryptography (it has good libraries for that kind of stuff).

I agree. I particularly like Go's web ecosystem. A web server is just a function, and that function is often a composition of other functions (for example, a tree of router functions and then a handler for each route). By contrast, it seems like Flask goes to great lengths to obscure such a simple concept (decorators for routes, global variables for state and resource management, etc).

I wouldn't call it obscure, it's just an abstraction.

But you can always use the underlying library (http://werkzeug.pocoo.org/), which does send everything through a function. Or just implement WSGI directly.

It's not a very good abstraction, because (as previously mentioned) it depends on global variables to manage shared resources (e.g., connection pools) and even request state. Hence "obscure".

It would be much cleaner to just define a handler type with the signature: `def handler(r: http.Request) -> http.Response`. Those handlers could be passed to routers (which themselves could be handlers), for example (not tested):

    class Route(typing.NamedTuple):
        path: typing.re.Pattern
        method: str
        handler: http.Handler

    class Router:
        def __init__(self, routes: typing.List[Route]) -> None:
            self.routes = routes

        def serve_http(self, r: http.Request) -> http.Response:
            """serve_http implements the http.Handler interface"""
            for route in self.routes:
                if route.path.matches(r.path):
                    return route.handler(r)
            return http.NotFound("404 NOT FOUND")
Note that since handlers are just functions, they can also be methods with object-level state. They needn't depend on global state at all, for example, notice how the following routes don't depend on the connection pool (or the request state) to be global:

    class Server(typing.NamedTuple):
        db: DBConnPool

        def first_route(self, r: http.Request) -> http.Response:
            """first_route uses shared `db` resource."""

        def second_route(self, r: http.Request) -> http.Response:
            """second_route uses shared `db` resource too!"""

I've always preferred CherryPy[0]. It's simple and if you write simple Object Oriented code (or have written some) you can turn it into a website, just need to "return" URLs. CherryPy has also been around 10+ years by this point (longer than Flask it seems). I like that I can stay high level, and when needed get really low level with CherrPy.

I've used Flask in one other instance, and it wasn't too bad, but I missed CherryPy through the process (cleaner looking code, and obviously more familiarity for me) but I was participating at a Hackathon so maybe my experience is a little shifted. Though I never picked Flask due to never liking how it looked from even just the Hello World I was not a fan of how it's written, but that is just me coming from other languages and looking at frameworks like Sinatra (though I don't do any Ruby it was pretty clean) and Nancy (C#).

[0] https://cherrypy.org/

It is possible to register error handlers for exceptions in Flask. See http://flask.pocoo.org/docs/1.0/patterns/apierrors/.

There are also exceptions corresponding to HTTP errors, e.g.:

  raise werkzeug.exceptions.NotFound
instead of abort(404)


It's my go-to prototype framework/server, but I think it's going to complicate things unnecessarily down the road if you want to scale. You can make it work for prod if need be, though.

But you can go from 0-59 with ease and easily translatable templates, etc.

Falcon is just as simple to learn as Flask but so much more pythonic. It also blazing fast.

With that said good to see Flask get to 1.0. Long time coming.

What about the ecosystem around it?

What about Pyramid?

Never even realised it wasn't 1.0, maybe I should pay attention to version numbers. Changelog looks good!

I've never understood logging in Flask or how to do it in a sane way for a simple app while using uWSGI, so I'm glad that has some improvements. I don't remember my exact issues but I couldn't get configuration from a text file to work and for some reason configuring it in-code wouldn't work either. I don't understand python's logger in general so I'm sure that's part of the problem. The changelog is vague on details, but hopefully whatever was modified really does make things simpler and solves my issues for me.

My processes always log to stdout. stdout + supervisor + rsyslog = fun and profit.

You can also log directly to rsyslog with python logger.

I have been logging to stdout mostly. Never used/heard of supervisor or rsyslog. What are their use cases?

Flask is an interesting project. Created by a true Python master only to be nearly abandoned, and yet it remained so popular it was later revived by a new group without a major fork. How often does THAT happen?

The post describes it as "stable for a long time" :)

It wasn't abandoned it just doesn't need very many updates anymore.

Also there was no new group this is the official Flask repo.

Flask does what it was intended to do. To add more stuff to it would defeat the purpose, and turn it from a micro-framework into a regular framework.

If a micro-framework adds a "web forms abstraction", honestly, run the other way.

Love Flask. It is my favorite back-end framework and has fit all of my needs. Getting a server up and running with Flask is incredibly simple and if anybody hasn't played with it yet, I highly recommend it.

It's all fun in games until the project you just started yesterday already needs an, albeit simple, upgrade.

This is epic. In theory now from V1 onwards it should be easier to convince people at big serious corps to use Flask as it cuts down a lot of Django bloat especially for smaller applications, microservices and other nimble backends.

Hopefully! There's a bad attitude I've noticed about Flask, people don't take it seriously and treat it like a learning tool or a library for quick and dirty hack projects. All because it's simple to learn and free of bullshit and Just Works™. Should lead to the opposite attitude, but nope. People apparently enjoy extra complexity.

There is a similar feeling towards SQLite

I think a lot of criticism is valid. Flask has a lot of bizarre conventions which don't scale well, like stuffing all shared resources into the global context or app-level dicts and using `@route()` decorators all over, for example. And I'm not sure what the benefit is, except that clever feeling one gets when they use decorators or other seemingly magical features unnecessarily and later need to workaround the tight coupling.

Decorators improve dev speed. No need to be constantly switching back and forth between views and urls.py.

Still, sometimes nice to see all in one place.

They only improve speed from an initial "get it working" point of view. That's part of the reason flask is rarely taken seriously as a production solution. Not having natural separation between views and urls is a real PITA for anyone trying to create a long term solution or larger project. For what it's worth, I also hate the argument that bad design increases Dev speed. That's only true until you need find something later, then you have to hunt around instead of having one place to look, wiping out any initial gains. It's false economy.

FYI with flask you don't have to use decorators for routing. You have the option to define all your routs in a single file.

True in a very large project, false on the rest. Congrats on your one-true-way argument. ;)

I'm a professional Python dev, I have no reason to believe that decorators save any time for any size of project. They're harder to reason about for developers of all experience levels and their is no obvious advantage--some argue that the syntax is more pleasant, but I don't perceive an increase in readability; certainly not one that makes up for the increased cognitive burden. The following is super straightforward, testable, and it doesn't depend on globals for shared resources or request state:

    def hello_handler(r: Request) -> Response:
        return Response.ok("Hello!")

    def goodbye_handler(r: Request) -> Response:
        return Response.ok("Goodbye!")

    if __name__ == "__main__":
        router = Router("/")
        router.register_route("/hello/", "GET", hello_handler)
        router.register_route("/goodbye/", "GET", goodbye_handler)

I was thinking more of the fact the are paired with the view. To be honest never gave the fact they are decorators much thought.

You don't have to use the Django "bloat": https://github.com/syntarsus/minimal-django

What's your application server setup like? Is there a standard for this? I tried using UWSGI and Gunicorn with varied results. It was just a pain to setup. I hope things have improved.

I found it pretty easy to set up with Gunicorn and nginx, all running in Docker

Is there any definite tutorial to set it up with Gunicorn and ngnix? I have used gunicorn before but not with ngnix.

Same setup as the other reply. Gunicorn and flask in docker. Works perfectly and is speedy.

Love Flask in theory. My biggest complaint was trying to do user management with it. Flask-Security was good, but the developer skipped town a few years ago. Did they come back? :D

Basically you are left to your own devices, which sounds great, but user+auth is pretty fundamental to be left to a random absentee third-party in my opinion.

I was disappointed to see Flask-Security and Flask-Principal are now abandoned. We went with Flask-Allows for security at my job. It’s actively maintained with a simple API. Handles the requirements of our Flask-based ERP really well.

Yet no Flask application I've ever written needed user auth :)

Indeed, its a risky choice for that.

Try farming out the auth to a middleware. That's what I do and it works really well.

Does it interface with sqlalchemy, onboarding, email, etc?

Your auth middleware can attach a user object to environ that your downstream apps could reference.

Whatever else you do (email, onboarding, sqlalchemy) you can do downstream, or directly in the (or a different ) middleware if you want.

Like openam? or what do you suggest.

Check out Flask-User. It's a lot like the user auth in Django. Developer still around.

Believe it is a part. I mentioned user+auth, but there is commonly a lot more around that for a typical sass app. Registration, password-reset, just to name two.

Awesome news! I am sad to see you leave Zero Versioning though. [1]

[1] https://0ver.org/#notable-zerover-projects

Why is Zero Versioning a good idea?

I believe the parent comment and ZeroVer are tongue-in-cheek. Reading through the site brings Poe's Law to mind.

Was it the literal link to https://en.wikipedia.org/wiki/Poe%27s_law on https://0ver.org/about.html ? :P

Countless people are already using 0ver, and always will. In other words, 0ver.org is descriptive, not prescriptive.

We (a big newspaper - 5k-10k visitors at any time) run on Flask. Quite a big application.

It was the biggest reason why I choose this job, as many python shops seem to run Django which I'm not a fan of.

Flash was the first backend framework I really understood. It was very easy to get started with. I no longer use it but it made it so easy to learn web development.

Is there a good "zero config" application server for Flask that is considered standard now? I absolutely loved building an app with Flask but I rememeber deployment being a pain.

PythonAnywhere isn't zero config, but pretty easy in my experience: https://help.pythonanywhere.com/pages/Flask/

Flask is an absolutely amazing experience for small-mid sized projects. You have to hand roll and pull in things for bigger projects, but I think it's great when you want "just what I need and nothing extra".

I'd be curious to see some sort of flask "bundles" that would allow it to make more sense for large-scale projects.

https://github.com/hack4impact/flask-base is an incredible boilerplate for Flask, I use it for every projects ! Lots of basic web stuff included, user management, redis queue for asynchronous tasks etc..

Every non-trivial Flask projects aims to become Django.

This has been my observation as well. It also seems that a lot of teams that do that are kind of snooty about Django, not realising that they've essentially invented a worse version of it.

I can't speak to large apps, but it sure is nice for rapid prototypes. I wanted to play with the Twilio API the other day, and it make things really easy: https://github.com/e-ht/89memes

This[0] is a pretty good starting point. The organisation of modules as well as the swagger documentation provides a pretty good insight about what can be done in flask. Out of curiosity, is it possible to change a few tags in the swagger doc that one gets to see in the browser? I would like to take a few tags out. I looked it up for spring and the process was pretty daunting.


Awesome news. Time to update my project templates.

wow, lot of Flask haters here.

I personally love it and have used it for a ton of smaller projects. For example, I just deployed this a couple days ago: http://dadjoke.info

FYI your home page refers to "DadJokeJunkie.com promises not to spam you or share your number and you can opt out at any time." but that is not your site :P

Yeah, I know. Was having problems with the domain and bought the .info to just make it work. Once I have a couple minutes, I'll make it work with the other

Another website built 100% with Flask: https://wakatime.com

Flask has scaled very well and never run into Django dead-ends, like where Django isn't flexible enough to do something and requires a hack.

Your website looks sleek. Hope dad joke newsletter business goes well for you.

Thanks, this will probably be a net-negative on my part, but was a fun project to work on. It stemmed from a hack day I had at work

Maybe add Telegram/FB Messenger support? US numbers only is a bit restrictive

Not a bad idea! That was I wouldn't have to pay non-US SMS rates.

US numbers only :(

I know:(, sorry. Reason is I'm using Twilio for the text messages and non-US numbers are really expensive. Since I'm not trying to monetize it I want to make sure that I am able to fund it out of my pocket.

I don't know about non-US numbers, but you can send text messages via email for free. You can usually do that by sending the email to the user's number at their provider. There are sites on the internet that will give you the user's provider from the phone number.

For example, a user who has AT&T can receive a text by emailing it to <phonenumber>@txt.att.net.


People always talk about scaling large apps with Flask or Django, but I think that misses the point. If your app gets large enough it will inevitably start to go its own way. The point of these libraries is that lets you do a hell of a lot really quickly.

I'm someone who quit web programming in around 2008 while IE6 was still a thing. I used to write PHP without a framework. As someone just getting back into it, Django and Flask or downright magical. I can do so much so quickly that would have taken days to do before. With Flask-RESTful you can turn some code into a microservice in about 10 minutes.

For me, this is what makes these libraries great, not that they will fit every need of every app ever.

I don't understand why use Flask instead of Django, I usually work with a lot of crud systems, I think that Django is the best option to do it. I think that Django is better because it has an autogenerated admin site and this is really helpful when you work with the customers, they can easily populate the database while you work in the logic

Django is pretty good at that! I think we usually try to compare frameworks to an extreme when partly it boils down to the type problem and the developer preferences.

Django was the main reason I started with Python. Really loved it more than Wordpress or Rails. However, Flask is just much simpler to get started. So nowadays, where I mostly have to achieve the most bang for a given set of bucks I usually choose Flask.

I have worked with the Django some, but not a lot, but I always find the admin site a bit frustrating and hard to configure and style. Maybe it's just my lack of knowledge and experience about Django, but it often times seems faster to generate a crud admin interface in many other frameworks like asp.net.

Otherwise I am a big fan of Django, I think it is possibly the best web dev framework out there even if I work in asp.net for most of the time.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact