4. Flask basics: install, first route, project layout

Now that you know the request, route, view function, and response loop, it is time to run that loop for real. On this page you will install Flask, create a tiny app.py, open it in the browser, and set up the folder structure the rest of the chapter uses.

Install Flask

Use the same virtual environment you used for the Music Time Machine work in Chapter 16. From the project folder, install Flask:

Terminal
pip install flask

Then check that Python can import it:

Terminal
python -c "from importlib.metadata import version; print(version('flask'))"

Flask installs a few helper packages with it. The two you will hear about most are Werkzeug, which handles the lower-level web server pieces, and Jinja2, which renders HTML templates. You do not need to configure either one yet.

Create app.py

Save this file as app.py in your Music Time Machine project folder:

app.py
from flask import Flask

app = Flask(__name__)


@app.route("/")
def home():
    return "Hello from the Music Time Machine!"


if __name__ == "__main__":
    app.run(debug=True)

There are four moving parts here:

  • from flask import Flask imports the class that creates your web application.
  • app = Flask(__name__) creates the Flask app object.
  • @app.route("/") connects the home-page URL to the function below it.
  • app.run(debug=True) starts the local development server when you run the file directly.

Run the app

Start the server from the terminal:

Terminal
python app.py

Flask will print output similar to this:

Terminal
 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 123-456-789

Because debug=True is on, Flask also prints a development-server WARNING and a debugger PIN. Both are expected locally and safe to ignore: the warning just reminds you not to serve this way in production (Chapter 20 covers what to use instead), and the PIN gates the in-browser debugger.

Open http://127.0.0.1:5000 in your browser. You should see the string returned by home(). The page is plain, but the full loop is working: browser request, Flask route, Python function, browser response.

Leave the terminal visible while you work. Flask logs each browser request there, which makes it easier to see whether the browser reached your app at all.

About debug=True

The debug=True setting is useful while you are building locally. It reloads the server when you save changes, and it shows detailed error pages when something breaks.

It must not be used on a public server. Debug pages can expose internal code details, and the interactive debugger is not safe for production. Chapter 20 covers the production version of this setup.

Set up the project folders

Flask follows two useful folder conventions:

  • templates/ stores HTML files that Flask renders with Jinja2.
  • static/ stores files the browser loads directly, such as CSS, JavaScript, and images.

For this chapter, keep the structure small:

music-time-machine/
music-time-machine/
├── app.py
├── music_time_machine.db
├── templates/
│   ├── home.html
│   ├── base.html
│   └── includes/
│       └── nav.html
└── static/
    └── css/
        └── style.css

You will not create every file immediately. This layout simply gives the next pages somewhere predictable to put templates and styles.

Create the folders now:

Terminal
# macOS / Linux
mkdir -p templates/includes static/css

# Windows PowerShell
New-Item -ItemType Directory -Force templates/includes, static/css

The app now has a working entry point and the folders Flask expects. Next you will expand the routing side: more URLs, URL variables, and links that Flask can generate for you.