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.
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