0

I have main.py and app.py. app.py contains create_app() which returns the app object. main.py calls create_app(). I have to construct a mutable global object in main.py. This global object takes app as input parameter. This seems complex to me in python. How do I possibly achieve this global object construction when the application starts up?

Specifically, I am using flask_oidc and needs to construct an oidc = OpenIDConnect(app) in main.py and makes oidc object available in other controller .py files. This oidc object will store user info and validates if a user is authenticated.

Any advice and insight is appreciated.

Kok How Teh
  • 3,298
  • 6
  • 47
  • 85

1 Answers1

1

You can create a module that initialize your oidc object at the start of the application

helper.py

oidc = None # global instance

def init_oidc(app):
  # initalise the oidc here and assign to the global variable
  global oidc
  oidc = OpenIDConnect(app)
  return oidc

main.py

import init_oidc from helper


app = create_app()
# init only once at the start of the application
oidc = init_oidc(app)

In other controller files sample_controller.py

import oidc from helper

# use the same oidc here

The other option is to create a singleton class with a attribute oidc in it, it will be helpfull if you need other methods along with oidc

Tushar Kolhe
  • 7,375
  • 1
  • 7
  • 13
  • `oidc = OpenIDConnect(app)` -> `oidc = OpenIDConnect(*args)` ? – Kok How Teh May 10 '21 at 10:13
  • I tried this but unfortunately the log shows `'NoneType' object has no attribute 'user_getinfo'` when the application runs. Not sure if the object was constructed properly at all. I access `oidc` in another file with `from src.common.Authentication import oidc` – Kok How Teh May 10 '21 at 10:15
  • Are you sure the call to the function that constructs the `oidc` object is before any use? Also, make sure both uses the same process the one that constructs the object and the one that uses it – Tushar Kolhe May 10 '21 at 10:21
  • I only call the `init_oidc` from main.py, the entry point of the application. In the consumer .py, I import the global `oidc` object directly. – Kok How Teh May 10 '21 at 10:35
  • can you share the code, in the question.? – Tushar Kolhe May 10 '21 at 10:53
  • Using `impot oidc from helper` within the consumer function works. Putting it outside doesn't. It is always NoneType. This is a problem when I need to use the `oidc` object in a decorator. For example: `@app.route('/api') @oidc.accept_token()` – Kok How Teh May 11 '21 at 01:22
  • This is solved by following to https://flask-oidc.readthedocs.io/en/latest/ – Kok How Teh May 11 '21 at 01:48