Web Coding Tutorial: Building Flask Apps in Visual Studio Code

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:

  1. Install the Python extension for Visual Studio Code.
  2. Install Python 3. This tutorial is written for Python 3. You can choose from various options:
  3. 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.

  1. Create a new folder on your system for this tutorial, such as hello_flask.

  2. 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.

  3. 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.

  4. 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”.

  5. 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

  1. 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.

  2. 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>
  3. Still in app.py, define a function that returns content—a simple string in this case—and use Flask’s app.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.

  4. Save app.py (⌘S (Windows, Linux Ctrl+S)).

  5. Run the app in the Integrated Terminal with python -m flask run. This command starts the Flask development server, which by default looks for app.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.

  6. Ctrl+click the http://127.0.0.1:5000/ URL in the terminal to open the rendered page in your default browser.

  7. 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>
  8. Stop the app by pressing Ctrl+C in the terminal.

Tip: When using a filename other than app.py, such as webapp.py, you must set the environment variable FLASK_APP to your chosen filename. Flask’s development server will then use this variable instead of the default app.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.

  1. 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.)

  2. 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:

  3. 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.

  4. 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 the configurations array.

  5. Find the “Python: Flask” configuration. It includes "module": "flask",, instructing VS Code to run Python with -m flask when debugging starts. The env property defines the FLASK_APP environment variable, set to app.py by default, but modifiable to specify a different startup file. The args 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.

  6. Save launch.json (⌘S (Windows, Linux Ctrl+S)). Select the Python: Flask configuration from the debug configuration dropdown.

  7. 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.

  8. 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 to http://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.

  9. Use Step Over to execute now = datetime.now().

  10. On the left, the Variables pane displays local variables like now and arguments like name. 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 like now might disrupt program flow. Modifications are usually for correcting initial incorrect values.

  11. 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. Select now.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.

  12. 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>
  13. Step through more code lines if desired, then select Continue (F5) to resume execution. The browser will display the result:

  14. 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.

  15. 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 print statement to output the URL. It will appear in the terminal, allowing Ctrl+click to open it in a browser.

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-click Flask (in app = 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.

  1. Create a folder named templates in the hello_flask folder. Flask looks for templates here by default.

  2. Inside templates, create hello_there.html with the following content. It includes placeholders name and date 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.

  3. In app.py, import Flask’s render_template function at the top:

    <span><span>from</span><span> flask </span><span>import</span><span> render_template</span></span>
  4. Modify the hello_there function in app.py to use render_template. Add a route to handle cases without a name. render_template assumes templates are in the templates 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.

  5. Run the program (inside or outside debugger, ⌃F5 (Windows, Linux Ctrl+F5)), navigate to /hello/name URLs, and observe the results.

  6. 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

  1. Create a folder named static in the hello_flask folder.

  2. Inside static, create site.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>
  3. 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.

  4. Replace the <body> content in templates/hello_there.html with the following, using the message 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>
  5. 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

  1. In the static folder, create data.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>
  2. In app.py, add a function with the route /api/data to return the static data file using send_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>
  3. 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.

  1. In templates, create layout.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), using url_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>
  2. 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.

  1. In VS Code, go to File > Preferences > Configure Snippets.

  2. Select html from the list (“html.json” under Existing Snippets if you’ve created snippets before).

  3. 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>
  4. Save html.json (⌘S (Windows, Linux Ctrl+S)).

  5. 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.

  1. In templates, create home.html. Type flext to see the snippet autocomplete:

    Selecting the completion inserts the snippet code with the cursor at the insertion point:

  2. 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.

  3. Create about.html in templates. Use the snippet, insert About us and <p>About page for the Visual Studio Code Flask tutorial.</p> in “title” and “content” blocks. Save.

  4. Repeat for templates/contact.html with Contact us and <p>Contact page for the Visual Studio Code Flask tutorial.</p> in the blocks.

  5. In app.py, add functions for /about/ and /contact/ routes using their respective templates. Modify the home function to use home.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:

  1. With your environment selected via Python: Select Interpreter, run Terminal: Create New Terminal (⌃⇧(Windows, Linux Ctrl+Shift+)) to open an activated terminal.
  2. 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.

  1. Create an app folder, like hello_app, to separate app files from project-level files like requirements.txt and .vscode settings.

  2. Move static and templates folders into hello_app.

  3. In hello_app, create views.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>
  4. 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>
  5. In hello_app, create webapp.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>
  6. 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>
  7. Delete the original app.py in the project root.

  8. Your project structure should now look like:

  9. Run the app in the debugger again. To run outside the debugger, use these terminal steps:

    1. 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).
    2. Navigate into hello_app and run python -m flask run.

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

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *