user9410135
user9410135

Reputation:

Flask ImportError: cannot import name ''

This is my application tree, since this application is relatively big, I am using blueprints divisional structure to structure it.

RPOSS
├───.idea
├───app
│   ├───customer_panel
│   │   ├───static
│   │   ├───templates
│   │   └───__pycache__
│   ├───owner_panel
│   │   ├───static
│   │   │   └───js
│   │   │       └───lib
│   │   ├───templates
│   │   └───__pycache__
│   ├───progressive_panel
│   │   ├───static
│   │   ├───templates
│   │   └───__pycache__
│   ├───static
│   ├───templates
│   └───__pycache__
├───Include
├───instance
│   └───__pycache__
├───Lib
├───Scripts
└───__pycache__

RPOSS/app/run.py:

from app import app
app.run()

RPOSS/app/__init__.py:

from app.views import Rmod
from app.customer_panel.views import Cmod
from app.owner_panel.views import Omod
from app.progressive_panel.views import Smod
from instance.config import engine
from sqlalchemy.orm import sessionmaker


app = Flask(__name__,
        static_folder='./static',
        instance_relative_config=True,
        instance_path=r"C:\Users\Orbit\RPOSS\instance")
app.config.from_object('config')
app.config.from_pyfile('config.py')

bcrypt = Bcrypt(app)
Session = sessionmaker(bind=engine)
db_session = Session()
Bootstrap(app)

app.register_blueprint(Cmod)
app.register_blueprint(Rmod, url_prefix="/RPOSS")
app.register_blueprint(Omod, url_prefix="/RPOSS/owner_panel")
app.register_blueprint(Smod, url_prefix="/RPOSS/progressive_panel")

RPOSS/app/views.py:

from flask import ...
from app.forms import ...
from app.models import ClassName


Rmod = Blueprint('RPOSS', __name__,
             template_folder='templates',
             static_folder='static')

RPOSS/app/models.py:

from app import bcrypt
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import ... 


Base = declarative_base()


class ClassName(Base):
    # I am using bcrypt here to hash values
    ...

Note: I ran the model and the database was created and everything was working fine.

Traceback (most recent call last):
  File "C:/Users/Orbit/RPOSS/app/models.py", line 1, in <module>
    from app import bcrypt
  File "C:\Users\Orbit\RPOSS\app\__init__.py", line 7, in <module>
    from app.views import Rmod
  File "C:\Users\Orbit\RPOSS\app\views.py", line 3, in <module>
    from app.models import Employee
  File "C:\Users\Orbit\RPOSS\app\models.py", line 1, in <module>
    from app import bcrypt
ImportError: cannot import name 'bcrypt'

Can someone help me figuring out what happened?

Upvotes: 1

Views: 5482

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124948

You have a circular import.

app.models tries to import app to resolve the name bcrypt:

  File "C:/Users/Orbit/RPOSS/app/models.py", line 1, in <module>
    from app import bcrypt

The app/__init__.py file first imports another module however, app.views:

  File "C:\Users\Orbit\RPOSS\app\__init__.py", line 7, in <module>
    from app.views import Rmod

This module wants to import from app.models:

  File "C:\Users\Orbit\RPOSS\app\views.py", line 3, in <module>
    from app.models import Employee

This is the file you started with, but you probably ran it as a script so was imported by Python as __main__, meaning Python will import it again under the app.model name.

But now you have a problem, because it imports app again:

  File "C:\Users\Orbit\RPOSS\app\models.py", line 1, in <module>
    from app import bcrypt

At this point, app has already been created, but has not yet completed importing. The name bcrypt has not yet been assigned to.

You need to move the name bcrypt to a line before you import app.model. Move the line from app.views import Rmod to below the bcrypt = Bcrypt(app) line, or use a separate function to import your blueprints later on.

I prefer using an Application Factory to set up the app and blueprints. Alter your __init__ method to import blueprints in the factory function.

Upvotes: 3

Related Questions