changed how the Flask app is configured: moved settings from env files to new module config.py; updated README
This commit is contained in:
parent
2d3583bbae
commit
f9e8b69a06
16
.flaskenv
16
.flaskenv
@ -1,13 +1,9 @@
|
||||
# Non-critical configuration values
|
||||
# Read automatically if python-dotenv is installed
|
||||
# Non-critical configuration values for the runtime environment
|
||||
# File is read automatically if python-dotenv is installed
|
||||
|
||||
# set this to your app's name if you want to omit the flask option '--app=<app_name>' on the command line
|
||||
FLASK_APP = "the_works"
|
||||
FLASK_ENV = "development"
|
||||
FLASK_SECRET_KEY = "f8148ee5d95b0a67122b1cab9993f637a6bf29528f584a9f1575af1a55566748"
|
||||
FLASK_TESTING = False
|
||||
#FLASK_MAX_CONTENT_LENGTH = 1024 * 1024
|
||||
FLASK_DEBUG = True
|
||||
|
||||
FLASK_SQLALCHEMY_DATABASE_URI = "sqlite:///../the_works.sqlite"
|
||||
FLASK_SQLALCHEMY_ECHO = False
|
||||
FLASK_SQLALCHEMY_RECORD_QUERIES = True
|
||||
# environment to run the app in; possible values are "development", "production", "testing"
|
||||
FLASK_APP_MODE = "development"
|
||||
|
||||
|
||||
37
README.md
37
README.md
@ -16,27 +16,43 @@ the_works also is
|
||||
|
||||
## Configuration
|
||||
|
||||
The file `.flaskenv` contains the default configuration. Flask reads the file at startup and adds its key-value-pairs to the runtime environment as environment variables. When the Flask app object is being created in `__init__.py`, all environment variables that start with the prefix "FLASK_" get added to the app configuration.
|
||||
### From the environment
|
||||
|
||||
This is true for any prefixed environment variable, not just the ones from `.flaskenv`. It is therefore possible to set additional config parameters by hand before running the app. Just make sure to prefix the variable name with "FLASK_".
|
||||
When the_works is started, the app first reads all environment variables prefixed with "FLASK_" (e.g. "FLASK_APP"). Any variables in the file `.flaskenv` will be added to the environment beforehand ("python-dotenv" must be installed). This can be used to determine the mode to run the app in (development, production etc.).
|
||||
|
||||
Configuration values from the runtime environment can be overridden by using Flask's `-e` command line switch to pass a second config file to the app. This file gets processed the same way as `.flaskenv`, which means that all its keys must be prefixed with "FLASK_". These vars take precedence over the default configuration.
|
||||
Note that only those environment variables get added to the_works' configuration that begin with "FLASK_". Ths is true whether they were added on the command line, defined in`.flaskenv`, or even added by using Python's `os.environ`.
|
||||
|
||||
Finally, you can override config settings with Python during the Flask app's instantiation through the factory. To do this, simply pass a dictionary with (unprefixed) key-value-pairs to `create_app()` method as named parameter `config`. Settings passed this way take precedence over those from the default configuration and additional config files.
|
||||
### From the_works/config.py
|
||||
|
||||
The main configuration happens inside the file `the_works/config.py`. All static variables defined in the class "Config" will be added as key-value-pairs to the_works' configuration dict.
|
||||
|
||||
In addition to "Config", the_works will then read all values from either "DevelopmentConfig", "ProductionConfig", or "TestingConfig". These classes are all subclasses of "Config". the_works determines which subclass to use by reading the Flask configuration setting "APP_MODE". If "APP_MODE" is one of either "development", "production", or "testing", the corresponding subclass will be used. If "APP_MODE" is set to a different value or not at all, "DevelopentConfig" will be used as default.
|
||||
|
||||
Note that if a value is defined in both "Config" and one of its subclasses, the value from the subclass will supersede the one from the base class.
|
||||
|
||||
### Settings for the_works
|
||||
|
||||
The following settings are specific to the_works:
|
||||
|
||||
* `APP_MODE = development | production | testing` – detemines witch configuration to use in addition to the base config; default is development
|
||||
|
||||
### Useful Flask settings
|
||||
|
||||
* `APP = <app_name>` – set this bevore running flask on the command line if you want to omit `--app the_works`
|
||||
* either `SQLALCHEMY_DATABASE_URI` or `SQLALCHEMY_DATABASE_URI` must be set or flask-sqlalchemy will throw an error; for URI syntax see the [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls)
|
||||
* see the list of builtin configuration values in the [Flask docs](https://flask.palletsprojects.com/en/stable/config/#builtin-configuration-values)
|
||||
|
||||
|
||||
## Flask commands
|
||||
|
||||
Execute commands with `python -m flask <command>`. You don't need to specify `--app the_works` as long as the environment variable "FLASK_APP" is set to "the_works"; the default configuration file does this.
|
||||
Execute commands with `python -m flask --app the_works <command>`. You can omit `--app` by setting the environment variable "FLASK_APP" to "the_works" (see [here](#useful-flask-settings))
|
||||
|
||||
Available commands:
|
||||
|
||||
* `run`: Serve app (don't use for production).
|
||||
<!--* `init-db`: Create empty SQLite database `works.sqlite` in project root. BE CAREFUL: If a database already exists, it will be deleted with everything in it. // 5/25: ich hab die Fkt. wieder rausgenommen, aber ich könnte sie eigentlich prima wieder einbauen … -->
|
||||
* `shell`: start a shell within the app context (I can i.e. import specific table models and test ORM data structures)
|
||||
*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -48,15 +64,12 @@ Available commands:
|
||||
Required pip packages
|
||||
|
||||
* flask
|
||||
* flask-sqlalchemy
|
||||
* python-dotenv
|
||||
* flask-sqlalchemy
|
||||
* Pillow
|
||||
* pytest
|
||||
|
||||
Optional pip packages
|
||||
|
||||
* flask-debugtoolbar (optional)
|
||||
* sqlacodegen (optional; only used from the command line during development)
|
||||
See also `requirements.txt`.
|
||||
|
||||
### CSS and Javascript resources
|
||||
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
import os
|
||||
import pytest
|
||||
from the_works import create_app
|
||||
from the_works.database import db as _db
|
||||
from the_works.models import Genre
|
||||
|
||||
TEST_DATABASE_URI = "sqlite:///:memory:"
|
||||
# set app mode to testing via environment variable
|
||||
os.environ["FLASK_APP_MODE"] = "testing"
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def _app():
|
||||
test_config = {
|
||||
"ENV": "Testing",
|
||||
"SQLALCHEMY_DATABASE_URI": TEST_DATABASE_URI,
|
||||
"SECRET_KEY": "This is my very secret key",
|
||||
"TESTING": True
|
||||
}
|
||||
_app = create_app(test_config)
|
||||
_app = create_app()
|
||||
|
||||
# other setup can go here
|
||||
context = _app.app_context()
|
||||
|
||||
@ -1,27 +1,29 @@
|
||||
from flask import Flask
|
||||
import dotenv # this import is not strictly necessary but it forces pipreqs-to include dotenv when generating `requirements.txt`
|
||||
import the_works.config as tw_conf
|
||||
from the_works.database import init_db
|
||||
from the_works.models import SIMPLE_MODELS
|
||||
from the_works.views import home, reihe, titelbild, text, veroeffentlichung, werk, ausgabe
|
||||
from the_works.views.simple_view import VIEWS, ViewAll, ViewCreate, ViewUpdate, ViewDelete
|
||||
|
||||
|
||||
def create_app(config=None):
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
|
||||
# read all config values from environment that are prefixed with "FLASK_"
|
||||
# read config from environment (all values are prefixed with "FLASK_")
|
||||
app.config.from_prefixed_env()
|
||||
|
||||
# some #DEBUG configuration
|
||||
# toolbar = DebugToolbarExtension(app) #DEBUG
|
||||
# app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False #DEBUG
|
||||
|
||||
# use config from function parameter if present
|
||||
if config:
|
||||
app.config.update(config)
|
||||
# read config from object(s)
|
||||
app.config.from_object(tw_conf.Config)
|
||||
if 'APP_MODE' in app.config.keys() and isinstance(env := app.config['APP_MODE'], str) and env.lower() == "production":
|
||||
app.config.from_object(tw_conf.ProductionConfig)
|
||||
elif 'APP_MODE' in app.config.keys() and isinstance(env := app.config['APP_MODE'], str) and env.lower() == "testing":
|
||||
app.config.from_object(tw_conf.TestingConfig)
|
||||
else:
|
||||
app.config.from_object(tw_conf.DevelopmentConfig)
|
||||
|
||||
# some #DEBUG output
|
||||
print(f"Current Environment: {app.config['ENV'] if 'ENV' in app.config.keys() else 'ENV is not set'}") #DEBUG
|
||||
print(f"Current mode: {app.config['APP_MODE'] if 'APP_MODE' in app.config.keys() else 'not set'}") #DEBUG
|
||||
|
||||
# initialize database
|
||||
init_db(app)
|
||||
|
||||
22
the_works/config.py
Normal file
22
the_works/config.py
Normal file
@ -0,0 +1,22 @@
|
||||
class Config(object):
|
||||
MAX_CONTENT_LENGTH = 2 * 1024 * 1024
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///../the_works.sqlite"
|
||||
SECRET_KEY = "f8148ee5d95b0a67122b1cab9993f637a6bf29528f584a9f1575af1a55566748"
|
||||
SQLALCHEMY_ECHO = False
|
||||
SQLALCHEMY_RECORD_QUERIES = True
|
||||
DEBUG = True
|
||||
|
||||
class ProductionConfig(Config):
|
||||
pass
|
||||
#SQLALCHEMY_DATABASE_URI =
|
||||
#SECRET_KEY = "differentsecretkey0123456789"
|
||||
#SQLALCHEMY_RECORD_QUERIES = False
|
||||
|
||||
class TestingConfig(Config):
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
|
||||
SECRET_KEY = "This is my very secret key"
|
||||
DEBUG = True
|
||||
TESTING = True
|
||||
|
||||
Loading…
Reference in New Issue
Block a user