Flask stands out as a streamlined Python framework tailored for web applications, offering essential tools for URL routing and rendering web pages.
Often referred to as a “micro” framework, Flask deliberately omits built-in features like form validation, database management, and authentication. Instead, it relies on specialized Python packages known as Flask extensions to provide these functionalities. These extensions seamlessly integrate with Flask, appearing as native features. For instance, while Flask doesn’t inherently include a template engine, it comes bundled with the Jinja templating engine by default. For simplicity, these default components are generally considered part of Flask.
This Flask tutorial guides you through the creation of a basic Flask application comprising three pages that share a common base template. Throughout this process, you’ll explore various features of Visual Studio Code, including the terminal, code editor, debugger, code snippets, and more, enhancing your web coding skills.
The complete code for this tutorial is available on GitHub: python-sample-vscode-flask-tutorial.
If you encounter any issues, you can find solutions or ask questions on the Python extension Discussions Q&A.
Prerequisites for Web Coding
To successfully follow this web coding tutorial with Flask, ensure you have completed the following prerequisites, similar to those in the general Python tutorial:
- Install the Python extension for Visual Studio Code.
- Install Python 3. This tutorial is written for Python 3. You can choose from various options:
- Download from python.org
- Install via the Microsoft Store (Windows)
- Using package managers on macOS (like Homebrew) or Linux distributions.
- On Windows, ensure your Python interpreter’s location is in your PATH environment variable. To check, run
path
in the command prompt. If the Python folder isn’t listed, go to Windows Settings, search for “environment variables”, select Edit environment variables for your account, and add the Python folder path to the Path variable.
Setting Up Your Web Coding Project Environment
In this section, you’ll establish a virtual environment for your web coding project, where Flask will be installed. Virtual environments keep your project’s dependencies isolated from your global Python installation, providing precise control over project libraries.
-
Create a new folder on your system for this tutorial, such as
hello_flask
. -
Open this folder in VS Code by navigating to it in a terminal and running
code .
, or by launching VS Code and using File > Open Folder. -
In VS Code, open the Command Palette (View > Command Palette or (⇧⌘P (Windows, Linux Ctrl+Shift+P))). Type and select Python: Create Environment to create a virtual environment. Choose
venv
and your desired Python environment for creation.Note: For manual environment creation or troubleshooting environment setup, refer to the Environments page.
-
After the virtual environment is created, run Terminal: Create New Terminal (⌃⇧
(Windows, Linux Ctrl+Shift+
)) from the Command Palette. This opens a terminal and automatically activates the virtual environment by running its activation script.Note: On Windows, if PowerShell is your default terminal, you might encounter an error about
activate.ps1
being disabled. The error message will provide a link to instructions on enabling scripts. Alternatively, use Terminal: Select Default Profile to switch your default terminal to “Command Prompt” or “Git Bash”. -
Install Flask within the virtual environment by running the following command in the VS Code Terminal:
<span><span>python</span><span> -m</span><span> pip</span><span> install</span><span> flask</span></span>
You now have a dedicated environment ready for web coding with Flask. VS Code automatically activates this environment for you in new terminals. If you use an external terminal, activate it manually with source .venv/bin/activate
(Linux/macOS) or .venvScriptsActivate.ps1
(Windows). An activated environment is indicated by (.venv) at the start of your command prompt.
Building a Minimal Flask Web App
-
In VS Code, create a new file in your project folder named
app.py
using File > New, Ctrl+N, or the new file icon in the Explorer View. -
In
app.py
, import Flask and instantiate a Flask object. Typing the code below will demonstrate VS Code’s IntelliSense and auto-completions for efficient web coding:<span><span>from</span><span> flask </span><span>import</span><span> Flask</span></span> <span><span>app = Flask(</span><span>__name__</span><span>)</span></span>
-
Still in
app.py
, define a function that returns content—a simple string in this case—and use Flask’sapp.route
decorator to link the URL route/
to this function:<span><span>@app.route</span><span>(</span><span>"/"</span><span>)</span></span> <span><span>def</span><span> home</span><span>():</span></span> <span><span> return</span><span> "Hello, Flask!"</span></span>
Tip: You can apply multiple decorators to a single function, each on a new line, to map different routes to the same function.
-
Save
app.py
(⌘S (Windows, Linux Ctrl+S)). -
Run the app in the Integrated Terminal with
python -m flask run
. This command starts the Flask development server, which by default looks forapp.py
. Upon successful execution, you should see output similar to:<span><span>(.venv) D:pyhello_flask>python -m flask run</span></span> <span><span> * Environment: production</span></span> <span><span> WARNING: Do not use the development server in a production environment.</span></span> <span><span> Use a production WSGI server instead.</span></span> <span><span> * Debug mode: off</span></span> <span><span> * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)</span></span>
If you encounter a “Flask module not found” error, ensure you installed Flask in your virtual environment using
python -m pip install flask
as described earlier.To run the development server on a different IP address or port, use the
--host
and--port
command-line arguments, for example:--host=0.0.0.0 --port=80
. -
Ctrl+click the
http://127.0.0.1:5000/
URL in the terminal to open the rendered page in your default browser. -
Visiting a URL like
/
will log an HTTP request in the debug terminal:<span><span>127.0.0.1 - - [11/Jul/2018 08:40:15] "GET / HTTP/1.1" 200 -</span></span>
-
Stop the app by pressing Ctrl+C in the terminal.
Tip: When using a filename other than
app.py
, such aswebapp.py
, you must set the environment variableFLASK_APP
to your chosen filename. Flask’s development server will then use this variable instead of the defaultapp.py
. For more details, see Flask command line interface.
Debugging Your Flask Web App
Debugging is a crucial skill in web coding, allowing you to pause your running application at specific code lines. This enables you to inspect variables, execute code in the Debug Console, and utilize other debugging features detailed in Debugging. Starting the debugger also automatically saves any file modifications before initiating the debugging session.
Before starting: Ensure you’ve stopped any running app instances from the previous section by pressing Ctrl+C in the terminal. If an app continues running, it will hold onto the port, preventing the debugger from working correctly. If debugging seems ineffective, verify no other app instance is active.
-
Replace the content of
app.py
with the code below. This adds a second route and function that you can step through with the debugger:<span><span>import</span><span> re</span></span> <span><span>from</span><span> datetime </span><span>import</span><span> datetime</span></span> <span><span>from</span><span> flask </span><span>import</span><span> Flask</span></span> <span><span>app = Flask(</span><span>__name__</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/"</span><span>)</span></span> <span><span>def</span><span> home</span><span>():</span></span> <span><span> return</span><span> "Hello, Flask!"</span></span> <span><span>@app.route</span><span>(</span><span>"/hello/<name>"</name></span><span>)</span></span> <span><span>def</span><span> hello_there</span><span>(</span><span>name</span><span>):</span></span> <span><span> now = datetime.now()</span></span> <span><span> formatted_now = now.strftime(</span><span>"%A, %d %B, %Y at %X"</span><span>)</span></span> <span><span> # Filter the name argument to letters only using regular expressions. URL arguments</span></span> <span><span> # can contain arbitrary text, so we restrict to safe characters only.</span></span> <span><span> match_object = re.match(</span><span>"[a-zA-Z]+"</span><span>, name)</span></span> <span><span> if</span><span> match_object:</span></span> <span><span> clean_name = match_object.group(</span><span>0</span><span>)</span></span> <span><span> else</span><span>:</span></span> <span><span> clean_name = </span><span>"Friend"</span></span> <span><span> content = </span><span>"Hello there, "</span><span> + clean_name + </span><span>"! It's "</span><span> + formatted_now</span></span> <span><span> return</span><span> content</span></span>
The new route
/hello/
decorator defines an endpoint that accepts an additional value. The identifier within< >
in the route signifies a variable passed to the function and usable in your code.URL routes are case-sensitive.
/hello/
is distinct from/Hello/
. To handle both, use decorators for each case.Always filter user-provided information to prevent app vulnerabilities. Here, the code filters the
name
argument to letters only, avoiding injection of control characters or HTML. (Template usage in later sections will handle automatic filtering.) -
Set a breakpoint on the first line of
hello_there
(now = datetime.now()
) using one of these methods:- Place the cursor on the line and press F9.
- Place the cursor on the line and select Run > Toggle Breakpoint.
- Click in the margin to the left of the line number (a red dot will appear on hover).
The breakpoint is shown as a red dot in the margin:
-
Switch to the Run and Debug view in VS Code (using the activity bar or ⇧⌘D (Windows, Linux Ctrl+Shift+D)). You might see “To customize Run and Debug create a launch.json file”. This indicates the absence of a
launch.json
debug configurations file. Click the create a launch.json file link to have VS Code generate one. -
Select the link and choose Flask from the dropdown. VS Code will create a
launch.json
file pre-configured for Flask debugging. This file contains various debug configurations as JSON objects in theconfigurations
array. -
Find the “Python: Flask” configuration. It includes
"module": "flask",
, instructing VS Code to run Python with-m flask
when debugging starts. Theenv
property defines theFLASK_APP
environment variable, set toapp.py
by default, but modifiable to specify a different startup file. Theargs
array allows changing the host and port.<span><span>{</span></span> <span><span> "name"</span><span>: </span><span>"Python Debugger: Flask"</span><span>,</span></span> <span><span> "type"</span><span>: </span><span>"debugpy"</span><span>,</span></span> <span><span> "request"</span><span>: </span><span>"launch"</span><span>,</span></span> <span><span> "module"</span><span>: </span><span>"flask"</span><span>,</span></span> <span><span> "env"</span><span>: {</span></span> <span><span> "FLASK_APP"</span><span>: </span><span>"app.py"</span><span>,</span></span> <span><span> "FLASK_DEBUG"</span><span>: </span><span>"1"</span></span> <span><span> },</span></span> <span><span> "args"</span><span>: [</span></span> <span><span> "run"</span><span>,</span></span> <span><span> "--no-debugger"</span><span>,</span></span> <span><span> "--no-reload"</span></span> <span><span> ],</span></span> <span><span> "jinja"</span><span>: </span><span>true</span><span>,</span></span> <span><span> "justMyCode"</span><span>: </span><span>true</span></span> <span><span>},</span></span>
Note: If your configuration contains
"FLASK_APP": "${workspaceFolder}/app.py"
, change it to"FLASK_APP": "app.py"
to avoid potential errors like “Cannot import module C”.Note: Once
launch.json
is created, an Add Configuration button appears, offering a list of additional configurations. The Run > Add Configuration menu command does the same. -
Save
launch.json
(⌘S (Windows, Linux Ctrl+S)). Select the Python: Flask configuration from the debug configuration dropdown. -
Start the debugger via Run > Start Debugging or the green Start Debugging arrow (F5):
The status bar will change color to indicate debugging mode:
A debugging toolbar appears with commands: Pause/Continue (F5), Step Over (F10), Step Into (F11), Step Out (⇧F11 (Windows, Linux Shift+F11)), Restart (⇧⌘F5 (Windows, Linux Ctrl+Shift+F5)), and Stop (⇧F5 (Windows, Linux Shift+F5)). See VS Code debugging for command details.
-
Output will appear in the “Python Debug Console” terminal. Ctrl+click the
http://127.0.0.1:5000/
link to open it in a browser. In the browser address bar, navigate tohttp://127.0.0.1:5000/hello/VSCode
. VS Code will pause execution at the breakpoint before rendering the page. A yellow arrow on the breakpoint marks the next line to execute. -
Use Step Over to execute
now = datetime.now()
. -
On the left, the Variables pane displays local variables like
now
and arguments likename
. Below are panes for Watch, Call Stack, and Breakpoints (see VS Code debugging). Expand values in Locals. Double-click values (or Enter (Windows, Linux F2)) to modify them. However, changing variables likenow
might disrupt program flow. Modifications are usually for correcting initial incorrect values. -
When paused, the Debug Console panel (distinct from “Python Debug Console”) allows you to experiment with expressions and code snippets using the current program state. After stepping over
now = datetime.now()
, you can test date/time formats. Selectnow.strftime("%A, %d %B, %Y at %X")
in the editor, right-click, and choose Evaluate in Debug Console to execute it there:<span><span>now.strftime(</span><span>"%A, %d %B, %Y at %X"</span><span>)</span></span> <span><span>'Wednesday, 31 October, 2018 at 18:13:39'</span></span>
Tip: The Debug Console also shows app exceptions not visible in the terminal. Check the Debug Console if you see a “Paused on exception” message in the Call Stack area.
-
Copy the line to the
>
prompt in the debug console and try different formats:<span><span>now.strftime(</span><span>"%a, %d %B, %Y at %X"</span><span>)</span></span> <span><span>'Wed, 31 October, 2018 at 18:13:39'</span></span> <span><span>now.strftime(</span><span>"%a, %d %b, %Y at %X"</span><span>)</span></span> <span><span>'Wed, 31 Oct, 2018 at 18:13:39'</span></span> <span><span>now.strftime(</span><span>"%a, %d %b, %y at %X"</span><span>)</span></span> <span><span>'Wed, 31 Oct, 18 at 18:13:39'</span></span>
-
Step through more code lines if desired, then select Continue (F5) to resume execution. The browser will display the result:
-
Modify the date/time format in the code, for example, to
now.strftime("%a, %d %b, %y at %X")
, and save the file. The Flask server will automatically reload, applying changes without debugger restart. Refresh the browser page to see updates. -
Close the browser and stop the debugger using the Stop toolbar button (red square) or Run > Stop Debugging (⇧F5 (Windows, Linux Shift+F5)).
Tip: For easier repeated navigation to URLs like
http://127.0.0.1:5000/hello/VSCode
, use a
Exploring Code Definitions
When working with Flask or other libraries, you might need to examine their code. VS Code offers two commands for navigating directly to object definitions:
- Go to Definition: Jumps from your code to the definition of an object. In
app.py
, right-clickFlask
(inapp = Flask(__name__)
) and select Go to Definition (or F12) to navigate to its definition in the Flask library. - Peek Definition: (⌥F12 (Windows Alt+F12, Linux Ctrl+Shift+F10), also in the context menu) displays the definition inline in the editor. Press Escape or the x in the top right to close.
Rendering Pages with Templates
The current app generates plain text web pages. While HTML can be directly coded, it’s discouraged due to cross-site scripting (XSS) attacks risks. For example, formatting output in hello_there
with content = "<h1>Hello there, " + clean_name + "!</h1>"
directly exposes the app. Malicious HTML, including JavaScript, in the URL could be executed in the browser.
A better approach is using templates to separate HTML from code. Code handles data, templates handle rendering.
- A template is an HTML file with placeholders for runtime values. The template engine substitutes these placeholders when rendering the page. Code focuses on data, templates on markup.
- Flask’s default template engine is Jinja, installed with Flask. Jinja offers features like automatic escaping (preventing XSS) and template inheritance. Inheritance allows defining a base page with common markup, extended by page-specific templates.
This section creates a single page using a template. Later sections cover serving static files and creating multi-page apps with base templates.
-
Create a folder named
templates
in thehello_flask
folder. Flask looks for templates here by default. -
Inside
templates
, createhello_there.html
with the following content. It includes placeholdersname
anddate
within{{
and}}
. Formatting code can also be embedded in templates:<span><span><span><!DOCTYPE html></span></span> <span><span><html lang="en"></span></span> <span><span><head></span></span> <span><span> <meta charset="utf-8" /></span></span> <span><span> <title>Hello, Flask</title></span></span> <span><span></head></span></span> <span><span><body></span></span> <span><span> {% if name %}</span></span> <span><span> <strong>Hello there, {{ name }}!</strong> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.</span></span> <span><span> {% else %}</span></span> <span><span> What's your name? Provide it after /hello/ in the URL.</span></span> <span><span> {% endif %}</span></span> <span><span></body></span></span> <span><span></html></span></span>
Tip: Flask developers often prefer flask-babel for date formatting over
strftime
for locale and timezone considerations. -
In
app.py
, import Flask’srender_template
function at the top:<span><span>from</span><span> flask </span><span>import</span><span> render_template</span></span>
-
Modify the
hello_there
function inapp.py
to userender_template
. Add a route to handle cases without a name.render_template
assumes templates are in thetemplates
folder. Template filenames are typically function-named but not required; you always specify the exact filename in code.<span><span>@app.route</span><span>(</span><span>"/hello/"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/hello/<name>"</name></span><span>)</span></span> <span><span>def</span><span> hello_there</span><span>(</span><span>name</span><span>=</span><span>None</span><span>):</span></span> <span><span> return</span><span> render_template(</span></span> <span><span> "hello_there.html"</span><span>,</span></span> <span><span> name=name,</span></span> <span><span> date=datetime.now()</span></span> <span><span> )</span></span>
The code is now simpler, focusing on data values, with markup and formatting in the template.
-
Run the program (inside or outside debugger, ⌃F5 (Windows, Linux Ctrl+F5)), navigate to
/hello/name
URLs, and observe the results. -
Try
/hello/<script>alert("Hi")</script>
to see Flask’s automatic escaping. The “name” value is plain text, not rendered as an HTML element, preventing script execution.
Serving Static Files in Web Coding
Static files come in two forms. First, files like stylesheets directly referenced by page templates, typically placed in a static
folder.
Second, files accessed in code, like API endpoints returning static files. Flask’s send_static_file
method serves static files from the app’s static
folder.
The following sections demonstrate both static file types.
Referencing Static Files in Templates
-
Create a folder named
static
in thehello_flask
folder. -
Inside
static
, createsite.css
with the following content. Observe VS Code’s CSS syntax highlighting and color preview:<span><span>.message</span><span> {</span></span> <span><span> font-weight</span><span>: </span><span>600</span><span>;</span></span> <span><span> color</span><span>: </span><span>blue</span><span>;</span></span> <span><span>}</span></span>
-
In
templates/hello_there.html
, add this line before</head>
to link the stylesheet:<span><span><link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" /></span></span>
Flask’s url_for tag creates the correct file path. It can programmatically control path generation using variables.
-
Replace the
<body>
content intemplates/hello_there.html
with the following, using themessage
style and displaying a message for/hello/
URLs without a name:<span><span><body></span></span> <span><span> {% if name %}</span></span> <span><span> <span class="message">Hello there, {{ name }}!</span> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.</span></span> <span><span> {% else %}</span></span> <span><span> <span class="message">What's your name? Provide it after /hello/ in the URL.</span></span> <span><span> {% endif %}</span></span> <span><span></body></span></span>
-
Run the app, navigate to a
/hello/name
URL, and the message should render in blue. Stop the app when done.
Serving Static Files from Code
-
In the
static
folder, createdata.json
with this sample data:<span><span>{</span></span> <span><span> "01": {</span></span> <span><span> "note": "This data is very simple because we're demonstrating only the mechanism."</span></span> <span><span> }</span></span> <span><span>}</span></span>
-
In
app.py
, add a function with the route/api/data
to return the static data file usingsend_static_file
:<span><span>@app.route</span><span>(</span><span>"/api/data"</span><span>)</span></span> <span><span>def</span><span> get_data</span><span>():</span></span> <span><span> return</span><span> app.send_static_file(</span><span>"data.json"</span><span>)</span></span>
-
Run the app and go to
/api/data
to see the static file returned. Stop the app afterward.
Creating Multi-Page Web Apps with Base Templates
Most web apps have multiple pages with shared elements. Base templates in Flask allow separating common elements for reuse across pages through template inheritance.
Using code snippets in VS Code streamlines creating new page templates that extend a base template, avoiding repetitive copy-pasting.
Creating a Base Page Template and Styles
A base template contains shared page parts like CSS and script references. It defines block tags ({% block <name> %}{% endblock %}
) for overriding in extending templates.
-
In
templates
, createlayout.html
with the following content, defining “title” and “content” blocks. It includes a nav bar with links to Home, About, and Contact pages (created later), usingurl_for
for route-based link generation:<span><span><span><!DOCTYPE html></span></span> <span><span><html lang="en"></span></span> <span><span><head></span></span> <span><span> <meta charset="utf-8" /></span></span> <span><span> <title>{% block title %}{% endblock %}</title></span></span> <span><span> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" /></span></span> <span><span></head></span></span> <span><span><body></span></span> <span><span> <div class="navbar"></span></span> <span><span> <a href="{{ url_for('home') }}" class="navbar-brand">Home</a></span></span> <span><span> <a href="{{ url_for('about') }}" class="navbar-item">About</a></span></span> <span><span> <a href="{{ url_for('contact') }}" class="navbar-item">Contact</a></span></span> <span><span> </div></span></span> <span><span> <div class="body-content"></span></span> <span><span> {% block content %}</span></span> <span><span> {% endblock %}</span></span> <span><span> <hr/></span></span> <span><span> <footer></span></span> <span><span> <p>© 2018</p></span></span> <span><span> </footer></span></span> <span><span> </div></span></span> <span><span></body></span></span> <span><span></html></span></span>
-
Add these styles to
static/site.css
below the existing “message” style and save. These styles are for demonstration and not responsive design:<span><span>.navbar</span><span> {</span></span> <span><span> background-color</span><span>: </span><span>lightslategray</span><span>;</span></span> <span><span> font-size</span><span>: </span><span>1em</span><span>;</span></span> <span><span> font-family</span><span>: </span><span>'Trebuchet MS'</span><span>, </span><span>'Lucida Sans Unicode'</span><span>, </span><span>'Lucida Grande'</span><span>, </span><span>'Lucida Sans'</span><span>, </span><span>Arial</span><span>, </span><span>sans-serif</span><span>;</span></span> <span><span> color</span><span>: </span><span>white</span><span>;</span></span> <span><span> padding</span><span>: </span><span>8px</span><span> 5px</span><span> 8px</span><span> 5px</span><span>;</span></span> <span><span>}</span></span> <span><span>.navbar</span><span> a</span><span> {</span></span> <span><span> text-decoration</span><span>: </span><span>none</span><span>;</span></span> <span><span> color</span><span>: </span><span>inherit</span><span>;</span></span> <span><span>}</span></span> <span><span>.navbar-brand</span><span> {</span></span> <span><span> font-size</span><span>: </span><span>1.2em</span><span>;</span></span> <span><span> font-weight</span><span>: </span><span>600</span><span>;</span></span> <span><span>}</span></span> <span><span>.navbar-item</span><span> {</span></span> <span><span> font-variant</span><span>: </span><span>small-caps</span><span>;</span></span> <span><span> margin-left</span><span>: </span><span>30px</span><span>;</span></span> <span><span>}</span></span> <span><span>.body-content</span><span> {</span></span> <span><span> padding</span><span>: </span><span>5px</span><span>;</span></span> <span><span> font-family</span><span>:</span><span>'Segoe UI'</span><span>, </span><span>Tahoma</span><span>, </span><span>Geneva</span><span>, </span><span>Verdana</span><span>, </span><span>sans-serif</span><span>;</span></span> <span><span>}</span></span>
Running the app now won’t show changes as the base template isn’t yet used. Continue to the next sections.
Creating a Code Snippet for Web Coding Templates
To speed up creating templates extending layout.html
, a VS Code code snippet can initialize new template files. Snippets ensure consistency and reduce copy-paste errors.
-
In VS Code, go to File > Preferences > Configure Snippets.
-
Select html from the list (“html.json” under Existing Snippets if you’ve created snippets before).
-
In
html.json
, add this entry within the curly braces. (Comments in the original tutorial JSON are omitted here for brevity but explain snippet details):<span><span>"Flask Tutorial: template extending layout.html"</span><span>: {</span></span> <span><span> "prefix"</span><span>: </span><span>"flextlayout"</span><span>,</span></span> <span><span> "body"</span><span>: [</span></span> <span><span> "{% extends "layout.html" %}"</span><span>,</span></span> <span><span> "{% block title %}"</span><span>,</span></span> <span><span> "$0"</span><span>,</span></span> <span><span> "{% endblock %}"</span><span>,</span></span> <span><span> "{% block content %}"</span><span>,</span></span> <span><span> "{% endblock %}"</span></span> <span><span> ],</span></span> <span><span> "description"</span><span>: </span><span>"Boilerplate template that extends layout.html"</span></span> <span><span>},</span></span>
-
Save
html.json
(⌘S (Windows, Linux Ctrl+S)). -
Now, typing
flext
will offer the snippet as autocomplete, as shown in the next section. You can also use Insert Snippet to choose from a menu.
Refer to Creating snippets for more on code snippets.
Adding Web Pages Using the Code Snippet
With the snippet created, quickly create templates for Home, About, and Contact pages.
-
In
templates
, createhome.html
. Typeflext
to see the snippet autocomplete:Selecting the completion inserts the snippet code with the cursor at the insertion point:
-
At the “title” block insertion point, type
Home
. In the “content” block, type<p>Home page for the Visual Studio Code Flask tutorial.</p>
. Save the file. These are the unique parts of this extended template. -
Create
about.html
intemplates
. Use the snippet, insertAbout us
and<p>About page for the Visual Studio Code Flask tutorial.</p>
in “title” and “content” blocks. Save. -
Repeat for
templates/contact.html
withContact us
and<p>Contact page for the Visual Studio Code Flask tutorial.</p>
in the blocks. -
In
app.py
, add functions for/about/
and/contact/
routes using their respective templates. Modify thehome
function to usehome.html
:<span><span># Replace the existing home function with the one below</span></span> <span><span>@app.route</span><span>(</span><span>"/"</span><span>)</span></span> <span><span>def</span><span> home</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"home.html"</span><span>)</span></span> <span><span># New functions</span></span> <span><span>@app.route</span><span>(</span><span>"/about/"</span><span>)</span></span> <span><span>def</span><span> about</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"about.html"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/contact/"</span><span>)</span></span> <span><span>def</span><span> contact</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"contact.html"</span><span>)</span></span>
Running the Multi-Page Web App
With all page templates set up, save app.py
, run the app, and open a browser. Navigate through pages to verify templates extend the base template correctly.
Note: If you don’t see the latest changes, a hard refresh might be needed to bypass cached files.
Optional Web Coding Activities
These optional steps can further enhance your Python and VS Code web coding workflow.
Creating a requirements.txt File for Your Web Coding Environment
When sharing your web app code, exclude the virtual environment folder. Instead, use a requirements.txt
file to list dependencies for environment recreation.
While you can create it manually, pip freeze
generates it based on installed libraries in the active environment:
- With your environment selected via Python: Select Interpreter, run Terminal: Create New Terminal (⌃⇧
(Windows, Linux Ctrl+Shift+
)) to open an activated terminal. - Run
pip freeze > requirements.txt
to create the file in your project folder.
Recipients can then use pip install -r requirements.txt
to reinstall the necessary packages (after creating their own virtual environment).
Note:
pip freeze
lists all installed packages, including unused ones, and specifies exact versions. You might adjust versions to ranges for flexibility. See Requirements Files in pip documentation.
Refactoring Your Web Coding Project for Development
For larger web coding projects, refactor app.py
into separate files for better organization and separation of concerns.
-
Create an app folder, like
hello_app
, to separate app files from project-level files likerequirements.txt
and.vscode
settings. -
Move
static
andtemplates
folders intohello_app
. -
In
hello_app
, createviews.py
for routes and view functions:<span><span>from</span><span> flask </span><span>import</span><span> Flask, render_template, send_static_file</span></span> <span><span>from</span><span> datetime </span><span>import</span><span> datetime</span></span> <span><span>from</span><span> . </span><span>import</span><span> app</span></span> <span><span>@app.route</span><span>(</span><span>"/"</span><span>)</span></span> <span><span>def</span><span> home</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"home.html"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/about/"</span><span>)</span></span> <span><span>def</span><span> about</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"about.html"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/contact/"</span><span>)</span></span> <span><span>def</span><span> contact</span><span>():</span></span> <span><span> return</span><span> render_template(</span><span>"contact.html"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/hello/"</span><span>)</span></span> <span><span>@app.route</span><span>(</span><span>"/hello/<name>"</name></span><span>)</span></span> <span><span>def</span><span> hello_there</span><span>(</span><span>name</span><span>=</span><span>None</span><span>):</span></span> <span><span> return</span><span> render_template(</span></span> <span><span> "hello_there.html"</span><span>,</span></span> <span><span> name=name,</span></span> <span><span> date=datetime.now()</span></span> <span><span> )</span></span> <span><span>@app.route</span><span>(</span><span>"/api/data"</span><span>)</span></span> <span><span>def</span><span> get_data</span><span>():</span></span> <span><span> return</span><span> send_static_file(</span><span>"data.json"</span><span>)</span></span>
-
In
hello_app
, create__init__.py
with:<span><span>import</span><span> flask</span></span> <span><span>app = flask.Flask(</span><span>__name__</span><span>)</span></span>
-
In
hello_app
, createwebapp.py
with:<span><span># Entry point for the application.</span></span> <span><span>from</span><span> . </span><span>import</span><span> app </span><span># For application discovery by the 'flask' command.</span></span> <span><span>from</span><span> . </span><span>import</span><span> views </span><span># For import side-effects of setting up routes.</span></span>
-
Update
launch.json
to point to the new startup object:<span><span>"env"</span><span>: {</span></span> <span><span> "FLASK_APP"</span><span>: </span><span>"hello_app.webapp"</span></span> <span><span>},</span></span>
-
Delete the original
app.py
in the project root. -
Your project structure should now look like:
-
Run the app in the debugger again. To run outside the debugger, use these terminal steps:
- Set
FLASK_APP
environment variable. (e.g.,export FLASK_APP=hello_app.webapp
on Linux/macOS,$env:FLASK_APP=hello_app.webapp
in PowerShell,set FLASK_APP=hello_app.webapp
in Command Prompt on Windows). - Navigate into
hello_app
and runpython -m flask run
.
- Set
Containerizing Your Flask Web App with Docker
The Docker extension simplifies building, managing, and deploying containerized apps from VS Code. To containerize your Flask app, see the Python in a container tutorial for steps on:
- Creating a
Dockerfile
for a simple Python container. - Building, running, and verifying a Flask app in a container.
- Debugging the containerized app.
For issues, check the Python extension Discussions Q&A.
Next Steps in Web Coding
Congratulations on completing this Flask in VS Code tutorial and enhancing your web coding skills!
The tutorial’s code is on GitHub: python-sample-vscode-flask-tutorial.
Explore the Jinja2 documentation for advanced template features and the Template Designer Documentation for template language details. Also, review the official Flask tutorial and extensions documentation.
To deploy your app, see Deploy Python apps to Azure App Service using Docker Containers. Azure also offers App Service on Linux for web app deployment from VS Code.
Further VS Code articles relevant to Python web coding include:
02/06/2025