Setting Up a Flask Application in PyCharm

Posted by
on under

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!

Become a Patron!

Hello, and thank you for visiting my blog! If you enjoyed this article, please consider supporting my work on this blog on Patreon!

39 comments
  • #26 Rakesh Srinivasa said

    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

    @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

    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

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

  • #30 yueyue.li said

    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

    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

    @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

    Thanks Miguel,
    really appreciate it.

  • #34 Jim Brousseau said

    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

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

  • #36 Eric said

    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 "<string>", line 1, in <module>
      File "/private/var/folders/cb/8kd21dtj6zg4_3zgjg8f43j80000gn/T/pip-install-yfjw5uw4/MarkupSafe/setup.py", line 6, in <module>
        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

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

  • #38 Joe said

    In trying to do this for the past hour, I can state that both PyCharm and Flask have moved from this set of instructions to a point where it no longer resembles anything that I'm seeing. I'm currently trying to get an application factory based flask app running and it just isn't working. Any chance there might be an update to this for 2021?

  • #39 Miguel Grinberg said

    @Joe: For the most part this article is up to date. There might be some minor UI changes in PyCharm since the time I did this, but overall the instructions are the same. I suggest you try to set up the same application I'm using first, then try your own once you have succeeded with mine.

Leave a Comment