As the title of the question says, all the routes which are not in the main file i.e. app.py
are throwing Not Found 404
error. Below are the details of my small project:
Directory structure:
server
-> user
-> __init__.py
-> models.py
-> routes.py
-> app.py
-> __init__.py
app.py
:
from flask import Flask
app = Flask(__name__)
from user import routes
@app.route('/') # THIS ROUTE WORKS
def index():
return '<h1>HOME</h1>'
if __name__ == '__main__':
app.run(debug = True)
routes.py
:
from app import app
@app.route('/register', methods=['GET']) # THIS DOESN'T WORK - 404 NOT FOUND ERROR
def register_user():
return '<h1>Register a user!</h1>'
I cannot find out what is wrong here, I also tried the Blueprint
method but I keep getting circular import error
.
EDIT:
Flask Blueprint approach:
app.py:
from flask import Flask
from pymongo import MongoClient
app = Flask(__name__)
mongo_client = MongoClient(mongoUri)
db = mongo_client[DB_NAME]
from user.routes import bp
app.register_blueprint(bp)
@app.route('/')
def index():
return '<h1>HOME</h1>'
if __name__ == '__main__':
app.run(debug = True)
user/routes.py:
from flask import Blueprint, render_template_string
from user.models import User # if I comment this, it starts working...
bp = Blueprint('user', __name__)
@bp.route('/register', methods=['POST'])
def register_user():
user = User()
user.register()
return user
@bp.route('/register', methods=['GET'])
def check_user():
return render_template_string('<h1>User Registered</h1>')
user/models.py:
import uuid
from urllib import request
from flask import jsonify
from app import db # fishy...
class User(object):
def register(self):
user = {
'_id': uuid.uuid4().hex,
'email': request.form.get('email'),
'password': request.form.get('password'),
}
db.users.insert_one(user):
return jsonify(user), 200
I'm now getting this error as I mentioned earlier:
Traceback (most recent call last):
File "D:\project\server\app.py", line 10, in <module>
from user.routes import bp
File "D:\project\server\user\routes.py", line 2, in <module>
from user.models import User
File "D:\project\server\user\models.py", line 5, in <module>
from app import db
File "D:\project\server\app.py", line 10, in <module>
from user.routes import bp
ImportError: cannot import name 'bp' from partially initialized module 'user.routes' (most likely due to a circular import) (D:\project\server\user\routes.py)
CodePudding user response:
You need to first define a Blueprint, and then use that for your routes/APIs. In route.py
write this:
from flask import Blueprint, render_template_string
from user.models import User
bp = Blueprint('user', __name__)
@bp.route('/register', methods=['POST'])
def register_user():
user = User()
user.register()
return user
@bp.route('/register', methods=['GET'])
def check_user():
return render_template_string('<h1>User Registered</h1>')
Then you need to import and register your blueprint. In app.py have this:
from flask import Flask
app = Flask(__name__)
from user.routes import bp
app.register_blueprint(bp)
@app.route('/')
def index():
return '<h1>HOME</h1>'
if __name__ == '__main__':
app.run(debug = True)
Have another file in the same directory as app.py
, you can call it extensions.py
:
from pymongo import MongoClient
mongo_client = MongoClient(mongoUri)
db = mongo_client[DB_NAME]```
And finally models.py
will look like this:
...
from extensions import db
...