简体   繁体   中英

How to access flask config variables outside application context according to my project structure?

spinngod.py - flask app starter code

from app import create_app
import sys

run_profile = str(sys.argv[1]) if len(sys.argv) >= 2 else 'development'
app = create_app(run_profile)

print("App Root Path:" + app.root_path)

if __name__ == '__main__':
    print sys.path
    app.run(debug=True, host='0.0.0.0')

app/ init .py - creates flask app

def create_app(profile_name):
    print "currently active profile:" + profile_name
    app = Flask(__name__)

    ############# configurations ####################
    app.config.from_object(config[profile_name])
    configure_app(app)
    configure_app_logger(app)

    #################### blueprint registration and rest_plus namespace additions ###############
    from api_1_0 import api as api_1_0_blueprint
    from api_1_0.restplus import api_restplus

    # ************************************************** #
    api_restplus.init_app(api_1_0_blueprint)
    api_restplus.add_namespace(application_namespace)
    api_restplus.add_namespace(pipeline_template_namespace)
    api_restplus.add_namespace(loadbalancer_namespace)
    api_restplus.add_namespace(servergroup_namespace)
    api_restplus.add_namespace(task_namespace)
    # ************************************************** #

    app.register_blueprint(api_1_0_blueprint)

    ##############################################################
    return app

I want to access flask config variables defined in config.py in some other files which are outside application context. The app configuration depends on which profile it is started with (dev,stage or production) which is being passed from command line as an arg.

The only way that I can think of accessing config variables outside app context is to set profile (dev,stage or prod) as an environment variable and then import directly from config file.

The second way that I tried was to move creation of flask app in app/ init .py outside method.

This is how I am trying to access config variables in another class.

import requests


class Client(object):
    def __init__(self):
        from app import app
        print "fjaijflkajsf" + app.config['SPINNAKER_BASE_URL']
        pass

Is there a way better of doing this in flask ?

From the docs :

Rather than passing the application around to each function, the current_app and g proxies are accessed instead.

The Flask application object has attributes, such as config, that are useful to access within views and CLI commands. However, importing the app instance within the modules in your project is prone to circular import issues.

Flask solves this issue with the application context. Rather than referring to an app directly, you use the the current_app proxy, which points to the application handling the current activity.

You import current_app like this:

from flask import current_app

and then access the config or other attributes like this:

config = current_app.config

Example:

src/application.py (where config is set in the context)

create_app():
  app = Flask('app')
  app.config.from_object(some_class)
  return app

src/module/another_module.py

from flask import current_app

def function_that_requires_config():
    config = current_app.config

Alternative:

src/application.py (where config is set in the context)

APP = create_app(os.environ.get('FLASK_ENV'))

src/module/another_module.py

from src.application import APP

def function_that_requires_config():
   config_value = APP.config.get(config_key, default_value)

Not sure if it is good to put it here as it may not respond to the question directly, but here is the cleanest way i've figured to use config values outside of requests, without having to pass config as a param.

The solution is actually pretty simple, juste consider the part of your code as a flask_extension. my exemple will be the use of external api, with ROOT_URL in the config file, and i don't want to make api call from within my routes, so the api is in its own module.

in my create_app fuction:


from flask import Flask

from .api import api
from .configmodule import Config
from .model import db

def create_app(environment):
    app = Flask(__name__)
    app.config.from_object(Config.get_config(environment))
    db.init_app(app)
    api.init_app(app) # here i use api.init_app the same way i do for sqlalchemy

and in api/ init .py

class Api:
    def init_app(self, app):
        self.config = app.config


api = Api()

and in any files in my api modude i can now write

from . import api

def foo():
   print(api.config.get("API_ROOT_URL"))

this can even be improved if you feel the need to access some other global app vars from your module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM