TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Things which aren't magic – Flask and app.route

160 pointsby StylifyYourBlogover 10 years ago

9 comments

level09over 10 years ago
Flask is incredible. since I&#x27;ve made the transition from PHP-based CMS&#x27;s I&#x27;ve never looked back.<p>if someone is interested in learning more about building larger scale&#x2F;production apps with flask, I have a series of tutorials at medium to get you started: <a href="https://medium.com/@level09" rel="nofollow">https:&#x2F;&#x2F;medium.com&#x2F;@level09</a><p>Disclaimer: I&#x27;m the creator of enferno (<a href="http://enferno.io" rel="nofollow">http:&#x2F;&#x2F;enferno.io</a>), A flask-based system pre-configured with caching&#x2F;user auth&#x2F;basic template&#x2F;ORM&#x2F;CRUD&#x2F;task queue&#x2F;mail functionality.
评论 #8808957 未加载
josefdlangeover 10 years ago
What&#x27;s throwing me off -- and I&#x27;m sure it&#x27;s something trivial I&#x27;m not seeing -- is how we add the functions to the routes dictionary. When is the decorator&#x27;s code actually executed? Is that done at import time? My assumption is that its code is executed when its counterpart is called, though clearly that mustn&#x27;t be the case.<p>Given my understanding from the article, there&#x27;s a hole: how does serving route &quot;&#x2F;&quot; know to call that function if (given my assumptions) the @app.route(&quot;&#x2F;&quot;) decoration is not executed until the function it decorates is called?
评论 #8808703 未加载
评论 #8808697 未加载
评论 #8809654 未加载
评论 #8810694 未加载
untitaker_over 10 years ago
The term <i>decorator generator</i> is incredibly misleading, as it implies relation to <i>Python generators</i>. The term <i>decorator factory</i> (or just <i>decorator with parameters</i>) is preferrable.
评论 #8810358 未加载
评论 #8810098 未加载
RubyPinchover 10 years ago
Something a bit more on the &quot;magic&quot; side, that some might find relevant <a href="https://gist.github.com/Socialery/40141aa2c2d70bd065e8" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;Socialery&#x2F;40141aa2c2d70bd065e8</a>
评论 #8808783 未加载
sauereover 10 years ago
As a Python newbie that just recently started using things like Flask and Bottle: wow, that was easy.
评论 #8808909 未加载
marvatuover 10 years ago
I did something similar when playing around trying to make a wsgi <a href="http://jibreel.me/blog/2/" rel="nofollow">http:&#x2F;&#x2F;jibreel.me&#x2F;blog&#x2F;2&#x2F;</a>
bigb9320over 10 years ago
Am I right in understanding that decorators are a form of closures as the decorator function is returning the function declared inside it ?
评论 #8808977 未加载
评论 #8809017 未加载
评论 #8809683 未加载
评论 #8808996 未加载
评论 #8808991 未加载
alangpierceover 10 years ago
Flask&#x27;s route decorator gives a nice syntax, but it goes against some ideal best practices:<p>* Imports shouldn&#x27;t have side-effects (like registering functions with flask).<p>* You shouldn&#x27;t use globals (like the flask app).<p>* Objects (such as the flask app) should be immutable whenever possible.<p>None of these are hard-and-fast rules, and Python code has a tendency to give up purity in favor of syntax, so it&#x27;s certainly justified for Flask to be designed this way, but it&#x27;s still a bit unsettling, and can lead to bugs, especially in larger cases when your handlers are split up across many files. Some examples:<p>* You need to make sure that you import every file with a request handler, and those imports often end up unused (only imported for their side-effects), which confuses linters and other static analysis tools.<p>* It&#x27;s also easy to accidentally import a new file through some other import chain, so someone rearranging imports later might accidentally disable part of your app by never importing it.<p>* It can break some &quot;advanced&quot; uses of modules&#x2F;imports, such as the reload function.<p>* Test code and scripts that want access to your request handlers are forced to build a (partial) Flask app, even if they have no use for one.<p>At my job, I recently changed our Flask handlers to be registered with a different approach (but the same API) that avoids most of these issues. Rather than setting things up with side-effects, it makes the route details easy to introspect later. Here&#x27;s what our implementation of @route() looks like now:<p><pre><code> def route(rule, **options): def route_decorator(func): # Attach the route rule to the request handler. func.func_dict.setdefault(&#x27;_flask_routes&#x27;, []).append((rule, options)) # Add the request handler to this module&#x27;s list of handlers. module = sys.modules[func.__module__] if not hasattr(module, &#x27;_FLASK_HANDLERS&#x27;): module. _FLASK_HANDLERS = {} module._FLASK_HANDLERS[func.__name__] = func return func return route_decorator </code></pre> So if you have a module called user_routes.py, with 3 Flask request handlers, then user_routes._FLASK_HANDLERS is a list containing those three functions. If one of those handlers is user_routes.create_user, then you can access user_routes.create_user._flask_routes in order to see the names of all of the route strings (usually just one) registered for that request handler.<p>Then, in separate code, there&#x27;s a list of all modules with request handlers, and we import and introspect all of them as part of a function that sets up and returns the Flask app. So outside code never has any way of accessing a partially-registered Flask app, imports of request handler modules are &quot;pure&quot;, and request handlers can often be defined without depending on Flask at all.
评论 #8809914 未加载
评论 #8809219 未加载
rev_birdover 10 years ago
That. Things _that_ aren&#x27;t magic.<p>On a more relevant note, thanks for sharing this. It&#x27;s always nice to read an explanation from somebody patient enough to not skip over a bunch of steps in the middle and avoid losing newbs like me.
评论 #8808583 未加载
评论 #8808756 未加载