[PYTHON] Configuration file best practices in Flask

Overview

When creating a configuration file in a Flask application I was studying how to divide each environment and hide the contents.

Read Official Documents and Articles from Overseas I will summarize that. Most of this page is made from the above two Japanese translations.

Config in Flask

Here is a summary of the parts that should be kept in the Flask configuration file.

Basic settings

You can write to the config variable of the Flask instance in dictionary format.

Basic settings


app.config['DEBUG'] = True

Settings from file

You can read the list of settings from the specified file.

Settings from file


#Pattern that directly specifies the file path
app.config.from_pyfile('config_file.cfg')

#A pattern that specifies an environment variable (absolute path) that indicates the location of a file
app.config.from_envvar('FLASK_CONFIG_FILE')

In the file, you can describe the settings in the following INI file format.

config_file.cfg


TESTING=False
DEBUG=True

Settings from object

You can load the settings as a Python object.

Settings from object


app.config.from_object('config.BaseConfig')

I felt that I could see from_json in the source code, but I will ignore it. Within the file you can structure the settings as a Python script as follows:

config.py


class BaseConfig(object):
    DEBUG = False
    TESTING = False


class DevelopmentConfig(BaseConfig):
    DEBUG = True
    TESTING = True


class TestingConfig(BaseConfig):
    DEBUG = False
    TESTING = True

Instance folder

Source version control is essential when developing applications, The configuration file contains passwords, API access keys, etc. There is information that you do not want to include in version control.

In Flask, "instance folder" is This is a function to exclude a specific configuration file from version control.

You can specify an instance folder with an absolute path when initializing Flask.

Specify the path of the instance folder


app = Flask(__name__, instance_path='/path/to/instance/folder')

If this is not specified, the default ʻinstance` directory will be It will be recognized as an instance folder.

If you write as follows, use a relative path from the instance folder You can read the configuration file.

Relative file invocation


app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile('application.cfg', silent=True)

Here we are referencing ʻinstance / application.cfg. silent = True` suppresses the error when the file is not found.

That doesn't mean it can be excluded from version control, though. Don't forget to put the path of the instance folder in ** .gitignore **. ** **

best practice

There is a section on Best Practices on the official page. The content is short and not very specific. (Due to the problem of English ability, I can only read "It is better to be easy to test" ...)

On the other hand, in the article here, it is stated as follows.

Good practice is to have a default configuration, which is under source control and to override it with sensitive and specific information kept in instance folders. For the default configuration you could use object-based configuration hierarchy(described in Object-based configuration section) and to manage which configuration object to load via environment variables:

The last item is to switch between development and production. Writing it as an object should make it easier to test.

As a specific example, it is described as follows.

Best practice (unofficial)


#The basic setting is config under version control.Described as an object in py
config = {
    "development": "bookshelf.config.DevelopmentConfig",
    "testing": "bookshelf.config.TestingConfig",
    "default": "bookshelf.config.DevelopmentConfig"
}

def configure_app(app):
    #Determine the configuration file to read using environment variables
    config_name = os.getenv('FLASK_CONFIGURATION', 'default')
    
    #Read settings as objects
    app.config.from_object(config[config_name])
    
    #Overwrite sensitive settings with the settings in the instance folder
    app.config.from_pyfile('config.cfg', silent=True)

Summary

I think it would be difficult to apply the above settings to all

I had the recognition that.

I've written it for a long time, but in the end it's about whether I can agree with it. Even if the configuration is dirty, there is no problem for the time being as long as the secret file is not leaked.

I hope to find a better shape as the application grows.

Recommended Posts

Configuration file best practices in Flask
File operations in Python
File operations in Python
Read logging settings from an external file in Flask
Change static file storage directories and URLs in Flask
Image uploader in Flask
Best practices for dynamically handling LINE Flex Messages in Django
tox configuration file cheat sheet
Download the file in Python
Learn best practices from cookiecutter-django
HTTP environment variables in Flask
__version__ traps and best practices
Display Japanese in JSON file
Upload multiple files in Flask
Check if the configuration file is read in an easy-to-understand manner
Trial of writing the configuration file in Python instead of .ini etc.