Skip to content

Running the Dev Server

During development you typically run:

  • flask run

This starts Werkzeug’s development server.

You’ll usually see:

  • the URL (like http://127.0.0.1:5000)
  • that it’s a development server
  • Default host: 127.0.0.1 (only accessible from your machine)
  • Default port: 5000

You can change them:

bash
flask run --host 0.0.0.0 --port 8000

Use it when you want access from another device on your network.

Be careful: exposing dev servers is not recommended on public networks.

  1. Browser connects to the host/port
  2. Sends GET /
  3. Dev server forwards to Flask app
  4. Flask finds a matching route and runs your view function
  5. Response is returned

If you get a 404, it usually means:

  • you didn’t define the route, or
  • your URL doesn’t match the route rule

What the routing table looks like before any request

Section titled “What the routing table looks like before any request”

Flask builds a url_map at import time. Every rule you registered is in it — plus one you did not write:

routes.py
for rule in app.url_map.iter_rules():
    print(rule, rule.endpoint, sorted(rule.methods - {"HEAD", "OPTIONS"}))
measured output
/                       index    ['GET']
/api/items              items    ['GET', 'POST']
/static/<path:filename> static   ['GET']     <- added automatically
/user/<name>            user     ['GET']

HEAD and OPTIONS are attached to every GET rule for you, and a /static/ route exists from the moment the app object is created.

diagram Diagram mermaid

Measured against the app above:

requeststatusnote
GET /nope404no rule matches
DELETE /api/items405rule exists, method does not
Allow header on that 405GET, POST, OPTIONS, HEAD

A 405 rather than a 404 is a useful signal: the URL is right and the verb is wrong.

slashes.py
@app.route("/dir/")     # declared WITH a slash
def d(): ...
 
@app.route("/file")     # declared WITHOUT one
def f(): ...
declaredrequestedresult
/dir//dir308 redirect to /dir/
/file/file/404

A rule ending in a slash behaves like a directory: ask without the slash and Flask redirects you. A rule without one behaves like a file: the slashed form simply does not exist. The redirect costs an extra round trip, and a POST that gets redirected can lose its body in some clients — so declare the form you intend and link to it exactly.

sketch Matching a request against the url_map p5.js
Flask checks the path first, then the method. That order is why a wrong verb gives 405 rather than 404.
pch.quizTag pch.quizDefaultTitle
  1. A route is declared as @app.route('/dir/') and a client requests /dir. What happens?

    pch.quizShowAnswer

    C — 308 redirect to /dir/ — A rule ending in a slash behaves like a directory and Flask redirects. The reverse is not symmetric: a rule declared '/file' requested as '/file/' gives 404.

  2. DELETE /api/items returns 405 rather than 404. What does that distinction tell you?

    pch.quizShowAnswer

    B — the path matched a rule but the method is not allowed for it — Flask matches the path first, then the method. A 405 means the URL is right and the verb is wrong, and the response carries an Allow header listing what is permitted.

  3. Which rule appears in app.url_map without you writing it?

    pch.quizShowAnswer

    B — /static/<path:filename> — Creating the Flask object registers the static route. Iterating url_map also shows HEAD and OPTIONS attached automatically to every GET rule.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading