forked from Github-Mirrors/canaille
feat: env_prefix
create_app variable can select the environment var prefix
This commit is contained in:
parent
b8645ce1a3
commit
afa0a6ff1e
4 changed files with 43 additions and 15 deletions
|
@ -1,9 +1,13 @@
|
|||
Added
|
||||
^^^^^
|
||||
- `env_prefix` create_app variable can select the environment var prefix.
|
||||
|
||||
[0.0.52] - 2024-04-22
|
||||
---------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
- `ENV_FILE` environment variable can customize/disable the .env file
|
||||
- `env_file` create_app variable can customize/disable the .env file
|
||||
|
||||
Changed
|
||||
^^^^^^^
|
||||
|
|
|
@ -124,7 +124,9 @@ def setup_flask_converters(app):
|
|||
app.url_map.converters[model_name.lower()] = model_converter(model_class)
|
||||
|
||||
|
||||
def create_app(config=None, validate=True, backend=None):
|
||||
def create_app(
|
||||
config=None, validate=True, backend=None, env_file=".env", env_prefix=""
|
||||
):
|
||||
from .app.configuration import setup_config
|
||||
from .app.i18n import setup_i18n
|
||||
from .app.themes import setup_themer
|
||||
|
@ -132,7 +134,13 @@ def create_app(config=None, validate=True, backend=None):
|
|||
|
||||
app = Flask(__name__)
|
||||
with app.app_context():
|
||||
if not setup_config(app, config, validate): # pragma: no cover
|
||||
if not setup_config(
|
||||
app=app,
|
||||
config=config,
|
||||
test_config=validate,
|
||||
env_file=env_file,
|
||||
env_prefix=env_prefix,
|
||||
): # pragma: no cover
|
||||
sys.exit(1)
|
||||
|
||||
sentry_sdk = setup_sentry(app)
|
||||
|
|
|
@ -13,7 +13,6 @@ from pydantic_settings import SettingsConfigDict
|
|||
from canaille.core.configuration import CoreSettings
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
DEFAULT_ENV_FILE = ".env"
|
||||
|
||||
|
||||
class RootSettings(BaseSettings):
|
||||
|
@ -60,10 +59,10 @@ class RootSettings(BaseSettings):
|
|||
"""
|
||||
|
||||
|
||||
def settings_factory(config):
|
||||
"""Overly complicated function that pushes the backend specific
|
||||
configuration into CoreSettings, in the purpose break dependency against
|
||||
backends libraries like python-ldap or sqlalchemy."""
|
||||
def settings_factory(config, env_file=".env", env_prefix=""):
|
||||
"""Pushes the backend specific configuration into CoreSettings, in the
|
||||
purpose break dependency against backends libraries like python-ldap or
|
||||
sqlalchemy."""
|
||||
attributes = {"CANAILLE": (CoreSettings, CoreSettings())}
|
||||
|
||||
if "CANAILLE_SQL" in config or any(
|
||||
|
@ -93,11 +92,11 @@ def settings_factory(config):
|
|||
**attributes,
|
||||
)
|
||||
|
||||
env_file = os.getenv("ENV_FILE", config.get("ENV_FILE", DEFAULT_ENV_FILE))
|
||||
return Settings(
|
||||
**config,
|
||||
_secrets_dir=os.environ.get("SECRETS_DIR"),
|
||||
_env_file=env_file,
|
||||
_env_prefix=env_prefix,
|
||||
)
|
||||
|
||||
|
||||
|
@ -121,7 +120,7 @@ def toml_content(file_path):
|
|||
raise Exception("toml library not installed. Cannot load configuration.")
|
||||
|
||||
|
||||
def setup_config(app, config=None, test_config=True):
|
||||
def setup_config(app, config=None, test_config=True, env_file=".env", env_prefix=""):
|
||||
from canaille.oidc.installation import install
|
||||
|
||||
app.config.from_mapping(
|
||||
|
@ -135,7 +134,9 @@ def setup_config(app, config=None, test_config=True):
|
|||
config = toml_content(os.environ.get("CONFIG"))
|
||||
|
||||
try:
|
||||
config_obj = settings_factory(config or {})
|
||||
config_obj = settings_factory(
|
||||
config or {}, env_file=env_file, env_prefix=env_prefix
|
||||
)
|
||||
except ValidationError as exc: # pragma: no cover
|
||||
app.logger.critical(str(exc))
|
||||
return False
|
||||
|
|
|
@ -41,6 +41,7 @@ def test_configuration_nestedsecrets_directory(tmp_path, backend, configuration)
|
|||
|
||||
|
||||
def test_configuration_from_environment_vars():
|
||||
"""Canaille should read configuration from environment vars."""
|
||||
os.environ["SECRET_KEY"] = "very-very-secret"
|
||||
os.environ["CANAILLE__SMTP__FROM_ADDR"] = "user@mydomain.tld"
|
||||
os.environ["CANAILLE_SQL__DATABASE_URI"] = "sqlite:///anything.db"
|
||||
|
@ -60,6 +61,22 @@ def test_configuration_from_environment_vars():
|
|||
del os.environ["CANAILLE_SQL__DATABASE_URI"]
|
||||
|
||||
|
||||
def test_disable_env_var_loading(tmp_path, configuration):
|
||||
"""Canaille should not read configuration from environment vars when
|
||||
env_prefix is False."""
|
||||
del configuration["SERVER_NAME"]
|
||||
os.environ["SERVER_NAME"] = "example.com"
|
||||
os.environ["FOOBAR_SERVER_NAME"] = "foobar.example.com"
|
||||
|
||||
app = create_app(configuration, env_prefix="")
|
||||
assert app.config["SERVER_NAME"] == "example.com"
|
||||
|
||||
app = create_app(configuration, env_prefix="FOOBAR_")
|
||||
assert app.config["SERVER_NAME"] == "foobar.example.com"
|
||||
|
||||
del os.environ["SERVER_NAME"]
|
||||
|
||||
|
||||
def test_dotenv_file(tmp_path, configuration):
|
||||
"""Canaille should read configuration from .env files."""
|
||||
oldcwd = os.getcwd()
|
||||
|
@ -81,8 +98,7 @@ def test_custom_dotenv_file(tmp_path, configuration):
|
|||
with open(dotenv, "w") as fd:
|
||||
fd.write("FOOBAR=other-custom-value")
|
||||
|
||||
configuration["ENV_FILE"] = dotenv
|
||||
app = create_app(configuration)
|
||||
app = create_app(configuration, env_file=dotenv)
|
||||
assert app.config["FOOBAR"] == "other-custom-value"
|
||||
|
||||
|
||||
|
@ -95,8 +111,7 @@ def test_disable_dotenv_file(tmp_path, configuration):
|
|||
with open(dotenv, "w") as fd:
|
||||
fd.write("FOOBAR=custom-value")
|
||||
|
||||
configuration["ENV_FILE"] = None
|
||||
app = create_app(configuration)
|
||||
app = create_app(configuration, env_file=None)
|
||||
assert "FOOBAR" not in app.config
|
||||
os.chdir(oldcwd)
|
||||
|
||||
|
|
Loading…
Reference in a new issue