Skip to content

Flask Command Line Interface (CLI)

Flask includes a CLI (built on Click) that makes development workflows smooth.

The CLI needs to know what Flask application to run.

Common ways:

  • FLASK_APP=app (points to app.py module)
  • FLASK_APP=package:create_app (factory pattern)

If you have app.py with app = Flask(__name__):

bash
export FLASK_APP=app
flask run
  • flask run — run dev server
  • flask routes — list all routes (very helpful!)
  • flask shell — open a Python shell with app context (commonly used in bigger apps)

Later, you can add custom commands like:

  • flask create-admin
  • flask seed-db

Typically you’ll register them through the app factory or extensions.

If you see errors like:

  • “Could not locate a Flask application”

It usually means:

  • FLASK_APP is not set
  • your import path is wrong
  • you’re in the wrong working directory

The flask command is a click application installed alongside Flask. Before it can do anything it has to locate your app object, and it looks in a fixed order:

diagram Diagram mermaid

Run from the wrong directory and you get exactly this, measured:

the error you will actually see
Error: Could not locate a Flask application. Use the 'flask --app' option,
'FLASK_APP' environment variable, or a 'wsgi.py' or 'app.py' file in the
current directory.

The fix is nearly always --app, which takes a module path rather than a file name:

usage
flask --app app run          # module app, i.e. app.py
flask --app myapp:create_app run    # a factory
flask --app app routes
flask --app app shell
flask --app app --help
Commands:
  routes  Show the routes for the app.
  run     Run a development server.
  shell   Run a shell in the app context.

flask routes is the fastest way to answer “why is my URL 404?” — measured on a small app:

flask --app app routes
Endpoint  Methods    Rule
--------  ---------  -----------------------
index     GET        /
items     GET, POST  /api/items
static    GET        /static/<path:filename>
user      GET        /user/<name>

Every rule the app really has, including the automatic static one. If the route you expected is missing, the module was never imported or the decorator never ran.

flask shell opens a REPL inside an application context, so current_app, url_for and your database session work without any setup. A plain python REPL gives you RuntimeError: Working outside of application context for the same code.

sketch How flask locates your app p5.js
The CLI checks --app, then FLASK_APP, then wsgi.py or app.py in the current directory, and fails if none of them resolve.
pch.quizTag pch.quizDefaultTitle
  1. In what order does the flask command look for your application?

    pch.quizShowAnswer

    B — --app, then FLASK_APP, then wsgi.py or app.py in the current directory — The explicit flag wins, then the environment variable, then the conventional file names. If none resolve you get 'Could not locate a Flask application'.

  2. Why does flask shell differ from running python and importing your app?

    pch.quizShowAnswer

    B — it opens the REPL inside an application context, so current_app and url_for work — Without an application context the same code raises RuntimeError: Working outside of application context. flask shell pushes one for you.

  3. You expect /profile to exist but get 404. What does flask routes tell you?

    pch.quizShowAnswer

    B — whether the rule is registered at all; if it is missing, the module was never imported or the decorator never ran — flask routes prints the real url_map. A missing rule is a registration problem, not a view problem — usually a blueprint that was never registered or a module never imported.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading