0

I am following this tutorial to build a JWT based authentication system.

app.py:

from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'd0cad49580952003e6ae01499c7bb190a4b4f9a5babd866f47064707f7b78506'

api = Api(app)
db = SQLAlchemy(app)


@app.before_first_request
def create_tables():
    db.create_all()


import resources, models

api.add_resource(resources.UserRegistration, '/registration')


if __name__ == '__main__':
    app.run()

models.py:

from app import db


class UserModel(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(150), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)

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

    @classmethod
    def find_by_username(cls, username):
        return cls.query.filter_by(username=username).first()

    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

resources.py:

from flask_restful import Resource, reqparse
from models import UserModel


class UserRegistration(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name', help='This field cannot be blank', required=True)
        parser.add_argument('email', help='This field cannot be blank', required=True)
        parser.add_argument('password', help='This field cannot be blank', required=True)

        data = parser.parse_args()

        if UserModel.find_by_username(data['name']):
            return {'message': 'User {} already exists'.format(data['name'])}

        new_user = UserModel(
            name=data['name'],
            password=data['password'],
            email=data['email']
        )
        try:
            new_user.save_to_db()
            return {
                'status': 'User {} was created'.format(data['username'])}

        except:
            return {'message': 'Something went wrong'}, 500

When I run app.py, I get the following error:

Traceback (most recent call last):
  File "G:\python\PycharmProjects\vumonic\app.py", line 19, in <module>
    import resources, models
  File "G:\python\PycharmProjects\vumonic\resources.py", line 2, in <module>
    from models import UserModel
  File "G:\python\PycharmProjects\vumonic\models.py", line 1, in <module>
    from app import db
  File "G:\python\PycharmProjects\vumonic\app.py", line 21, in <module>
    api.add_resource(resources.UserRegistration, '/registration')
AttributeError: module 'resources' has no attribute 'UserRegistration'

This error dissapears when I remove from models import UserModel from resources.py.

I cannot figure out the reason for the error.

I am using Flask==1.1.2, Flask-SQLAlchemy==2.4.4 and Flask-RESTful==0.3.8

This is the first time Iam developing an API so any help would be appreciated.

2
  • You have a circular dependency - app imports models which imports app. Commented Jul 28, 2020 at 11:18
  • @EugenePakhomov I tried removing import models, but it has no effect on the error. Commented Jul 28, 2020 at 11:24

1 Answer 1

1

you are facing circular import issue.

When Python imports a module, it checks the module registry to see if the module was already imported. If the module was already registered, Python uses that existing object from cache. The module registry is a table of modules that have been initialized and indexed by module name. This table can be accessed through sys.modules.

If it was not registered, Python finds the module, initializes it if necessary, and executes it in the new module's namespace.

to know more about circular import you can read the article:

https://stackabuse.com/python-circular-imports/

https://www.stefaanlippens.net/circular-imports-type-hints-python.html

this tutorial of Miguel Grinberg is a life savior https://www.youtube.com/watch?v=NH-8oLHUyDc&t=3205s

Sign up to request clarification or add additional context in comments.

2 Comments

It was indeed acircular import issue but it wasn't caused because of importing flask ,as flask is a library and i think it is the only way to import it.
i forgot to edit the description. i had to answer similar question where his script name was 'flask'. forgot to eliminate the line, i hope your issue has been resolved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.