I'm using Flask-OpenID for user logins in my silly practice app.
The first thing to do create an openid object, which is used later to decorate the login handlers (and other things):
oid = flask.ext.openid.OpenID(app, '/path/to/store')
@oid.loginhandler
def login():
...
@oid.after_login
def after_login():
...
However, I want to initialize Flask-OpenID in my app's __init__.py
file but use the OpenId object oid
in other files, like my app's views.py
file and possible others. What is the expected way to do this? How do flask developers usually make something like oid
global to the app?
In this similar question, the SQLAlchemy object is moved to the models
module but initialized somewhere else during application setup, which makes some sense because the db
object is coupled to the models. The OpenID object follows the same pattern. But I don't want to put oid
in views.py
; it clearly doesn't belong there. So where would you put it? I can think of solutions, but I want to know what flask developers usually do. Here are some ideas:
Put oid
in __init__.py
and initialize it there as well. In this option, how do you access oid
in another part of the app module?
Make a auth.py
file for objects and methods associated with Flask-OpenID and Flask-Login. Then auth.oid
would work anywhere in the app. Do I then create a new file for every extension that isn't coupled directly somewhere else? Is this overkill, or is it the right pattern for scaling up and staying organized?
Alternatively, create a single file for all of those little extension objects, perhaps called globals.py
or exts.py
. This seems awkward and kludgy. Or do most flask apps eventually have a random bucket for all this other crap that just needs to be located somewhere?
The three options have various trade offs (as you have discovered):
auth
in __init__.py
- this results in circular references between your views and your base app - it can work, but it makes it more difficult to factor (as moving two otherwise unrelated imports can result in an error).There is also a 4th option - add auth
to your view layer, as how you are authenticated is specific to your application logic (rather than your domain model, for example).
I would recommend avoiding #1 entirely (the extra cost of skipping the "two modules" phase to go straight to the "three or more modules phase" is negligible). Which of the remaining three options is right for your project is really specific to the project and the developers working on it.