2018-07-23T17:01:26Z

Setting Up a Flask Application in PyCharm

In this short article and video I want to give you a few tips on setting up a PyCharm project for your Flask application. The idea is to set up a Flask application so that it can be executed, debugged, and tested from inside PyCharm Community Edition, which is fantastic IDE for Python that is completely free to download and use. If you want to see me go through the exercise, watch the video below. Then you can come to the article if you want a quick reference and summary of the steps required.

Creating a Flask Project in PyCharm

This part is very simple. All you need to do to create your Flask project is to start PyCharm, select Open, and then choose the top-level directory of your application. PyCharm will create a new project and open it. The left sidebar will now show you a tree structure with all the files in your project.

Adding a Run and Debug Configuration

One of the first things you'll probably want to do is run your project. PyCharm works with the concept of "configurations", which are sets of parameters that define a run or debug task. To create or edit configurations you have to select Run|Edit Configurations... from the menu. If this option appears disabled, you just need to wait a little bit and let PyCharm complete its initial background parsing of the project.

To create a new configuration, click the + sign, and then select Python. For the Name field, enter a description of this configuration, such as "webapp". I like to check the Single Instance Only option, because for a web application it isn't very useful to run multiple instances.

Under Script path you need to select the flask tool, which is located in the bin directory of your virtual environment. Here you can use the little ... button to the right to browse and select this script. If you store your virtual environments outside of your project, or if you use a virtual environment wrapper such as pipenv which has its own location for virtualenvs, you will need to find out where the virtualenv is located and browse to that directory and then down into bin to find the flask command. If your virtualenv is in the same directory as your project this is much easier to do. I should note that if you are doing this on Windows, your virtualenv is not going to have a "bin" subdirectory. On Windows look for a Scripts subdirectory, and inside it look for a flask.exe file to select.

In the Parameters field you are going to enter run. This combined with the previous option configure PyCharm to run the familiar flask run command.

As I'm sure you also remember, the flask command requires a FLASK_APP environment variable to point to your Flask application. This variable needs to be defined in the Environment variables section. The value of the variable will be the same value you use when you run your application from the command line. If you are using a .flaskenv file in your project and you have the python-dotenv package installed, then you are all set, the environment variable will be imported from there.

The final change you need to make is to set the Working directory to point to the top-level directory of your project instead of to the location of the flask command.

You can now close the configuration window. The dropdown on the top-right of your main PyCharm window should now be set to the configuration you just added. If you now click the green "play" button your project should start, and if instead you click the green "bug" button the project will start under the debugger. Running with the debugger is very useful, because you can set breakpoints to stop the program execution and inspect variables or run a part of your application step by step.

Running Unit Tests

In addition to being able to run and debug your application, it is useful to have PyCharm run your unit tests. This requires a second configuration to be added to the project. So go back to the Run|Edit Configurations... menu option, and then click the + button once again, to create a new configuration. This time select the Python tests configuration type, and then pick the test runner that you would like to use. In the video demonstration above I picked Unittests, which is the runner based on the Python's unittest package.

Set the name of the configuration to tests of something similar. In the Target field make sure Script path is selected, and then choose the directory where your tests are located by clicking on the ... button to the right. In the Pattern field, enter a file pattern that applies to all the modules that contain tests. A few common patterns are test_*.py, *_test.py or *test*.py. To complete the test configuration, set the Working directory field to the top-level directory of your project.

After you close the configurations window, the dropdown in the top right of the PyCharm window will have tests selected. You can use this dropdown to go back to the webapp configuration when you need to. With tests selected, you can click the green run button to run your unit tests. PyCharm detects you are running tests, so it uses a dedicated panel in the bottom portion of the window to show you how the tests are doing. Any tests that fail will be displayed, and if you click on each one you can see the output it produced. You can also opt to run the tests under the debugger by clicking the green bug button, and that gives you the power to set breakpoints and run a specific part of a test step by step.

PyCharm also adds a little run button on the sidebar, next to each unit test function or method, and this is extremely convenient, as it allows you to run or debug a single test just by clicking its button.

Improved Debug Configuration

If you've got to this point, your project is nicely configured to run under PyCharm, but there is one detail that is missing. When your Flask application crashes, you know that there are two possible outcomes. If debug mode is not enabled, the client receives a 500 status code, and if debug mode is enabled, you are thrown into the browser-based debugger. When you run your application under the PyCharm debugger, it would be nice if crashes would stop the application at the crash point so that you can inspect variables and figure out what went wrong. Unfortunately due to a bug that has existed in Flask for a long time, this does not work if you configure your PyCharm project as I shown you above. More specifically, this is a bug that affects Flask applications that are started with the flask run command, but works well with the old app.run() method of running the application.

If you want to take advantage of the PyCharm debugger when your application crashes, you have to switch to app.run(). First, make sure your application's main script (which is usually the script that you set in the FLASK_APP environment variable) has this at the bottom:

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

This creates an alternative way to start the Flask application, without affecting the flask run command, which you can continue to use when you need to. The app.run() call that I added enables debug mode, but turns off the debugger and the reloader, so that they don't interfere with PyCharm. The passthrough_errors option is the key to make crashes reach the PyCharm debugger. Unfortunately this option cannot be set when you start your application via flask run.

The next change is to modify the run configuration in PyCharm to start the application through the app.run() call. Select the webapp configuration in the top-right corner of the PyCharm window, and then go back to Run|Edit Configurations.... Change the Script path field to point to your main script, the one that now has the app.run() call. The Parameters field must be empty, so clear the "run" that was there from before. The FLASK_APP environment variable does not need to be set when using app.run(), so you can remove it from the configuration, although it doesn't hurt anything to leave it there.

If you now start the application, any crashes triggered by exceptions will reach PyCharm, which will stop the application and show you the location of the crash, an interactive stack trace, and the ability to check variable values.

Conclusion

I hope this was a useful guide to get started with PyCharm. Note that I have done a similar step-by-step setup for the Visual Studio Code IDE, which will allow you to compare these two IDEs.

Do you have any other useful set up steps when you work with PyCharm? Let me know below in the comments!

37 comments

  • #26 Rakesh Srinivasa said 2019-12-21T19:01:22Z

    Hi Miguel,

    Thanks for the wonderful Video,i have a problem where in using pycharm,it says application is running in localhost but the browser gives "Not Found"

  • #27 Miguel Grinberg said 2019-12-22T10:40:06Z

    @Rakesh: A not found error means that the URL that you are requesting is not implemented in the server, it does not mean that the server isn't running. So you need to check the URL.

  • #28 Steven said 2020-01-19T18:12:11Z

    Somehow I don't see the database files.

    I go the following errors installing the requirements:

    Failed building wheel for alembic Failed building wheel for blinker Failed building wheel for dominate Failed building wheel for Flask-Bootstrap Failed building wheel for Flask-Mail Failed building wheel for Flask-Migrate Failed building wheel for Flask-Moment Failed building wheel for itsdangerous Failed building wheel for Mako Failed building wheel for Markdown Failed building wheel for MarkupSafe Failed building wheel for python-editor Failed building wheel for SQLAlchemy Failed building wheel for visitor Failed building wheel for WTForms Failed building wheel for Flask-Script

    And now I do not see the data-dev.sqlite file after running deploy. Am I missing some dependency? Thanks!

  • #29 Miguel Grinberg said 2020-01-19T18:37:26Z

    @Steven: try creating a brand new virtualenv, the one that you are using appears to be bad.

  • #30 yueyue.li said 2020-03-28T16:48:48Z

    I am reading your book: Flask Web Development, 2nd Edition I am reading your blog for how to integrate FLASK with PyCharm Community I am QA and is your fun Thank you!

    As a newbie, there is a sentence not exact: "If you are using a .flaskenv file in your project, then you are all set, the environment variable will be imported from there."

    It may be better to say: first you install the python-dotenv package, then use the .flaskenv

    Thank you again and your wonderful book and blog

  • #31 C21 said 2020-07-12T15:37:37Z

    Hi miguel, ive just tried running the app for the first time having followed through but im getting the following errors saying app is not defined?

    Traceback (most recent call last): File "/Users//Documents/Flasky/flasky/venv/bin/flask", line 8, in <module> sys.exit(main()) File "/Users//Documents/Flasky/venv/lib/python3.8/site-packages/flask/cli.py", line 967, in main cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None) ... File "/Users//Documents/Flasky/app.py", line 1, in <module> @app.route('/login/<int:city_id>', methods=["GET", "POST"]) NameError: name 'app' is not defined

  • #32 Miguel Grinberg said 2020-07-12T22:35:36Z

    @C21: the app variable is undefined in your app.py file. You forgot to define the application instance, or you put it in another file and forgot to import it before you use it.

  • #33 C21 said 2020-07-16T08:19:17Z

    Thanks Miguel, really appreciate it.

  • #34 Jim Brousseau said 2020-08-14T22:55:51Z

    I was following your video and ran into some problems running the app. First I was getting an error about time.clock() being invalid and found that I needed to update mako and sqlalchemy, however I needed to update the flask_sqlalchemy/init.py to change from time.clock() to time.process_time(). Now I get: D:\GitHub\flasky\venv\Scripts\python.exe D:/GitHub/flasky/venv/Scripts/flask.exe run * Serving Flask app "flasky" * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 127.0.0.1 - - [14/Aug/2020 15:39:24] "GET / HTTP/1.1" 500 - Error on request: Traceback (most recent call last): File "D:\GitHub\flasky\venv\Lib\site-packages\flask\app.py", line 1612, in full_dispatch_request rv = self.dispatch_request() File "D:\GitHub\flasky\venv\Lib\site-packages\flask\app.py", line 1598, in dispatch_request return self.view_functionsrule.endpoint File "D:\GitHub\flasky\app\main\views.py", line 52, in index pagination = query.order_by(Post.timestamp.desc()).paginate( File "D:\GitHub\flasky\venv\Lib\site-packages\flask_sqlalchemy_init.py", line 475, in paginate items = self.limit(per_page).offset((page - 1) * per_page).all() File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 3341, in all return list(self) File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 3503, in iter__ return self._execute_and_instances(context) File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 3528, in _execute_and_instances result = conn.execute(querycontext.statement, self._params) File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 1014, in execute return meth(self, multiparams, params) File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\sql\elements.py", line 298, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 1127, in _execute_clauseelement ret = self._execute_context( File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 1317, in _execute_context self._handle_dbapi_exception( File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 1511, in _handle_dbapi_exception util.raise( File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\util\compat.py", line 178, in raise_ raise exception File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 1277, in _execute_context self.dialect.do_execute( File "D:\GitHub\flasky\venv\Lib\site-packages\sqlalchemy\engine\default.py", line 593, in do_execute cursor.execute(statement, parameters) sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: posts [SQL: SELECT posts.id AS posts_id, posts.body AS posts_body, posts.body_html AS posts_body_html, posts.timestamp AS posts_timestamp, posts.author_id AS posts_author_id FROM posts ORDER BY posts.timestamp DESC LIMIT ? OFFSET ?] [parameters: (20, 0)] (Background on this error at: http://sqlalche.me/e/13/e3q8) It appears that the database is not created or something similar.

    BTW, I have your book on Flask. Great book.

  • #35 Miguel Grinberg said 2020-08-14T22:59:39Z

    @Jim: the error is "no such table: posts". You did not create this table in your database.

  • #36 Eric said 2020-11-27T06:01:33Z

    Hi Miguel, Every time I try to install the requirements (from your video), I encounter the following error:

    Collecting MarkupSafe==1.0 Using cached MarkupSafe-1.0.tar.gz (14 kB)

    ERROR: Command errored out with exit status 1: command: /Users/erichanson/flasky/venv/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-install-yfjw5uw4/MarkupSafe/setup.py'"'"'; __file__='"'"'/private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-install-yfjw5uw4/MarkupSafe/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-pip-egg-info-vfi5uywi cwd: /private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-install-yfjw5uw4/MarkupSafe/ Complete output (5 lines): Traceback (most recent call last): File "&lt;string&gt;", line 1, in &lt;module&gt; File "/private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-install-yfjw5uw4/MarkupSafe/setup.py", line 6, in &lt;module&gt; from setuptools import setup, Extension, Feature ImportError: cannot import name 'Feature' from 'setuptools' (/Users/erichanson/flasky/venv/lib/python3.8/site-packages/setuptools/__init__.py)

    Could you help? Thanks.

  • #37 Miguel Grinberg said 2020-11-27T08:00:49Z

    @Eric: Change MarkupSafe from version 1.0 to version 1.1.1 and then you should be fine.

Leave a Comment