Merge pull request '2020.12.8' (#5) from 2020.12.8 into 2020.12
Reviewed-on: sh-edraft.de/sh_common_py_lib#5
This commit is contained in:
commit
bb5b1f5944
@ -12,6 +12,8 @@ class Version(ConfigurationModelBase):
|
|||||||
minor: int = None,
|
minor: int = None,
|
||||||
micro: float = None
|
micro: float = None
|
||||||
):
|
):
|
||||||
|
ConfigurationModelBase.__init__(self)
|
||||||
|
|
||||||
self._major: Optional[int] = major
|
self._major: Optional[int] = major
|
||||||
self._minor: Optional[int] = minor
|
self._minor: Optional[int] = minor
|
||||||
self._micro: Optional[int] = micro
|
self._micro: Optional[int] = micro
|
||||||
|
@ -7,8 +7,8 @@ from sh_edraft.configuration.base.configuration_base import ConfigurationBase
|
|||||||
from sh_edraft.configuration.model.configuration_variable_name import ConfigurationVariableName
|
from sh_edraft.configuration.model.configuration_variable_name import ConfigurationVariableName
|
||||||
from sh_edraft.environment.base.environment_base import EnvironmentBase
|
from sh_edraft.environment.base.environment_base import EnvironmentBase
|
||||||
from sh_edraft.environment.hosting_environment import HostingEnvironment
|
from sh_edraft.environment.hosting_environment import HostingEnvironment
|
||||||
from sh_edraft.environment.model import EnvironmentName
|
from sh_edraft.environment.model.environment_name import EnvironmentName
|
||||||
from sh_edraft.utils import Console
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
class Configuration(ConfigurationBase):
|
class Configuration(ConfigurationBase):
|
||||||
|
1
src/sh_edraft/database/__init__.py
Normal file
1
src/sh_edraft/database/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# imports:
|
3
src/sh_edraft/database/connection/__init__.py
Normal file
3
src/sh_edraft/database/connection/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .database_connection import DatabaseConnection
|
3
src/sh_edraft/database/connection/base/__init__.py
Normal file
3
src/sh_edraft/database/connection/base/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .database_connection_base import DatabaseConnectionBase
|
@ -0,0 +1,21 @@
|
|||||||
|
from abc import abstractmethod, ABC
|
||||||
|
|
||||||
|
from sqlalchemy import engine
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseConnectionBase(ABC):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def __init__(self): pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def engine(self) -> engine: pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def session(self) -> Session: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def connect(self, connection_string: str): pass
|
51
src/sh_edraft/database/connection/database_connection.py
Normal file
51
src/sh_edraft/database/connection/database_connection.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from sqlalchemy import engine, create_engine
|
||||||
|
from sqlalchemy.orm import Session, sessionmaker
|
||||||
|
|
||||||
|
from sh_edraft.database.connection.base.database_connection_base import DatabaseConnectionBase
|
||||||
|
from sh_edraft.database.model.database_settings import DatabaseSettings
|
||||||
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseConnection(DatabaseConnectionBase):
|
||||||
|
|
||||||
|
def __init__(self, database_settings: DatabaseSettings):
|
||||||
|
DatabaseConnectionBase.__init__(self)
|
||||||
|
|
||||||
|
self._db_settings = database_settings
|
||||||
|
|
||||||
|
self._engine: Optional[engine] = None
|
||||||
|
self._session: Optional[Session] = None
|
||||||
|
self._credentials: Optional[str] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def engine(self) -> engine:
|
||||||
|
return self._engine
|
||||||
|
|
||||||
|
@property
|
||||||
|
def session(self) -> Session:
|
||||||
|
return self._session
|
||||||
|
|
||||||
|
def connect(self, connection_string: str):
|
||||||
|
try:
|
||||||
|
self._engine = create_engine(connection_string)
|
||||||
|
|
||||||
|
if self._db_settings.encoding is not None:
|
||||||
|
self._engine.encoding = self._db_settings.encoding
|
||||||
|
|
||||||
|
if self._db_settings.case_sensitive is not None:
|
||||||
|
self._engine.case_sensitive = self._db_settings.case_sensitive
|
||||||
|
|
||||||
|
if self._db_settings.echo is not None:
|
||||||
|
self._engine.echo = self._db_settings.echo
|
||||||
|
|
||||||
|
self._engine.connect()
|
||||||
|
|
||||||
|
db_session = sessionmaker(bind=self._engine)
|
||||||
|
self._session = db_session()
|
||||||
|
Console.write_line(f'[{__name__}] Connected to database', 'green')
|
||||||
|
except Exception as e:
|
||||||
|
Console.write_line(f'[{__name__}] Database connection failed -> {e}', 'red')
|
||||||
|
exit()
|
||||||
|
|
3
src/sh_edraft/database/context/__init__.py
Normal file
3
src/sh_edraft/database/context/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .database_context import DatabaseContext
|
3
src/sh_edraft/database/context/base/__init__.py
Normal file
3
src/sh_edraft/database/context/base/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .database_context_base import DatabaseContextBase
|
27
src/sh_edraft/database/context/base/database_context_base.py
Normal file
27
src/sh_edraft/database/context/base/database_context_base.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from sqlalchemy import engine
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from sh_edraft.service.base.service_base import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseContextBase(ServiceBase):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def __init__(self):
|
||||||
|
ServiceBase.__init__(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def engine(self) -> engine: pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def session(self) -> Session: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def connect(self, connection_string: str): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _create_tables(self): pass
|
45
src/sh_edraft/database/context/database_context.py
Normal file
45
src/sh_edraft/database/context/database_context.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from sqlalchemy import engine, Table
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from sh_edraft.database.connection.database_connection import DatabaseConnection
|
||||||
|
from sh_edraft.database.connection.base.database_connection_base import DatabaseConnectionBase
|
||||||
|
from sh_edraft.database.context.base.database_context_base import DatabaseContextBase
|
||||||
|
from sh_edraft.database.model.dbmodel import DBModel
|
||||||
|
from sh_edraft.database.model.database_settings import DatabaseSettings
|
||||||
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseContext(DatabaseContextBase):
|
||||||
|
|
||||||
|
def __init__(self, database_settings: DatabaseSettings):
|
||||||
|
DatabaseContextBase.__init__(self)
|
||||||
|
|
||||||
|
self._db: DatabaseConnectionBase = DatabaseConnection(database_settings)
|
||||||
|
self._tables: list[Table] = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def engine(self) -> engine:
|
||||||
|
return self._db.engine
|
||||||
|
|
||||||
|
@property
|
||||||
|
def session(self) -> Session:
|
||||||
|
return self._db.session
|
||||||
|
|
||||||
|
def create(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def connect(self, connection_string: str):
|
||||||
|
self._db.connect(connection_string)
|
||||||
|
self._create_tables()
|
||||||
|
|
||||||
|
def _create_tables(self):
|
||||||
|
try:
|
||||||
|
for subclass in DBModel.__subclasses__():
|
||||||
|
self._tables.append(subclass.__table__)
|
||||||
|
|
||||||
|
DBModel.metadata.drop_all(self._db.engine, self._tables)
|
||||||
|
DBModel.metadata.create_all(self._db.engine, self._tables, checkfirst=True)
|
||||||
|
Console.write_line(f'[{__name__}] Created tables', 'green')
|
||||||
|
except Exception as e:
|
||||||
|
Console.write_line(f'[{__name__}] Creating tables failed -> {e}', 'red')
|
||||||
|
exit()
|
5
src/sh_edraft/database/model/__init__.py
Normal file
5
src/sh_edraft/database/model/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .database_settings import DatabaseSettings
|
||||||
|
from .database_settings_name import DatabaseSettingsName
|
||||||
|
from .dbmodel import DBModel
|
75
src/sh_edraft/database/model/database_settings.py
Normal file
75
src/sh_edraft/database/model/database_settings.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import traceback
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase
|
||||||
|
from sh_edraft.database.model.database_settings_name import DatabaseSettingsName
|
||||||
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseSettings(ConfigurationModelBase):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
ConfigurationModelBase.__init__(self)
|
||||||
|
|
||||||
|
self._connection_string: Optional[str] = None
|
||||||
|
self._credentials: Optional[str] = None
|
||||||
|
self._encoding: Optional[str] = None
|
||||||
|
self._case_sensitive: Optional[bool] = None
|
||||||
|
self._echo: Optional[bool] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connection_string(self) -> str:
|
||||||
|
return self._connection_string
|
||||||
|
|
||||||
|
@connection_string.setter
|
||||||
|
def connection_string(self, connection_string: str):
|
||||||
|
self._connection_string = connection_string
|
||||||
|
|
||||||
|
@property
|
||||||
|
def credentials(self) -> str:
|
||||||
|
return self._credentials
|
||||||
|
|
||||||
|
@credentials.setter
|
||||||
|
def credentials(self, credentials: str):
|
||||||
|
self._credentials = credentials
|
||||||
|
|
||||||
|
@property
|
||||||
|
def encoding(self) -> str:
|
||||||
|
return self._encoding
|
||||||
|
|
||||||
|
@encoding.setter
|
||||||
|
def encoding(self, encoding: str) -> None:
|
||||||
|
self._encoding = encoding
|
||||||
|
|
||||||
|
@property
|
||||||
|
def case_sensitive(self) -> bool:
|
||||||
|
return self._case_sensitive
|
||||||
|
|
||||||
|
@case_sensitive.setter
|
||||||
|
def case_sensitive(self, case_sensitive: bool) -> None:
|
||||||
|
self._case_sensitive = case_sensitive
|
||||||
|
|
||||||
|
@property
|
||||||
|
def echo(self) -> bool:
|
||||||
|
return self._echo
|
||||||
|
|
||||||
|
@echo.setter
|
||||||
|
def echo(self, echo: bool) -> None:
|
||||||
|
self._echo = echo
|
||||||
|
|
||||||
|
def from_dict(self, settings: dict):
|
||||||
|
try:
|
||||||
|
self._connection_string = settings[DatabaseSettingsName.connection_string.value]
|
||||||
|
self._credentials = settings[DatabaseSettingsName.credentials.value]
|
||||||
|
|
||||||
|
if DatabaseSettingsName.encoding.value in settings:
|
||||||
|
self._encoding = settings[DatabaseSettingsName.encoding.value]
|
||||||
|
|
||||||
|
if DatabaseSettingsName.case_sensitive.value in settings:
|
||||||
|
self._case_sensitive = bool(settings[DatabaseSettingsName.case_sensitive.value])
|
||||||
|
|
||||||
|
if DatabaseSettingsName.echo.value in settings:
|
||||||
|
self._echo = bool(settings[DatabaseSettingsName.echo.value])
|
||||||
|
except Exception as e:
|
||||||
|
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings', 'red')
|
||||||
|
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}', 'red')
|
10
src/sh_edraft/database/model/database_settings_name.py
Normal file
10
src/sh_edraft/database/model/database_settings_name.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseSettingsName(Enum):
|
||||||
|
|
||||||
|
connection_string = 'ConnectionString'
|
||||||
|
credentials = 'Credentials'
|
||||||
|
encoding = 'Encoding'
|
||||||
|
case_sensitive = 'CaseSensitive'
|
||||||
|
echo = 'Echo'
|
3
src/sh_edraft/database/model/dbmodel.py
Normal file
3
src/sh_edraft/database/model/dbmodel.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
|
DBModel: declarative_base = declarative_base()
|
@ -5,18 +5,25 @@ from sh_edraft.configuration.base.configuration_base import ConfigurationBase
|
|||||||
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
||||||
from sh_edraft.hosting.application_runtime import ApplicationRuntime
|
from sh_edraft.hosting.application_runtime import ApplicationRuntime
|
||||||
from sh_edraft.hosting.base.application_host_base import ApplicationHostBase
|
from sh_edraft.hosting.base.application_host_base import ApplicationHostBase
|
||||||
from sh_edraft.service.service_provider import ServiceProvider
|
from sh_edraft.service.providing.service_provider import ServiceProvider
|
||||||
from sh_edraft.service.base.service_provider_base import ServiceProviderBase
|
from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase
|
||||||
|
|
||||||
|
|
||||||
class ApplicationHost(ApplicationHostBase):
|
class ApplicationHost(ApplicationHostBase):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ApplicationHostBase.__init__(self)
|
ApplicationHostBase.__init__(self)
|
||||||
|
|
||||||
|
# Init
|
||||||
self._config = Configuration()
|
self._config = Configuration()
|
||||||
self._app_runtime = ApplicationRuntime(self._config)
|
self._app_runtime = ApplicationRuntime(self._config)
|
||||||
self._services = ServiceProvider(self._app_runtime)
|
self._services = ServiceProvider(self._app_runtime)
|
||||||
|
|
||||||
|
# Create
|
||||||
|
self._config.create()
|
||||||
|
self._services.create()
|
||||||
|
|
||||||
|
# Set vars
|
||||||
self._start_time: datetime = datetime.now()
|
self._start_time: datetime = datetime.now()
|
||||||
self._end_time: datetime = datetime.now()
|
self._end_time: datetime = datetime.now()
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
|
|||||||
|
|
||||||
from sh_edraft.configuration.base.configuration_base import ConfigurationBase
|
from sh_edraft.configuration.base.configuration_base import ConfigurationBase
|
||||||
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
||||||
from sh_edraft.service.base.service_provider_base import ServiceProviderBase
|
from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase
|
||||||
|
|
||||||
|
|
||||||
class ApplicationHostBase(ABC):
|
class ApplicationHostBase(ABC):
|
||||||
|
@ -5,9 +5,9 @@ from string import Template
|
|||||||
|
|
||||||
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
||||||
from sh_edraft.logging.base.logger_base import LoggerBase
|
from sh_edraft.logging.base.logger_base import LoggerBase
|
||||||
from sh_edraft.logging.model import LoggingSettings
|
from sh_edraft.logging.model.logging_settings import LoggingSettings
|
||||||
from sh_edraft.logging.model.logging_level import LoggingLevel
|
from sh_edraft.logging.model.logging_level import LoggingLevel
|
||||||
from sh_edraft.time.model import TimeFormatSettings
|
from sh_edraft.time.model.time_format_settings import TimeFormatSettings
|
||||||
from sh_edraft.utils.console import Console
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +28,8 @@ class Logger(LoggerBase):
|
|||||||
self._level = self._log_settings.level
|
self._level = self._log_settings.level
|
||||||
self._console = self._log_settings.console
|
self._console = self._log_settings.console
|
||||||
|
|
||||||
|
self.create()
|
||||||
|
|
||||||
def _get_datetime_now(self) -> str:
|
def _get_datetime_now(self) -> str:
|
||||||
try:
|
try:
|
||||||
return datetime.datetime.now().strftime(self._time_format_settings.date_time_format)
|
return datetime.datetime.now().strftime(self._time_format_settings.date_time_format)
|
||||||
|
@ -2,9 +2,9 @@ import traceback
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase
|
from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase
|
||||||
from sh_edraft.publishing.model import Template
|
from sh_edraft.publishing.model.template import Template
|
||||||
from sh_edraft.publishing.model.publish_settings_name import PublishSettingsName
|
from sh_edraft.publishing.model.publish_settings_name import PublishSettingsName
|
||||||
from sh_edraft.utils import Console
|
from sh_edraft.utils.console import Console
|
||||||
|
|
||||||
|
|
||||||
class PublishSettings(ConfigurationModelBase):
|
class PublishSettings(ConfigurationModelBase):
|
||||||
|
@ -21,6 +21,7 @@ class Template(ConfigurationModelBase):
|
|||||||
author: Optional[str] = None,
|
author: Optional[str] = None,
|
||||||
version: Optional[dict] = None
|
version: Optional[dict] = None
|
||||||
):
|
):
|
||||||
|
ConfigurationModelBase.__init__(self)
|
||||||
self._template_path: Optional[str] = template_path
|
self._template_path: Optional[str] = template_path
|
||||||
self._name: Optional[str] = name
|
self._name: Optional[str] = name
|
||||||
self._description: Optional[str] = description
|
self._description: Optional[str] = description
|
||||||
|
@ -20,7 +20,6 @@ __version__ = '2020.12.5'
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
# imports:
|
# imports:
|
||||||
from .service_provider import ServiceProvider
|
|
||||||
|
|
||||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||||
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
||||||
|
@ -21,7 +21,6 @@ from collections import namedtuple
|
|||||||
|
|
||||||
# imports:
|
# imports:
|
||||||
from .service_base import ServiceBase
|
from .service_base import ServiceBase
|
||||||
from .service_provider_base import ServiceProviderBase
|
|
||||||
|
|
||||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||||
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
||||||
|
4
src/sh_edraft/service/providing/__init__.py
Normal file
4
src/sh_edraft/service/providing/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# imports:
|
||||||
|
from .service_provider import ServiceProvider
|
||||||
|
|
||||||
|
from .service_provider import ServiceProviderBase
|
3
src/sh_edraft/service/providing/base/__init__.py
Normal file
3
src/sh_edraft/service/providing/base/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .service_provider_base import ServiceProviderBase
|
@ -1,15 +1,21 @@
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod, ABC
|
||||||
from collections import Callable
|
from collections import Callable
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from sh_edraft.database.context.base.database_context_base import DatabaseContextBase
|
||||||
from sh_edraft.service.base.service_base import ServiceBase
|
from sh_edraft.service.base.service_base import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
class ServiceProviderBase(ServiceBase):
|
class ServiceProviderBase(ABC):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(self):
|
def __init__(self): pass
|
||||||
ServiceBase.__init__(self)
|
|
||||||
|
@abstractmethod
|
||||||
|
def add_db_context(self, db_context: Type[DatabaseContextBase]): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_db_context(self) -> Callable[DatabaseContextBase]: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass
|
def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass
|
3
src/sh_edraft/service/providing/model/__init__.py
Normal file
3
src/sh_edraft/service/providing/model/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# imports:
|
||||||
|
|
||||||
|
from .provide_state import ProvideState
|
@ -1,6 +1,6 @@
|
|||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
from sh_edraft.service.base import ServiceBase
|
from sh_edraft.service.base.service_base import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
class ProvideState:
|
class ProvideState:
|
@ -1,10 +1,11 @@
|
|||||||
from collections import Callable
|
from collections import Callable
|
||||||
from inspect import signature, Parameter
|
from inspect import signature, Parameter
|
||||||
from typing import Type
|
from typing import Type, Optional
|
||||||
|
|
||||||
from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase
|
from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase
|
||||||
|
from sh_edraft.database.context.base.database_context_base import DatabaseContextBase
|
||||||
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase
|
||||||
from sh_edraft.service.base.service_provider_base import ServiceProviderBase
|
from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase
|
||||||
from sh_edraft.service.base.service_base import ServiceBase
|
from sh_edraft.service.base.service_base import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ class ServiceProvider(ServiceProviderBase):
|
|||||||
def __init__(self, app_runtime: ApplicationRuntimeBase):
|
def __init__(self, app_runtime: ApplicationRuntimeBase):
|
||||||
ServiceProviderBase.__init__(self)
|
ServiceProviderBase.__init__(self)
|
||||||
self._app_runtime: ApplicationRuntimeBase = app_runtime
|
self._app_runtime: ApplicationRuntimeBase = app_runtime
|
||||||
|
self._database_context: Optional[DatabaseContextBase] = None
|
||||||
|
|
||||||
self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {}
|
self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {}
|
||||||
self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {}
|
self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {}
|
||||||
@ -29,6 +31,9 @@ class ServiceProvider(ServiceProviderBase):
|
|||||||
if issubclass(parameter.annotation, ApplicationRuntimeBase):
|
if issubclass(parameter.annotation, ApplicationRuntimeBase):
|
||||||
params.append(self._app_runtime)
|
params.append(self._app_runtime)
|
||||||
|
|
||||||
|
elif issubclass(parameter.annotation, DatabaseContextBase):
|
||||||
|
params.append(self._database_context)
|
||||||
|
|
||||||
elif issubclass(parameter.annotation, ServiceBase):
|
elif issubclass(parameter.annotation, ServiceBase):
|
||||||
params.append(self.get_service(parameter.annotation))
|
params.append(self.get_service(parameter.annotation))
|
||||||
|
|
||||||
@ -37,6 +42,12 @@ class ServiceProvider(ServiceProviderBase):
|
|||||||
|
|
||||||
return service(*params)
|
return service(*params)
|
||||||
|
|
||||||
|
def add_db_context(self, db_context: Type[DatabaseContextBase]):
|
||||||
|
self._database_context = self._create_instance(db_context)
|
||||||
|
|
||||||
|
def get_db_context(self) -> Callable[DatabaseContextBase]:
|
||||||
|
return self._database_context
|
||||||
|
|
||||||
def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]):
|
def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]):
|
||||||
self._transient_services[service_type] = service
|
self._transient_services[service_type] = service
|
||||||
|
|
||||||
@ -45,8 +56,8 @@ class ServiceProvider(ServiceProviderBase):
|
|||||||
|
|
||||||
def add_singleton(self, service_type: Type[ServiceBase], service: Callable[ServiceBase]):
|
def add_singleton(self, service_type: Type[ServiceBase], service: Callable[ServiceBase]):
|
||||||
for known_service in self._singleton_services:
|
for known_service in self._singleton_services:
|
||||||
if type(known_service) == type(service_type):
|
if type(known_service) == service_type:
|
||||||
raise Exception(f'Service with type {type(service_type)} already exists')
|
raise Exception(f'Service with type {service_type} already exists')
|
||||||
|
|
||||||
self._singleton_services[service_type] = self._create_instance(service)
|
self._singleton_services[service_type] = self._create_instance(service)
|
||||||
|
|
@ -21,6 +21,7 @@ from collections import namedtuple
|
|||||||
|
|
||||||
# imports:
|
# imports:
|
||||||
from .console import Console
|
from .console import Console
|
||||||
|
from .credential_manager import CredentialManager
|
||||||
|
|
||||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||||
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
version_info = VersionInfo(major=2020, minor=12, micro=5)
|
||||||
|
17
src/sh_edraft/utils/credential_manager.py
Normal file
17
src/sh_edraft/utils/credential_manager.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import base64
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialManager:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def encrypt(string: str) -> str:
|
||||||
|
return base64.b64encode(string.encode('utf-8')).decode('utf-8')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def decrypt(string: str) -> str:
|
||||||
|
return base64.b64decode(string).decode('utf-8')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build_string(string: str, credentials: str):
|
||||||
|
return string.replace('$credentials', CredentialManager.decrypt(credentials))
|
||||||
|
|
@ -4,5 +4,10 @@
|
|||||||
"Filename": "log_$start_time.log",
|
"Filename": "log_$start_time.log",
|
||||||
"ConsoleLogLevel": "TRACE",
|
"ConsoleLogLevel": "TRACE",
|
||||||
"FileLogLevel": "TRACE"
|
"FileLogLevel": "TRACE"
|
||||||
|
},
|
||||||
|
"DatabaseSettings": {
|
||||||
|
"ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl",
|
||||||
|
"Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==",
|
||||||
|
"Encoding": "utf8mb4"
|
||||||
}
|
}
|
||||||
}
|
}
|
0
src/tests_dev/db/__init__.py
Normal file
0
src/tests_dev/db/__init__.py
Normal file
14
src/tests_dev/db/city.py
Normal file
14
src/tests_dev/db/city.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from sqlalchemy import Column, Integer, String
|
||||||
|
|
||||||
|
from sh_edraft.database.model import DBModel
|
||||||
|
|
||||||
|
|
||||||
|
class City(DBModel):
|
||||||
|
__tablename__ = 'Cities'
|
||||||
|
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
|
||||||
|
Name = Column(String(64), nullable=False)
|
||||||
|
ZIP = Column(String(5), nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, name: str, zip_code: str):
|
||||||
|
self.Name = name
|
||||||
|
self.ZIP = zip_code
|
18
src/tests_dev/db/user.py
Normal file
18
src/tests_dev/db/user.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from sqlalchemy import Column, Integer, String, ForeignKey
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from sh_edraft.database.model import DBModel
|
||||||
|
from tests_dev.db.city import City as CityModel
|
||||||
|
|
||||||
|
|
||||||
|
class User(DBModel):
|
||||||
|
__tablename__ = 'Users'
|
||||||
|
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
|
||||||
|
Name = Column(String(64), nullable=False)
|
||||||
|
City_Id = Column(Integer, ForeignKey('Cities.Id'), nullable=False)
|
||||||
|
City = relationship("City")
|
||||||
|
|
||||||
|
def __init__(self, name: str, city: CityModel):
|
||||||
|
self.Name = name
|
||||||
|
self.City_Id = city.Id
|
||||||
|
self.City = city
|
23
src/tests_dev/db/user_repo.py
Normal file
23
src/tests_dev/db/user_repo.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from sh_edraft.database.context.base import DatabaseContextBase
|
||||||
|
from tests_dev.db.city import City
|
||||||
|
from tests_dev.db.user import User
|
||||||
|
from tests_dev.db.user_repo_base import UserRepoBase
|
||||||
|
|
||||||
|
|
||||||
|
class UserRepo(UserRepoBase):
|
||||||
|
|
||||||
|
def __init__(self, db_context: DatabaseContextBase):
|
||||||
|
UserRepoBase.__init__(self)
|
||||||
|
|
||||||
|
self._session = db_context.session
|
||||||
|
self._user_query = db_context.session.query(User)
|
||||||
|
|
||||||
|
def create(self): pass
|
||||||
|
|
||||||
|
def add_test_user(self):
|
||||||
|
city = City('Haren', '49733')
|
||||||
|
city2 = City('Meppen', '49716')
|
||||||
|
self._session.add(city2)
|
||||||
|
user = User('TestUser', city)
|
||||||
|
self._session.add(user)
|
||||||
|
self._session.commit()
|
10
src/tests_dev/db/user_repo_base.py
Normal file
10
src/tests_dev/db/user_repo_base.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from sh_edraft.service.base import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
|
class UserRepoBase(ServiceBase):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def __init__(self):
|
||||||
|
ServiceBase.__init__(self)
|
@ -1,11 +1,17 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from sh_edraft.configuration.base import ConfigurationBase
|
from sh_edraft.configuration.base import ConfigurationBase
|
||||||
|
from sh_edraft.database.context import DatabaseContext
|
||||||
|
from sh_edraft.database.model import DatabaseSettings
|
||||||
from sh_edraft.hosting import ApplicationHost
|
from sh_edraft.hosting import ApplicationHost
|
||||||
from sh_edraft.hosting.base import ApplicationBase
|
from sh_edraft.hosting.base import ApplicationBase
|
||||||
from sh_edraft.logging import Logger
|
from sh_edraft.logging import Logger
|
||||||
from sh_edraft.logging.base import LoggerBase
|
from sh_edraft.logging.base import LoggerBase
|
||||||
from sh_edraft.service.base import ServiceProviderBase
|
from sh_edraft.service.providing.base import ServiceProviderBase
|
||||||
|
from sh_edraft.utils import CredentialManager
|
||||||
|
|
||||||
|
from tests_dev.db.user_repo import UserRepo
|
||||||
|
from tests_dev.db.user_repo_base import UserRepoBase
|
||||||
|
|
||||||
|
|
||||||
class Program(ApplicationBase):
|
class Program(ApplicationBase):
|
||||||
@ -24,7 +30,6 @@ class Program(ApplicationBase):
|
|||||||
self._services = self._app_host.services
|
self._services = self._app_host.services
|
||||||
|
|
||||||
def create_configuration(self):
|
def create_configuration(self):
|
||||||
self._configuration.create()
|
|
||||||
self._configuration.add_environment_variables('PYTHON_')
|
self._configuration.add_environment_variables('PYTHON_')
|
||||||
self._configuration.add_environment_variables('CPL_')
|
self._configuration.add_environment_variables('CPL_')
|
||||||
self._configuration.add_argument_variables()
|
self._configuration.add_argument_variables()
|
||||||
@ -33,13 +38,21 @@ class Program(ApplicationBase):
|
|||||||
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True)
|
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True)
|
||||||
|
|
||||||
def create_services(self):
|
def create_services(self):
|
||||||
self._services.create()
|
# Create and connect to database
|
||||||
|
db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings)
|
||||||
|
self._services.add_db_context(DatabaseContext)
|
||||||
|
db: DatabaseContext = self._services.get_db_context()
|
||||||
|
db.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
|
||||||
|
|
||||||
|
self._services.add_scoped(UserRepoBase, UserRepo)
|
||||||
|
|
||||||
|
# Add and create logger
|
||||||
self._services.add_singleton(LoggerBase, Logger)
|
self._services.add_singleton(LoggerBase, Logger)
|
||||||
self._logger = self._services.get_service(LoggerBase)
|
self._logger = self._services.get_service(LoggerBase)
|
||||||
self._logger.create()
|
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
self._logger.header(f'{self._configuration.environment.application_name}:')
|
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'Host: {self._configuration.environment.host_name}')
|
||||||
self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}')
|
self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}')
|
||||||
self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}')
|
self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}')
|
||||||
|
self._services.get_service(UserRepoBase).add_test_user()
|
||||||
|
Loading…
Reference in New Issue
Block a user