2019-09-09T12:07:38Z

Setting Up a Flask Application in Visual Studio Code

As a follow up to my Setting Up a Flask Application in PyCharm article, today I'm going to show you how to set up your project with Visual Studio Code (Code, for short), which is a free and open source integrated development environment from Microsoft with great support for Python. Like I did in the previous article, you can see me going through all the required steps to set up an example project in the video below. After the video, I provide a short written summary of the process.

Creating a Project in Visual Studio Code

To open a project for the first time in Code you just use the File|Open menu option and select the top level folder of the project. I've found that sometimes Code does not detect a Python project until you open a file with the .py extension, so if you don't see a Python interpreter displayed in the status bar at the bottom of the Code window, just open a Python file to trigger the Python subsystem to initialize. Note that the official Python plugin for Code needs to be installed beforehand.

The status bar shows the selected Python interpreter for the project. In general I've seen code pick up virtual environments that are in the project folder directly. If your virtualenv is somewhere else, click the Python interpreter section of the status bar and then you will be given the option to select your interpreter.

Adding Run and Debug Configurations

In Code, run configurations for a project are created in the debugger section of the user interface. So click on the little bug icon on the left side, and then on the configuration list drop down next to the green "run" button. Because this is a new project, the configuration list is empty and only has an "Add Configuration" option. Click this option and then you will be prompted to select from a list of project types. Very conveniently Flask is one of the list options, so select that. The Flask configuration will then prompt you for the application location, which must be given exactly as you set it in the FLASK_APP environment variable.

The new run configuration is stored in a new file called .vscode/launch.json. Since this is a standard JSON file, you can make changes or tweaks as you see necessary. And if you plan on using the Code configuration often you can also add this file to source control so that it is preserved.

With the configuration created you can now run the application with or without debugging, either from the Debug menu or by using the green "play" icon. When the application is running its output is captured in the bottom panel of the Code window. A small floating toolbar also appears near the top of the window with a Stop button. If you are running with the debugger enabled, you can add breakpoints by clicking in the left margin of the corresponding lines of code. Other buttons in the floating debug toolbar are used to step through the code when the application stops at a breakpoint.

Configuring Unit Tests

By looking at the Code window you will not find any indication that you can add unit testing to your configuration. Unfortunately the support for testing is somewhat hidden. To define unit tests you need to open Code's command palette, using Ctrl+Shift+P (Windows, Linux) or Cmd+Shift+P (Mac). In the command palette, you can type "tests" to search and filter the long list of available functions. Once you locate the function "Python: Discover Tests" select it.

The Discover Tests function will detect that unit testing isn't configured and will ask you if you want to configure it. Click the "Enable and Configure a Test Framework" to begin the configuration process. The test configuration is done with guided prompts, like the run configuration. In the first prompt, you have to select your test runner, which can be unittest, pytest or nose. The second prompt is to select the directory within the project that has all the tests. The third and last prompt is to select the file pattern for the test files. For this third prompt in general I use the *test*.py pattern, which covers pretty much all naming conventions for test files.

When you complete the configuration Code will go off to discover tests in the project. You will also notice that now there is a new icon for tests in the left sidebar. You can click this option to see all the discovered tests, along with options to run or debug all the tests together, or a single test individually.

Better Debug Configuration

The project configuration at this point is almost complete. There is actually one small problem with it, that is not caused by Code but by an old bug in Flask. The problem occurs when the application crashes, at which point a normal Flask application would either show the in-browser debugger when you are in debug mode, or else just show an Internal Server Error page and log the exception to the terminal and/or log file. When working with Code, it would be desirable to have crashes reported in the Code debugger, and this is unfortunately not possible with the current configuration.

The problem is in Flask, which does not properly configure the bubbling up of errors for external debuggers, so any crashes will never make it into Code. The workaround to address this problem is to switch from the flask run method of starting the application to the older app.run() method, which has more configuration options, including one to specify that exceptions should not be caught by Flask and should be let bubble up into another debugger.

To do this, you have to add the familiar app.run() snippet of code to the module that contains the application:

if __name__ == '__main__':
    app.run(use_debugger=False, use_reloader=False, passthrough_errors=True)

This configures the alternative app.run() runner properly for Code, where there is no need to use the in-browser debugger or the reloader. The passthrough_errors option is the one that allows errors to bubble up, an option that is unfortunately not available when you run the application with flask run.

To complete this change you have to go into the .vscode/launch.json file and change the module setting, which was set to flask in the original configuration to the name of your module (without the .py extension). The args options contained run and a couple other options, which now are not needed, so this setting should be change into an empty list.

With these changes the application can properly report unexpected errors and crashes into the Code debugger. It's important to note that flask run can still be used when you want to run your application outside of Code.

Conclusion

I hope this was a useful article and video. You may want to also check out the article and video that I've made for the PyCharm IDE based on the same project.

5 comments

  • #1 Tiago said 2019-09-10T17:33:22Z

    Hi Miguel, I've been following all your posts and learning a lot. Please, could you prepare an article explaining for example: Where should we keep our business logic in Flask or Django ? What about Fat Model ? It could be very cool. Thanks.

  • #2 Miguel Grinberg said 2019-09-10T18:08:31Z

    @Tiago: Have you seen my longer tutorials, like the Mega-Tutorial or my O'Reilly book?

  • #3 Maulin Tolia said 2019-10-02T13:20:15Z

    Do you use a linter on vscode?

  • #4 Miguel Grinberg said 2019-10-02T13:25:07Z

    @Maulin: On some projects I do. But in general I have the linter running from tox, separately from vscode.

  • #5 Oleksis said 2019-10-02T19:34:26Z

    Thanks for the tips, i want add one tip is use the terminal integrantes shell of Git bash.exe in Windows, why default i get the error in Visual Code python debugger: ConnectionRefusedError [WinError 10061] Then my settings.json is: { .... "terminal.external.windows Exec": " C:\\Program Files\\Git\\bin\\bash.exe", "terminal.integrated.shell.windows": " C:\\Program Files\\Git\\bin\\bash.exe" }

Leave a Comment