Merge pull request '2021.4.2' (#12) from 2021.4.2 into 2021.4

Reviewed-on: sh-edraft.de/sh_common_py_lib#12
This commit is contained in:
Sven Heidemann 2021-03-29 15:48:58 +02:00
commit e2544f90fe
111 changed files with 1095 additions and 522 deletions

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "2021", "Major": "2021",
"Minor": "04", "Minor": "04",
"Micro": "01-15" "Micro": "02"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -15,11 +15,11 @@ __title__ = 'sh_cpl.cpl'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.application'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -23,9 +23,7 @@ from collections import namedtuple
from .application_abc import ApplicationABC from .application_abc import ApplicationABC
from .application_builder import ApplicationBuilder from .application_builder import ApplicationBuilder
from .application_builder_abc import ApplicationBuilderABC from .application_builder_abc import ApplicationBuilderABC
from .application_runtime import ApplicationRuntime
from .application_runtime_abc import ApplicationRuntimeABC
from .startup_abc import StartupABC from .startup_abc import StartupABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,21 +1,21 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment import ApplicationEnvironmentABC
class ApplicationABC(ABC): class ApplicationABC(ABC):
@abstractmethod @abstractmethod
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
ABC of application ABC of application
""" """
self._configuration: Optional[ConfigurationABC] = config self._configuration: Optional[ConfigurationABC] = config
self._runtime: Optional[ApplicationRuntimeABC] = runtime self._environment: Optional[ApplicationEnvironmentABC] = self._configuration.environment
self._services: Optional[ServiceProviderABC] = services self._services: Optional[ServiceProviderABC] = services
def run(self): def run(self):

View File

@ -2,10 +2,9 @@ from typing import Type, Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.application_abc import ApplicationABC
from cpl.application.application_builder_abc import ApplicationBuilderABC from cpl.application.application_builder_abc import ApplicationBuilderABC
from cpl.application.application_runtime import ApplicationRuntime
from cpl.application.startup_abc import StartupABC from cpl.application.startup_abc import StartupABC
from cpl.configuration import Configuration from cpl.configuration.configuration import Configuration
from cpl.dependency_injection import ServiceProvider from cpl.dependency_injection.service_collection import ServiceCollection
class ApplicationBuilder(ApplicationBuilderABC): class ApplicationBuilder(ApplicationBuilderABC):
@ -19,8 +18,8 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup: Optional[StartupABC] = None self._startup: Optional[StartupABC] = None
self._configuration = Configuration() self._configuration = Configuration()
self._runtime = ApplicationRuntime() self._environment = self._configuration.environment
self._services = ServiceProvider(self._configuration, self._runtime) self._services = ServiceCollection(self._configuration)
def use_startup(self, startup: Type[StartupABC]): def use_startup(self, startup: Type[StartupABC]):
""" """
@ -28,7 +27,7 @@ class ApplicationBuilder(ApplicationBuilderABC):
:param startup: :param startup:
:return: :return:
""" """
self._startup = startup(self._configuration, self._runtime, self._services) self._startup = startup(self._configuration, self._services)
def build(self) -> ApplicationABC: def build(self) -> ApplicationABC:
""" """
@ -39,4 +38,4 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup.configure_configuration() self._startup.configure_configuration()
self._startup.configure_services() self._startup.configure_services()
return self._app(self._configuration, self._runtime, self._services) return self._app(self._configuration, self._services.build_service_provider())

View File

@ -1,52 +0,0 @@
import pathlib
from datetime import datetime
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
class ApplicationRuntime(ApplicationRuntimeABC):
def __init__(self):
"""
Representation of the application runtime
"""
ApplicationRuntimeABC.__init__(self)
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@ -1,49 +0,0 @@
from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationRuntimeABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for application runtime
"""
pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -27,4 +27,4 @@ from .configuration_variable_name_enum import ConfigurationVariableNameEnum
from .console_argument import ConsoleArgument from .console_argument import ConsoleArgument
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -11,7 +11,7 @@ from cpl.configuration.console_argument import ConsoleArgument
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment import ApplicationEnvironment from cpl.environment.application_environment import ApplicationEnvironment
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum from cpl.environment.environment_name_enum import EnvironmentNameEnum

View File

@ -4,7 +4,7 @@ from typing import Type, Union, Optional
from cpl.configuration.console_argument import ConsoleArgument from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_model_abc import ConfigurationModelABC from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ConfigurationABC(ABC): class ConfigurationABC(ABC):
@ -82,8 +82,7 @@ class ConfigurationABC(ABC):
pass pass
@abstractmethod @abstractmethod
def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[ def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[str, Callable[ConfigurationModelABC]]:
str, Callable[ConfigurationModelABC]]:
""" """
Returns value in configuration by given type Returns value in configuration by given type
:param search_type: :param search_type:

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -27,4 +27,4 @@ from .foreground_color_enum import ForegroundColorEnum
from .spinner_thread import SpinnerThread from .spinner_thread import SpinnerThread
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -25,4 +25,4 @@ from .database_settings import DatabaseSettings
from .database_settings_name_enum import DatabaseSettingsNameEnum from .database_settings_name_enum import DatabaseSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database.connection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -24,4 +24,4 @@ from .database_connection import DatabaseConnection
from .database_connection_abc import DatabaseConnectionABC from .database_connection_abc import DatabaseConnectionABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database.context'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -24,4 +24,4 @@ from .database_context import DatabaseContext
from .database_context_abc import DatabaseContextABC from .database_context_abc import DatabaseContextABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -6,6 +6,10 @@ from sqlalchemy.orm import Session
class DatabaseContextABC(ABC): class DatabaseContextABC(ABC):
@abstractmethod
def __init__(self, *args):
pass
@property @property
@abstractmethod @abstractmethod
def engine(self) -> engine: pass def engine(self) -> engine: pass

View File

@ -15,14 +15,17 @@ __title__ = 'cpl.dependency_injection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
from .service_abc import ServiceABC from .service_collection import ServiceCollection
from .service_collection_abc import ServiceCollectionABC
from .service_descriptor import ServiceDescriptor
from .service_lifetime_enum import ServiceLifetimeEnum
from .service_provider import ServiceProvider from .service_provider import ServiceProvider
from .service_provider_abc import ServiceProviderABC from .service_provider_abc import ServiceProviderABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,11 +0,0 @@
from abc import ABC, abstractmethod
class ServiceABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC to represent a service
"""
pass

View File

@ -0,0 +1,65 @@
from typing import Union, Type, Callable, Optional
from cpl.configuration.configuration_abc import ConfigurationABC
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):
def __init__(self, config: ConfigurationABC):
ServiceCollectionABC.__init__(self)
self._configuration: ConfigurationABC = config
self._database_context: Optional[DatabaseContextABC] = None
self._service_descriptors: list[ServiceDescriptor] = []
def _add_descriptor(self, service: Union[type, object], lifetime: ServiceLifetimeEnum):
found = False
for descriptor in self._service_descriptors:
if isinstance(service, descriptor.service_type):
found = True
if found:
service_type = service
if not isinstance(service, type):
service_type = type(service)
raise Exception(f'Service of type {service_type} already exists')
self._service_descriptors.append(ServiceDescriptor(service, lifetime))
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
self._database_context = db_context_type(db_settings)
self._database_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):
impl = None
if service is not None:
if isinstance(service, type):
impl = self.build_service_provider().build_service(service)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
else:
if isinstance(service_type, type):
impl = self.build_service_provider().build_service(service_type)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
def add_scoped(self, service_type: Type, service: Callable = None):
raise Exception('Not implemented')
def add_transient(self, service_type: Union[type], service: Union[type] = None):
if service is not None:
self._add_descriptor(service, ServiceLifetimeEnum.transient)
else:
self._add_descriptor(service_type, ServiceLifetimeEnum.transient)
def build_service_provider(self) -> ServiceProviderABC:
return ServiceProvider(self._service_descriptors, self._configuration, self._database_context)

View File

@ -0,0 +1,64 @@
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
class ServiceCollectionABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for service providing
"""
pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC], db_settings: DatabaseSettings):
"""
Adds database context
:param db_context:
:param db_settings:
:return:
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None):
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def build_service_provider(self) -> ServiceProviderABC:
"""
Creates instance of the service provider
"""
pass

View File

@ -0,0 +1,33 @@
from typing import Union, Optional
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
class ServiceDescriptor:
def __init__(self, implementation: Union[type, Optional[object]], lifetime: ServiceLifetimeEnum):
self._service_type = implementation
self._implementation = implementation
self._lifetime = lifetime
if not isinstance(implementation, type):
self._service_type = type(implementation)
else:
self._implementation = None
@property
def service_type(self) -> type:
return self._service_type
@property
def implementation(self) -> Union[type, Optional[object]]:
return self._implementation
@implementation.setter
def implementation(self, implementation: Union[type, Optional[object]]):
self._implementation = implementation
@property
def lifetime(self) -> ServiceLifetimeEnum:
return self._lifetime

View File

@ -0,0 +1,8 @@
from enum import Enum
class ServiceLifetimeEnum(Enum):
singleton = 0
scoped = 1 # not supported yet
transient = 2

View File

@ -1,45 +1,61 @@
from collections import Callable from collections import Callable
from inspect import signature, Parameter from inspect import signature, Parameter
from typing import Type, Optional, Union from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.configuration.configuration_model_abc import ConfigurationModelABC from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.database.context.database_context_abc import DatabaseContextABC from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.dependency_injection.service_descriptor import ServiceDescriptor
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ServiceProvider(ServiceProviderABC): class ServiceProvider(ServiceProviderABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, service_descriptors: list[ServiceDescriptor], config: ConfigurationABC, db_context: Optional[DatabaseContextABC]):
"""
Service for service providing
:param runtime:
"""
ServiceProviderABC.__init__(self) ServiceProviderABC.__init__(self)
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
self._configuration: ConfigurationABC = config self._configuration: ConfigurationABC = config
self._runtime: ApplicationRuntimeABC = runtime self._database_context = db_context
self._database_context: Optional[DatabaseContextABC] = None
self._transient_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {} def _find_service(self, service_type: type) -> [ServiceDescriptor]:
self._scoped_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {} for descriptor in self._service_descriptors:
self._singleton_services: dict[Type[ServiceABC], Callable[ServiceABC], ServiceABC] = {} if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
return descriptor
def _create_instance(self, service: Union[Callable[ServiceABC], ServiceABC]) -> Callable[ServiceABC]: return None
"""
Creates an instance of given type def _get_service(self, parameter: Parameter) -> object:
:param service: for descriptor in self._service_descriptors:
:return: if descriptor.service_type == parameter.annotation or issubclass(descriptor.service_type, parameter.annotation):
""" if descriptor.implementation is not None:
sig = signature(service.__init__) return descriptor.implementation
implementation = self.build_service(descriptor.service_type)
if descriptor.lifetime == ServiceLifetimeEnum.singleton:
descriptor.implementation = implementation
return implementation
def build_service(self, service_type: type) -> object:
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
if descriptor.implementation is not None:
service_type = type(descriptor.implementation)
else:
service_type = descriptor.service_type
break
sig = signature(service_type.__init__)
params = [] params = []
for param in sig.parameters.items(): for param in sig.parameters.items():
parameter = param[1] parameter = param[1]
if parameter.name != 'self' and parameter.annotation != Parameter.empty: if parameter.name != 'self' and parameter.annotation != Parameter.empty:
if issubclass(parameter.annotation, ApplicationRuntimeABC): if issubclass(parameter.annotation, ServiceProviderABC):
params.append(self._runtime) params.append(self)
elif issubclass(parameter.annotation, ApplicationEnvironmentABC): elif issubclass(parameter.annotation, ApplicationEnvironmentABC):
params.append(self._configuration.environment) params.append(self._configuration.environment)
@ -53,70 +69,22 @@ class ServiceProvider(ServiceProviderABC):
elif issubclass(parameter.annotation, ConfigurationABC): elif issubclass(parameter.annotation, ConfigurationABC):
params.append(self._configuration) params.append(self._configuration)
elif issubclass(parameter.annotation, ServiceProviderABC):
params.append(self)
else: else:
params.append(self.get_service(parameter.annotation)) params.append(self._get_service(parameter))
return service(*params) return service_type(*params)
def add_db_context(self, db_context: Type[DatabaseContextABC]): def get_service(self, service_type: type) -> Optional[Callable[object]]:
self._database_context = self._create_instance(db_context) result = self._find_service(service_type)
def get_db_context(self) -> Callable[DatabaseContextABC]: if result is None:
return self._database_context return None
def add_transient(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): if result.implementation is not None:
if service is None: return result.implementation
self._transient_services[service_type] = service_type
else:
self._transient_services[service_type] = service
def add_scoped(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): implementation = self.build_service(service_type)
if service is None: if result.lifetime == ServiceLifetimeEnum.singleton:
self._scoped_services[service_type] = service_type result.implementation = implementation
else:
self._scoped_services[service_type] = service
def add_singleton(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): return implementation
for known_service in self._singleton_services:
if type(known_service) == service_type:
raise Exception(f'Service with type {service_type} already exists')
if service is None:
self._singleton_services[service_type] = self._create_instance(service_type)
else:
self._singleton_services[service_type] = self._create_instance(service)
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
if issubclass(instance_type, ServiceProviderABC):
return self
for service in self._transient_services:
if service == instance_type and isinstance(self._transient_services[service], type(instance_type)):
return self._create_instance(self._transient_services[service])
for service in self._scoped_services:
if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)):
return self._create_instance(self._scoped_services[service])
for service in self._singleton_services:
if service == instance_type and isinstance(self._singleton_services[service], instance_type):
return self._singleton_services[service]
def remove_service(self, instance_type: Type[ServiceABC]):
for service in self._transient_services:
if service == instance_type and isinstance(self._transient_services[service], type(instance_type)):
del self._transient_services[service]
return
for service in self._scoped_services:
if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)):
del self._scoped_services[service]
return
for service in self._singleton_services:
if service == instance_type and isinstance(self._singleton_services[service], instance_type):
del self._singleton_services[service]
return

View File

@ -1,9 +1,6 @@
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from collections import Callable from collections import Callable
from typing import Type from typing import Type, Optional
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
class ServiceProviderABC(ABC): class ServiceProviderABC(ABC):
@ -16,66 +13,19 @@ class ServiceProviderABC(ABC):
pass pass
@abstractmethod @abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC]): def build_service(self, service_type: type) -> object:
""" """
Adds database context Creates instance of given type
:param db_context:
:return:
"""
pass
@abstractmethod
def get_db_context(self) -> Callable[DatabaseContextABC]:
""""
Returns database context
:return Callable[DatabaseContextABC]:
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
:param service_type: :param service_type:
:param service:
:return: :return:
""" """
pass pass
@abstractmethod @abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None): def get_service(self, instance_type: Type) -> Optional[Callable[object]]:
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
""" """
Returns instance of given type Returns instance of given type
:param instance_type: :param instance_type:
:return: :return:
""" """
pass pass
@abstractmethod
def remove_service(self, instance_type: type):
"""
Removes service
:param instance_type:
:return:
"""
pass

View File

@ -15,14 +15,14 @@ __title__ = 'cpl.environment'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
from .environment_abc import ApplicationEnvironmentABC from .application_environment_abc import ApplicationEnvironmentABC
from .environment_name_enum import EnvironmentNameEnum from .environment_name_enum import EnvironmentNameEnum
from .application_environment import ApplicationEnvironment from .application_environment import ApplicationEnvironment
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,7 +1,9 @@
import pathlib
from datetime import datetime
from socket import gethostname from socket import gethostname
from typing import Optional from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum from cpl.environment.environment_name_enum import EnvironmentNameEnum
@ -20,6 +22,11 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
self._customer: Optional[str] = None self._customer: Optional[str] = None
self._content_root_path: Optional[str] = crp self._content_root_path: Optional[str] = crp
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property @property
def environment_name(self) -> str: def environment_name(self) -> str:
return str(self._environment_name.value) return str(self._environment_name.value)
@ -55,3 +62,37 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
@property @property
def host_name(self): def host_name(self):
return gethostname() return gethostname()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@ -1,4 +1,5 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationEnvironmentABC(ABC): class ApplicationEnvironmentABC(ABC):
@ -45,3 +46,40 @@ class ApplicationEnvironmentABC(ABC):
@property @property
@abstractmethod @abstractmethod
def host_name(self) -> str: pass def host_name(self) -> str: pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.logging'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -27,4 +27,4 @@ from .logging_settings import LoggingSettings
from .logging_settings_name_enum import LoggingSettingsNameEnum from .logging_settings_name_enum import LoggingSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,16 +1,14 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class LoggerABC(ServiceABC): class LoggerABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
""" """
ABC for logging ABC for logging
""" """
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def header(self, string: str): def header(self, string: str):

View File

@ -3,9 +3,9 @@ import os
import traceback import traceback
from string import Template from string import Template
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.logging.logging_level_enum import LoggingLevelEnum from cpl.logging.logging_level_enum import LoggingLevelEnum
from cpl.logging.logging_settings import LoggingSettings from cpl.logging.logging_settings import LoggingSettings
@ -14,7 +14,7 @@ from cpl.time.time_format_settings import TimeFormatSettings
class Logger(LoggerABC): class Logger(LoggerABC):
def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_runtime: ApplicationRuntimeABC): def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
""" """
Service for logging Service for logging
:param logging_settings: :param logging_settings:
@ -23,13 +23,13 @@ class Logger(LoggerABC):
""" """
LoggerABC.__init__(self) LoggerABC.__init__(self)
self._app_runtime = app_runtime self._env = env
self._log_settings: LoggingSettings = logging_settings self._log_settings: LoggingSettings = logging_settings
self._time_format_settings: TimeFormatSettings = time_format self._time_format_settings: TimeFormatSettings = time_format
self._log = Template(self._log_settings.filename).substitute( self._log = Template(self._log_settings.filename).substitute(
date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), date_time_now=self._env.date_time_now.strftime(self._time_format_settings.date_time_format),
start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) start_time=self._env.start_time.strftime(self._time_format_settings.date_time_log_format)
) )
self._path = self._log_settings.path self._path = self._log_settings.path
self._level = self._log_settings.level self._level = self._log_settings.level

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.mailing'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -27,4 +27,4 @@ from .email_client_settings import EMailClientSettings
from .email_client_settings_name_enum import EMailClientSettingsNameEnum from .email_client_settings_name_enum import EMailClientSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,17 +1,16 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.mailing.email import EMail from cpl.mailing.email import EMail
class EMailClientABC(ServiceABC): class EMailClientABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
""" """
ABC to send emails ABC to send emails
""" """
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def connect(self): def connect(self):

View File

@ -2,7 +2,7 @@ import ssl
from smtplib import SMTP from smtplib import SMTP
from typing import Optional from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC from cpl.mailing.email_client_abc import EMailClientABC

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.time'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -24,4 +24,4 @@ from .time_format_settings import TimeFormatSettings
from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.utils'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -25,4 +25,4 @@ from .string import String
from .pip import Pip from .pip import Pip
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'sh_cpl.cpl_cli'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -29,4 +29,4 @@ from .main import main
from .startup import Startup from .startup import Startup
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,7 +1,6 @@
from typing import Optional from typing import Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection import ServiceProviderABC from cpl.dependency_injection import ServiceProviderABC
@ -22,11 +21,11 @@ from cpl_cli.command.version_service import VersionService
class CLI(ApplicationABC): class CLI(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
CPL CLI CPL CLI
""" """
ApplicationABC.__init__(self, config, runtime, services) ApplicationABC.__init__(self, config, services)
self._command_handler: Optional[CommandHandler] = None self._command_handler: Optional[CommandHandler] = None

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -28,4 +28,4 @@ from .publish_service import PublishService
from .version_service import VersionService from .version_service import VersionService
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,4 +1,3 @@
from cpl.console.console import Console
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.publish.publisher_abc import PublisherABC from cpl_cli.publish.publisher_abc import PublisherABC
@ -21,4 +20,3 @@ class BuildService(CommandABC):
:return: :return:
""" """
self._publisher.build() self._publisher.build()
Console.write('\n')

View File

@ -1,7 +1,6 @@
import os import os
from collections import Callable from collections import Callable
from cpl.application.application_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
@ -18,11 +17,10 @@ from cpl_cli.templates.template_file_abc import TemplateFileABC
class GenerateService(CommandABC): class GenerateService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, configuration: ConfigurationABC):
""" """
Service for the CLI command generate Service for the CLI command generate
:param configuration: :param configuration:
:param runtime:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
@ -54,7 +52,7 @@ class GenerateService(CommandABC):
} }
self._config = configuration self._config = configuration
self._runtime = runtime self._env = self._config.environment
@staticmethod @staticmethod
def _help(message: str): def _help(message: str):
@ -105,7 +103,7 @@ class GenerateService(CommandABC):
template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path) template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path)
file_path = os.path.join(self._runtime.working_directory, template.path, template.name) file_path = os.path.join(self._env.working_directory, template.path, template.name)
if not os.path.isdir(os.path.dirname(file_path)): if not os.path.isdir(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path)) os.makedirs(os.path.dirname(file_path))
@ -113,9 +111,9 @@ class GenerateService(CommandABC):
Console.error(f'{String.first_to_upper(schematic)} already exists!') Console.error(f'{String.first_to_upper(schematic)} already exists!')
exit() exit()
message = f'Creating {self._runtime.working_directory}/{template.path}/{template.name}' message = f'Creating {self._env.working_directory}/{template.path}/{template.name}'
if template.path == '': if template.path == '':
message = f'Creating {self._runtime.working_directory}/{template.name}' message = f'Creating {self._env.working_directory}/{template.name}'
Console.spinner( Console.spinner(
message, message,
@ -148,5 +146,3 @@ class GenerateService(CommandABC):
else: else:
self._help('Usage: cpl generate <schematic> [options]') self._help('Usage: cpl generate <schematic> [options]')
exit() exit()
Console.write('\n')

View File

@ -35,5 +35,3 @@ class HelpService(CommandABC):
Console.write(f'\n\t{name} ') Console.write(f'\n\t{name} ')
Console.set_foreground_color(ForegroundColorEnum.default) Console.set_foreground_color(ForegroundColorEnum.default)
Console.write(f'{description}') Console.write(f'{description}')
Console.write('\n')

View File

@ -4,9 +4,9 @@ import subprocess
from packaging import version from packaging import version
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
@ -18,18 +18,18 @@ from cpl_cli.error import Error
class InstallService(CommandABC): class InstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings, project_settings: ProjectSettings, def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings, project_settings: ProjectSettings,
cli_settings: CLISettings): cli_settings: CLISettings):
""" """
Service for the CLI command install Service for the CLI command install
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
:param cli_settings: :param cli_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
self._cli_settings = cli_settings self._cli_settings = cli_settings
@ -147,7 +147,7 @@ class InstallService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2)) project_file.write(json.dumps(config, indent=2))
project_file.close() project_file.close()
@ -163,5 +163,3 @@ class InstallService(CommandABC):
self._install_project() self._install_project()
else: else:
self._install_package(args[0]) self._install_package(args[0])
Console.write('\n')

View File

@ -7,7 +7,6 @@ from packaging import version
import cpl import cpl
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
@ -20,7 +19,8 @@ from cpl_cli.configuration.version_settings_name_enum import VersionSettingsName
from cpl_cli.templates.new.console.license import LicenseTemplate from cpl_cli.templates.new.console.license import LicenseTemplate
from cpl_cli.templates.new.console.readme_py import ReadmeTemplate from cpl_cli.templates.new.console.readme_py import ReadmeTemplate
from cpl_cli.templates.new.console.src.application import ApplicationTemplate from cpl_cli.templates.new.console.src.application import ApplicationTemplate
from cpl_cli.templates.new.console.src.main import MainWithApplicationHostAndStartupTemplate, MainWithoutApplicationHostTemplate, MainWithApplicationHostTemplate from cpl_cli.templates.new.console.src.main import MainWithApplicationHostAndStartupTemplate, \
MainWithoutApplicationBaseTemplate, MainWithApplicationBaseTemplate, MainWithDependencyInjection
from cpl_cli.templates.new.console.src.startup import StartupTemplate from cpl_cli.templates.new.console.src.startup import StartupTemplate
from cpl_cli.templates.new.console.src.tests.init import TestsInitTemplate from cpl_cli.templates.new.console.src.tests.init import TestsInitTemplate
from cpl_cli.templates.template_file_abc import TemplateFileABC from cpl_cli.templates.template_file_abc import TemplateFileABC
@ -28,16 +28,15 @@ from cpl_cli.templates.template_file_abc import TemplateFileABC
class NewService(CommandABC): class NewService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, configuration: ConfigurationABC):
""" """
Service for the CLI command new Service for the CLI command new
:param configuration: :param configuration:
:param runtime:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._config = configuration self._config = configuration
self._runtime = runtime self._env = self._config.environment
self._project: ProjectSettings = ProjectSettings() self._project: ProjectSettings = ProjectSettings()
self._project_dict = {} self._project_dict = {}
@ -127,22 +126,26 @@ class NewService(CommandABC):
Gets project path Gets project path
:return: :return:
""" """
project_path = os.path.join(self._runtime.working_directory, self._project.name) project_path = os.path.join(self._env.working_directory, self._project.name)
if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0: if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0:
Console.error('Project path is not empty\n') Console.error('Project path is not empty\n')
return None return None
return project_path return project_path
def _get_project_informations(self): def _get_project_information(self):
""" """
Gets project informations from user Gets project information's from user
:return: :return:
""" """
result = Console.read('Do you want to use application host? (y/n) ') result = Console.read('Do you want to use application base? (y/n) ')
if result.lower() == 'y': if result.lower() == 'y':
self._use_application_api = True self._use_application_api = True
result = Console.read('Do you want to use service providing? (y/n) ')
if result.lower() == 'y':
self._use_service_providing = True
if self._use_application_api: if self._use_application_api:
result = Console.read('Do you want to use startup? (y/n) ') result = Console.read('Do you want to use startup? (y/n) ')
if result.lower() == 'y': if result.lower() == 'y':
@ -150,11 +153,6 @@ class NewService(CommandABC):
Console.set_foreground_color(ForegroundColorEnum.default) Console.set_foreground_color(ForegroundColorEnum.default)
# else:
# result = Console.read('Do you want to use service providing? (y/n) ')
# if result.lower() == 'y':
# self._use_service_providing = True
def _build_project_dir(self, project_path: str): def _build_project_dir(self, project_path: str):
""" """
Builds the project files Builds the project files
@ -173,15 +171,20 @@ class NewService(CommandABC):
ReadmeTemplate(), ReadmeTemplate(),
TestsInitTemplate() TestsInitTemplate()
] ]
if self._use_application_api: if self._use_application_api:
templates.append(ApplicationTemplate()) templates.append(ApplicationTemplate())
if self._use_startup: if self._use_startup:
templates.append(StartupTemplate()) templates.append(StartupTemplate())
templates.append(MainWithApplicationHostAndStartupTemplate()) templates.append(MainWithApplicationHostAndStartupTemplate())
else: else:
templates.append(MainWithApplicationHostTemplate()) templates.append(MainWithApplicationBaseTemplate())
else: else:
templates.append(MainWithoutApplicationHostTemplate()) if self._use_service_providing:
templates.append(MainWithDependencyInjection())
else:
templates.append(MainWithoutApplicationBaseTemplate())
for template in templates: for template in templates:
Console.spinner( Console.spinner(
@ -226,7 +229,7 @@ class NewService(CommandABC):
if path is None: if path is None:
return return
self._get_project_informations() self._get_project_information()
try: try:
self._build_project_dir(path) self._build_project_dir(path)
except Exception as e: except Exception as e:
@ -249,5 +252,3 @@ class NewService(CommandABC):
else: else:
self._help('Usage: cpl new <schematic> [options]') self._help('Usage: cpl new <schematic> [options]')
exit() exit()
Console.write('\n')

View File

@ -21,4 +21,3 @@ class PublishService(CommandABC):
:return: :return:
""" """
self._publisher.publish() self._publisher.publish()
Console.write('\n')

View File

@ -2,9 +2,9 @@ import json
import os import os
import subprocess import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
@ -14,17 +14,17 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UninstallService(CommandABC): class UninstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings, def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings,
project_settings: ProjectSettings): project_settings: ProjectSettings):
""" """
Service for the CLI command uninstall Service for the CLI command uninstall
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
@ -74,7 +74,7 @@ class UninstallService(CommandABC):
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings), ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2)) project_file.write(json.dumps(config, indent=2))
project_file.close() project_file.close()

View File

@ -2,9 +2,9 @@ import json
import os import os
import subprocess import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
@ -16,20 +16,20 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UpdateService(CommandABC): class UpdateService(CommandABC):
def __init__(self, def __init__(self,
runtime: ApplicationRuntimeABC, env: ApplicationEnvironmentABC,
build_settings: BuildSettings, build_settings: BuildSettings,
project_settings: ProjectSettings, project_settings: ProjectSettings,
cli_settings: CLISettings): cli_settings: CLISettings):
""" """
Service for the CLI command update Service for the CLI command update
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
:param cli_settings: :param cli_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
self._cli_settings = cli_settings self._cli_settings = cli_settings
@ -117,7 +117,7 @@ class UpdateService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project:
project.write(json.dumps(config, indent=2)) project.write(json.dumps(config, indent=2))
project.close() project.close()
@ -131,5 +131,3 @@ class UpdateService(CommandABC):
self._check_project_dependencies() self._check_project_dependencies()
self._check_outdated() self._check_outdated()
Pip.reset_executable() Pip.reset_executable()
Console.write('\n')

View File

@ -1,13 +1,11 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class CommandABC(ServiceABC): class CommandABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def run(self, args: list[str]): pass def run(self, args: list[str]): pass

View File

@ -1,25 +1,25 @@
import os import os
from abc import ABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_abc import ServiceABC from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.error import Error from cpl_cli.error import Error
from cpl_cli.command_model import CommandModel from cpl_cli.command_model import CommandModel
class CommandHandler(ServiceABC): class CommandHandler(ABC):
def __init__(self, runtime: ApplicationRuntimeABC, config: ConfigurationABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
Service to handle incoming commands and args Service to handle incoming commands and args
:param runtime: :param config:
:param services: :param services:
""" """
ServiceABC.__init__(self) ABC.__init__(self)
self._runtime = runtime
self._config = config self._config = config
self._env = self._config.environment
self._services = services self._services = services
self._commands: list[CommandModel] = [] self._commands: list[CommandModel] = []
@ -43,7 +43,7 @@ class CommandHandler(ServiceABC):
""" """
for command in self._commands: for command in self._commands:
if cmd == command.name or cmd in command.aliases: if cmd == command.name or cmd in command.aliases:
if command.is_project_needed and not os.path.isfile(os.path.join(self._runtime.working_directory, 'cpl.json')): if command.is_project_needed and not os.path.isfile(os.path.join(self._env.working_directory, 'cpl.json')):
Error.error('The command requires to be run in an CPL project, but a project could not be found.') Error.error('The command requires to be run in an CPL project, but a project could not be found.')
return return
@ -51,3 +51,4 @@ class CommandHandler(ServiceABC):
self._config.add_json_file('cpl.json', optional=True, output=False) self._config.add_json_file('cpl.json', optional=True, output=False)
self._services.get_service(command.command).run(args) self._services.get_service(command.command).run(args)
Console.write('\n')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -28,4 +28,4 @@ from .version_settings import VersionSettings
from .version_settings_name_enum import VersionSettingsNameEnum from .version_settings_name_enum import VersionSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.live_server'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,33 +1,33 @@
import os import os
import time import time
from abc import ABC
from contextlib import suppress from contextlib import suppress
import psutil as psutil import psutil as psutil
from watchdog.events import FileSystemEventHandler from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer from watchdog.observers import Observer
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection.service_abc import ServiceABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.live_server.live_server_thread import LiveServerThread from cpl_cli.live_server.live_server_thread import LiveServerThread
class LiveServerService(ServiceABC, FileSystemEventHandler): class LiveServerService(ABC, FileSystemEventHandler):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings): def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings):
""" """
Service for the live development server Service for the live development server
:param runtime: :param env:
:param build_settings: :param build_settings:
""" """
ServiceABC.__init__(self) ABC.__init__(self)
FileSystemEventHandler.__init__(self) FileSystemEventHandler.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._src_dir = os.path.join(self._runtime.working_directory, self._build_settings.source_path) self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._ls_thread = None self._ls_thread = None
self._observer = None self._observer = None

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
@ -24,4 +24,4 @@ from .publisher_abc import PublisherABC
from .publisher_service import PublisherService from .publisher_service import PublisherService
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,13 +1,11 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class PublisherABC(ServiceABC): class PublisherABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
ServiceABC.__init__(self) ABC.__init__(self)
@property @property
@abstractmethod @abstractmethod

View File

@ -7,9 +7,9 @@ import setuptools
from packaging import version from packaging import version
from setuptools import sandbox from setuptools import sandbox
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.configuration.project_settings import ProjectSettings from cpl_cli.configuration.project_settings import ProjectSettings
from cpl_cli.publish.publisher_abc import PublisherABC from cpl_cli.publish.publisher_abc import PublisherABC
@ -19,21 +19,21 @@ from cpl_cli.templates.publish.setup_template import SetupTemplate
class PublisherService(PublisherABC): class PublisherService(PublisherABC):
def __init__(self, runtime: ApplicationRuntimeABC, project: ProjectSettings, build: BuildSettings): def __init__(self, env: ApplicationEnvironmentABC, project: ProjectSettings, build: BuildSettings):
""" """
Service to build or publish files for distribution Service to build or publish files for distribution
:param runtime: :param env:
:param project: :param project:
:param build: :param build:
""" """
PublisherABC.__init__(self) PublisherABC.__init__(self)
self._runtime = runtime self._env = env
self._project_settings = project self._project_settings = project
self._build_settings = build self._build_settings = build
self._source_path = os.path.join(self._runtime.working_directory, self._build_settings.source_path) self._source_path = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._output_path = os.path.join(self._runtime.working_directory, self._build_settings.output_path) self._output_path = os.path.join(self._env.working_directory, self._build_settings.output_path)
self._included_files: list[str] = [] self._included_files: list[str] = []
self._included_dirs: list[str] = [] self._included_dirs: list[str] = []

View File

@ -1,7 +1,7 @@
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC from cpl.application.startup_abc import StartupABC
from cpl.configuration.console_argument import ConsoleArgument from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.command.build_service import BuildService from cpl_cli.command.build_service import BuildService
from cpl_cli.command.generate_service import GenerateService from cpl_cli.command.generate_service import GenerateService
@ -22,21 +22,21 @@ from cpl_cli.publish.publisher_abc import PublisherABC
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self) StartupABC.__init__(self)
self._configuration = config self._configuration = config
self._application_runtime = runtime self._env = self._configuration.environment
self._services = services self._services = services
self._application_runtime.set_runtime_directory(__file__) self._env.set_runtime_directory(__file__)
def configure_configuration(self) -> ConfigurationABC: def configure_configuration(self) -> ConfigurationABC:
self._configuration.argument_error_function = Error.error self._configuration.argument_error_function = Error.error
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_json_file('appsettings.json', path=self._application_runtime.runtime_directory, self._configuration.add_json_file('appsettings.json', path=self._env.runtime_directory,
optional=False, output=False) optional=False, output=False)
self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], '')) self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], ''))
self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[ self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[
@ -80,4 +80,4 @@ class Startup(StartupABC):
self._services.add_transient(UpdateService) self._services.add_transient(UpdateService)
self._services.add_transient(VersionService) self._services.add_transient(VersionService)
return self._services return self._services.build_service_provider()

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.build'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.generate'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -11,17 +11,16 @@ class ApplicationTemplate(TemplateFileABC):
self._name = 'application.py' self._name = 'application.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_abc import ApplicationABC from cpl.application import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC from cpl.configuration import ConfigurationABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.console import Console
from cpl.console.console import Console from cpl.dependency_injection import ServiceProviderABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class Application(ApplicationABC): class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, runtime, services) ApplicationABC.__init__(self, config, services)
def configure(self): def configure(self):
pass pass

View File

@ -11,7 +11,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_builder import ApplicationBuilder from cpl.application import ApplicationBuilder
from application import Application from application import Application
from startup import Startup from startup import Startup
@ -40,7 +40,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
return self._value return self._value
class MainWithApplicationHostTemplate(TemplateFileABC): class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self): def __init__(self):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
@ -48,7 +48,7 @@ class MainWithApplicationHostTemplate(TemplateFileABC):
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_builder import ApplicationBuilder from cpl.application import ApplicationBuilder
from application import Application from application import Application
@ -75,7 +75,7 @@ class MainWithApplicationHostTemplate(TemplateFileABC):
return self._value return self._value
class MainWithoutApplicationHostTemplate(TemplateFileABC): class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self): def __init__(self):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
@ -83,7 +83,7 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.console.console import Console from cpl.console import Console
def main(): def main():
@ -105,3 +105,49 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
@property @property
def value(self) -> str: def value(self) -> str:
return self._value return self._value
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.configuration import Configuration, ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@ -11,27 +11,25 @@ class StartupTemplate(TemplateFileABC):
self._name = 'startup.py' self._name = 'startup.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_runtime_abc import ApplicationRuntimeABC from cpl.application import StartupABC
from cpl.application.startup_abc import StartupABC from cpl.configuration import ConfigurationABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self) StartupABC.__init__(self)
self._configuration = config self._configuration = config
self._application_runtime = runtime self._environment = self._configuration.environment
self._services = services self._services = services
def configure_configuration(self) -> ConfigurationABC: def configure_configuration(self) -> ConfigurationABC:
return self._configuration return self._configuration
def configure_services(self) -> ServiceProviderABC: def configure_services(self) -> ServiceProviderABC:
return self._services return self._services.build_service_provider()
""") """)
@property @property

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src.tests'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.2'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -6,6 +6,15 @@ def test_spinner():
time.sleep(2) 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__': if __name__ == '__main__':
Console.write_line('Hello World\n') Console.write_line('Hello World\n')
Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan,
@ -25,5 +34,6 @@ if __name__ == '__main__':
# cursor_foreground_color=ForegroundColorEnum.red # cursor_foreground_color=ForegroundColorEnum.red
# ) # )
# Console.write_line(f'You selected: {selected}') # Console.write_line(f'You selected: {selected}')
# test_console()
Console.write_line() Console.write_line()

View File

@ -1,13 +0,0 @@
from cpl.console.console import Console
from model.test_model import TestModel
def main():
Console.write_line('Hello World')
Console.write_line('Dies ist ein test')
test = TestModel()
if __name__ == '__main__':
main()

View File

@ -1,22 +0,0 @@
import time
from cpl.console import Console
class TestModel:
def __init__(self):
Console.spinner('Waiting: ', self._wait, 10)
option = Console.select('->', 'Select option: ', [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6'
])
Console.write_line('You selected', option)
@staticmethod
def _wait(count: int):
time.sleep(count)

View File

@ -0,0 +1,8 @@
{
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "TRACE",
"FileLogLevel": "TRACE"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -1,6 +1,6 @@
{ {
"ProjectSettings": { "ProjectSettings": {
"Name": "cpl-test", "Name": "database",
"Version": { "Version": {
"Major": "0", "Major": "0",
"Minor": "0", "Minor": "0",
@ -16,18 +16,20 @@
"LicenseName": "", "LicenseName": "",
"LicenseDescription": "", "LicenseDescription": "",
"Dependencies": [ "Dependencies": [
"sh_cpl==2021.4.1.post13" "sh_cpl==2021.4.2.dev1"
], ],
"PythonVersion": ">=3.9.2", "PythonVersion": ">=3.9.2",
"PythonPath": "/home/sven/Nextcloud_Sven/Schreibtisch/git_sh-edraft_de/sh_common_py_lib/src/tests/custom/general/../../../../cpl-env/bin/python3.9", "PythonPath": {
"linux": ""
},
"Classifiers": [] "Classifiers": []
}, },
"BuildSettings": { "BuildSettings": {
"SourcePath": "src", "SourcePath": "src",
"OutputPath": "dist", "OutputPath": "dist",
"Main": "main", "Main": "main",
"EntryPoint": "cpl-test", "EntryPoint": "database",
"IncludePackageData": true, "IncludePackageData": false,
"Included": [], "Included": [],
"Excluded": [ "Excluded": [
"*/__pycache__", "*/__pycache__",

View File

@ -0,0 +1,36 @@
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
from model.user_repo_abc import UserRepoABC
from model.user_repo import UserRepo
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}')
user_repo: UserRepo = self._services.get_service(UserRepoABC)
user_repo.add_test_user()
Console.write_line('Users:')
for user in user_repo.get_users():
Console.write_line(user.Id, user.Name, user.City_Id, user.City.Id, user.City.Name, user.City.ZIP)
Console.write_line('Cities:')
for city in user_repo.get_cities():
Console.write_line(city.Id, city.Name, city.ZIP)

View File

@ -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()

View File

@ -0,0 +1,14 @@
from sqlalchemy import Column, Integer, String
from cpl.database import DatabaseModel
class CityModel(DatabaseModel):
__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

View File

@ -0,0 +1,8 @@
from cpl.database import DatabaseSettings
from cpl.database.context import DatabaseContext
class DBContext(DatabaseContext):
def __init__(self, db_settings: DatabaseSettings):
DatabaseContext.__init__(self, db_settings)

View File

@ -0,0 +1,18 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from cpl.database import DatabaseModel
from .city_model import CityModel
class UserModel(DatabaseModel):
__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("CityModel")
def __init__(self, name: str, city: CityModel):
self.Name = name
self.City_Id = city.Id
self.City = city

View File

@ -0,0 +1,29 @@
from cpl.database.context import DatabaseContextABC
from .city_model import CityModel
from .user_model import UserModel
from .user_repo_abc import UserRepoABC
class UserRepo(UserRepoABC):
def __init__(self, db_context: DatabaseContextABC):
UserRepoABC.__init__(self)
self._session = db_context.session
self._user_query = db_context.session.query(UserModel)
def create(self): pass
def add_test_user(self):
city = CityModel('Haren', '49733')
city2 = CityModel('Meppen', '49716')
self._session.add(city2)
user = UserModel('TestUser', city)
self._session.add(user)
self._session.commit()
def get_users(self) -> list[UserModel]:
return self._session.query(UserModel).all()
def get_cities(self) -> list[CityModel]:
return self._session.query(CityModel).all()

View File

@ -0,0 +1,12 @@
from abc import ABC, abstractmethod
from .user_model import UserModel
class UserRepoABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def get_users(self) -> list[UserModel]: pass

View File

@ -0,0 +1,39 @@
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
from model.user_repo import UserRepo
from model.user_repo_abc import UserRepoABC
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(UserRepoABC, UserRepo)
self._services.add_singleton(LoggerABC, Logger)
return self._services.build_service_provider()

View File

@ -2,19 +2,19 @@ import time
from typing import Optional from typing import Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC from cpl.mailing.email_client_abc import EMailClientABC
from tests.custom.general.test_service import TestService
class Application(ApplicationABC): class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, runtime, services) ApplicationABC.__init__(self, config, services)
self._logger: Optional[LoggerABC] = None self._logger: Optional[LoggerABC] = None
self._mailer: Optional[EMailClientABC] = None self._mailer: Optional[EMailClientABC] = None
@ -28,15 +28,6 @@ class Application(ApplicationABC):
mail.body = 'Dies ist ein Test :D' mail.body = 'Dies ist ein Test :D'
self._mailer.send_mail(mail) 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 @staticmethod
def _wait(time_ms: int): def _wait(time_ms: int):
time.sleep(time_ms) time.sleep(time_ms)
@ -50,6 +41,7 @@ class Application(ApplicationABC):
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}')
Console.spinner('Test', self._wait, 20, spinner_foreground_color='red') Console.spinner('Test', self._wait, 2, spinner_foreground_color='red')
test: TestService = self._services.get_service(TestService)
test.run()
# self.test_send_mail() # self.test_send_mail()
# self.test_console()

View File

@ -1,23 +1,20 @@
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC from cpl.application.startup_abc import StartupABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.database.context.database_context import DatabaseContext from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.database.database_settings import DatabaseSettings
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.logging.logger_service import Logger from cpl.logging.logger_service import Logger
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email_client_service import EMailClient from cpl.mailing.email_client_service import EMailClient
from cpl.mailing.email_client_abc import EMailClientABC from cpl.mailing.email_client_abc import EMailClientABC
from cpl.utils.credential_manager import CredentialManager from tests.custom.general.test_service import TestService
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self) StartupABC.__init__(self)
self._configuration = config self._configuration = config
self._application_runtime = runtime
self._services = services self._services = services
def configure_configuration(self) -> ConfigurationABC: def configure_configuration(self) -> ConfigurationABC:
@ -31,13 +28,8 @@ class Startup(StartupABC):
return self._configuration return self._configuration
def configure_services(self) -> ServiceProviderABC: 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: DatabaseContext = self._services.get_db_context()
db.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
self._services.add_singleton(LoggerABC, Logger) self._services.add_singleton(LoggerABC, Logger)
self._services.add_singleton(EMailClientABC, EMailClient) self._services.add_singleton(EMailClientABC, EMailClient)
self._services.add_singleton(TestService)
return self._services return self._services.build_service_provider()

View File

@ -0,0 +1,15 @@
from abc import ABC
from cpl.console.console import Console
from cpl.dependency_injection import ServiceProviderABC
class TestService(ABC):
def __init__(self, provider: ServiceProviderABC):
ABC.__init__(self)
self._provider = provider
def run(self):
Console.write_line('Hello World!', self._provider)

View File

View File

View File

@ -0,0 +1,41 @@
{
"ProjectSettings": {
"Name": "simple-app",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl==2021.4.2"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"SourcePath": "src",
"OutputPath": "dist",
"Main": "main",
"EntryPoint": "simple-app",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {}
}
}

View File

@ -0,0 +1,16 @@
from cpl.application import ApplicationABC
from cpl.configuration import ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')

View File

@ -0,0 +1,12 @@
from cpl.application import ApplicationBuilder
from application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()

View File

@ -0,0 +1 @@
# imports:

View File

@ -0,0 +1,41 @@
{
"ProjectSettings": {
"Name": "simple-console",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl==2021.4.2"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"SourcePath": "src",
"OutputPath": "dist",
"Main": "main",
"EntryPoint": "simple-console",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {}
}
}

View File

@ -0,0 +1,9 @@
from cpl.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()

View File

@ -0,0 +1 @@
# imports:

View File

Some files were not shown because too many files have changed in this diff Show More