Hacker News new | past | comments | ask | show | jobs | submit login
Discover Flask (discoverflask.com)
247 points by rkda on Feb 21, 2016 | hide | past | favorite | 75 comments

It's interesting (exciting) to see all of the excitement about Python frameworks on HN lately. I've used both Flask and Django extensively, and highly recommend them.

I used to be on the Flask "micro-framework" bandwagon...until I realized that almost everything I was integrating into Flask was already included in Django (e.g. a test suite, an ORM, database migrations, authentication, an admin interface, etc.). Don't get me wrong; I love Flask. It launched me into web development with Python at a time when Django only confused me. But I just can't justify using Flask for a big project anymore when Django is just so much faster to work with (for me). If I need to, I can customize nearly any part of Django I want, store it as a project template, and use `django-admin startproject myproject --template="https://sometemplate.com/in/a/git/repo.git" ` to start a new project with it.

This is mostly true if your application is mostly CRUD with HTML endpoints (the use case Django was designed for), particularly very "solved" use cases like blogs.

(As an aside, for very crud-heavy applications that are client-heavy with primarily JSON data endpoints, I suggest using PostgREST if possible. It is almost certainly going to be better than any CRUD API you produce yourself)

If your application is mostly endpoints that do "interesting" stuff, you aren't going to hit much of the Django infrastructure, and piece you are most likely to hit (the ORM) is so far behind the dominant Python ORM (SQLAlchemy) that it is just painful.

Flask is a lot better at getting "out of your way" than Django. The main problem I see with flask is that it isn't obvious to people picking up the library the right way to structure and scale an application code base.

> The main problem I see with flask is that it isn't obvious to people picking up the library the right way to structure and scale an application code base.

I wholeheartedly agree! Do you have any resources in mind (even perhaps not specific to flask) that you think would be useful to people hitting that wall?

> I used to be on the Flask "micro-framework" bandwagon...until I realized that almost everything I was integrating into Flask was already included in Django

This exactly. Every site I've attempted to build in Flask ends up having so many dependencies for even the simplest of things. I shouldn't have to go and find what the most popular recent library for each aspect is (even if they are out there and are great). Once you learn Django, it's just so much faster to work in from the maturity of the framework itself to the docs to the community.

That said I do have one project today I keep in Flask. It's a small personal website which serves a few templated pages, has a very small content database, and just a couple API endpoints used privately. In all it may be a couple hundred lines of code.

Django is cool, and has been my choice for a fair number of projects. Although recently I had an interesting experience with it when I wanted to use websockets (yes, I know it's not written for that use case).

It was stunning that most of the solutions out there rely on some sort of a hack to get it working. I ended up porting over my project to Tornado, because I need websockets for a lot of the features I'm working on. And it worked out really well, especially after I combined it with SQLAlchemy and Alembic. 80% of the feature set right there. And SQLAlchemy is such a fantastic toolkit.

I'm hoping that django channels (http://channels.readthedocs.org/en/latest/) stabilizes soon.

I prefer to split a server app into a connection management layer and a backend logic layer. This way the backend can remain stateless which makes for easier maintenance. I use Django as the backend piece in most of my realtime apps (for example WebhookInbox) and it works great.

Of course, native support for long-lived connections in Django would be cool, if only because it would mean the connection management layer could be built with Django too.

The Django community knows full well that this is a missing feature in modern web development. There was a talk featuring this topic at DUTH this fall. https://opbeat.com/events/duth/#twisted-and-django

The whole "WSGI revision" effort is intended to solve the problem of websockets (and HTTP 2.0) across frameworks and servers.

Interestingly, I went the other way around, did a toy project with django, hated the ORM, didn't like the template so much, and at the tolime django didn't support python 3. I then discovered bottlepy sqlalchemy base (so I write raw SQL, but I can easily switch database underneath), and mako templates, and was in a much better place.

I have also worked in flask environments, flask does have the advantage of having a bigger plugin ecosystem, and a bigger network effect (way more users!), which translate in more recipes, entries on SO, etc...

I work with both Django and Flask too. The difference is that with Flask you have the flexibility of doing things your way. Useful for systems that don't fit the typical CRUD architecture.

I won't disagree when it comes to authentication and admin interface, but test suites (pytest), an ORM (SQLAlchemy), and migrations (Alembic) are not very hard to set up. Furthermore, you can use them in other non-frameworked projects.

Of course, it's hard to build something like an authentication/admin interface framework without there being some standardized ORM/migration system, so the argument is more or less moot.

If Django replaced their very limited ORM for SQLAlchemy, I'd agree.

There are just so many apps that end up requiring queries complex enough that with the Django ORM you have to resort to raw SQL. With SQLAlchemy, you can express any SQL you want without giving up composition.

Can you give an example for a thing where with the Django ORM you have to resort to raw SQL?

Conditional aggregates were a problem until 1.8 or 1.9. Joins on more that one field would be another.

Arbitrary explicit joins make a lot of data reporting much easier.

Why not just use SQLAlchemy with Django and ignore the built-in ORM?

Because the Admin and other features won't work?

In order to get the admin and other features, all you need to do is define your models in Django's system.

After that you can use SqlAlechemy as a side channel, just like a lot of people use NoSQL databases.

Yes I couldn't agree more. I've used both Flask and Django, and with Flask you just recreate everything in Django. Plus the Django community is more vibrant and the Django docs are super good.

This is mostly my experience as somewhat of a newbie. Every project I contemplate needs user accounts and admin. And db access & migrations make development so much easier. I guess if there was a solid recommendation on what Flask components/addons would be good to use for a "regular" web site, Id be OK. Otherwise, it ends up being so much more comfortable to go "full stack".

Great job. I recommend Flask to everyone who wants a clean and modern framework that is simple to use and manage/deploy.

I'm also planning to write a series on how to build a simple SAAS with flask, hope some will find that interesting.

Flask is using globals everywhere, and for very long time did not support Python 3.x.

Although most of the methods are globally bound to the current request, Flask is thread safe and I can't see any problem with it. (except that it encourages beginners to use globals, which might be process and thread-unsafe).

I really don't see any benefit or sense in the Flask way of exposing request state through imported globals. It makes testing of views unnecessarily complex: you have to either patch the import or set up the thread local context in every test. And like you mentioned, it encourages unnecessary coupling.

It would be so much simpler to just have a request argument passed to each view.

But then you have to explicitly pass the context to everything you call.

Dynamic scoping would solve this problem (and similar problems, like dependency injection), but Python doesn't have that.

Flasks way emulates it as well as possible.

Great work, but in my opinion using Flask for full-stack, end-to-end web development is wrong. A microframework should never be used as an end-all-be-all. By the time you're done you've added god knows how many external dependencies and bits of homegrown code to support "standard" features such as authentication, forms, etc. that are part of a proper full-stack (read: not micro) web framework. In this case, something like Django would be much more suitable because by the time you've finished this Flask tutorial you've basically implemented key parts of the Django standard library.

I found it very strange that the domain (discoverflask.com) is just a redirection to the Github repository.

Anyway, great content for Flask beginner. It's a wonderful framework for anybody wanting to write clean APIs and it's this kind of content that makes the community awesome.

I've done that redirect-to-github thing in the past. Usually, the intention is that the redirect is intended to be a temporary placeholder until I can create a "real" site at the domain.

I've been very happy with Bottle. http://bottlepy.org Pretty similar, but lighter.

Glad to see Bottle is still alive. I contributed to it a tiny bit a few years back, and it was definitely a fun too. I ended up moving to Flask because the larger community and wider set of plugins and tutorials.

And here's a link to the Vagrant instance


Great work. I'll definitely look into this one

Thanks! :)

This is great. For anyone interested in learning further, this is basically considered the Flask bible:


If the owner of the repo drops by, I'd just like to say thank you for pulling all this together. Side note, I'm definitely more of a fan of the blog post tutorials like with the first 2. It's nice to be able to easily skim through for what you need, the documentation is also nice and condensed like cliff notes of the actual documentation. I also like how it's accompanied by the videos too though, so if you're looking for a little more detail you can go check out the video really quick to see what other side comments or pointers are made in the vid. Yes one can just look at the documentation, especially with how great the Flask documentation is, but sometimes it's just easier to check it these tutorial styled helpers since they have certain objectives and extra commentary.

I've played with a bunch of Python web frameworks and amongst the micro-frameworks, Flask is the one I've settled on. Larger community, more integration with other packages.

I've also recently been using Django, and I'd say the biggest advantage of Flask is simplicity.

When you get to something the scale of Django, there's a whole load of decisions and culture baked into the approach, and you have to learn that in order to use it.

For small projects, I'd recommend Flask.

After reading some comments pinning Flask and Django for "big" projects, I feel compelled to write my own experience.

Flask is a micro-framework, but it's not a toy framework (anymore). I've used it professionally for all web related projects big and small for the last 4 years with great success. I wholeheartedly recommend it. It's not for everybody though, as one can attest by various comments lamenting its minimalist approach. Things that attract someone like me who likes a certain degree of control on how my tools are set up and work, may be the same that repulse someone else more concerned with having everything available in the kitchen sink.

When I moved to Python for web development Django was the most common recommendation. I had toyed with it a bit previously and considered settling for it. Amid the raves though were a few complains that gave me pause, most coming from experienced Python programmers. A common remark was that as time went and as they evolved with the framework, it wasn't uncommon to swap parts out of it for external libraries. SQLAlchemy, WTForms, Jinja2. In some case basically ending with only the routing module and the admin. Which raised the question of the relevance of using a full-stack framework not necessarily designed with interchangeability in mind, if you end up just using it like a glue mini-framework. Having worked with full-stack frameworks before I identified with the highlighted pain points and Flask became very attractive. I picked it up for a first project and never looked back. It's been over 4 years now. It's entirely possible that I'm missing out by not working with something more like Django, although I doubt it very much.

Flask itself is small, made of bits of the Werkzeug WSGI toolkit and the Jinja2 template engine. It's simple in concept, simple to set up, and simple to use, but anyone who's been developing with it for anything more than basic projects (static sites, microblogs, etc) knows that to do more complicated stuff than displaying template pages you will need to add some dependencies (as it should be). You can do it the old-fashion Python way, by simply importing modules and working with them, or you can install an extension. There's currently a great variety of extensions, the official list is here http://flask.pocoo.org/extensions/, with lots more available from Github and PyPI. Furthermore it's dead simple to make your own if you're not satisfied with the offering. All of this is probably the reason why 5+ years after its creation you see a good number of guidelines on how to work with it for ambitious web projects.

I haven't checked the quality, but I love the idea and presentation. This is an awesome way to approach showing people how to build fullstack websites in any framework or language to advanced beginner or intermediate programmers.

As someone who procrastinates on their own blog to teach people this topic, this is going to inspire my direction a lot.

I don't know anything of flask or python really. Is Flask in python 2 or 3? Do I go learn python 2.7 right now or Python 3? Is stuff broken the the eco system. Does it make sense moving over from JavaScript for easier backend CRUD'ish app's? Thanks HN.

Python 2.7 will be around for a while due to legacy code, but it's only a matter of time before Python 3.x is more widely used. Don't invest time learning skills that will only dwindle in value.

Some stuff is broken in the ecosystem. That's true of all ecosystems. If you're coming from the JS world it's far, far better. But if you are importing every 0.x versioned library that vaguely solves a problem close to your problem, no ecosystem will save you.

Python is a solid choice of language for the back ends of web applications.

> Python is a solid choice of language for the back ends of web applications.

With caution advised when it comes to scaling. You might, or might not, pay a pretty hefty premium in the amount of hardware needed.

You can always rewrite it if needed. A tactical rewrite of specific heavily-used routes that cuts out unnecessary abstractions often doesn't take too long and gets most of the benefit.

I can't see even a slow interpreted language being unable to process 100 requests/second. That leaves like 40 million clock cycles per request. Especially since they tend to come with built-in bytecode compilers, and most of the pure algorithmic code is written in C. Most web requests just don't take that much work to answer.

Most performance issues I see with web applications are somebody writing ORMTable->find(x) in a loop or the equivalent, and then papering it over with a cache(or 3). Or memory leaks. Or badly-written SQL queries(no index, too many indices, disabling seq scans, using CTEs to elegantly 'refactor' SQL, etc.). Or doing blocking calculations/service requests as part of the original web request. The underlying language is almost never what's holding them back.

In addition to the things other people have mentioned, you also have the ability to easily call C code from python (compared to the unpleasantness that is JNI, for instance), and there are tools like Cython, Numba, Blaze, etc that let you rewrite your hot code into a more performant variant.

Of course, at megascale these optimizations might still not be sufficient, but there is no reason you can't deliver hundreds of thousands of requests per second very affordably with a python stack.

I don't want to come across as a Python zealot here, but in my experience, Python has almost never been the problem in scaling. Certainly not to the extent where I would say that it costs a premium in hardware. Though, I suppose it depends on the application.

My experience has been that Python will give you more than enough rope to hang yourself with, and lots of apps that are meant to scale have some homegrown crap of an architecture, or people try to get fancy when they don't need to and try to write go or scala in Python.

If you have a clear understanding of your data model, Python backends scale quite well vertically. Run one instance of your app per core you have available and use IPTables to round robin (or whatever. you can get fancier if you feel like it) to each app instance. Boom. You are now banging on all 4 or 8 or however many cores your server has without the context switch overhead of the multiprocessing module and also without the headaches that go along with the shared memory space of the multithreading libs. Not to mention cleaner, nicer code.

If you build your product to work well in this way, then scaling horizontally also becomes a non-issue as far as Python code is concerned. You just put haproxy in front of multiple machines, set up health checks, and for the vast majority of use cases, you're done until you need to scale the storage horizontally. Then you have some serious decisions to make. But that's a different topic.

But back to my original point: every case where I've seen Python being all slow has really been an artifact of a crap architecture, or bolting on crap front end frameworks, or depending too much on an ORM like SQLAlchemy without really understanding your data and depending on it to do everything for you instead of thinking rationally about what your data is. Or some combination of all three above.

Yes, I know that there are languages that execute much faster than Python. I work with C#/.NET/SQL Server almost as much as I use the Python/Pyramid/PostgreSQL stack. I can write a crappy, slow, messy architecture on either stack. And in fact, when I was first getting to know C# and still writing Python code in that language, I did that.

The bottom line is that if you understand the strengths, weaknesses, and idioms of the language you are working with right now, almost every high-level language in common use today is sufficient for massive-scale deployments for the most common types of web apps. Heavy computing or scientific purposes obviously excepted. But most web apps that scale to hundreds of millions of users are basically "window-on-data" type applications.

I can't really think of a case where some other language besides Python would be noticeably cheaper hardware-wise.

Maybe you have to know your entire stack a bit better if you want scalable Python apps, maybe you have to do a little more Jiggery-Pokery with your Linux servers, but if you are serving at massive scale, you are going to have to go there anyway, especially when you start dealing with storage. That's part of the game.

> Run one instance of your app per core you have available and use IPTables to round robin (or whatever. you can get fancier if you feel like it) to each app instance.

But if you're using Flask and you have 4 cores with 4 instances, and you're making 4 database requests at the same time you're whole application is suddenly locked. And it's not uncommon for a single view to make up to 4 separate database requests. Most modern web applications are I/O bound, therefore a single Node.js process would have better performance here.

Wait, in PROD, you don't use Python as the server, you stick uWSGI in front of python/flask, that will deal with the network I/O limitation.

How does uWSGI help here? The OP recommended running 4 instances of Flask/Python, and with uWSGI you still have 4 instances. It doesn't help with I/O.

Because with uWSGI you can mix a number of threads and processes (recommended because more processes than cores wastes time with context switches, and a low number of threads per process is a waste of cycle. uWSGi is an event loop (not unlike node) which makes dispatching requests to threads and processes very easy.

It has not been my experience that web applications are I/O bound using typical architectures in Python. I think you would have a very hard time arguing that Node.JS is more performance than nginx.

"It has not been my experience that web applications are I/O bound using typical architectures in Python."

Okay, my experience differs. Most modern web applications are relatively lightweight, and are mostly "proxies" or thin wrappers between the load balancer and the database.

That's exactly the kind of apps I usually write, and nginx is fast enough that the DB is typically the bottleneck. In rare cases I've run into CPU as the bottleneck for computationally intensive tasks. If I/O is your bottleneck, then that indicates to me that Node.JS is actually performing worse for you on I/O than nginx is for me.

That hasn't been my experience. If your ACLs are set up properly, you won't encounter a full table lock, and therefore won't have problems like you described.

I agree that this could be a problem in theory. In practice, it has not been. Again, it boils down to how you architect your code.

EDIT: you need to stick your sessions to a specific instance. Otherwise, you are correct that there's a problem. But as long as you stick your sessions, there's no problem with a database lock.

I wasn't talking about database locks. My point was that making a database request takes a really long time relative to processing a request in the web application. Therefore the web application spends most of the time doing nothing and waiting for the database request to complete.

So, write data-backed applications without calling a database?

Not sure what you are getting at here.

If you are talking about the raw scalability of your database, yes, you are correct. The speed with which you are able to get info from your DB will be a limiting factor.

But that's a totally different point than the one I was making, which was about how to scale Python, not your database.

If I understand you correctly, the time spent in retrieving stuff from your database will be a limiting factor no matter what language you are using. The DB I/O will eventually limit C# or go or node.js or whatever. I really don't see how this is relevant.

But since you brought it up, you can really cut down on data access times by relying less on ORMs and getting your fingers dirty with stored procedures and building tables that make sense to SQL instead of pretending everything in your RDBMS is a class.

Node.js can asynchronously make multiple (i.e. hundreds) database requests without locking the instance.

Why do you believe four requests from python would lock a database but hundreds from js wouldn't?

> it's only a matter of time before Python 3.x is more widely used

I've been hearing that for a long time...

You can use Flask with either Python 2 or Python 3. I personally use Python 3 for everything, so I can't comment on packages that don't work in Python 2.

Any experience with meteor vs flask and if its worth going through one or the other these days. Flask seems better hooked up to Postgres than meteor and having weird stuff with mongo but I'm still new to backend.

I would choose Flask over Meteor any day. JavaScript is the unholy union of various browsers introducing hacks which are then standardized by committee. Considering that's the design process, it actually is pretty well done. But there's no reason to inflict JavaScript on yourself when you can use a language with a coherent design.

I haven't used meteor, but I have used a few other JS frameworks and libraries on the backend. My major criticisms of JS on the back end are: they like magic, in that they tend to decouple code to the point that there's no way to trace the code. Instead, pieces are structured and tied together by convention, i.e. thingController goes with thingModel, and stuffController goes with stuffModel. It creates terse code, but a) if you need to do anything slightly unique (and you will) you're screwed, b) it's a huge pain to debug and trace because you can't just read function calls, and c) since the JS world doesn't care about reverse compatibility, you have to always know when the convention changes, and if you fall a few versions behind, you're basically stuck there. In particular, Ember.JS gave me PTSD. Meteor may avoid some of these issues, but when I evaluated it a while back it didn't seem like it did.

reframing the question to "python vs. node" on the server-side, the answer seems very dependent on the use-case. there's not (to my knowledge?) much agreement in the python community about how to compile to javascript, much less regarding an ecosystem of client-side libraries. if a rich client-side that shares logic with the server-side is part of the story, i don't think python is a good choice. i wonder if the Django project could do anything a/b this or if it's too big a chunk to bite off?

all that aside, i like Flask a whole lot. Proxy objects are brilliant, and i wouldn't be surprised if koa.js was partially influenced by Flask. i'm considering going back and fiddling w/ Sinatra for the project after next as i'm given to understand that it was a partial inspiration for Flask's routing.

all in all, there's a lot of cross-pollination. i suppose jquery + html -> frontend framework (angular, marionette, etc.) -> express.js + sequelize/bookshelf -> Flask + SQLAlchemy would be a pretty smooth transition w/ lots of docs, stack overflow, community, and sample code to help out.

I don't think many python devs are espousing Python for the client side. I use react/underscore/Jasmine/sinon with ES6 run through Babelify for the client side.

Sharing logic between client and server side means that your client and server side don't have clearly-defined responsibilities. The one exception to this might be input syntax validation, but generally that's a place where you don't want to roll your own anyway.

idk, could imagine wanting computation to run on the client when it's a desktop (to save server cycles) or the server when it's mobile (to save battery)... not a level of optimization i practically run into, but not an unreasonable example.

i guess a better thing to say is "exactly": specs often change and responsibility gets shifted around. so "runs everywhere" can be useful, whether it be js or otherwise.

I disagree, that's a totally unreasonable example. Not only is that a bizarre combination of requirements, but that's not a good way to approach meeting those requirements. I'd write the code to run on the server and then profile and optimize on the server. JavaScript if never going to outperform hot spots rewritten in C.

You're forgetting the first rule of optimization: profile.

> But there's no reason to inflict JavaScript on yourself when you can use a language with a coherent design.

JavaScript has a coherent design specially if you're using ES6+ in strict mode with a linter. Modern JavaScript is a great language, and comparable to Python.

I'm using ES6 in strict mode with a linter and Babelify to transpile for browser compatibility and I stand by what I said. I've been writing JavaScript since there was JavaScript to write, and the situation has improved drastically, but JavaScript is still far from being a coherently designed language.

Most people will tell you they're using 2.7 in production.

Because of legacy, but these days there is no reason not to use python 3 on new projects. Note that Python 2.x will no longer be supported in 2020.

New projects depends on that legacy - in form of existing libraries. So, one may find themselves writing somewhat more code than they had expected, either as a new libraries or patching the existing ones to work with Python 3.

Well, not that doing so is a bad thing - it's the contrary, esp. if the patch goes to the upstream - but still this may be frustrating to some.

(Most common libraries are actually work pretty well with Python 3. But there are still a lot of stuff PyPI that's Python 2-only at the moment.)

This used to be an issue, but, in the past 2 years pretty much all the most used libraries have added a python 3 version.

I wish I could say this about our dependencies but it's not quite true yet.

I do run our requirements.txt through https://caniusepython3.com every few months though.

There are a good amount of dependencies that haven't been ported to 3 yet. Using one of these directly, or as a secondary dependency, is the reason running 3 in prod is impractical for many of us.


So, ndg-httpsclient, mrjob, numpy, scrapy, monotonic and possibly others do have python3 compatibility.

Then there's a bunch of deployment tools like ansible, fabric, and marionette which don't really need to be python3 compatible for use.

Then there's tools like MySQL-python, python-gflags, python-cjson, INITools, filechunkio, which have python3 compatible alternatives, often in the standard library.

That brings the total up to 331

That leaves basically 3 categories of things left: mozilla tools, database connectors (many of which probably have python3 bindings though I haven't looked), and single sign on tools. Those account for 12 of the remaining 29 libraries.

That's pretty ready.

Great documentation set-out.

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