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:
pip install flask
Then check that Python can import it:
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:
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 Flaskimports 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:
python app.py
Flask will print output similar to this:
* 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/
├── 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:
# 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.