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 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.
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.
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.
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.
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).
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!
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.
> 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)
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.
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.
> 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 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?
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.
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 (!!!).
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.
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
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.
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.
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 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.