Search code examples
pythonflaskruntime-error

How to fix "RuntimeError: Working outside of application context." when creating blueprints with Flask?


I'm trying to create a Blueprint and ran into this problem:

Traceback (most recent call last):
  File "C:\Users\Max\PycharmProjects\python1\flask_first\__init__.py", line 3, in <module>
    from models import db
  File "C:\Users\Max\PycharmProjects\python1\flask_first\models.py", line 5, in <module>
    current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'  # access to the SQL
  File "C:\python3.9\lib\site-packages\werkzeug\local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "C:\python3.9\lib\site-packages\werkzeug\local.py", line 306, in _get_current_object
    return self.__local()
  File "C:\python3.9\lib\site-packages\flask\globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

I've already done a lot of research and nothing works for me (or I'm just not looking properly enough).

This is the models.py code:

from flask_sqlalchemy import SQLAlchemy
from flask import current_app


current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'  # access to the SQL
current_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(current_app)

class users(db.Model):
    __tablename__ = 'users'
    _id = db.Column('id', db.Integer, primary_key=True)
    name = db.Column(db.String(80))
    email = db.Column(db.String(120))
    password = db.Column(db.Integer)

    def __init__(self, name, email, password):
        self.name = name
        self.email = email
        self.password = password

And this is the __init__.py:

from datetime import timedelta
from flask import Flask
from models import db
from flask_first.admin.second import second

def create_app():
    app = Flask(__name__)
    with app.app_context():

        db.init_app(app)
    return app

create_app.secret_key = 'hello world'
create_app.permanent_session_lifetime = timedelta(minutes=5)  # setting the time for long-lasting session

if __name__ == '__main__':
    db.create_all()
    create_app.run(debug=True)

Here is a screenshot of my structure:
file/folder structure


Solution

  • Here I'll expand on my comment into an answer.

    Python executes your code line-by-line, and that includes import statements. As the error indicates, when it entered __init__.py and got to the from models import db line, it immediately jumped to models.py, and started executing your lines there.

    Traceback (most recent call last):
      File "...\__init__.py", line 3, in <module>
        from models import db
      File "...\models.py", line 5, in <module>
        current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'
    

    At this point, the imported current_app does not exist yet, because the create_app from __init__.py seems to have not been called yet. This is where you'll get the common Flask error of "working outside of application context:

    RuntimeError: Working outside of application context.
    
    This typically means that you attempted to use functionality that needed
    to interface with the current application object in some way. To solve
    this, set up an application context with app.app_context().  See the
    documentation for more information.
    

    Most of the time you get this type of error, the solution is to reorder your initialization codes. Make sure that the Flask app instance is already created before you do anything else. It should usually be the first thing your code does.

    Following the Quickstart tutorial from flask-sqlalchemy, you can put the db object initialization near the app initialization.

    # Create app object
    app = Flask(__name__)
    
    # Set configs
    app.config['...'] = ...
    
    # Create db object
    db = SQLAlchemy(app)
    

    The app and db objects typically reside together in some top-level main module. Then, in your other sub-modules (controllers, models, etc.) where you need to setup each component separately, import the app and/or db from the main module:

    from some_main_module import app, db
    
    # Do stuff with app and db