Hacker News new | past | comments | ask | show | jobs | submit login
Flask 0.7 Released (Python Web Framework) (pocoo.org)
173 points by hiddenbayes on June 28, 2011 | hide | past | favorite | 77 comments



Flask is awesome and can be easily supercharged by pairing it with Paste Deploy: http://pythonpaste.org/deploy

This way you get Flask simplicity and elegance, but also you get Rails-like separation of configuration test/development/production environments.

Another misconception people seem to have is that Flask means Jinja2. Fortunately that's not the case, swapping Jinja with Mako is also extremely easy.

Finally, Flask can run on top of any WSGI server, not just a built-in one: at http://mailgun.net we have Flask services running on Tornado and on Paster servers - the thing is rock solid.


I notice that several projects (including Flask) do not build in support for DB schema management- e.g. migrations.

For those of you who are writing apps in Flask, how do you guys manage changes in DB schema ?


I don't use Flask, but sqlalchemy. If you want an orm in a flask-based app, you will most probably end up using sqlalchemy, and there is a migration tool for sqlalchemy: http://code.google.com/p/sqlalchemy-migrate/


Flask has become my framework of choice because it's incredibly well designed, the code is clean, and also because it's decoupled from an ORM.

Rails and Django emerged at a time when RDBMS ruled, and they were both built around an ORM. Now you have more database options that have less of an impedance mismatch, but because Rails and Django are so ORM-centric, forgoing the RDBMS in favor of another option means you now have a framework mismatch.

Graphs are a much more elegant way of storing relational data. With graph databases you don't have to mess with tables or joins -- everything is explicitly joined.

For most Web development projects, I have shifted from a relational database to a graph database as the primary datastore, and use Redis, Memcached, and MongoDB for specialized purposes when called for.

Neo4j Community Edition (http://neo4j.org/) is open source and now free, and pairing it with the TinkerPop stack (http://www.tinkerpop.com/) is ideal.

With Neo4j you can now store 32 billion nodes (http://blog.neo4j.org/2011/03/neo4j-13-abisko-lampa-m04-size...) with 2 million traversals per second (http://www.infoq.com/news/2010/02/neo4j-10), and you can use Gremlin with it (the graph traversal language), which let's you calculate PageRank in 2 lines -- to see what you can do with Gremlin, check out this 10 min screencast (http://www.youtube.com/watch?v=5wpTtEBK4-E).

For tabular data, relational databases rock. But the relational model doesn't align well with object-orientated programming so you have an ORM layer that adds complexity to your code. And with relational databases, the complexity of your schema grows with the complexity of the data.

The graph-database model simplifies much of this and makes working with the modern-day social graph so much cleaner. Graphs allow you to do powerful things like find inferences inside the data in ways that would be hard to do with relational databases.

There is an open-source Python persistence framework in the works called Bulbs that connects to Neo4j through the Rexster REST server, and there are binary bindings in the works as well. There is also a Python open-source Web development framework for graph databases called Bulbflow that is built on Bulbs and Flask, which will provide stuff like authentication and authorization, in a graph-DB way. Both frameworks should be released in the next few weeks.


Rails and Django emerged at a time when RDBMS ruled, and they were both built around an ORM. Now you have more database options that have less of an impedance mismatch, but because Rails and Django are so ORM-centric, forgoing the RDBMS in favor of another option means you now have a framework mismatch.

And Rails & Django were (at the time) also built around a specific ORM. Compare this to Catalyst, which also came out same time as Rails & Django, was built from the ground up with an agnostic model and thus could use any ORM available or easily adapt to different data models.


Flask doesn't have any sort of database interaction built in. You do it all with the more general Python tools. SQLAlchemy is a common ORM for Flask, probably because of the Flask-SQLAlchemy extension. I've never done any migrations with Flask, but I would think http://code.google.com/p/sqlalchemy-migrate/ could do it.


I might be a little old school but I wouldn't seriously let a complicated system take care of schema migrations for me. Well, actually I do (in a system unrelated to Rails or Flask) and it's a mess.

For my current side-project, I'm actually building a thin ORM layer that basically handles migrations through hand-written SQL scripts.


I'm always impressed by Flask - especially its documentation. In fact, this seems like a good occasion to have a poke around and build something with it.

On a slightly related note - although jinja2 is already quite compact, I'm a fan of haml and I'm always surprised by the lack of support for it in Python. Is there something I'm missing? Uncanny valley for Pythonistas?


There's hamlish-jinja which is a preprocessor for haml-like[1] syntax for Jinja.

The project with the most traction seems to be HamlPy[2], but it's limited to Django templates.

The only generic implementation of Haml in Python that I'm aware of is PyHAML[3], but I have never used it.

[1] https://github.com/Pitmairen/hamlish-jinja [2] https://github.com/jessemiller/HamlPy [3] https://github.com/mikeboers/PyHAML


There's a Nemo[1] a "pythonic haml". It doesn't follow the Haml spec exactly, but rather tries to take the good parts and apply them to something suitable for Pythonistas.

It's built over Mako templates, so its faster and far more flexible than one built against the Django template markup.

[1] https://github.com/9cloud/Nemo


This is much better than what I found last time I went looking, thanks. I think I need to roll up my sleeves and dig deeper... Being able to mutate the templates to suit what I usually might build seems cool (but a big time sink!).


You can roll out your own or use one of the existing translators which translate from haml to jinja2 syntax.

Do you use slim templates? I recently wrote a hand rolled recursive decent parser which translates slim to jinja2 - https://github.com/thoughtnirvana/slimish-jinja2. Jinja2 supports extensions and after adding this extension, you can write slim templates which will be translated to jinja2 on the run.

The lexer and parser are simple enough - you can make code changes or roll out your own if you want to.


Interesting. Seems I haven't grasped the flexibility of jinja. I'll look into this, thanks.


There was a Haml-like language called GHRML a while back, but it seems to have disappeared. There is something like it called SHPAML: http://shpaml.webfactional.com/

Though I think Ruby has better markup libraries in general. For example, they have Nokogiri, which is an absolute joy to use for XML parsing. And implementations of Markdown and Textile with actual parsers, whereas Python Markdown and Python Textile are straight regex-using ports of the Perl/PHP versions. It's kinda sad really.


To learn Ruby I decided to redo my website in it, and I felt the complete opposite. I was surprised there's nothing comparable in the Ruby world to Jinja2 or Mako. Nothing supports blocks/macros or template inheritance, so I wrote my own small template engine in Ruby that does.


Check out Pantyshot/Upskirt for Markdown, it's worked out pretty well for me.


XML parsing: lxml (lxml.html is particularly wonderful).

Markdown/Textile; in the Python world people mostly use Restructured Text, not least because of its privileged position in docstrings.


python-markdown is in no way port of perl version. It's complete parser which can be extended and so on. But python-markdown2 is port of perl version, based on regexps instead of being real parser.


Of particular interest are the generic or 'pluggable' class-based views. They work in a very similar manner to the ones that came with Django 1.3.

http://flask.pocoo.org/docs/views/

It's good timing; I was just getting to the stage in my app where I was noticing the need for some view refactoring.


Same for me. Class-based views were basically the only thing I missed from django for my particular app.


Right now, I'm writing most of my projects in Tornado.. Not because I need the async, but because I wanted a simple web.py like format that was under active development.

Can someone help me understand where Flask fits into things? It would essentially be a replacement for Tornado? What's the advantage of this over Tornado? Ease of use?

I can understand the simplicity argument; I chose to avoid Django because it was too heavy, so I'd love to hear more about how Flask compares.


Tornado is batteries included. Flask uses Werkzeug and Jinja2 and encourages packaging extensions for localization, form processing, ORM's etc.. Flask, Werkzeug and Jinja2 are all Pocoo projects that have a good community around them and excellent documentation. Technically I would not like to argue the superiority of either, although Flask seems to fit my tastes much better.

Flask's use and deployment of "magic" is pretty spot on. For example by making the request object omnipresent (that is flask.request is always bound and has the right context). That way it is not passed around the MVC stack but just imported and introspected when needed.

Flask is probably the "healthiest" project I've encountered.


Why would it be good to avoid passing around the request object?


Armin explains the request object here (http://flask.pocoo.org/docs/reqcontext/) and here (http://flask.pocoo.org/docs/quickstart/#id4), and the concept of "context locals" in detail here (http://werkzeug.pocoo.org/docs/local/).


Can someone help me understand where Flask fits into things? It would essentially be a replacement for Tornado? What's the advantage of this over Tornado? Ease of use?

Pretty much yes to all of this.

I can understand the simplicity argument; I chose to avoid Django because it was too heavy, so I'd love to hear more about how Flask compares.

Flask "feels" more like CherryPy than Django to me, but yes, it's more lightweight than Django and more modular (doesn't define an ORM, etc).

The thing that keeps me from using Flask for any serious work is Django's admin interface. That thing saves me ridiculous amounts of time.


Couldn't you use inspectdb to introspect your Flask database and use Django's admin that way? You'd have to remember to do it every time you changed your database; but it'd probably get you most of the way there.


>You'd have to remember to do it every time you changed your database;

That's probably why he just finds it easier to use django.


I don't disagree with that sentiment for use during development; but for a long-lived application I don't think it's nearly as big a deal.

I don't know about you, but I've personally found that after a few months of working on an application the models tend to be pretty stable.


For a web framework(non async run of the mill), I would say Flask has an edge. My Flask stack is:

1. SQLAlchemy for ORM.

2. Jinja2 for templates (flask default).

3. Flask for basic web framework functionality.

4. WTForm for forms.

5. Other extensions as needed.

Flask itself is built on werkzeug which is a clean, high-level wrapper over WSGI. Basically Flask is assembling working components into coherent applications. I have done some applications in flask and I can say it's suited for applications of all size.

Tornado, on the other hand, implements its own templating and orm.


Tornado doesn't have any orm, it only has a very thin wrapper around MySQLdb.


Flask is a simple web.py-like framework that is under active development, and I would argue it's one of the cleanest Python Web frameworks (if not the cleanest) out there.

My current project requires real-time stuff so I started to develop it using Tornado and then decided to switch to the Quora model -- use a traditional Web framework for most things, and connect back to Tornado for the real-time stuff.

Quora uses Pylons, but Pylons reached its end-of-life with 1.0, and it's now Pyramid, which is really repoze.bfd and shares no code with Pylons 1.0.

So I swapped out Pylons for Flask and use Sockeit.IO (http://socket.io/) to connect back to Torando for real-time connections.

In addition to just being really-well designed, Flask has an amazing debugger that makes me more productive, and it's easier to write unittests for Flask because you can write them in a traditional way and don't have to contend with Tornado's IOLoop.

When I switched to this model, the development process sped up considerably.

For real-time stuff, you could forgo Tornado all together and instead use gevent to deploy your Flask app (http://flask.pocoo.org/docs/deploying/others/#gevent), like some have done with Django and Pyramid (http://blog.abourget.net/2011/3/17/new-and-hot-part-4-pyrami...), but I haven't tried this yet.


BTW: Charlie Cheever, one of Quora's founders, recently said they would have considered Flask if it had been released by the time they were setting things up (http://www.quora.com/Why-did-Quora-choose-to-develop-in-Pylo...).


You can actually use Flask from within Tornado's WSGI adapter.

http://flask.pocoo.org/docs/deploying/others/

This lets your leverage Tornado's high-performance IO loop while still developing your web application using Flask.


I really enjoy Flask's simplicity (relative to Django) and light-weightness. It was the first web framework I used, actually. Armin Ronacher & team make quality products.


I actually started diving into Python a few months ago, and after a day or two into it I had already ported a feed aggregator from PHP to Python thanks to Flask: https://github.com/giu/hsr-twitterverse. I've also written a simple paste site using Flask without any headaches.

Its simplicity is just amazing, and it's really fun to work with.


The debugger is badass. I built a few simple sites with Flask year and it was the thing I wished most I could have in Rails.


Can't help you with Rails, but in case you or anyone else didn't know the Django-Extensions app adds the Flask (Werkzeug) debugger to Django projects with the run_plus command.


For Perl developers - The debugger has been ported to PSGI/Plack - http://blog.plackperl.org/2011/05/miyagawaplack-middleware-i...


I've been looking at light-weight scripting-language frameworks, any experience with Catalyst? I'm a fan of Perl.


Catalyst is a full blown MVC web framework. For light-weight (micro) web frameworks in Perl have a look at:

* Dancer (http://perldancer.org/)

* Mojolicious::Lite (http://mojolicio.us/)

* Squatting (http://p3rl.org/Squatting)

* Web::Simple (http://p3rl.org/Web::Simple)


Great, thanks for the suggestions


Thats OK.

PS. Here is a presentation doing a loose comparison between Dancer & Flask called "Dancer for Python programmers" (http://www.slideshare.net/xSawyer/perl-dancer-for-python-pro...)


Catalyst is not light weight. You would need to look at Dancer or Mojolicious for Perl equivalents.


No, sorry.



How does Flask compare to Bottle (http://bottlepy.org/docs/dev/index.html)? Any advantages/disadvantages?


Flask has more features, more and better documentation, a bigger community and ecosystem as well as more developers behind it.

Furthermore Bottle does magic that is frowned upon by some people.


Then again, I also dislike some of the magic in Flask.


We're getting rid of all the magic we can avoid. With 0.7 barely any magic is left with the notable exception of backwards compatibility.


For what reason?


Magic can come to haunt you when you get stuck. For e.g. flask has thread locals where the request variable gets populated with the current request's context dynamically.

For the most part though, Flask is very magic free and the source is small enough to quickly figure out whats going on.


Because I just dislike magic.


"does magic that is frowned upon by some people."

Can you elaborate?


I would describe it more carefully. Bottle's advantage that it's self contained and in a single file, however bottle's design also hides away the application object from you which makes it quite hard to have more than one of them. It is possible with the stacked object thing and I think they changed it even to make it possible to do what Flask did, but when Flask started at least there was a design difference there.

By now I really would like to see them merge, but Bottle wants to stick to the design idea of just having one file which Flask will never be able to do because of the dependencies.


Any reasons why they should merge if they are so different?


Merge is an excellent idea when two projects, frameworks, etc have the same goals (Not necessarily the same features). For example The Pylons Project taking BFG as is base and making Pyramid, with all the experience from Pylons community and BFG. This will make changes on both sides of the community but brings a new Framework with the possibility of improvement. I guess the idea is take the best from both frameworks y make a new one, better, with a big community, and a lot of knowledge from the previous experiences.


Consolidation of resources and talents. That is all I can think of.


An example would be that Bottle creates an application object implicitly and assumes that all resources(templates, static files, etc.) are relative to the cwd. However the WSGI specification doesn't define what the cwd points to so you have to work around that for some servers.

If you use Flask you create the application object explicitly and pass it the name of the module, relative to which Flask looks up resources.


> assumes that all resources(templates, static files, etc.)

Reading the source, I see no evidence of this.

https://github.com/defnull/bottle/blob/master/bottle.py#L161...


I must have been mistaken for static files, for templates however it is the case:

https://github.com/defnull/bottle/blob/master/bottle.py#L263...

You can override it but you would have to do that for every call to `template` or by monkey patching `TEMPLATE_PATH`.


In the big picture, I don't see having to write a wrapper function for template rendering with a fixed template_lookup argument being a big deal (I'm basing all of my judgments on source alone, I've only fiddled with either framework).


It's still a problem for modularity, something like Flask's blueprints are basically impossible for Bottle.


Bottle is pretty much standalone. Flask requires Jinja2 just to function, for instance.

Bottle runs on Python 2.5+ and on Python 3.x.


I've used it for small side-projects and liked it. What I would like to know is how to do logging, both day-to-day ("user Joe created") and for debugging (like JSON dumps of objects). It should work both with the built-in server and with gunicorn, for deployment. I looked but wasn't able to find a solution that worked. The documentation mentioned logging facilities, but I found no working examples.


I believe that refers to the standard python "logging" module.


Right, but do I have to manually add a logging handler? Where does my logging.warn("...") end up?


Flask seems nice and simple until you need to access a database such as MySQL. With SQLAlchemy it seems like there's a lot more code needed just to perform simple CRUD operations, whereas Django's ORM is really simple. Is there a better alternative to SQLAlchemy? Is it possible to use Django's ORM in Flask?


Gonna answer this one myself: Seems http://www.sqlobject.org/ might be a good alternative.


I take the occasion to ask here if someone could point or write some documentation on unittest in Flask. I am trying to get that right using mongodb...


http://flask.pocoo.org/docs/testing/

For testing a MongoDB database, I wrote a simple unittest.TestCase subclass that in the setUp and tearDown, creates and then deletes a test database.


Could you put an example on pastebin or somewhere? I would really appreciate this.


Along the lines of http://flask.pocoo.org/docs/patterns/mongokit/, I have a MONGODB_DATABASE setting, which is set to my normal database name. Then access the database via the connections' dictionary syntax, instead of attribute syntax (I have a helper method to make this prettier):

  connection[app.config['MONGODB_DATABASE']].mycollection.find_one()

The unittest code just modifies the setting:

  import unittest
  def setUp(self):
    myapp.app.config['MONGODB_DATABASE'] = 'test'
    self.app = myapp.app.test_client()

  def tearDown(self):
    # can clean up here, e.g.
    connection.test.drop_collection('mycollection')


Thanks a lot man. This was really useful, I am on my first steps with unittest.


[deleted]



This should not be downvoted and in fact probably needs to be a top-level comment to counter the kind of misinformation the grandparent of this post is basing his complaint on.


They are not ignoring P3. They are laying plans to move to it. Patience is a virtue. I am learning Python 3 and would love to be using Flask and even Django. It will happen. There was a 5 year plan for P3 adoption and we are only half way there.


I think if you looked you'd see that they have indeed looked into Python 3 support and have found it technically inviable without breaking a number of things.

Python 3 was backwards incompatible to 2.6/2.7, and there are very large code-bases comprising things like Django that can't just be carted over part and parcel.

As somebody who's spent time building enterprise-class Django applications for a very slow-moving set of customers (e.g., the Federal government) I'm glad they're not pushing forward faster than the rest of the world.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: