diff --git a/config.dev.yml b/config.dev.yml index 8fe1ddb..61bb3a8 100644 --- a/config.dev.yml +++ b/config.dev.yml @@ -1 +1,6 @@ +# Secret key (CHANGE TO RANDOM STRING IN PRODUCTION!) SECRET_KEY: 'development' + +# Database configuration +SQLALCHEMY_DATABASE_URI: 'sqlite:////tmp/test.db' +SQLALCHEMY_ECHO: false diff --git a/tofu_api/app.py b/tofu_api/app.py index f5a2038..4bb9329 100644 --- a/tofu_api/app.py +++ b/tofu_api/app.py @@ -1,10 +1,9 @@ import os -import yaml from flask import Flask from tofu_api.api import TofuApiBlueprint -from tofu_api.config import DefaultConfig +from tofu_api.common.config import Config from tofu_api.dependencies import Dependencies @@ -12,6 +11,12 @@ class App(Flask): """ Flask application for Tofu API. """ + # Override Flask classes + config_class = Config + + # Set type hint for config + config: Config + # Dependencies container dependencies: Dependencies @@ -25,10 +30,9 @@ class App(Flask): instance_path=project_root_dir, instance_relative_config=True, ) - self.config.from_object(DefaultConfig) # Load app configuration from YAML file - self.config.from_file(os.getenv('FLASK_CONFIG_FILE', default='config.yml'), load=yaml.safe_load) + self.config.from_yaml(os.getenv('FLASK_CONFIG_FILE', default='config.yml')) # Initialize DI container self.dependencies = Dependencies() diff --git a/tofu_api/common/config/__init__.py b/tofu_api/common/config/__init__.py new file mode 100644 index 0000000..d7bf64b --- /dev/null +++ b/tofu_api/common/config/__init__.py @@ -0,0 +1,2 @@ +from .config import Config +from .defaults import DefaultConfig diff --git a/tofu_api/common/config/config.py b/tofu_api/common/config/config.py new file mode 100644 index 0000000..37186bd --- /dev/null +++ b/tofu_api/common/config/config.py @@ -0,0 +1,32 @@ +import yaml +from flask import Config as BaseConfig + +from .defaults import DefaultConfig + + +class Config(BaseConfig): + """ + Custom config class for the Flask application. + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Set app-specific default values + self.from_object(DefaultConfig) + + def from_yaml(self, filename: str, *, silent: bool = False) -> bool: + """ + Update config from a YAML file. + """ + return self.from_file(filename, load=yaml.safe_load, silent=silent) + + # Properties for type safe access to config values + + @property + def sqlalchemy_database_uri(self) -> str: + return self.get('SQLALCHEMY_DATABASE_URI') + + @property + def sqlalchemy_echo(self) -> bool: + return bool(self.get('SQLALCHEMY_ECHO')) diff --git a/tofu_api/common/config/defaults.py b/tofu_api/common/config/defaults.py new file mode 100644 index 0000000..9ff5c29 --- /dev/null +++ b/tofu_api/common/config/defaults.py @@ -0,0 +1,13 @@ +__all__ = [ + 'DefaultConfig', +] + + +class DefaultConfig: + """ + This class defines default values for the app configuration. + """ + + # Database configuration + SQLALCHEMY_DATABASE_URI = None + SQLALCHEMY_ECHO = False diff --git a/tofu_api/common/database/sqlalchemy.py b/tofu_api/common/database/sqlalchemy.py index f3ab214..1d1cbe9 100644 --- a/tofu_api/common/database/sqlalchemy.py +++ b/tofu_api/common/database/sqlalchemy.py @@ -5,6 +5,7 @@ from sqlalchemy import MetaData, create_engine from sqlalchemy.engine import Engine from sqlalchemy.orm import Session, scoped_session, sessionmaker +from tofu_api.common.config import Config from .metadata import metadata_obj __all__ = [ @@ -23,19 +24,22 @@ class SQLAlchemy: """ Initializes the SQLAlchemy engine. """ - self._engine = self._create_engine() + self._engine = self._create_engine(app.config) self._scoped_session = self._create_scoped_session() @app.teardown_appcontext def shutdown_session(_exception=None): self._scoped_session.remove() - def _create_engine(self) -> Engine: + @staticmethod + def _create_engine(config: Config) -> Engine: """ Create the database engine using the app configuration. """ - # TODO: Use config - return create_engine('sqlite:////tmp/test.db') + return create_engine( + config.sqlalchemy_database_uri, + echo=config.sqlalchemy_echo, + ) def _create_scoped_session(self) -> scoped_session: """ diff --git a/tofu_api/config.py b/tofu_api/config.py deleted file mode 100644 index fbca7a3..0000000 --- a/tofu_api/config.py +++ /dev/null @@ -1,5 +0,0 @@ -class DefaultConfig: - """ - This class defined default values for the app configuration. - """ - # TODO