WIP: dev into master #184

Draft
edraft wants to merge 121 commits from dev into master
26 changed files with 90 additions and 177 deletions
Showing only changes of commit 58dbd3ed1e - Show all commits

View File

@@ -1,6 +1,6 @@
from abc import ABC, abstractmethod
from cpl.dependency.service_collection_abc import ServiceCollectionABC
from cpl.dependency.service_collection import ServiceCollection
class AsyncStartupABC(ABC):
@@ -15,9 +15,9 @@ class AsyncStartupABC(ABC):
r"""Creates configuration of application"""
@abstractmethod
async def configure_services(self, service: ServiceCollectionABC):
async def configure_services(self, service: ServiceCollection):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection_abc`
services: :class:`cpl.dependency.service_collection`
"""

View File

@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from cpl.core.configuration.configuration import Configuration
from cpl.dependency.service_collection_abc import ServiceCollectionABC
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment.environment import Environment
@@ -22,10 +22,10 @@ class AsyncStartupExtensionABC(ABC):
"""
@abstractmethod
async def configure_services(self, service: ServiceCollectionABC, env: Environment):
async def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection_abc`
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from cpl.core.configuration import Configuration
from cpl.dependency.service_collection_abc import ServiceCollectionABC
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment import Environment
@@ -22,10 +22,10 @@ class StartupABC(ABC):
"""
@abstractmethod
def configure_services(self, service: ServiceCollectionABC, env: Environment):
def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection_abc`
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
from cpl.core.configuration import Configuration
from cpl.dependency.service_collection_abc import ServiceCollectionABC
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment.environment import Environment
@@ -24,10 +24,10 @@ class StartupExtensionABC(ABC):
"""
@abstractmethod
def configure_services(self, service: ServiceCollectionABC, env: Environment):
def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection_abc`
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -1,3 +1,23 @@
from .database_settings_name_enum import DatabaseSettingsNameEnum
from cpl.dependency import ServiceCollection as _ServiceCollection
from . import mysql
from .database_settings import DatabaseSettings
from .database_settings_name_enum import DatabaseSettingsNameEnum
from .mysql.context import DatabaseContextABC, DatabaseContext
from .table_abc import TableABC
def add_mysql(collection: _ServiceCollection):
from cpl.core.console import Console
from cpl.core.configuration import Configuration
try:
collection.add_singleton(DatabaseContextABC, DatabaseContext)
database_context = collection.build_service_provider().get_service(DatabaseContextABC)
db_settings: DatabaseSettings = Configuration.get(DatabaseSettings)
database_context.connect(db_settings)
except ImportError as e:
Console.error("cpl-translation is not installed", str(e))
_ServiceCollection.with_module(add_mysql, mysql.__name__)

View File

@@ -4,7 +4,7 @@ import mysql.connector as sql
from mysql.connector.abstracts import MySQLConnectionAbstract
from mysql.connector.cursor import MySQLCursorBuffered
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.mysql.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.database_settings import DatabaseSettings
from cpl.core.utils.credential_manager import CredentialManager

View File

@@ -1,9 +1,9 @@
from typing import Optional
from cpl.database.connection.database_connection import DatabaseConnection
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.database.mysql.connection.database_connection import DatabaseConnection
from cpl.database.mysql.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.mysql.context.database_context_abc import DatabaseContextABC
from cpl.database.database_settings import DatabaseSettings
from mysql.connector.cursor import MySQLCursorBuffered

View File

@@ -1,7 +1,6 @@
from .scope import Scope
from .scope_abc import ScopeABC
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

View File

@@ -1,24 +1,26 @@
from typing import Union, Type, Callable, Optional
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.database.database_settings import DatabaseSettings
from cpl.dependency.service_collection_abc import ServiceCollectionABC
from cpl.dependency.service_descriptor import ServiceDescriptor
from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum
from cpl.dependency.service_provider import ServiceProvider
from cpl.dependency.service_provider_abc import ServiceProviderABC
from cpl.core.log.logger import Logger
from cpl.core.log.logger_abc import LoggerABC
from cpl.core.pipes.pipe_abc import PipeABC
from cpl.core.typing import T, Service
from cpl.dependency.service_descriptor import ServiceDescriptor
from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum
from cpl.dependency.service_provider import ServiceProvider
from cpl.dependency.service_provider_abc import ServiceProviderABC
class ServiceCollection(ServiceCollectionABC):
class ServiceCollection:
r"""Representation of the collection of services"""
_modules: dict[str, Callable] = {}
@classmethod
def with_module(cls, func: Callable, name: str = None):
cls._modules[func.__name__ if name is None else name] = func
return cls
def __init__(self):
ServiceCollectionABC.__init__(self)
self._database_context: Optional[DatabaseContextABC] = None
self._service_descriptors: list[ServiceDescriptor] = []
def _add_descriptor(self, service: Union[type, object], lifetime: ServiceLifetimeEnum, base_type: Callable = None):
@@ -44,10 +46,19 @@ class ServiceCollection(ServiceCollectionABC):
return self
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
self.add_singleton(DatabaseContextABC, db_context_type)
self._database_context = self.build_service_provider().get_service(DatabaseContextABC)
self._database_context.connect(db_settings)
def add_module(self, module: str | object):
if not isinstance(module, str):
module = module.__name__
if module not in self._modules:
raise ValueError(f"Module {module} not found")
self._modules[module](self)
# def add_mysql(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
# self.add_singleton(DatabaseContextABC, db_context_type)
# self._database_context = self.build_service_provider().get_service(DatabaseContextABC)
# self._database_context.connect(db_settings)
def add_logging(self):
self.add_transient(LoggerABC, Logger)
@@ -71,6 +82,6 @@ class ServiceCollection(ServiceCollectionABC):
return self
def build_service_provider(self) -> ServiceProviderABC:
sp = ServiceProvider(self._service_descriptors, self._database_context)
sp = ServiceProvider(self._service_descriptors)
ServiceProviderABC.set_global_provider(sp)
return sp

View File

@@ -1,90 +0,0 @@
from abc import abstractmethod, ABC
from typing import Type
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.database.database_settings import DatabaseSettings
from cpl.dependency.service_provider_abc import ServiceProviderABC
from cpl.core.typing import T, Source
class ServiceCollectionABC(ABC):
r"""ABC for the class :class:`cpl.dependency.service_collection.ServiceCollection`"""
@abstractmethod
def __init__(self):
pass
@abstractmethod
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
r"""Adds database context
Parameter:
db_context: Type[:class:`cpl.database.context.database_context_abc.DatabaseContextABC`]
Database context
"""
@abstractmethod
def add_logging(self):
r"""Adds the CPL internal logger"""
@abstractmethod
def add_pipes(self):
r"""Adds the CPL internal pipes as transient"""
def add_translation(self):
r"""Adds the CPL translation"""
raise NotImplementedError("You should install and use the cpl-translation package")
def add_mail(self):
r"""Adds the CPL mail"""
raise NotImplementedError("You should install and use the cpl-mail package")
@abstractmethod
def add_transient(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
r"""Adds a service with transient lifetime
Parameter:
service_type: :class:`Type`
Type of the service
service: :class:`Callable`
Object of the service
Returns:
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
"""
@abstractmethod
def add_scoped(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
r"""Adds a service with scoped lifetime
Parameter:
service_type: :class:`Type`
Type of the service
service: :class:`Callable`
Object of the service
Returns:
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
"""
@abstractmethod
def add_singleton(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
r"""Adds a service with singleton lifetime
Parameter:
service_type: :class:`Type`
Type of the service
service: :class:`Callable`
Object of the service
Returns:
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
"""
@abstractmethod
def build_service_provider(self) -> ServiceProviderABC:
r"""Creates instance of the service provider
Returns:
Object of type :class:`cpl.dependency.service_provider_abc.ServiceProviderABC`
"""

View File

@@ -5,7 +5,6 @@ from typing import Optional
from cpl.core.configuration import Configuration
from cpl.core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.core.environment import Environment
from cpl.core.typing import T, R, Source
from cpl.dependency.scope_abc import ScopeABC
@@ -31,12 +30,10 @@ class ServiceProvider(ServiceProviderABC):
def __init__(
self,
service_descriptors: list[ServiceDescriptor],
db_context: Optional[DatabaseContextABC],
):
ServiceProviderABC.__init__(self)
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
self._database_context = db_context
self._scope: Optional[ScopeABC] = None
def _find_service(self, service_type: type) -> Optional[ServiceDescriptor]:
@@ -95,9 +92,6 @@ class ServiceProvider(ServiceProviderABC):
elif issubclass(parameter.annotation, Environment):
params.append(Environment)
elif issubclass(parameter.annotation, DatabaseContextABC):
params.append(self._database_context)
elif issubclass(parameter.annotation, ConfigurationModelABC):
params.append(Configuration.get(parameter.annotation))

View File

@@ -1,3 +1,4 @@
from cpl.dependency import ServiceCollection as _ServiceCollection
from .abc.email_client_abc import EMailClientABC
from .email_client import EMailClient
from .email_client_settings import EMailClientSettings
@@ -6,21 +7,15 @@ from .email_model import EMail
from .mail_logger import MailLogger
def add_mail(self):
def add_mail(collection: _ServiceCollection):
from cpl.core.console import Console
from cpl.core.log import LoggerABC
try:
self.add_singleton(EMailClientABC, EMailClient)
self.add_transient(LoggerABC, MailLogger)
collection.add_singleton(EMailClientABC, EMailClient)
collection.add_transient(LoggerABC, MailLogger)
except ImportError as e:
Console.error("cpl-translation is not installed", str(e))
def init():
from cpl.dependency import ServiceCollection
ServiceCollection.add_mail = add_mail
init()
_ServiceCollection.with_module(add_mail, __name__)

View File

@@ -1,10 +1,11 @@
from cpl.dependency import ServiceCollection as _ServiceCollection
from .translate_pipe import TranslatePipe
from .translation_service import TranslationService
from .translation_service_abc import TranslationServiceABC
from .translation_settings import TranslationSettings
def add_translation(self):
def add_translation(collection: _ServiceCollection):
from cpl.core.console import Console
from cpl.core.pipes import PipeABC
from cpl.translation.translate_pipe import TranslatePipe
@@ -12,16 +13,10 @@ def add_translation(self):
from cpl.translation.translation_service_abc import TranslationServiceABC
try:
self.add_singleton(TranslationServiceABC, TranslationService)
self.add_transient(PipeABC, TranslatePipe)
collection.add_singleton(TranslationServiceABC, TranslationService)
collection.add_transient(PipeABC, TranslatePipe)
except ImportError as e:
Console.error("cpl-translation is not installed", str(e))
def init():
from cpl.dependency import ServiceCollection
ServiceCollection.add_translation = add_translation
init()
_ServiceCollection.with_module(add_translation, __name__)

View File

@@ -1,6 +1,6 @@
from cpl.application.async_startup_abc import AsyncStartupABC
from cpl.core.configuration import ConfigurationABC
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
from cpl.dependency import ServiceProviderABC, ServiceCollection
from cpl.core.environment import Environment
@@ -13,5 +13,5 @@ class Startup(AsyncStartupABC):
) -> ConfigurationABC:
return configuration
async def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
async def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
return services.build_service_provider()

View File

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

View File

@@ -1,5 +1,5 @@
from cpl.core.console import Console
from cpl.database.context import DatabaseContextABC
from cpl.database.mysql.context import DatabaseContextABC
from .city_model import CityModel
from .user_model import UserModel

View File

@@ -1,11 +1,9 @@
from cpl.application import StartupABC
from cpl.core.configuration import Configuration
from cpl.database import DatabaseSettings
from cpl.dependency import ServiceCollectionABC, ServiceProviderABC
from cpl.core.environment import Environment
from cpl.core.log import Logger, LoggerABC
from model.db_context import DBContext
from cpl.database import mysql
from cpl.dependency import ServiceCollection
from model.user_repo import UserRepo
from model.user_repo_abc import UserRepoABC
@@ -23,11 +21,8 @@ class Startup(StartupABC):
self._configuration = configuration
def configure_services(self, services: ServiceCollectionABC, environment: Environment):
# Create and connect to database
db_settings: DatabaseSettings = self._configuration.get(DatabaseSettings)
services.add_db_context(DBContext, db_settings)
def configure_services(self, services: ServiceCollection, environment: Environment):
services.add_module(mysql)
services.add_singleton(UserRepoABC, UserRepo)
services.add_singleton(LoggerABC, Logger)

View File

@@ -1,6 +1,6 @@
from cpl.application import StartupABC
from cpl.core.configuration import ConfigurationABC
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
from cpl.dependency import ServiceProviderABC, ServiceCollection
from cpl.core.environment import Environment
from di.test1_service import Test1Service
from di.test2_service import Test2Service
@@ -17,7 +17,7 @@ class Startup(StartupABC):
def configure_configuration(self, configuration: ConfigurationABC, environment: Environment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
services.add_scoped(TestService)
services.add_scoped(DITesterService)

View File

@@ -1,6 +1,7 @@
from cpl import mail
from cpl.application import StartupABC
from cpl.core.configuration import Configuration
from cpl.dependency import ServiceCollectionABC, ServiceProviderABC
from cpl.dependency import ServiceCollection, ServiceProviderABC
from cpl.core.environment import Environment
from cpl.core.pipes import IPAddressPipe
from test_service import TestService
@@ -15,8 +16,8 @@ class Startup(StartupABC):
config.add_json_file(f"appsettings.{env.get_environment()}.json")
config.add_json_file(f"appsettings.{env.get_host_name()}.json", optional=True)
def configure_services(self, services: ServiceCollectionABC, env: Environment):
def configure_services(self, services: ServiceCollection, env: Environment):
services.add_logging()
services.add_mail()
services.add_module(mail)
services.add_transient(IPAddressPipe)
services.add_singleton(TestService)

View File

@@ -1,7 +1,7 @@
from cpl.application import StartupExtensionABC
from cpl.core.configuration import Configuration
from cpl.core.console import Console
from cpl.dependency import ServiceCollectionABC
from cpl.dependency import ServiceCollection
from cpl.core.environment import Environment
@@ -12,5 +12,5 @@ class TestStartupExtension(StartupExtensionABC):
def configure_configuration(self, config: Configuration, env: Environment):
Console.write_line("config")
def configure_services(self, services: ServiceCollectionABC, env: Environment):
def configure_services(self, services: ServiceCollection, env: Environment):
Console.write_line("services")

View File

@@ -1,6 +1,6 @@
from cpl.application import StartupABC
from cpl.core.configuration import ConfigurationABC
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
from cpl.dependency import ServiceProviderABC, ServiceCollection
from cpl.core.environment import Environment
@@ -12,6 +12,6 @@ class Startup(StartupABC):
configuration.add_json_file("appsettings.json")
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
services.add_translation()
return services.build_service_provider()