DataLens

Your first Flask app and routes

Create a Flask app, connect URLs to Python functions with @app.route, and send requests to it.

Level: Foundations · 8 min read

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

The idea

In the last module you saw that a web server's whole job is: receive a request, send back a response. Flask is a small Python framework that handles the plumbing (reading requests, writing responses, speaking HTTP) so you only write the interesting part: what should happen when someone visits this URL?

Flask calls itself a micro-framework. It gives you routing, requests and responses, templates and little else. You add only what you need, which makes it a great framework for learning how the web really works, and for building small APIs and internal tools at work.

The smallest Flask app

Here's a complete web app in seven lines. When someone visits the home page of the site, it answers with a welcome message. Small as it is, every Flask app you'll ever build has these same parts:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Selamat datang di Toko Kita!"

Line by line:

That's a complete web app. On this site, press Run, then open the Browser tab under the editor and press Send: it requests / from your app and shows the response.

Running it on your computer

Save the code as app.py, add Flask to your project with uv, and start the development server:

uv add flask
uv run flask --app app run --debug

Flask prints Running on http://127.0.0.1:5000. Open that address in your browser and you'll see your message. --debug turns on the reloader (the server restarts when you save the file) and shows detailed error pages. Use it while developing, never on a real public server.

Note

This site can't open real network ports, so the Browser tab sends requests straight to your app object, using Flask's built-in test client. It's the same request and response a browser would get, without the network in between.

Routes: mapping URLs to functions

A route connects a URL path to a view function. Add as many as you like:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Selamat datang di Toko Kita!"

@app.route("/about")
def about():
    return "Toko Kita sells coffee, kitchen gear and desk accessories."

@app.route("/contact")
def contact():
    return "Email us at [email protected]"

Now /about and /contact work too. Request a path with no route, like /careers, and Flask returns 404 Not Found for you automatically.

A few rules of thumb:

Returning HTML

A view can return HTML as a string, and the browser renders it as a page:

@app.route("/")
def home():
    return "<h1>Toko Kita</h1><p>Fresh coffee, delivered.</p>"

That's fine for a heading, but long HTML strings in Python get messy fast. In the templates module you'll move HTML into separate files, which is the clean way to do it. For now, short strings are perfect for learning.

What a response contains

When your view returns a string, Flask wraps it in a full HTTP response with three parts:

PartExampleMeaning
Status code200 OKDid it work? 200 means success, 404 means not found.
HeadersContent-Type: text/htmlExtra information, such as what kind of data the body is.
BodySelamat datang di Toko Kita!The actual content.

You can return a different status code by adding it after the body, as a tuple:

@app.route("/old-shop")
def old_shop():
    return "This page has moved to /", 410

410 Gone means "this existed once but was removed on purpose". You'll learn the important status codes in a later module.

Testing your app with the test client

Clicking around in a browser is slow and easy to forget. Flask has a test client that sends requests from Python and gives you the response to inspect. This is how professional Flask apps get tested, and it's also how the checks on this site work.

client = app.test_client()
response = client.get("/about")
print(response.status_code)
print(response.get_data(as_text=True))
200
Toko Kita sells coffee, kitchen gear and desk accessories.

Why this matters for clean code

A route is a promise: "this URL does this one thing". Keep view functions small and focused. If a view starts doing five jobs (loading data, calculating, formatting, sending email), move those jobs into normal functions and call them from the view. Small views are easy to read, easy to test with the test client, and easy to change without breaking the rest of the site.

Recap

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

Next: Dynamic routes and URL parameters →