
Python web micro-framework battle - whit537
http://www.slideshare.net/r1chardj0n3s/web-microframework-battle
======
llambda
Line count is a silly way to score when all are around the same anyway (fewer
than 100 lines). And the framework line count is another metric that shouldn't
matter.

That said, really the only valid point here against Flask is Python 3 support.
Other than that Bottle and Flask are pretty much on par with each other.

~~~
MostAwesomeDude
Flask has the advantages of fast templates, strong WSGI features, serious unit
testability at the app and library level, complete documentation...

~~~
zzzeek
but didn't you read the presentation ? templates are _out_ man. Write your
HTML as string concatenations "<html>" + helloworld + "</html>" right inside
your __init__.py or YOU'RE NOT COOL.

~~~
glenjamin
The presentation stated that templates were not part of the assessment
criteria - since with most microframeworks template systems are either not
bundled or easily replacable.

~~~
zzzeek
hey you're right, this wasn't very apparent from the slides.

------
kenneth_reitz
This seems like an illogical conclusion. I didn't see API Design mentioned
once in any of these slides.

Aside from Python3 Support (which is a bit irrelevant at this point), what
does Bottle actually offer that Flask does not?

Nothing, that I can see. Flask has a thriving community, first-class
extensions, _extremely_ high quality documentation, and an elegant API. It
even lets you dip down into the lower-level werkzeug when you want.

Is Bottle being chosen because of LOC? Again, completely irrelevant.

~~~
dagw
You have to consider his primary use case (which he explains in the video).
He's not writing web apps per se, but wrapping up existing python code in a
simple http frontend. From that point of view I agree with him that bottle is
quicker and easier to use than flask. That being said, flask is easily my go
to framework for getting serious web app work done in python.

~~~
kenneth_reitz
Great point. Interesting.

------
LeafStorm
I don't think counting Python 3 support is really important for Web
frameworks. All of the major server distros are still on Python 2.x anyway
(last I checked, Arch is the only one where "pacman -S python" will get you
Python 3 instead of 2), and the question of WSGI is still up in the air if you
want to handle encoding properly instead of just fudge it.

------
nnythm
Discounting pyramid as a microframework doesn't seem valid, given that it can
be scaled up or down arbitrarily.
<https://docs.pylonsproject.org/projects/pyramid/1.2/> has an extremely
concise pyramid web app above the fold.

~~~
anthonyb
Compare it with Bottle's version though and it doesn't look quite so concise
any more: <http://bottlepy.org/docs/dev/>

~~~
mcdonc
Seems appropriate to link this here:
[https://docs.pylonsproject.org/projects/pyramid/1.2/designde...](https://docs.pylonsproject.org/projects/pyramid/1.2/designdefense.html#microframeworks-
have-smaller-hello-world-programs)

~~~
anthonyb
Seems pretty defensive to me. How does, say, separating out the route and the
view declarations help your application? Code like this:

    
    
       config = Configurator()
       config.add_route('hello', '/hello/{name}')
       config.add_view(hello_world, route_name='hello')
    

is really just boilerplate, which is better done as a decorator. Count how
many times the word 'hello' appears in that snippet above. And this is just
for a hello world program. Once you start on a real app, that's only going to
multiply.

~~~
mmerickel
The ordering of your patterns matters, so that is done at config time. However
it's very common to want to have unrelated code executed depending on the type
of request to a URL. Pyramid will do this lookup for you, rather than
polluting a gigantic view function with multiple code-paths for distinct
functionality.

    
    
        @view_config(route_name='hello', request_method='GET')
        def get_hello(request):
            return Response('a GET request for %s' % request.matchdict['name'])
    
        @view_config(route_name='hello', request_method='POST')
        def post_hello(request):
            return Response('stored info')
    
        config = Configurator()
        config.add_route('hello', '/hello/{name}')
        config.scan()
        app = config.make_wsgi_app()

~~~
mcdonc
Bottle and Flask actually allow for this too. Bottle's variant:

    
    
       @route('/hello/:name', method='GET')
       def hello_get(name):
           return 'Hello %s' % name
    
       @route('/hello/:name', method='POST')
       def hello_post(name):
           return 'Hello %s' % name
    

Pyramid permits a larger variety of predicates (including custom ones),
however:
[https://docs.pylonsproject.org/projects/pyramid/1.2/narr/vie...](https://docs.pylonsproject.org/projects/pyramid/1.2/narr/viewconfig.html#predicate-
arguments)

~~~
mmerickel
Yes but while implicit route ordering works a lot of the time, I'll gladly
keep Pyramid's concept of explicit ordering, which is the main source of
verbosity in the Pyramid setup which separates routes from views.

~~~
mcdonc
The order the decorators are run at import time is explicit. Everybody loves
module-scope programming and import-time side-effects! What's wrong with you
man? ;-)

------
socratic
I used web.py for a few years before switching over to mostly coding in Rails
for the last few months.

Is this for real? Do people find the difference between the style of these
micro-frameworks substantial? Maybe I've been out of Python-land for too long,
but 70% of these look almost identical (raising exceptions for redirects, a
combination of lists and naming conventions or decorators for routes/methods,
etc.) and the other 30% look awful.

Furthermore, when all of the frameworks are basically the same, isn't a much
more important question what scenario they were designed for, or what extra
features they have, or performance, or how big a community they have? (Even
where the author seems to have reasonable criteria, like WSGI, he doesn't seem
able to look up that web.py is WSGI-based.) And seriously, does _anyone_ care
about Python 3 and/or PyPy support in 2011?

Another way of putting this: do the criteria that the author lists match
anyone's criteria who is currently writing Python web applications in the real
world?

------
the_mitsuhiko
I have no idea how the LOC numbers of Flask come together though. Flask itself
is 1.4KLOC, Jinja2 is 6.5KLOC and Werkzeug is 10KLOC (all measured without
tests). Even if you add them up you don't end up with 32KLOC.

~~~
defnull
The author probably did something like this:

    
    
        sudo pip install -u flask
        cd /usr/local/lib/python2.6/dist-packages
        find flask/ werkzeug/ jinja2/ -name '*.py' | xargs wc
        ...
          34936  127298 1658380 total
    

Werkzeug alone has 18KLOC and does not ship with tests.

~~~
the_mitsuhiko
Those are not lines of code. That includes docstrings which all of Pocoo code
is full of. If you _want_ to measure lines of code you at least have to skip
comments, docstrings and empty lines. And for that there is sloccount. This
also includes the testsuites btw.

With this little script (<http://paste.pocoo.org/show/465885/>) I get the
following results:

    
    
        Flask      1467 LOC
        Jinja2     6560 LOC
        Werkzeug   9923 LOC
        Bottle     1910 LOC
    

(FWIW)

~~~
defnull
There are better ways to count LOC, I agree. But the idea is the same: Bottle
does what it does with 1/10 of the code that runs flask.

~~~
DasIch
Flask also has more features and unless you find a way to accurately rate
features for their usefulness and compare all those somehow the LOC metric has
practically no meaning.

It would be much more interesting for potential users if people started
comparing lines of documentation(LOD) and showed the quotient lines of
tests/lines of code.

~~~
defnull
LOC and LOD suffer from the same problem: You can write (or generate) lots of
code or documentation that does not help the user. You can even write docs
that confuse the user, repeat a lot, to not get to the point and so on. In
that case, more is even worse than less. There is no number to measure the
usefulness of a framework or the quality of code. And there is no point in
comparing frameworks just by numbers.

~~~
DasIch
You will notice bad documentation almost immediately which makes the
disadvantage of using LOD as a metric practically irrelevant.

------
binarycrusader
The author's examples for cherrypy were way more complicated than they needed
to be, and they didn't take performance into account. I also find some of the
conclusions about its documentation and wsgi questionable. The author also
drops some frameworks immediately due to maturity, but then fails to rank the
remainder based on that. What about ipv6 and proper Unicode support? What
about http/wsgi compliance? And of course, at the end they show all the extras
the frameworks have but don't take those into account.

------
vessenes
To count out sessions and templating means truly "micro." I can't think of
many useful web applications that do not require these to some extent.

With those criteria, I'm sort of switching between Flask and Tornado right
now.

Speed is a major consideration with any python framework, too. You've got
serious threading concerns. Even with Tornado, advertised as non-blocking, the
default solution is nginx running against a whole bunch of tornado threads.
...

------
rushabh
I also like the way bottle handles static files and apps compared to flask. I
lost flask when it went into blueprints. Bottle seems more intuitive, though
there is not much difference.

~~~
DasIch
You can write Flask applications without ever having heard of the term
blueprint. I don't see how they could complicate things.

~~~
rushabh
If you are planning to have a lot of functionality, i.e. routings, you need
some way to modularise. Bottle does seem to have a more pythonic way. Flask
creates new concepts that seem counter intuitive to me at the first look.

~~~
DasIch
Bottle has no concept at all for this, besides sticking independent
applications together.

You can do that with Flask as well, in fact the documentation there is an
entire document describing various approaches[1].

Blueprints are a "new" concept but the approach is basically the same, however
they are able to interact with the application at a Flask-level, they can
modify the application and share information like the configuration.

This is something Bottle doesn't support at a framework level, forcing you to
abuse the functionality it provides from a semantical standpoint.

This concept is more difficult to understand but than again it is very trivial
compared to other concepts any web developer should grasp.

[1]: <http://flask.pocoo.org/docs/patterns/appdispatch/>

------
shabda
I did something similar a while back, in case any-one's still interested ..

<https://github.com/agiliq/so-starving>

------
yashh
Flask is clearly a better framework than bottle. I started with bottle and hit
a bug. (<https://github.com/defnull/bottle/issues/192>). I had to switch to
flask to avoid it.

------
3KWA
The video is also available at
<http://www.youtube.com/PyconAU#p/u/7/AYjPIMe0BhA>

Interesting if somewhat very biased.

------
mattdeboard
Where does one draw the distinction between micro- and megaframeworks? Or, for
that reference, just a "framework"?

~~~
d0m
Things a company will ask you to know is a megaframeworks. Else, it's a micro
or simply framework.

Obviously, I'm not serious here; but there's some truth in it. I.e. You'll see
some companies ask for django or rails developers; not for flask python hacker
right ;-)

~~~
defnull
Your point is interesting, but I would look at it from a different angle: If
you need a highly paid specialist with many years of experience to fully
master a framework, call it mega-framework. If it fits your brain and can be
learned over the weekend, its a micro framework. Everything in between is just
a framework :)

------
puredemo
Pesto wins if you count the extra features at the end.

------
wyclif
tl;dr: Bottle wins.

~~~
mhd
I think the scoring part (being very particular to the tester and not weighted
at all) is the least interesting part of the presentation, the code and the
comments for each framework are actually quite interesting. I just wish that
Twisted / Tornade would've been in the fray.

------
drivebyacct2
God, this is ridiculous. I can't advance slides, when I do, it skips multiple
slides at a time and I have to register to download a copy that I might
actually be able to view.

