Search code examples
pythonpython-decorators

How does flask know which function to call for a specific web adress?


In the populair web framework flask a basic web page looks like this:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

I am pretty new to python and i was wondering how this exactly works. I get that @ is a decorator that decorates the hello function but how does flask that is has to call the underlying hello funtion or even knows it exists, because the code does not run the hello function like this:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

hello()

When i am coding i like to know how something works before i just randomly accept anything. I searched my but off looking for an answer but could not find a pleasent answer. Also i looked in the source code but i was not able to find out how it works

So now the real question: How can i recreate something similair in plain python? So running a function without really calling it in the main code first.

Ps. Sorry for my bad english, it is not my main language.


Solution

  • app.route() remembers the URL ("/") and the function associated with it (hello). Later, app.run() can query that association and invoke hello.

    How can i recreate something similair in plain python?

    This program might give you an understanding of how hello() is invoked:

    class Flask:
        def __init__(self):
            self.routes = {}
    
        def route(self, path):
            def wrapper(fn):
                self.routes[path] = fn
                return fn
            return wrapper
    
        def run(self):
            # Networking code goes here.
            # Suppose "/" comes in as a request, then this happens:
            self.routes["/"]()
    
    app = Flask()
    
    
    @app.route("/")
    def hello():
        print("Inside hello")
        return "Hello World!"
    
    app.run()
    

    Alternatively, you can examine the flask source: https://github.com/pallets/flask Specifically, app.route() is defined here: https://github.com/pallets/flask/blob/0.12.2/flask/app.py#L1054 and the call to hello() is here: https://github.com/pallets/flask/blob/0.12.2/flask/app.py#L1052