From 31793fb290c70f8d622e1ec0e6f1ad1d34c68528 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 29 Mar 2021 13:25:15 +0200 Subject: [PATCH] Added db context handling --- docs/todo.txt | 4 +- .../database/context/database_context_abc.py | 4 ++ .../service_collection.py | 9 ++-- .../service_collection_abc.py | 4 +- src/tests/custom/console/main.py | 10 +++++ src/tests/custom/database/LICENSE | 0 src/tests/custom/database/README.md | 0 src/tests/custom/database/__init__.py | 0 .../database/appsettings.development.json | 8 ++++ .../database/appsettings.edrafts-lapi.json | 22 ++++++++++ .../database/appsettings.edrafts-pc.json | 22 ++++++++++ src/tests/custom/database/appsettings.json | 15 +++++++ src/tests/custom/database/cpl.json | 41 +++++++++++++++++++ src/tests/custom/database/src/__init__.py | 0 src/tests/custom/database/src/application.py | 24 +++++++++++ src/tests/custom/database/src/main.py | 14 +++++++ .../custom/database/src/model/__init__.py | 0 src/tests/custom/database/src/startup.py | 35 ++++++++++++++++ .../custom/database/src/tests/__init__.py | 1 + src/tests/custom/general/application.py | 10 ----- src/tests/custom/general/startup.py | 8 ---- 21 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 src/tests/custom/database/LICENSE create mode 100644 src/tests/custom/database/README.md create mode 100644 src/tests/custom/database/__init__.py create mode 100644 src/tests/custom/database/appsettings.development.json create mode 100644 src/tests/custom/database/appsettings.edrafts-lapi.json create mode 100644 src/tests/custom/database/appsettings.edrafts-pc.json create mode 100644 src/tests/custom/database/appsettings.json create mode 100644 src/tests/custom/database/cpl.json create mode 100644 src/tests/custom/database/src/__init__.py create mode 100644 src/tests/custom/database/src/application.py create mode 100644 src/tests/custom/database/src/main.py create mode 100644 src/tests/custom/database/src/model/__init__.py create mode 100644 src/tests/custom/database/src/startup.py create mode 100644 src/tests/custom/database/src/tests/__init__.py diff --git a/docs/todo.txt b/docs/todo.txt index 7260f7e1..66c7d178 100644 --- a/docs/todo.txt +++ b/docs/todo.txt @@ -1,3 +1 @@ -- dbContext!!! -- templates for better Di using! -- app-runtime -> app-env \ No newline at end of file +- dbContext!!! \ No newline at end of file diff --git a/src/cpl/database/context/database_context_abc.py b/src/cpl/database/context/database_context_abc.py index 4c4d5dca..0bbf3dd5 100644 --- a/src/cpl/database/context/database_context_abc.py +++ b/src/cpl/database/context/database_context_abc.py @@ -6,6 +6,10 @@ from sqlalchemy.orm import Session class DatabaseContextABC(ABC): + @abstractmethod + def __init__(self, *args): + pass + @property @abstractmethod def engine(self) -> engine: pass diff --git a/src/cpl/dependency_injection/service_collection.py b/src/cpl/dependency_injection/service_collection.py index d3bb4be1..4be8ed7b 100644 --- a/src/cpl/dependency_injection/service_collection.py +++ b/src/cpl/dependency_injection/service_collection.py @@ -1,12 +1,14 @@ from typing import Union, Type, Callable, Optional from cpl.configuration.configuration_abc import ConfigurationABC -from cpl.database.context import DatabaseContextABC +from cpl.database.database_settings import DatabaseSettings +from cpl.database.context.database_context_abc import DatabaseContextABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC from cpl.dependency_injection.service_descriptor import ServiceDescriptor from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum from cpl.dependency_injection.service_provider import ServiceProvider +from cpl.utils.credential_manager import CredentialManager class ServiceCollection(ServiceCollectionABC): @@ -36,8 +38,9 @@ class ServiceCollection(ServiceCollectionABC): self._service_descriptors.append(ServiceDescriptor(service, lifetime)) - def add_db_context(self, db_context: Type[DatabaseContextABC]): - pass + def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings): + db_context = db_context_type(db_settings) + db_context.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials)) def add_singleton(self, service_type: Union[type, object], service: Union[type, object] = None): if service is not None: diff --git a/src/cpl/dependency_injection/service_collection_abc.py b/src/cpl/dependency_injection/service_collection_abc.py index 281497bc..d3e33b5a 100644 --- a/src/cpl/dependency_injection/service_collection_abc.py +++ b/src/cpl/dependency_injection/service_collection_abc.py @@ -2,6 +2,7 @@ from abc import abstractmethod, ABC from collections import Callable from typing import Type +from cpl.database.database_settings import DatabaseSettings from cpl.database.context.database_context_abc import DatabaseContextABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC @@ -16,10 +17,11 @@ class ServiceCollectionABC(ABC): pass @abstractmethod - def add_db_context(self, db_context: Type[DatabaseContextABC]): + def add_db_context(self, db_context: Type[DatabaseContextABC], db_settings: DatabaseSettings): """ Adds database context :param db_context: + :param db_settings: :return: """ pass diff --git a/src/tests/custom/console/main.py b/src/tests/custom/console/main.py index 97882af2..6dfe9a9c 100644 --- a/src/tests/custom/console/main.py +++ b/src/tests/custom/console/main.py @@ -6,6 +6,15 @@ def test_spinner(): time.sleep(2) +def test_console(): + Console.write_line('Hello World') + Console.write('\nName: ') + Console.write_line(' Hello', Console.read_line()) + Console.clear() + Console.write_at(5, 5, 'at 5, 5') + Console.write_at(10, 10, 'at 10, 10') + + if __name__ == '__main__': Console.write_line('Hello World\n') Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, @@ -25,5 +34,6 @@ if __name__ == '__main__': # cursor_foreground_color=ForegroundColorEnum.red # ) # Console.write_line(f'You selected: {selected}') + # test_console() Console.write_line() diff --git a/src/tests/custom/database/LICENSE b/src/tests/custom/database/LICENSE new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/custom/database/README.md b/src/tests/custom/database/README.md new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/custom/database/__init__.py b/src/tests/custom/database/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/custom/database/appsettings.development.json b/src/tests/custom/database/appsettings.development.json new file mode 100644 index 00000000..62ec6c61 --- /dev/null +++ b/src/tests/custom/database/appsettings.development.json @@ -0,0 +1,8 @@ +{ + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + } +} \ No newline at end of file diff --git a/src/tests/custom/database/appsettings.edrafts-lapi.json b/src/tests/custom/database/appsettings.edrafts-lapi.json new file mode 100644 index 00000000..c78e3458 --- /dev/null +++ b/src/tests/custom/database/appsettings.edrafts-lapi.json @@ -0,0 +1,22 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }, + + "DatabaseSettings": { + "AuthPlugin": "mysql_native_password", + "ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl", + "Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==", + "Encoding": "utf8mb4" + } +} \ No newline at end of file diff --git a/src/tests/custom/database/appsettings.edrafts-pc.json b/src/tests/custom/database/appsettings.edrafts-pc.json new file mode 100644 index 00000000..c78e3458 --- /dev/null +++ b/src/tests/custom/database/appsettings.edrafts-pc.json @@ -0,0 +1,22 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }, + + "DatabaseSettings": { + "AuthPlugin": "mysql_native_password", + "ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl", + "Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==", + "Encoding": "utf8mb4" + } +} \ No newline at end of file diff --git a/src/tests/custom/database/appsettings.json b/src/tests/custom/database/appsettings.json new file mode 100644 index 00000000..fd8ddf6c --- /dev/null +++ b/src/tests/custom/database/appsettings.json @@ -0,0 +1,15 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "WARN" + } +} \ No newline at end of file diff --git a/src/tests/custom/database/cpl.json b/src/tests/custom/database/cpl.json new file mode 100644 index 00000000..17d75984 --- /dev/null +++ b/src/tests/custom/database/cpl.json @@ -0,0 +1,41 @@ +{ + "ProjectSettings": { + "Name": "database", + "Version": { + "Major": "0", + "Minor": "0", + "Micro": "0" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "sh_cpl==2021.4.2.dev1" + ], + "PythonVersion": ">=3.9.2", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "SourcePath": "src", + "OutputPath": "dist", + "Main": "main", + "EntryPoint": "database", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {} + } +} \ No newline at end of file diff --git a/src/tests/custom/database/src/__init__.py b/src/tests/custom/database/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/custom/database/src/application.py b/src/tests/custom/database/src/application.py new file mode 100644 index 00000000..85b5505c --- /dev/null +++ b/src/tests/custom/database/src/application.py @@ -0,0 +1,24 @@ +from typing import Optional + +from cpl.application import ApplicationABC +from cpl.configuration import ConfigurationABC +from cpl.console import Console +from cpl.dependency_injection import ServiceProviderABC +from cpl.logging import LoggerABC + + +class Application(ApplicationABC): + + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + + self._logger: Optional[LoggerABC] = None + + def configure(self): + self._logger = self._services.get_service(LoggerABC) + + def main(self): + self._logger.header(f'{self._configuration.environment.application_name}:') + self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') + self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') + self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') diff --git a/src/tests/custom/database/src/main.py b/src/tests/custom/database/src/main.py new file mode 100644 index 00000000..6e678925 --- /dev/null +++ b/src/tests/custom/database/src/main.py @@ -0,0 +1,14 @@ +from cpl.application import ApplicationBuilder + +from application import Application +from startup import Startup + + +def main(): + app_builder = ApplicationBuilder(Application) + app_builder.use_startup(Startup) + app_builder.build().run() + + +if __name__ == '__main__': + main() diff --git a/src/tests/custom/database/src/model/__init__.py b/src/tests/custom/database/src/model/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/custom/database/src/startup.py b/src/tests/custom/database/src/startup.py new file mode 100644 index 00000000..f4a37129 --- /dev/null +++ b/src/tests/custom/database/src/startup.py @@ -0,0 +1,35 @@ +from cpl.application import StartupABC +from cpl.configuration import ConfigurationABC +from cpl.database import DatabaseSettings +from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC +from cpl.logging import LoggerABC, Logger +from model.db_context import DBContext + + +class Startup(StartupABC): + + def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC): + StartupABC.__init__(self) + + self._configuration = config + self._environment = self._configuration.environment + self._services = services + + def configure_configuration(self) -> ConfigurationABC: + self._configuration.add_environment_variables('PYTHON_') + self._configuration.add_environment_variables('CPL_') + self._configuration.add_console_arguments() + self._configuration.add_json_file(f'appsettings.json') + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json') + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True) + + return self._configuration + + def configure_services(self) -> ServiceProviderABC: + # Create and connect to database + db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings) + self._services.add_db_context(DBContext, db_settings) + + self._services.add_singleton(LoggerABC, Logger) + return self._services.build_service_provider() + diff --git a/src/tests/custom/database/src/tests/__init__.py b/src/tests/custom/database/src/tests/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/src/tests/custom/database/src/tests/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/src/tests/custom/general/application.py b/src/tests/custom/general/application.py index ff1140ca..f7af31b0 100644 --- a/src/tests/custom/general/application.py +++ b/src/tests/custom/general/application.py @@ -28,15 +28,6 @@ class Application(ApplicationABC): mail.body = 'Dies ist ein Test :D' self._mailer.send_mail(mail) - def test_console(self): - self._logger.debug(__name__, 'Started console_old model') - Console.write_line('Hello World') - Console.write('\nName: ') - Console.write_line(' Hello', Console.read_line()) - Console.clear() - Console.write_at(5, 5, 'at 5, 5') - Console.write_at(10, 10, 'at 10, 10') - @staticmethod def _wait(time_ms: int): time.sleep(time_ms) @@ -54,4 +45,3 @@ class Application(ApplicationABC): test: TestService = self._services.get_service(TestService) test.run() # self.test_send_mail() - # self.test_console() diff --git a/src/tests/custom/general/startup.py b/src/tests/custom/general/startup.py index 3630004e..d0370bff 100644 --- a/src/tests/custom/general/startup.py +++ b/src/tests/custom/general/startup.py @@ -1,14 +1,11 @@ from cpl.application.startup_abc import StartupABC from cpl.configuration.configuration_abc import ConfigurationABC -from cpl.database.context.database_context import DatabaseContext -from cpl.database.database_settings import DatabaseSettings from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.logging.logger_service import Logger from cpl.logging.logger_abc import LoggerABC from cpl.mailing.email_client_service import EMailClient from cpl.mailing.email_client_abc import EMailClientABC -from cpl.utils.credential_manager import CredentialManager from tests.custom.general.test_service import TestService @@ -31,11 +28,6 @@ class Startup(StartupABC): return self._configuration def configure_services(self) -> ServiceProviderABC: - # Create and connect to database - # db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings) - # self._services.add_db_context(DatabaseContext) - # db.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials)) - self._services.add_singleton(LoggerABC, Logger) self._services.add_singleton(EMailClientABC, EMailClient) self._services.add_singleton(TestService)