The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Our server is sending us HTML! It's sending a 404 that it could not find the resource we requested. Although it appears to be an error (and technically it is), this is evidence that the Flask server is running successfully. It's time to add some routes. Routes in Flask --------------- In a Flask app, you define the URLs in your application using the ``@app.route`` decorator. Specifications of the ``@app.route`` decorator include: * Must be placed on the line before the declaration of a Python function. * Requires a string argument which is the path of the URL (not including the base URL) * Takes an argument ``methods`` which should be a list of strings containing the names of valid HTTP methods (e.g. ``GET``, ``POST``, ``PUT``, ``DELETE``) When the URL + HTTP method combination is requested, Flask will call the decorated function. Tangent: What is a Python Decorator? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A decorator is a function that takes another function as an input and extends its behavior in some way. The decorator function itself must return a function which includes a call to the original function plus the extended behavior. The typical structure of a decorator is as follows: .. code-block:: python3 :linenos: def my_decorator(some_func): def func_to_return(): # extend the behavior of some_func by doing some processing # before it is called (optional) do_something_before() # call the original function some_func(*args, **kwargs) # extend the behavior of some_func by doing some processing # after it is called (optional) do_something_after() return func_to_return As an example, consider this test program: .. code-block:: python3 :linenos: def print_decorator(f): def func_to_return(*args, **kwargs): print(f'args: {args}; kwargs: {kwargs}') val = f(*args, **kwargs) print(f'return: {val}') return val return func_to_return @print_decorator def foo(a): return a+1 result = foo(2) print(f'Got the result: {result}') Our ``@print_decorator`` decorator gets executed automatically when we call ``foo(2)``. Without the decorator, the final output would be: .. code-block:: text Got the result: 3 By using the decorator, however, the final output is instead: .. code-block:: text args: (2,); kwargs: {} return: 3 Got the result: 3 Define the Hello World Route ---------------------------- The original Flask app we wrote above (in ``app.py``) did not define any routes. Let's define a "hello world" route for the base URL. Meaning if someone were to curl against the base URL (``/``) of our server, we would want to return the message "Hello, world!". To do so, add the following lines to your ``app.py`` script: .. code-block:: python3 :linenos: :emphasize-lines: 5-7 from flask import Flask app = Flask(__name__) @app.route('/', methods=['GET']) def hello_world(): return 'Hello, world!\n' # the next statement should usually appear at the bottom of a flask app if __name__ == '__main__': app.run(debug=True, host='0.0.0.0') The ``@app.route`` decorator on line 5 is expecting ``GET`` requests at the base URL ``/``. When it receives such a request, it will execute the ``hello_world()`` function below it. In your active SSH terminal, execute the curl command again (you may need to restart the Flask app); you should see: .. code-block:: console [coe332-vm]$ curl localhost:5000/ Hello, world! Routes with URL Parameters -------------------------- Flask makes it easy to create routes (or URLs) with variables in the URL. The variable name simply must appear in angled brackets (``<>``) within the ``@app.route()`` decorator statement. Then, specify the variable as a parameter to the actual function. For example, the following would grant the function below it access to a variable called ``year``: .. code-block:: python3 @app.route('/