2

I have 3 blueprints in a flask app and the dir structure is like:

main/
   __init__.py
   books/
   users/
   authors/
   apps/

Every package inisde main is a blueprint. In my main/__init__.py i have

from flask import Flask
from flask_pymongo import PyMongo

app = Flask(__name__)

from main.users.views import users
from main.admin.views import admin
app.register_blueprint(users, url_prefix='/api/users')

MONGO_HOST = os.environ['MONGO_HOST']
MONGO_PORT = os.environ['MONGO_PORT']

app.config["MONGO_URI"] = "mongodb://{}:{}/".format(MONGO_HOST, MONGO_PORT)
mongo = PyMongo(app)

How do I access mongo inside each blueprint ? Is this even correct way of using mongo here. in official documentation it says not to use something like db=Pymongo(app)

Ami Hollander
  • 2,435
  • 3
  • 29
  • 47
anekix
  • 2,393
  • 2
  • 30
  • 57

1 Answers1

0

I guess the answer comes too late for you, but eventually it will help anyways.

I usually exclude the database-lines in an external file, e.g. database.py. and then import the mongo instance in my app and in the blueprints, respectively. Please consider the example below. For the sake of completion and comprehension I also added other elements that make sense for the functions.

database.py

from flask_pymongo import PyMongo
mongo = PyMongo()

forms.py

from wtforms import Form
from wtforms.fields import BooleanField, PasswordField, StringField
from wtforms.validators import Email, Required

class LoginForm(Form):
    email = StringField('Email', validators=[Required(), Email('Not a valid email address')])
    password = PasswordField('Password',validators=[Required()])
    remember = BooleanField('Remember')

authentication.py

from flask import Blueprint, redirect, render_template, request
from flask_login import LoginManager, UserMixin, current_user, login_user
from werkzeug.security import check_password_hash
from database import mongo
from forms import LoginForm

authentication = Blueprint('authentication', __name__, template_folder='templates')

login_manager = LoginManager()
login_manager.login_view = 'authentication.log_in'

@authentication.route('/login', methods=['GET', 'POST'])
def log_in():
    if (current_user.is_authenticated):
        return redirect(url_for('get_index'))

    login_form = LoginForm(request.form)

    if (request.method == 'POST'):
        if (login_form.validate()):
            user_collection = mongo.db.user
            user = user_collection.find_one({'email':login_form.email.data})

            if (user) and (check_password_hash(user['password'],
                            login_form.password.data)):
                login_user(User(user), login_form.remember)
                return redirect(url_for('get_index'))
            else:
                return render_template('login.html', form=login_form)

    elif (request.method == 'GET'):
        return render_template('login.html', form=login_form)

class User(UserMixin):

    def __init__(self, user):
        super()
        self.id = user['_id']
        self.email = user['email']

    def get(user_id, mongo):
        user_collection = mongo.db.user
        user = user_collection.find_one({'_id':ObjectId(user_id)})
        return User(user)


@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id, mongo)

app.py

from flask import Flask, render_template, request
from flask_login import login_required

from authentication import authentication, login_manager
from database import mongo
from forms import LoginForm

app = Flask(__name__)
app.secret_key = os.urandom(24)

app.config['MONGO_URI'] = 'mongodb:27017/app'
mongo.init_app(app)

app.register_blueprint(authentication)
login_manager.init_app(app)

@app.route('/', methods=['GET'])
@login_required
def get_index():
    if (request.method == 'GET'):
        render_template('index.html')

if __name__ == '__main__':
    app.run(host="0.0.0.0")
Patrick Na
  • 119
  • 1
  • 9