1
votes

I'm looking for a reasonable answer to this question:

https://news.ycombinator.com/item?id=4207314

I have no doubt that if I dug into it then it would all make sense, but my first instinct is this: how much of this complexity (proxy objects to thread locals, context stacks etc) results from the fact that doing:

    from flask import request
is just a bad idea? Perhaps things would be easier if instead of:

    from flask import request

    ...

    @app.route('/'):
    def index():
        return "Hello from %s" % request.args.get('name')
we did:

    @app.route('/'):
    def index(request):
        return "Hello from %s" % request.args.get('name')

Armin's response the the above is not very satisfying:

I was a huge opponent of thread locals for a really long time but I finally had to acknowledge that they make things easier instead of harder.

...

The fact that you can do `_app_ctx_stack.top.mydatabase_connection` to get a database connection from anywhere is very helpful.

...

TL;DR: you can't live without thread locals or you have a horrible API.

I don't see how _app_ctx_stack.top.mydatabase_connection is any better than request.app.my_database_connection.

1
Take into account that with an explicit argument, you now have to pass requests to any and all utility functions your views may need to use than need access to the request state. This includes 3rd party libraries. - Martijn Pieters♦
I cannot understand this library argument that gets repeated. Of course you have to pass arguments to a library function. What is the alternative? That a 3rd-party library does from flask import request and now depends on flask? - avdd
If you have to pass in a request argument, the library depends, at a bare minimum, on Werkzeug already. What I am talking about is several layers of calls, where view-related code is ultimately being called. Now you need a means to pass through the request object, or be able to access the response that'll be produced, but any and all 3rd party libraries along that path have to cooperate. - Martijn Pieters♦
In any case, you can try out working with both Pyramid and Flask to see the difference. And then you find that even Pyramid offers access to a thread-local 'current request' object. I have been coding web apps with Python for 15 years and I find that not having to pass request through several layers of calls tremendously helpful, even after being very resistant to the idea at first. - Martijn Pieters♦
Sometimes practicality beats purity. Flask is just explicit about it, but just about all other frameworks use thread locals too! Bottle, Zope (and more so Plone), And Pyramid do. For Django there is a popular piece of middleware (also see stackoverflow.com/q/3227180). But Armin made it an explicit API choice and is somehow worse? - Martijn Pieters♦

1 Answers

0
votes

you shouldn't only think in controllers (where you can access the request object). It's important also in other layers of your application (imagine a reusable service layer where there are important business rules)