3

I would like to use the following basic authentication decorator in my blueprints:

def requires_auth(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        request_auth = request.authorization
        if not request_auth or not auth.authenticate(request_auth.username, request_auth.password):
            return api.response_auth_failed()
        return func(*args, **kwargs)
    return decorated

And in the blueprint:

@bp.route("/")
@requires_auth
def root():
  return "root"

But it relies on the flask_peewee.auth module which also requires a db instance, which requires the app instance as the Database() module uses the app for configuration:

db = Database(app)
auth = Auth(app, db)

I had this working before when the application was simpler by instantiating all of this in the one app.py file, but now I'd like to organize it a little better.

Would it be possible to move my db.Model definitions, and the above requires_auth decorator to another file, say a db_models.py module, and import the requires_auth decorator into my individual Blueprint definitions? How can I do that if I need access to the app object to create the db object?


Edit: I've reorganized my app to look like this: http://charlesleifer.com/blog/structuring-flask-apps-a-how-to-for-those-coming-from-django/ I put the requires_auth function in my auth.py module an I can import and use it in the view.py but when I try and import it into one of my blueprints it fails. I think it's because auth module imports the app module, and the blueprint is extending the app module so I'm getting a circular import. Any ideas?

Chris Matta
  • 3,263
  • 3
  • 35
  • 48

1 Answers1

3

As you've noted, I think the problem is your module organization. What if you create a decorators module that contains requires_auth?

Then you will structure your imports to flow like:

  1. app.py (instantiate app & db)
  2. auth.py (instantiate auth, imports from app.py)
  3. api.py (instantiate api, imports from app.py)
  4. decorators.py (define requires_auth, imports from auth and api)
  5. blueprints/views.py (imports from app.py, auth.py, api.py, decorators.py)
  6. main.py (imports app, auth, api, decorators, blueprints) and is entry-point for application.
coleifer
  • 24,887
  • 6
  • 60
  • 75
  • It was the fact that I was registering the blueprints in the app.py module instead of main.py. I'm now registering blueprints in the main.py module and avoiding any of the circular imports. This is also allowing me to define the `requires_auth` function in the auth module which makes sense. Thanks a lot. – Chris Matta Dec 16 '13 at 17:32